eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/eap_am_type_aka_symbian.cpp
changeset 0 c8830336c852
child 2 1c7bc153c08e
equal deleted inserted replaced
-1:000000000000 0:c8830336c852
       
     1 /*
       
     2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  EAP and WLAN authentication protocols.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // This is enumeration of EAPOL source code.
       
    20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    21 	#undef EAP_FILE_NUMBER_ENUM
       
    22 	#define EAP_FILE_NUMBER_ENUM 604 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 // INCLUDE FILES
       
    28 
       
    29 #include "eap_tools.h"
       
    30 #include "eap_am_type_aka_symbian.h"
       
    31 #include "eap_am_tools_symbian.h"
       
    32 #include "eap_state_notification.h"
       
    33 #include "EapAkaDbDefaults.h"
       
    34 #include "EapAkaDbParameterNames.h"
       
    35 #include "EapAkaDbUtils.h"
       
    36 #include "eap_am_trace_symbian.h"
       
    37 
       
    38 #include <d32dbms.h>	// For DBMS
       
    39 #include <s32strm.h> 	// For RReadStream
       
    40 
       
    41 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
    42 // These are needed only for the server and test environment (Plugin tester)
       
    43 // Enable USE_EAP_TYPE_SERVER_AKA in eapol.mmh to build for test environment.
       
    44 #include "eap_crypto_api.h"
       
    45 #include "eap_am_aka_milenage_algorithm.h"
       
    46 #endif // #if defined (USE_EAP_TYPE_SERVER_AKA)
       
    47 
       
    48 #if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
    49 	#include "EapAkaInterface.h"	
       
    50 #endif // End of #if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
    51 
       
    52 // This is needed for cf_str_EAP_AKA_2_digit_mnc_map_of_mcc_of_imsi_array.
       
    53 #include "eap_type_aka_types.h"
       
    54 
       
    55 const TUint AKA_IMSI_LENGTH = 15u;
       
    56 const TUint KMaxSqlQueryLength = 512;
       
    57 const TUint KMaxDBFieldNameLength = 255;
       
    58 const TInt 	KDefaultColumnInView_One = 1; // For DB view.
       
    59 const TInt 	KMicroSecsInASecond = 1000000; // 1000000 micro seconds is 1 second.
       
    60 
       
    61 const u8_t EAP_AKA_DEFAULT_REAUTHENTICATION_REALM[] = "dymmy.reauth.org";
       
    62 const u32_t EAP_AKA_DEFAULT_REAUTHENTICATION_REALM_LENGTH = sizeof(EAP_AKA_DEFAULT_REAUTHENTICATION_REALM)-1ul;
       
    63 
       
    64 #if defined (USE_EAP_TYPE_SERVER_AKA) || defined(__WINS__)
       
    65 
       
    66 const char TEST_IMSI[] = "244070100000001";
       
    67 
       
    68 #endif
       
    69 
       
    70 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
    71 // For the server side.
       
    72 
       
    73 struct eap_aka_encryption_imsi_block_s
       
    74 {
       
    75 	u8_t id_type:1;
       
    76 	u8_t imsi_length:7;
       
    77 	u8_t imsi_and_padding[AKA_IMSI_LENGTH];
       
    78 };
       
    79 
       
    80 struct eap_aka_pseudonym_s
       
    81 {
       
    82 	u32_t encryption_key_index;
       
    83 	union _IV
       
    84 	{
       
    85 		u8_t IV_8[EAP_AES_BLOCK_SIZE];
       
    86 		u32_t IV_32[EAP_AES_BLOCK_SIZE/sizeof(u32_t)];
       
    87 	} encryption_IV;
       
    88 
       
    89 	eap_aka_encryption_imsi_block_s imsi_block;
       
    90 
       
    91 	u8_t MAC[HMAC_SHA1_128_SIZE];
       
    92 };
       
    93 
       
    94 const u32_t ENCRYPTION_KEY_INDEX_SCRAMBLE_CONST = 0xa7b3c922;
       
    95 
       
    96 #endif //#if defined (USE_EAP_TYPE_SERVER_AKA)
       
    97 
       
    98 // ================= MEMBER FUNCTIONS =======================
       
    99 
       
   100 
       
   101 eap_am_type_aka_symbian_c::eap_am_type_aka_symbian_c(
       
   102 	abs_eap_am_tools_c * const tools,
       
   103 	abs_eap_base_type_c * const partner,
       
   104 	const TIndexType aIndexType,
       
   105 	const TInt aIndex,
       
   106 	const eap_type_value_e aTunnelingType,
       
   107 	const bool aIsClient,
       
   108 	const eap_am_network_id_c * const receive_network_id)
       
   109 : eap_am_type_aka_c(tools)
       
   110 , m_am_tools(static_cast<eap_am_tools_symbian_c*>(tools)) // Tools class must be of type eap_am_tools_symbian because
       
   111 														  // this is Symbian specific code.
       
   112 , m_partner(partner)
       
   113 , m_nai_realm(tools)
       
   114 , m_index_type(aIndexType)
       
   115 , m_index(aIndex)
       
   116 , m_tunneling_type(aTunnelingType)
       
   117 , m_is_valid(false)
       
   118 , m_is_client(aIsClient)
       
   119 , m_stored_reauth_id(tools)
       
   120 , m_stored_pseudonym(tools)
       
   121 , m_previous_imsi(tools)
       
   122 , m_stored_required_completion(eap_type_aka_complete_none)
       
   123 , m_stored_received_eap_identifier(0)
       
   124 , m_shutdown_was_called(false)
       
   125 , m_aka_algorithm(0)
       
   126 , m_aka_if(0)
       
   127 , m_simulator_aka_K(tools)
       
   128 , m_simulator_aka_OP(tools)
       
   129 , m_simulator_aka_AMF(tools)
       
   130 , m_authentication_vector(0)
       
   131 , m_pseudonym_identity(tools)
       
   132 , m_reauthentication_identity(tools)
       
   133 , m_username(tools)
       
   134 , m_receive_network_id(tools)
       
   135 , m_IMSI(tools)
       
   136 , m_required_identity(aka_payload_NONE)
       
   137 , m_required_completion(eap_type_aka_complete_none)
       
   138 , m_identity_type(AKA_IDENTITY_TYPE_NONE)
       
   139 , m_completion_action(eap_type_aka_complete_none)
       
   140 , m_next_eap_identifier(0)
       
   141 , m_aka_authentication_vector_status(eap_aka_authentication_vector_status_ok)
       
   142 , m_pseudonym_key_index(0u)
       
   143 , m_pseudonym_key(tools)
       
   144 , m_pseudonym_MAC_key(tools)
       
   145 , m_prev_pseudonym_key(tools)
       
   146 , m_prev_pseudonym_MAC_key(tools)
       
   147 , m_pseudonym_key_use_count(0u)
       
   148 , m_RAND(tools)
       
   149 , m_AUTN(tools)
       
   150 , m_max_session_time(0)
       
   151 {
       
   152 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   153 
       
   154 #ifdef USE_EAP_EXPANDED_TYPES
       
   155 
       
   156 	m_tunneling_vendor_type = m_tunneling_type.get_vendor_type();
       
   157 
       
   158 #else
       
   159 
       
   160 	m_tunneling_vendor_type = static_cast<TUint>(m_tunneling_type);
       
   161 
       
   162 #endif //#ifdef USE_EAP_EXPANDED_TYPES
       
   163 
       
   164 	if (receive_network_id != 0
       
   165 		&& receive_network_id->get_is_valid_data() == true)
       
   166 	{
       
   167 		eap_status_e status = m_receive_network_id.set_copy_of_network_id(
       
   168 			receive_network_id);
       
   169 		if (status != eap_status_ok)
       
   170 		{
       
   171 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   172 			(void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   173 			return;
       
   174 		}
       
   175 	}
       
   176 
       
   177 	set_is_valid();
       
   178 
       
   179 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   180 }
       
   181 
       
   182 
       
   183 //--------------------------------------------------
       
   184 
       
   185 void eap_am_type_aka_symbian_c::ConstructL()
       
   186 {
       
   187 
       
   188 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
   189 
       
   190 	// For the server.
       
   191 	m_aka_algorithm = new eap_am_aka_milenage_algorithm_c(m_am_tools, m_is_client);
       
   192 	if (m_aka_algorithm == 0
       
   193 		|| m_aka_algorithm->get_is_valid() == false)
       
   194 	{
       
   195 		if (m_aka_algorithm != 0)
       
   196 		{
       
   197 			m_aka_algorithm->shutdown();
       
   198 		}
       
   199 		delete m_aka_algorithm;
       
   200 		m_aka_algorithm = 0;
       
   201 		return;
       
   202 	}
       
   203 #endif // #if defined (USE_EAP_TYPE_SERVER_AKA)	
       
   204 
       
   205 	// Open/create database
       
   206 	EapAkaDbUtils::OpenDatabaseL(m_database, m_session, m_index_type, m_index, m_tunneling_type);	
       
   207 		
       
   208 	// SIM IMSI, RES, CK, IK and AUTS are queried from SIM using AKA interface. 
       
   209 	// If this is not used then Nokia test algorithms and test values are used.
       
   210 #if defined (USE_EAP_AKA_INTERFACE)	&& !defined(__WINS__)
       
   211 	if (m_is_client == true)
       
   212 	{
       
   213 		m_aka_if = CEapAkaInterface::NewL(m_am_tools, this);
       
   214 	} 
       
   215 	else
       
   216 	{
       
   217 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAP-AKA server does not work at the moment in plugintester.\n")));
       
   218 		User::Leave(KErrNotSupported);
       
   219 	}
       
   220 #endif //#if defined (USE_EAP_AKA_INTERFACE)	&& !defined(__WINS__)
       
   221 }
       
   222 
       
   223 //--------------------------------------------------
       
   224 
       
   225 eap_am_type_aka_symbian_c* eap_am_type_aka_symbian_c::NewL(
       
   226 	abs_eap_am_tools_c * const aTools,
       
   227 	abs_eap_base_type_c * const aPartner,
       
   228 	const TIndexType aIndexType,
       
   229 	const TInt aIndex,
       
   230 	const eap_type_value_e aTunnelingType,
       
   231 	const bool aIsClient,
       
   232 	const eap_am_network_id_c * const receive_network_id)
       
   233 {
       
   234 	eap_am_type_aka_symbian_c* self = new(ELeave) eap_am_type_aka_symbian_c(
       
   235 		aTools, 
       
   236 		aPartner, 
       
   237 		aIndexType, 
       
   238 		aIndex, 
       
   239 		aTunnelingType,
       
   240 		aIsClient,
       
   241 		receive_network_id);
       
   242 		
       
   243 	CleanupStack::PushL(self);
       
   244 	
       
   245 	self->ConstructL();
       
   246 
       
   247 	if (self->get_is_valid() != true)
       
   248 	{
       
   249 		User::Leave(KErrGeneral);
       
   250 	}
       
   251 	
       
   252 	CleanupStack::Pop();
       
   253 	return self;
       
   254 }
       
   255 
       
   256 //--------------------------------------------------
       
   257 
       
   258 EAP_FUNC_EXPORT eap_am_type_aka_symbian_c::~eap_am_type_aka_symbian_c()
       
   259 {
       
   260 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   261 
       
   262 	EAP_TRACE_DEBUG(
       
   263 		m_am_tools, 
       
   264 		TRACE_FLAGS_DEFAULT, 
       
   265 		(EAPL("eap_am_type_aka_symbian_c::~eap_am_type_aka_symbian_c(): this = 0x%08x\n"),
       
   266 		this));
       
   267 
       
   268 	m_database.Close();
       
   269 	m_session.Close();
       
   270 
       
   271 #if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
   272 	if (m_is_client == true)
       
   273 	{
       
   274 		delete m_aka_if;
       
   275 	}
       
   276 #endif
       
   277 
       
   278 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   279 }
       
   280 
       
   281 //--------------------------------------------------
       
   282 
       
   283 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::configure()
       
   284 {
       
   285 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   286 
       
   287 	{
       
   288 		eap_status_e status = type_configure_read(
       
   289 			cf_str_EAP_AKA_manual_realm.get_field(),
       
   290 			&m_nai_realm);
       
   291 		if (status == eap_status_ok
       
   292 			&& m_nai_realm.get_is_valid_data() == true)
       
   293 		{
       
   294 			// OK NAI realm configured.
       
   295 		}
       
   296 		else
       
   297 		{
       
   298 			// No NAI realm configured.
       
   299 			// Lets use dummy.
       
   300 			status = m_nai_realm.set_copy_of_buffer(EAP_AKA_DEFAULT_REAUTHENTICATION_REALM,
       
   301 				EAP_AKA_DEFAULT_REAUTHENTICATION_REALM_LENGTH);
       
   302 			if (status != eap_status_ok)
       
   303 			{
       
   304 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   305 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   306 			}
       
   307 		}
       
   308 	}
       
   309 
       
   310 	{
       
   311 		// Read Maximum Session Validity Time from the config file
       
   312 		eap_variable_data_c sessionTimeFromFile(m_am_tools);
       
   313 		
       
   314 		eap_status_e status = m_partner->read_configure(
       
   315 			cf_str_EAP_AKA_max_session_validity_time.get_field(),
       
   316 			&sessionTimeFromFile);
       
   317 		
       
   318 		if (status == eap_status_ok
       
   319 			&& sessionTimeFromFile.get_is_valid_data() == true
       
   320 			&& sessionTimeFromFile.get_data_length() == sizeof(u32_t))
       
   321 		{
       
   322 			u32_t *session = reinterpret_cast<u32_t *>(sessionTimeFromFile.get_data());
       
   323 			if (session != 0)
       
   324 			{
       
   325 				// Update the max session time (in micro seconds).
       
   326 				// configuration file saves the time in seconds. We have to convert it to micro seconds.
       
   327 				m_max_session_time = static_cast<TInt64>(*session) * static_cast<TInt64>(KMicroSecsInASecond);
       
   328 			}
       
   329 		}		
       
   330 	}
       
   331 
       
   332 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
   333 
       
   334 	// We have to set the values for K, OP and AMF in simulator.
       
   335 	
       
   336 	{
       
   337 		eap_status_e status = m_partner->read_configure(
       
   338 			cf_str_EAP_AKA_simulator_aka_k.get_field(),
       
   339 			&m_simulator_aka_K);
       
   340 		if (status == eap_status_ok
       
   341 			&& m_simulator_aka_K.get_is_valid_data() == true
       
   342 			&& m_simulator_aka_K.get_data_length() > 0ul
       
   343 			&& m_simulator_aka_K.get_data(
       
   344 				m_simulator_aka_K.get_data_length()) != 0)
       
   345 		{
       
   346 			// OK.
       
   347 			eap_status_e status = m_aka_algorithm->set_simulator_aka_k(&m_simulator_aka_K);
       
   348 			if (status != eap_status_ok)
       
   349 			{
       
   350 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   351 			}
       
   352 		}
       
   353 		else
       
   354 		{
       
   355 			EAP_TRACE_DEBUG(
       
   356 				m_am_tools,
       
   357 				TRACE_FLAGS_DEFAULT,
       
   358 				(EAPL("ERROR: illegal configuration value %s\n"),
       
   359 				 cf_str_EAP_AKA_simulator_aka_k.get_field()->get_field()));
       
   360 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   361 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
   362 		}
       
   363 	}
       
   364 
       
   365 	{
       
   366 		eap_status_e status = m_partner->read_configure(
       
   367 			cf_str_EAP_AKA_simulator_aka_op.get_field(),
       
   368 			&m_simulator_aka_OP);
       
   369 		if (status == eap_status_ok
       
   370 			&& m_simulator_aka_OP.get_is_valid_data() == true
       
   371 			&& m_simulator_aka_OP.get_data_length() > 0ul
       
   372 			&& m_simulator_aka_OP.get_data(
       
   373 				m_simulator_aka_OP.get_data_length()) != 0)
       
   374 		{
       
   375 			// OK.
       
   376 			eap_status_e status = m_aka_algorithm->set_simulator_aka_op(&m_simulator_aka_OP);
       
   377 			if (status != eap_status_ok)
       
   378 			{
       
   379 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   380 			}
       
   381 		}
       
   382 		else
       
   383 		{
       
   384 			EAP_TRACE_DEBUG(
       
   385 				m_am_tools,
       
   386 				TRACE_FLAGS_DEFAULT,
       
   387 				(EAPL("ERROR: illegal configuration value %s\n"),
       
   388 				 cf_str_EAP_AKA_simulator_aka_op.get_field()->get_field()));
       
   389 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   390 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
   391 		}
       
   392 	}
       
   393 
       
   394 	{
       
   395 		eap_status_e status = m_partner->read_configure(
       
   396 			cf_str_EAP_AKA_simulator_aka_amf.get_field(),
       
   397 			&m_simulator_aka_AMF);
       
   398 		if (status == eap_status_ok
       
   399 			&& m_simulator_aka_AMF.get_is_valid_data() == true
       
   400 			&& m_simulator_aka_AMF.get_data_length() == sizeof(u16_t)
       
   401 			&& m_simulator_aka_AMF.get_data(
       
   402 				m_simulator_aka_AMF.get_data_length()) != 0)
       
   403 		{
       
   404 			// OK.
       
   405 			eap_status_e status = m_aka_algorithm->set_simulator_aka_amf(&m_simulator_aka_AMF);
       
   406 			if (status != eap_status_ok)
       
   407 			{
       
   408 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   409 			}
       
   410 		}
       
   411 		else
       
   412 		{
       
   413 			EAP_TRACE_DEBUG(
       
   414 				m_am_tools,
       
   415 				TRACE_FLAGS_DEFAULT,
       
   416 				(EAPL("ERROR: illegal configuration value %s\n"),
       
   417 				 cf_str_EAP_AKA_simulator_aka_amf.get_field()->get_field()));
       
   418 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   419 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
   420 		}
       
   421 	}	
       
   422 
       
   423 	if (m_pseudonym_key.get_is_valid_data() == false)
       
   424 	{
       
   425 		crypto_aes_c aes(m_am_tools);
       
   426 
       
   427 		if (aes.get_is_valid() == false)
       
   428 		{
       
   429 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   430 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   431 		}
       
   432 
       
   433 		// Note this function generates cryptographically strong random bytes.
       
   434 		// Here we use those bytes as a secret encryption key.
       
   435 		eap_status_e status = generate_encryption_IV(
       
   436 			&m_pseudonym_key,
       
   437 			aes.get_block_size());
       
   438 		if (status != eap_status_ok)
       
   439 		{
       
   440 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   441 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   442 		}
       
   443 
       
   444 		status = generate_encryption_IV(
       
   445 			&m_pseudonym_MAC_key,
       
   446 			aes.get_block_size());
       
   447 		if (status != eap_status_ok)
       
   448 		{
       
   449 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   450 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   451 		}
       
   452 		
       
   453 		++m_pseudonym_key_index;
       
   454 	}
       
   455 
       
   456 #endif // #if defined (USE_EAP_TYPE_SERVER_AKA)
       
   457 
       
   458 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   459 	return eap_status_ok;
       
   460 	
       
   461 }
       
   462 
       
   463 //--------------------------------------------------
       
   464 
       
   465 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::reset()
       
   466 {
       
   467 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   468 
       
   469 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   470 	return eap_status_ok;
       
   471 }
       
   472 
       
   473 //--------------------------------------------------
       
   474 
       
   475 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::shutdown()
       
   476 {
       
   477 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   478 
       
   479 	EAP_TRACE_DEBUG(
       
   480 		m_am_tools,
       
   481 		TRACE_FLAGS_DEFAULT,
       
   482 		(EAPL("%s: eap_am_type_aka_symbian_c::shutdown(), m_shutdown_was_called=%d\n"),
       
   483 		(m_is_client == true) ? "client": "server",
       
   484 		m_shutdown_was_called));
       
   485 
       
   486 	if (m_shutdown_was_called == true)
       
   487 	{
       
   488 		// Shutdown function was called already.
       
   489 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   490 	}
       
   491 	m_shutdown_was_called = true;
       
   492 	
       
   493 	
       
   494 	if (m_aka_algorithm != 0)
       
   495 	{
       
   496 		m_aka_algorithm->shutdown();
       
   497 		delete m_aka_algorithm;
       
   498 		m_aka_algorithm = 0;
       
   499 	}	
       
   500 
       
   501 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   502 	return eap_status_ok;
       
   503 }
       
   504 
       
   505 //--------------------------------------------------
       
   506 
       
   507 void eap_am_type_aka_symbian_c::send_error_notification(const eap_status_e error)
       
   508 {
       
   509 	// Here we swap the addresses.
       
   510 	eap_am_network_id_c send_network_id(m_am_tools,
       
   511 		m_receive_network_id.get_destination_id(),
       
   512 		m_receive_network_id.get_source_id(),
       
   513 		m_receive_network_id.get_type());
       
   514 
       
   515 	// Notifies the lower level of an authentication error.
       
   516 	eap_state_notification_c notification(
       
   517 		m_am_tools,
       
   518 		&send_network_id,
       
   519 		m_is_client,
       
   520 		eap_state_notification_eap,
       
   521 		eap_protocol_layer_general,
       
   522 		eap_type_aka,
       
   523 		eap_state_none,
       
   524 		eap_general_state_authentication_error,
       
   525 		0,
       
   526 		false);
       
   527 
       
   528 	notification.set_authentication_error(error);
       
   529 
       
   530 	m_partner->state_notification(&notification);
       
   531 }
       
   532 
       
   533 //--------------------------------------------------
       
   534 
       
   535 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::store_pseudonym_id(
       
   536 	const eap_am_network_id_c * const send_network_id,
       
   537 	const eap_variable_data_c * const pseudonym)
       
   538 {
       
   539 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   540 
       
   541 	// Send error if the pseudonym is too long.
       
   542 	if(pseudonym != NULL && pseudonym->get_data_length() > KMaxPseudonymIdLengthInDB)
       
   543 	{
       
   544 		// Pseudonym too long. Can't store this in DB.
       
   545 		
       
   546 		EAP_TRACE_DEBUG(
       
   547 			m_am_tools,
       
   548 			TRACE_FLAGS_DEFAULT,
       
   549 			(EAPL("eap_am_type_aka_symbian_c::store_pseudonym_id: ")
       
   550 			 EAPL("Too long Pseudonym. Length=%d\n"),
       
   551 			 pseudonym->get_data_length()));
       
   552 		
       
   553 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   554 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   555 	}
       
   556 	
       
   557 	eap_status_e status(eap_status_ok);
       
   558 
       
   559 	TRAPD(err, store_pseudonym_idL(send_network_id, pseudonym));
       
   560 	if (err != KErrNone)
       
   561 	{
       
   562 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
   563 		send_error_notification(status);
       
   564 	}
       
   565 
       
   566 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   567 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   568 }
       
   569 
       
   570 //--------------------------------------------------
       
   571 
       
   572 void eap_am_type_aka_symbian_c::store_pseudonym_idL(
       
   573 	const eap_am_network_id_c * const /*network_id*/,
       
   574 	const eap_variable_data_c * const pseudonym)
       
   575 {
       
   576 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   577 
       
   578 	// Form the insertion command
       
   579 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
   580 	TPtr sqlStatement = buf->Des();
       
   581 
       
   582 	_LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
   583 	sqlStatement.Format(KSQLInsert, &KPseudonymId, &KAkaTableName, 
       
   584 		&KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
   585 
       
   586 	// Evaluate view
       
   587 	RDbView view;
       
   588 	User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited));
       
   589 	CleanupClosePushL(view);
       
   590 	
       
   591 	User::LeaveIfError(view.EvaluateAll());
       
   592 	
       
   593 	// Update the columns in the database
       
   594 	view.FirstL();
       
   595 	view.UpdateL();	
       
   596 	
       
   597 	// Get column set so we get the correct column numbers
       
   598 	CDbColSet* colSet = view.ColSetL();		
       
   599 	CleanupStack::PushL(colSet);
       
   600 	
       
   601 	// Create pointer to the data
       
   602 	if ((pseudonym != NULL) 
       
   603 		&& (pseudonym->get_is_valid_data() == true))
       
   604 	{		
       
   605 		TPtrC8 pseudonymId(
       
   606 			pseudonym->get_data(pseudonym->get_data_length()),
       
   607 			pseudonym->get_data_length());
       
   608 				
       
   609 		EAP_TRACE_DATA_DEBUG(
       
   610 			m_am_tools,
       
   611 			TRACE_FLAGS_DEFAULT,
       
   612 			(EAPL("pseudonymId to DB"),
       
   613 			pseudonymId.Ptr(),
       
   614 			pseudonymId.Length()));
       
   615 		
       
   616 		view.SetColL(colSet->ColNo(KPseudonymId), pseudonymId);		
       
   617 	} 
       
   618 	else 
       
   619 	{
       
   620 		// If passed pseudonym was 0 that means the field must be cleared.
       
   621 		view.SetColNullL(colSet->ColNo(KPseudonymId));
       
   622 	}
       
   623 
       
   624 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
   625 	
       
   626 	view.PutL();
       
   627 	
       
   628 	// Close database
       
   629 	CleanupStack::PopAndDestroy(2); // view, buf
       
   630 
       
   631 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   632 }
       
   633 
       
   634 //--------------------------------------------------
       
   635 
       
   636 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::store_reauthentication_id(
       
   637 	const eap_am_network_id_c * const send_network_id,
       
   638 	const eap_variable_data_c * const reauthentication_identity)
       
   639 {
       
   640 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   641 	
       
   642 	// Send error if the reauthentication id is too long.
       
   643 	if(reauthentication_identity != NULL 
       
   644 		&& reauthentication_identity->get_data_length() > KMaxReauthIdLengthInDB)
       
   645 	{
       
   646 		// Reauth id too long. Can't store this in DB.
       
   647 		
       
   648 		EAP_TRACE_DEBUG(
       
   649 			m_am_tools,
       
   650 			TRACE_FLAGS_DEFAULT,
       
   651 			(EAPL("eap_am_type_aka_symbian_c::store_reauthentication_id: ")
       
   652 			 EAPL("Too long reauth id. Length=%d\n"),
       
   653 			 reauthentication_identity->get_data_length()));
       
   654 		
       
   655 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   656 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   657 	}
       
   658 		
       
   659 	eap_status_e status(eap_status_ok);
       
   660 
       
   661 	TRAPD(err, store_reauthentication_idL(send_network_id, reauthentication_identity));
       
   662 	if (err != KErrNone)
       
   663 	{
       
   664 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
   665 		send_error_notification(status);
       
   666 	}
       
   667 
       
   668 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   669 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   670 }
       
   671 
       
   672 //--------------------------------------------------
       
   673 
       
   674 void eap_am_type_aka_symbian_c::store_reauthentication_idL(
       
   675 	const eap_am_network_id_c * const /*network_id*/,
       
   676 	const eap_variable_data_c * const reauthentication_id)
       
   677 {
       
   678 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   679 
       
   680 	// Form the insertion command
       
   681 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
   682 	TPtr sqlStatement = buf->Des();
       
   683 
       
   684 	_LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
   685 	sqlStatement.Format(KSQLInsert, &KReauthId, &KAkaTableName, 
       
   686 		&KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
   687 		
       
   688 	// Evaluate view
       
   689 	RDbView view;
       
   690 	User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited));
       
   691 	CleanupClosePushL(view);
       
   692 	
       
   693 	User::LeaveIfError(view.EvaluateAll());
       
   694 	view.FirstL();
       
   695 
       
   696 	view.UpdateL();
       
   697 
       
   698 	// Get column set so we get the correct column numbers
       
   699 	CDbColSet* colSet = view.ColSetL();
       
   700 	CleanupStack::PushL(colSet);
       
   701 
       
   702 	// Create pointer to the data
       
   703 	if ((reauthentication_id != NULL) 
       
   704 		&& (reauthentication_id->get_is_valid_data() == true))
       
   705 	{
       
   706 		TPtrC8 reauthId(
       
   707 			reauthentication_id->get_data(reauthentication_id->get_data_length()), 
       
   708 			reauthentication_id->get_data_length());
       
   709 
       
   710 		EAP_TRACE_DATA_DEBUG(
       
   711 			m_am_tools,
       
   712 			TRACE_FLAGS_DEFAULT,
       
   713 			(EAPL("reauthId to DB"),
       
   714 			reauthId.Ptr(),
       
   715 			reauthId.Length()));
       
   716 		
       
   717 		view.SetColL(colSet->ColNo(KReauthId), reauthId);
       
   718 		
       
   719 	} 
       
   720 	else 
       
   721 	{
       
   722 		// If passed reauthentication_id was 0 that means the field must be cleared.
       
   723 		view.SetColNullL(colSet->ColNo(KReauthId));
       
   724 	}
       
   725 
       
   726 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
   727 	
       
   728 	view.PutL();	
       
   729 		
       
   730 	// Close database
       
   731 	CleanupStack::PopAndDestroy(2); // view, buf
       
   732 
       
   733 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   734 }
       
   735 
       
   736 //--------------------------------------------------
       
   737 
       
   738 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::store_reauth_parameters(
       
   739 	const eap_variable_data_c * const XKEY,
       
   740 	const eap_variable_data_c * const K_aut,
       
   741 	const eap_variable_data_c * const K_encr,
       
   742 	const u32_t reauth_counter)
       
   743 {
       
   744 	// These kind of wrapper functions are needed because the Symbian L-functions must be executed in 
       
   745 	// trap harness.
       
   746 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   747 
       
   748 	// Send error if any of the parameters are invalid.
       
   749 	if(XKEY == NULL 
       
   750 		|| K_aut == NULL
       
   751 		|| K_encr == NULL)
       
   752 	{
       
   753 		// Some of the parameters are invalid.
       
   754 		
       
   755 		EAP_TRACE_DEBUG(
       
   756 			m_am_tools,
       
   757 			TRACE_FLAGS_DEFAULT,
       
   758 			(EAPL("eap_am_type_aka_symbian_c::store_reauth_parameters: ")
       
   759 			 EAPL("ERROR: Invalid parameters\n")));
       
   760 		
       
   761 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   762 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   763 	}
       
   764 	
       
   765 	// Send error if any of the parameters are too long.
       
   766 	if(XKEY->get_data_length() > KMaxXKeyLengthInDB 
       
   767 		|| K_aut->get_data_length() > KMaxK_autLengthInDB 
       
   768 		|| K_encr->get_data_length() > KMaxK_encrLengthInDB )
       
   769 	{
       
   770 		// Some of the parameters are too long. Can't store them in DB.
       
   771 		
       
   772 		EAP_TRACE_DEBUG(
       
   773 			m_am_tools,
       
   774 			TRACE_FLAGS_DEFAULT,
       
   775 			(EAPL("eap_am_type_aka_symbian_c::store_reauth_parameters: ")
       
   776 			 EAPL("Too long parameters. Length: XKEY=%d, K_aut=%d, K_encr=%d\n"),
       
   777 			 XKEY->get_data_length(), K_aut->get_data_length(), K_encr->get_data_length()));
       
   778 		
       
   779 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   780 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   781 	}
       
   782 
       
   783 	eap_status_e status(eap_status_ok);
       
   784 
       
   785 	TRAPD(err, store_reauth_parametersL(XKEY, K_aut, K_encr, reauth_counter));
       
   786 	if (err != KErrNone)
       
   787 	{
       
   788 		// Convert the leave error code to EAPOL stack error code.
       
   789 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
   790 		send_error_notification(status);
       
   791 	}
       
   792 
       
   793 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   794 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   795 }
       
   796 
       
   797 //--------------------------------------------------
       
   798 
       
   799 void eap_am_type_aka_symbian_c::store_reauth_parametersL(
       
   800 	const eap_variable_data_c * const XKEY,
       
   801 	const eap_variable_data_c * const K_aut,
       
   802 	const eap_variable_data_c * const K_encr,
       
   803 	const u32_t reauth_counter)
       
   804 {	
       
   805 	// The _L functions do the actual thing.
       
   806 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   807 
       
   808 	// Form the insertion command
       
   809 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
   810 	TPtr sqlStatement = buf->Des();
       
   811 
       
   812 	_LIT(KSQLInsert, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
   813 	sqlStatement.Format(KSQLInsert, &KXKey, &KK_aut, &KK_encr, &KReauthCounter, &KAkaTableName, 
       
   814 		&KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
   815 		
       
   816 	// Evaluate view
       
   817 	RDbView view;
       
   818 	User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited));
       
   819 	CleanupClosePushL(view);
       
   820 	
       
   821 	User::LeaveIfError(view.EvaluateAll());
       
   822 	
       
   823 	// Create pointers to the data
       
   824 	TPtrC8 key(XKEY->get_data(XKEY->get_data_length()), XKEY->get_data_length());
       
   825 	TPtrC8 aut(K_aut->get_data(K_aut->get_data_length()), K_aut->get_data_length());
       
   826 	TPtrC8 enc(K_encr->get_data(K_encr->get_data_length()), K_encr->get_data_length());
       
   827 	
       
   828 	// Update the columns in the database
       
   829 	view.FirstL();	
       
   830 	view.UpdateL();
       
   831 
       
   832 	// Get column set so we get the correct column numbers
       
   833 	CDbColSet* colSet = view.ColSetL();
       
   834 	CleanupStack::PushL(colSet);
       
   835 	
       
   836 	EAP_TRACE_DATA_DEBUG(
       
   837 		m_am_tools,
       
   838 		TRACE_FLAGS_DEFAULT,
       
   839 		(EAPL("XKEY to DB"), key.Ptr(),	key.Length()));
       
   840 
       
   841 	EAP_TRACE_DATA_DEBUG(
       
   842 		m_am_tools,
       
   843 		TRACE_FLAGS_DEFAULT,
       
   844 		(EAPL("K_aut to DB"), aut.Ptr(),	aut.Length()));
       
   845 
       
   846 	EAP_TRACE_DATA_DEBUG(
       
   847 		m_am_tools,
       
   848 		TRACE_FLAGS_DEFAULT,
       
   849 		(EAPL("K_encr to DB"), enc.Ptr(),	enc.Length()));
       
   850 	
       
   851 	view.SetColL(colSet->ColNo(KXKey), key); // XKEY
       
   852 	view.SetColL(colSet->ColNo(KK_aut), aut); // K_aut
       
   853 	view.SetColL(colSet->ColNo(KK_encr), enc); // K_encr
       
   854 	view.SetColL(colSet->ColNo(KReauthCounter), reauth_counter); // ReauthCounter
       
   855 
       
   856 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
   857 
       
   858 	view.PutL();
       
   859 
       
   860 	EAP_TRACE_DEBUG(
       
   861 		m_am_tools,
       
   862 		TRACE_FLAGS_DEFAULT,
       
   863 		(EAPL("eap_am_type_aka_symbian_c::store_reauth_keys_L(): %s, m_saved_reauth_counter %d.\n"),
       
   864 		 (m_is_client == true ? "client": "server"),
       
   865 		 reauth_counter));
       
   866 
       
   867 	// Close database
       
   868 	CleanupStack::PopAndDestroy(2); // view, buf
       
   869 
       
   870 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   871 }
       
   872 
       
   873 //--------------------------------------------------
       
   874 
       
   875 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::authentication_finished(
       
   876 	const bool true_when_successfull,
       
   877 	const eap_aka_authentication_type_e authentication_type,
       
   878 	const eap_type_aka_identity_type identity_type)
       
   879 {
       
   880 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   881 
       
   882 	eap_status_e status(eap_status_ok);
       
   883 	
       
   884 	TInt err(KErrNone);	
       
   885 
       
   886 	// Store the authentication time if the full authentication is successful
       
   887 	if (true_when_successfull == true
       
   888 		&& authentication_type == AKA_AUTHENTICATION_TYPE_FULL_AUTH)
       
   889 	{
       
   890 		TRAP(err,store_authentication_timeL());
       
   891 		if (err != KErrNone)
       
   892 		{
       
   893 			status = m_am_tools->convert_am_error_to_eapol_error(err);
       
   894 			send_error_notification(status);
       
   895 		}
       
   896 	}
       
   897 
       
   898 	if (true_when_successfull == false)
       
   899 	{
       
   900 		if( identity_type == AKA_IDENTITY_TYPE_IMSI_ID 
       
   901 			|| identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID )
       
   902 		{
       
   903 			(void) store_pseudonym_id(0,0);
       
   904 		}
       
   905 		
       
   906 		if( identity_type == AKA_IDENTITY_TYPE_IMSI_ID 
       
   907 			|| identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID )
       
   908 		{
       
   909 			(void) store_reauthentication_id(0,0);			
       
   910 		}
       
   911 	}
       
   912 
       
   913 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   914 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   915 }
       
   916 
       
   917 //--------------------------------------------------
       
   918 
       
   919 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_reauth_parameters(
       
   920 	eap_variable_data_c * const XKEY,
       
   921 	eap_variable_data_c * const K_aut,
       
   922 	eap_variable_data_c * const K_encr,
       
   923 	u32_t * const reauth_counter)
       
   924 {
       
   925 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
   926 	eap_status_e status(eap_status_ok);
       
   927 
       
   928 	TRAPD(err, query_reauth_parametersL(XKEY, K_aut, K_encr, reauth_counter));
       
   929 	if (err != KErrNone)
       
   930 	{
       
   931 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
   932 		send_error_notification(status);
       
   933 	}
       
   934 
       
   935 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   936 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   937 }
       
   938 
       
   939 //--------------------------------------------------
       
   940 
       
   941 void eap_am_type_aka_symbian_c::query_reauth_parametersL(
       
   942 	eap_variable_data_c * const XKEY,
       
   943 	eap_variable_data_c * const reauth_K_aut,
       
   944 	eap_variable_data_c * const reauth_K_encr,
       
   945 	u32_t * const reauth_counter)
       
   946 {
       
   947 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   948 
       
   949 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
   950 	TPtr sqlStatement = buf->Des();
       
   951 
       
   952 	// Form the query
       
   953 	_LIT(KSQLQuery, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
   954 	sqlStatement.Format(KSQLQuery, &KXKey, &KK_aut, &KK_encr, &KReauthCounter, &KAkaTableName, 
       
   955 		&KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
   956 		
       
   957 	RDbView view;
       
   958 	// Evaluate view
       
   959 	User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement)));
       
   960 	CleanupClosePushL(view);
       
   961 	
       
   962 	User::LeaveIfError(view.EvaluateAll());
       
   963 		
       
   964 	// Get the first (and only) row
       
   965 	view.FirstL();
       
   966 	view.GetL();
       
   967 	
       
   968 	// Get column set so we get the correct column numbers
       
   969 	CDbColSet* colSet = view.ColSetL();
       
   970 	CleanupStack::PushL(colSet);
       
   971 
       
   972 	// Get the values from DB
       
   973 	TPtrC8 key = view.ColDes8(colSet->ColNo(KXKey));	
       
   974 	TPtrC8 aut = view.ColDes8(colSet->ColNo(KK_aut));
       
   975 	TPtrC8 enc = view.ColDes8(colSet->ColNo(KK_encr));
       
   976 
       
   977 	EAP_TRACE_DATA_DEBUG(
       
   978 		m_am_tools,
       
   979 		TRACE_FLAGS_DEFAULT,
       
   980 		(EAPL("XKEY from DB"), key.Ptr(),	key.Length()));
       
   981 
       
   982 	EAP_TRACE_DATA_DEBUG(
       
   983 		m_am_tools,
       
   984 		TRACE_FLAGS_DEFAULT,
       
   985 		(EAPL("K_aut from DB"), aut.Ptr(),	aut.Length()));
       
   986 
       
   987 	EAP_TRACE_DATA_DEBUG(
       
   988 		m_am_tools,
       
   989 		TRACE_FLAGS_DEFAULT,
       
   990 		(EAPL("K_encr from DB"), enc.Ptr(),	enc.Length()));
       
   991 					
       
   992 	eap_status_e status(eap_status_process_general_error);
       
   993 	
       
   994 	// Store the values to the supplied buffers
       
   995 	status = XKEY->set_copy_of_buffer(key.Ptr(),key.Length());
       
   996 	if (status != eap_status_ok)
       
   997 	{
       
   998 		User::Leave(
       
   999 			m_am_tools->convert_eapol_error_to_am_error(
       
  1000 				EAP_STATUS_RETURN(m_am_tools, status)));
       
  1001 	}
       
  1002 
       
  1003 	status = reauth_K_aut->set_copy_of_buffer(aut.Ptr(),aut.Length());
       
  1004 	if (status != eap_status_ok)
       
  1005 	{
       
  1006 		User::Leave(
       
  1007 			m_am_tools->convert_eapol_error_to_am_error(
       
  1008 				EAP_STATUS_RETURN(m_am_tools, status)));
       
  1009 	}
       
  1010 
       
  1011 	status = reauth_K_encr->set_copy_of_buffer(enc.Ptr(),enc.Length());	
       
  1012 	if (status != eap_status_ok)
       
  1013 	{
       
  1014 		User::Leave(
       
  1015 			m_am_tools->convert_eapol_error_to_am_error(
       
  1016 				EAP_STATUS_RETURN(m_am_tools, status)));
       
  1017 	}
       
  1018 	
       
  1019 	*reauth_counter = view.ColUint(colSet->ColNo(KReauthCounter));
       
  1020 
       
  1021 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
  1022 
       
  1023 	EAP_TRACE_DEBUG(
       
  1024 		m_am_tools,
       
  1025 		TRACE_FLAGS_DEFAULT,
       
  1026 		(EAPL("eap_am_type_aka_symbian_c::query_reauth_parametersL(): %s, m_saved_reauth_counter %d.\n"),
       
  1027 		 (m_is_client == true ? "client": "server"),
       
  1028 		 *reauth_counter));
       
  1029 
       
  1030 	// Close database
       
  1031 	CleanupStack::PopAndDestroy(2); // view, buf
       
  1032 
       
  1033 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1034 }
       
  1035 
       
  1036 //--------------------------------------------------
       
  1037 
       
  1038 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::increase_reauth_counter()
       
  1039 {
       
  1040 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1041 	eap_status_e status(eap_status_ok);
       
  1042 
       
  1043 	TRAPD(err, increase_reauth_counterL());
       
  1044 	if (err != KErrNone)
       
  1045 	{
       
  1046 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
  1047 		send_error_notification(status);
       
  1048 	}
       
  1049 
       
  1050 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1051 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1052 }
       
  1053 
       
  1054 //--------------------------------------------------
       
  1055 
       
  1056 void eap_am_type_aka_symbian_c::increase_reauth_counterL()
       
  1057 {
       
  1058 	// Form the insertion command
       
  1059 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1060 		
       
  1061 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
  1062 	TPtr sqlStatement = buf->Des();
       
  1063 
       
  1064 	_LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
  1065 	sqlStatement.Format(KSQLInsert, &KReauthCounter, &KAkaTableName, 
       
  1066 		&KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
  1067 		
       
  1068 	// Evaluate view
       
  1069 	RDbView view;
       
  1070 	User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited));
       
  1071 	CleanupClosePushL(view);
       
  1072 	
       
  1073 	User::LeaveIfError(view.EvaluateAll());
       
  1074 	
       
  1075 	view.FirstL();
       
  1076 	view.GetL();
       
  1077 
       
  1078 	// Get column set so we get the correct column numbers
       
  1079 	CDbColSet* colSet = view.ColSetL();
       
  1080 	CleanupStack::PushL(colSet);
       
  1081 	
       
  1082 	// Get the previous value
       
  1083 	TUint counter = view.ColUint(colSet->ColNo(KReauthCounter));
       
  1084 
       
  1085 	view.UpdateL();
       
  1086 	
       
  1087 	// Increment the value
       
  1088 	view.SetColL(colSet->ColNo(KReauthCounter), counter + 1); 
       
  1089 
       
  1090 	counter = view.ColUint(colSet->ColNo(KReauthCounter));
       
  1091 	
       
  1092 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
  1093 	
       
  1094 	EAP_TRACE_DEBUG(
       
  1095 		m_am_tools,
       
  1096 		TRACE_FLAGS_DEFAULT,
       
  1097 		(EAPL("eap_am_type_aka_symbian_c::increase_reauth_counterL(): %s, m_saved_reauth_counter %d.\n"),
       
  1098 		 (m_is_client == true ? "client": "server"),
       
  1099 		 counter));
       
  1100 
       
  1101 	view.PutL();
       
  1102 
       
  1103 	// Close database
       
  1104 	CleanupStack::PopAndDestroy(2); // view, buf
       
  1105 
       
  1106 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1107 }
       
  1108 
       
  1109 //--------------------------------------------------
       
  1110 
       
  1111 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_AKA_IMSI_or_pseudonym_or_reauthentication_id(
       
  1112 	eap_variable_data_c * const IMSI,
       
  1113 	eap_variable_data_c * const pseudonym_identity,
       
  1114 	eap_variable_data_c * const reauthentication_identity,
       
  1115 	eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter.
       
  1116 	u32_t * const /*length_of_mnc*/,
       
  1117 	const aka_payload_AT_type_e required_identity, ///< This parameter indicated the type of identity required.
       
  1118 	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.
       
  1119 	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.
       
  1120 	)
       
  1121 {
       
  1122 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1123 
       
  1124 	eap_status_e status(eap_status_ok);
       
  1125 
       
  1126 	EAP_ASSERT((IMSI != 0) && (pseudonym_identity != 0) && (reauthentication_identity != 0));
       
  1127 
       
  1128 	m_stored_required_completion = required_completion;
       
  1129 	m_stored_received_eap_identifier = received_eap_identifier;
       
  1130 
       
  1131 	TRAPD(err, query_AKA_IMSI_or_pseudonym_or_reauthentication_idL(IMSI,
       
  1132 																 pseudonym_identity,
       
  1133 																 reauthentication_identity,
       
  1134 																 automatic_realm,
       
  1135 																 required_identity,
       
  1136 																 required_completion,
       
  1137 																 received_eap_identifier));
       
  1138 	if (err != KErrNone)
       
  1139 	{
       
  1140 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
  1141 
       
  1142 		if (status != eap_status_pending_request)
       
  1143 		{
       
  1144 			send_error_notification(status);
       
  1145 		}
       
  1146 	} 
       
  1147 
       
  1148 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1149 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1150 }
       
  1151 
       
  1152 //--------------------------------------------------
       
  1153 
       
  1154 void eap_am_type_aka_symbian_c::query_AKA_IMSI_or_pseudonym_or_reauthentication_idL(
       
  1155 	eap_variable_data_c * const IMSI,
       
  1156 	eap_variable_data_c * const pseudonym_identity,
       
  1157 	eap_variable_data_c * const reauthentication_identity,
       
  1158 	eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter.
       
  1159 	const aka_payload_AT_type_e required_identity,
       
  1160 	const eap_type_aka_complete_e /*required_completion*/,
       
  1161 	const u8_t /*received_eap_identifier*/)
       
  1162 {
       
  1163 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1164 
       
  1165 	eap_status_e status(eap_status_process_general_error);
       
  1166 
       
  1167 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
  1168 	TPtr sqlStatement = buf->Des();
       
  1169 	
       
  1170 	// Reset everything
       
  1171 	IMSI->reset();
       
  1172 	pseudonym_identity->reset();
       
  1173 	reauthentication_identity->reset();
       
  1174 	automatic_realm->reset();
       
  1175 	m_stored_pseudonym.reset();
       
  1176 	m_stored_reauth_id.reset();
       
  1177 	m_previous_imsi.reset();
       
  1178 
       
  1179 	_LIT(KSQLQuery, "SELECT %S, %S, %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
  1180 	sqlStatement.Format(KSQLQuery, &KReauthId, &KReauthCounter, &KPseudonymId,
       
  1181 						&KPreviousIMSI, &KAkaTableName,
       
  1182 						&KServiceType, m_index_type, 
       
  1183 						&KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
  1184 
       
  1185 	RDbView view;
       
  1186 	// Evaluate view
       
  1187 	User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement)));
       
  1188 	CleanupClosePushL(view);
       
  1189 	
       
  1190 	User::LeaveIfError(view.EvaluateAll());
       
  1191 	
       
  1192 	// Get the first (and only) row
       
  1193 	view.FirstL();
       
  1194 	view.GetL();
       
  1195 	
       
  1196 	// Get column set so we get the correct column numbers
       
  1197 	CDbColSet* colSet = view.ColSetL();
       
  1198 	CleanupStack::PushL(colSet);
       
  1199 	
       
  1200 	// Get the values
       
  1201 	TUint reauthCount = view.ColUint32(colSet->ColNo(KReauthCounter));	
       
  1202 
       
  1203 	EAP_TRACE_DEBUG(
       
  1204 		m_am_tools,
       
  1205 		TRACE_FLAGS_DEFAULT,
       
  1206 		(EAPL("query_AKA_IMSI_or_pseudonym_or_reauthentication_idL: ")
       
  1207 		 EAPL("required_identity=%d, reauthCount from DB %d\n"),
       
  1208 		 required_identity, reauthCount));
       
  1209 	
       
  1210 	// A stream is needed for LONG columns in DB.
       
  1211 	RDbColReadStream readStream;
       
  1212 
       
  1213 	// Get pseudonym ID from DB.
       
  1214 	HBufC8* pseudonymIdBuf = HBufC8::NewLC(KMaxPseudonymIdLengthInDB); // Buffer for pseudonym id.
       
  1215 	TPtr8 pseudonymId = pseudonymIdBuf->Des();
       
  1216 	
       
  1217 	readStream.OpenLC(view, colSet->ColNo(KPseudonymId));
       
  1218 	readStream.ReadL(pseudonymId, view.ColLength(colSet->ColNo(KPseudonymId)));
       
  1219 	readStream.Close();
       
  1220 	CleanupStack::Pop(&readStream); // Pop readStream.
       
  1221 	
       
  1222 	EAP_TRACE_DATA_DEBUG(
       
  1223 		m_am_tools,
       
  1224 		TRACE_FLAGS_DEFAULT,
       
  1225 		(EAPL("pseudonymId from DB"), pseudonymId.Ptr(), pseudonymId.Length()));
       
  1226 
       
  1227 	// Get reauthentication ID from DB.
       
  1228 	HBufC8* reauthIdBuf = HBufC8::NewLC(KMaxReauthIdLengthInDB); // Buffer for reauthentication id.
       
  1229 	TPtr8 reauthId = reauthIdBuf->Des();
       
  1230 	
       
  1231 	readStream.OpenLC(view, colSet->ColNo(KReauthId));
       
  1232 	readStream.ReadL(reauthId, view.ColLength(colSet->ColNo(KReauthId)));
       
  1233 	readStream.Close();
       
  1234 	CleanupStack::Pop(&readStream); // Pop readStream.
       
  1235 
       
  1236 	EAP_TRACE_DATA_DEBUG(
       
  1237 		m_am_tools,
       
  1238 		TRACE_FLAGS_DEFAULT,
       
  1239 		(EAPL("reauthId from DB"), reauthId.Ptr(), reauthId.Length()));	
       
  1240 	
       
  1241 #if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
  1242 
       
  1243 	// Get the previous IMSI. Used for checking if SIM has been changed.
       
  1244 	// The checking is done in complete_AKA_imsi_L
       
  1245 	
       
  1246 	TPtrC8 tmp_imsi = view.ColDes8(colSet->ColNo(KPreviousIMSI));
       
  1247 
       
  1248 	status = m_previous_imsi.set_copy_of_buffer(tmp_imsi.Ptr(), tmp_imsi.Length());
       
  1249 	if (status != eap_status_ok)
       
  1250 	{
       
  1251 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1252 		User::Leave(KErrNoMemory);
       
  1253 	}
       
  1254 	
       
  1255 	EAP_TRACE_DATA_DEBUG(
       
  1256 		m_am_tools,
       
  1257 		TRACE_FLAGS_DEFAULT,
       
  1258 		(EAPL("imsi from DB"), tmp_imsi.Ptr(), tmp_imsi.Size()));
       
  1259 	
       
  1260 #endif
       
  1261 	
       
  1262 	if (required_identity == aka_payload_AT_ANY_ID_REQ)
       
  1263 	{
       
  1264 		if (is_session_valid() )
       
  1265 		{
       
  1266 			if(reauthId.Length() > 0)
       
  1267 			{
       
  1268 				
       
  1269 #if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
  1270 				// Store the reauth id in case we are using asynchronous processing (= ISA interface)
       
  1271 				status = m_stored_reauth_id.set_copy_of_buffer(reauthId.Ptr(), reauthId.Length());
       
  1272 				if (status != eap_status_ok)
       
  1273 				{
       
  1274 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1275 					User::Leave(KErrNoMemory);
       
  1276 				}	
       
  1277 #endif
       
  1278 				status = reauthentication_identity->set_copy_of_buffer(reauthId.Ptr(), reauthId.Length());
       
  1279 				if (status != eap_status_ok)
       
  1280 				{
       
  1281 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1282 					User::Leave(KErrNoMemory);
       
  1283 				}	
       
  1284 			}
       
  1285 		}
       
  1286 	}
       
  1287 
       
  1288 	CleanupStack::PopAndDestroy(reauthIdBuf); // Delete reauthIdBuf	
       
  1289 	
       
  1290 	if (required_identity == aka_payload_AT_ANY_ID_REQ
       
  1291 			|| required_identity == aka_payload_AT_FULLAUTH_ID_REQ)
       
  1292 	{
       
  1293 		if (pseudonymId.Length() > 0)
       
  1294 		{
       
  1295 			
       
  1296 #if defined(USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
  1297 			// Store the pseudonym in case we are using
       
  1298 			// asynchronous processing (= ISA interface)
       
  1299 			status = m_stored_pseudonym.set_copy_of_buffer(
       
  1300 				pseudonymId.Ptr(),
       
  1301 				pseudonymId.Length());
       
  1302 			if (status != eap_status_ok)
       
  1303 			{
       
  1304 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1305 				User::Leave(KErrNoMemory);
       
  1306 			}
       
  1307 #endif
       
  1308 			status = pseudonym_identity->set_copy_of_buffer(
       
  1309 				pseudonymId.Ptr(),
       
  1310 				pseudonymId.Length());
       
  1311 			if (status != eap_status_ok)
       
  1312 			{
       
  1313 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1314 				User::Leave(KErrNoMemory);
       
  1315 			}
       
  1316 		}
       
  1317 	}
       
  1318 
       
  1319 	CleanupStack::PopAndDestroy(pseudonymIdBuf); // Delete pseudonymIdBuf
       
  1320 
       
  1321 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
  1322 
       
  1323 	CleanupStack::PopAndDestroy( &view ); // Close view.
       
  1324 
       
  1325 	CleanupStack::PopAndDestroy(buf); // Delete buf
       
  1326 
       
  1327 	if (IMSI->get_is_valid_data() == false
       
  1328 		|| IMSI->get_buffer_length() < AKA_IMSI_LENGTH)
       
  1329 	{
       
  1330 		status = IMSI->init(AKA_IMSI_LENGTH);
       
  1331 		if (status != eap_status_ok)
       
  1332 		{
       
  1333 			User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
       
  1334 		}
       
  1335 
       
  1336 		IMSI->set_is_valid();
       
  1337 	}
       
  1338 
       
  1339 	{
       
  1340 	
       
  1341 #if defined (USE_EAP_AKA_INTERFACE)	&& !defined(__WINS__)
       
  1342 	
       
  1343 		// For real AKA USIM interface.
       
  1344 		// Use real AKA interface active object.
       
  1345 		// This gets the IMSI from the real USIM, using Custom API.
       
  1346 		
       
  1347 		m_aka_if->QueryIMSIL();
       
  1348 		
       
  1349 		// KErrCompletion means that the operation is pending.
       
  1350 		User::Leave(KErrCompletion);
       
  1351 
       
  1352 #elif defined(__WINS__) // For plugin tester.
       
  1353 
       
  1354 		// Here we get the Nokia test SIM IMSI since the USIM interface is disabled.
       
  1355 		u32_t imsi_length = 0u;
       
  1356 		
       
  1357 		status = query_SIM_imsi(
       
  1358 			IMSI->get_buffer(AKA_IMSI_LENGTH),
       
  1359 			AKA_IMSI_LENGTH,
       
  1360 			&imsi_length);
       
  1361 
       
  1362 		if (status != eap_status_ok
       
  1363 			|| imsi_length != AKA_IMSI_LENGTH)
       
  1364 		{			
       
  1365 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1366 			User::Leave(KErrGeneral);
       
  1367 		}
       
  1368 		
       
  1369 		status = IMSI->set_data_length(imsi_length);
       
  1370 
       
  1371 		if (status != eap_status_ok)
       
  1372 		{			
       
  1373 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1374 			User::Leave(KErrGeneral);
       
  1375 		}
       
  1376 
       
  1377 #endif // End of #if defined (USE_EAP_AKA_INTERFACE)	&& !defined(__WINS__)
       
  1378 	
       
  1379 	}
       
  1380 		
       
  1381 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  1382 }
       
  1383 
       
  1384 //--------------------------------------------------
       
  1385 
       
  1386 eap_status_e eap_am_type_aka_symbian_c::complete_AKA_imsi_L(
       
  1387 	const eap_variable_data_c * const IMSI,
       
  1388 	const eap_status_e completion_status )
       
  1389 {
       
  1390 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1391 	eap_status_e status(eap_status_process_general_error);
       
  1392 	
       
  1393 	if (completion_status != eap_status_ok)
       
  1394 	{
       
  1395 		// IMSI query failed
       
  1396 		status = get_am_partner()->complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(
       
  1397 			IMSI, 
       
  1398 			&m_stored_pseudonym, 
       
  1399 			&m_stored_reauth_id, 
       
  1400 			0,
       
  1401 			EAP_TYPE_AKA_DEFAULT_MNC_LENGTH_3_BYTES,
       
  1402 			m_stored_required_completion, 
       
  1403 			m_stored_received_eap_identifier,
       
  1404 			completion_status);	
       
  1405 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1406 		return status;
       
  1407 	}
       
  1408 
       
  1409 	if (IMSI == 0
       
  1410 		|| IMSI->get_is_valid_data() == false)
       
  1411 	{
       
  1412 		// IMSI query failed
       
  1413 		status = get_am_partner()->complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(
       
  1414 			IMSI, 
       
  1415 			&m_stored_pseudonym, 
       
  1416 			&m_stored_reauth_id, 
       
  1417 			0,
       
  1418 			EAP_TYPE_AKA_DEFAULT_MNC_LENGTH_3_BYTES,
       
  1419 			m_stored_required_completion, 
       
  1420 			m_stored_received_eap_identifier,
       
  1421 			eap_status_hardware_not_ready);	
       
  1422 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1423 		return status;
       
  1424 	}
       
  1425 
       
  1426 	if (m_previous_imsi.get_data_length() == 0)
       
  1427 	{
       
  1428 		EAP_TRACE_DEBUG(
       
  1429 			m_am_tools,
       
  1430 			TRACE_FLAGS_DEFAULT,
       
  1431 			(EAPL("Previous IMSI not valid. Storing new IMSI.\n")));
       
  1432 
       
  1433 		// Store new IMSI
       
  1434 		status = store_imsi(IMSI);
       
  1435 		if (status != eap_status_ok)
       
  1436 		{
       
  1437 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1438 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1439 		}		
       
  1440 	}
       
  1441 	else if (IMSI->compare(&m_previous_imsi) != 0)
       
  1442 	{
       
  1443 		EAP_TRACE_DEBUG(
       
  1444 			m_am_tools,
       
  1445 			TRACE_FLAGS_DEFAULT,
       
  1446 			(EAPL("SIM has been changed since last authentication. ")
       
  1447 			 EAPL("Clear pseudonym & reauth IDs.\n")));
       
  1448 
       
  1449 		// Different IMSI -> SIM has been changed.
       
  1450 		// Reset pseudonym and reauthentication ID. 
       
  1451 		status = store_reauthentication_id(0, 0);
       
  1452 		if (status != eap_status_ok)
       
  1453 		{
       
  1454 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1455 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1456 		}
       
  1457 		status = store_pseudonym_id(0, 0);
       
  1458 		if (status != eap_status_ok)
       
  1459 		{
       
  1460 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1461 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1462 		}
       
  1463 		// Store new IMSI
       
  1464 		status = store_imsi(IMSI);
       
  1465 		if (status != eap_status_ok)
       
  1466 		{
       
  1467 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1468 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1469 		}
       
  1470 		// Reset stored pseudonym & reauthentication ID
       
  1471 		m_stored_pseudonym.reset();
       
  1472 		m_stored_reauth_id.reset();
       
  1473 	}
       
  1474 	else
       
  1475 	{
       
  1476 		EAP_TRACE_DEBUG(
       
  1477 			m_am_tools,
       
  1478 			TRACE_FLAGS_DEFAULT,
       
  1479 			(EAPL("SIM has not been changed.\n")));
       
  1480 	}
       
  1481 
       
  1482 	status = get_am_partner()->complete_AKA_IMSI_or_pseudonym_or_reauthentication_id_query(
       
  1483 		IMSI,
       
  1484 		&m_stored_pseudonym,
       
  1485 		&m_stored_reauth_id,
       
  1486 		0,
       
  1487 		0ul,
       
  1488 		m_stored_required_completion,
       
  1489 		m_stored_received_eap_identifier,
       
  1490 		eap_status_ok);
       
  1491 
       
  1492 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1493 
       
  1494 	return status;
       
  1495 }
       
  1496 
       
  1497 //--------------------------------------------------
       
  1498 
       
  1499 eap_status_e eap_am_type_aka_symbian_c::store_imsi(
       
  1500 	const eap_variable_data_c * const imsi)
       
  1501 {
       
  1502 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  1503 	
       
  1504 	// Send error if the IMSI is too long.
       
  1505 	if(imsi != NULL && imsi->get_data_length() > KMaxIMSILengthInDB)
       
  1506 	{
       
  1507 		// IMSI too long. Can't store this in DB.
       
  1508 		
       
  1509 		EAP_TRACE_DEBUG(
       
  1510 			m_am_tools,
       
  1511 			TRACE_FLAGS_DEFAULT,
       
  1512 			(EAPL("eap_am_type_aka_symbian_c::store_imsi: ")
       
  1513 			 EAPL("Too long IMSI. Length=%d\n"),
       
  1514 			 imsi->get_data_length()));
       
  1515 		
       
  1516 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1517 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1518 	}
       
  1519 
       
  1520 	eap_status_e status(eap_status_ok);
       
  1521 
       
  1522 	TRAPD(err, store_imsiL(imsi));
       
  1523 	if (err != KErrNone)
       
  1524 	{
       
  1525 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
  1526 		send_error_notification(status);
       
  1527 	}
       
  1528 
       
  1529 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1530 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1531 }
       
  1532 
       
  1533 //--------------------------------------------------
       
  1534 
       
  1535 void eap_am_type_aka_symbian_c::store_imsiL(
       
  1536 	const eap_variable_data_c * const imsi)
       
  1537 {
       
  1538 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1539 	
       
  1540 	// Form the insertion command
       
  1541 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
  1542 	TPtr sqlStatement = buf->Des();
       
  1543 
       
  1544 	_LIT(KSQLInsert, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
  1545 	sqlStatement.Format(KSQLInsert, &KPreviousIMSI, &KAkaTableName, 
       
  1546 		&KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
  1547 		
       
  1548 	// Evaluate view
       
  1549 	RDbView view;
       
  1550 	
       
  1551 	User::LeaveIfError(view.Prepare(m_database,TDbQuery(sqlStatement), TDbWindow::EUnlimited));
       
  1552 	CleanupClosePushL(view);
       
  1553 	
       
  1554 	User::LeaveIfError(view.EvaluateAll());
       
  1555 	view.FirstL();
       
  1556 
       
  1557 	view.UpdateL();
       
  1558 
       
  1559 	// Get column set so we get the correct column numbers
       
  1560 	CDbColSet* colSet = view.ColSetL();
       
  1561 	CleanupStack::PushL(colSet);
       
  1562 
       
  1563 	// Create pointer to the data
       
  1564 	if ((imsi != 0) 
       
  1565 		&& (imsi->get_is_valid_data() == true))
       
  1566 	{
       
  1567 		TPtrC8 tmp_imsi(
       
  1568 			imsi->get_data(imsi->get_data_length()), 
       
  1569 			imsi->get_data_length());	
       
  1570 	
       
  1571 		EAP_TRACE_DATA_DEBUG(
       
  1572 			m_am_tools,
       
  1573 			TRACE_FLAGS_DEFAULT,
       
  1574 			(EAPL("IMSI to DB"), tmp_imsi.Ptr(), tmp_imsi.Length()));
       
  1575 		
       
  1576 		view.SetColL(colSet->ColNo(KPreviousIMSI), tmp_imsi); 
       
  1577 	} 
       
  1578 	else 
       
  1579 	{
       
  1580 		// If passed IMSI was 0 that means the field must be cleared.
       
  1581 		view.SetColNullL(colSet->ColNo(KPreviousIMSI));
       
  1582 	}
       
  1583 	
       
  1584 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
  1585 	
       
  1586 	view.PutL();	
       
  1587 	
       
  1588 	// Close database
       
  1589 	CleanupStack::PopAndDestroy(2); // view, buf
       
  1590 
       
  1591 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1592 }
       
  1593 
       
  1594 //--------------------------------------------------
       
  1595 
       
  1596 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_AKA_IMSI_or_pseudonym_or_reauthentication_id_query()
       
  1597 {
       
  1598 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1599 #if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
  1600 	if (m_is_client == true)
       
  1601 	{
       
  1602 		m_aka_if->Cancel();
       
  1603 	}
       
  1604 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1605 	return eap_status_ok;
       
  1606 #else
       
  1607 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1608 	return eap_status_not_supported;
       
  1609 #endif
       
  1610 }
       
  1611 
       
  1612 //--------------------------------------------------
       
  1613 
       
  1614 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_AKA_RES(
       
  1615 	eap_type_aka_authentication_vector_c * const authentication_vector)
       
  1616 {
       
  1617 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1618 
       
  1619 	// NOTE if user needs to use state_selector or n_rands after return from query_AKA_RES()
       
  1620 	// function those parameters MUST be copied using copy() member function of each parameter.
       
  1621 	// For example: saved_n_rands = n_rands->copy()
       
  1622 
       
  1623 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  1624 
       
  1625 	if (authentication_vector == 0
       
  1626 		|| authentication_vector->get_is_valid() == false)
       
  1627 	{
       
  1628 		// Something is really wrong.
       
  1629 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1630 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1631 	}
       
  1632 
       
  1633 	eap_status_e status = eap_status_process_general_error;
       
  1634 
       
  1635 	if (authentication_vector->get_RAND()->get_is_valid_data() == false)
       
  1636 	{
       
  1637 		// No RAND. cannot continue.
       
  1638 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1639 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1640 	}
       
  1641 
       
  1642 	if (authentication_vector->get_AUTN()->get_is_valid_data() == false)
       
  1643 	{
       
  1644 		// No AUTN. cannot continue.
       
  1645 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1646 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1647 	}
       
  1648 	
       
  1649 	// Update the member variables with current values for RAND and AUTN.
       
  1650 	// These are needed for synchronization failure.
       
  1651 	status = m_RAND.set_copy_of_buffer( authentication_vector->get_RAND() );
       
  1652 	if (status != eap_status_ok)
       
  1653 	{
       
  1654 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1655 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1656 	}
       
  1657 	
       
  1658 	status = 	m_AUTN.set_copy_of_buffer( authentication_vector->get_AUTN() );
       
  1659 	if (status != eap_status_ok)
       
  1660 	{
       
  1661 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1662 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1663 	}	
       
  1664 		
       
  1665 #if !defined (USE_EAP_AKA_INTERFACE)
       
  1666 
       
  1667 	if (authentication_vector == 0)
       
  1668 	{
       
  1669 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1670 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1671 	}
       
  1672 
       
  1673 	status = m_aka_algorithm->generate_RES( authentication_vector );
       
  1674 
       
  1675 #elif !defined(__WINS__)
       
  1676 	
       
  1677 	TRAPD(err, m_aka_if->QueryRESL( &m_RAND , &m_AUTN ); );	
       
  1678 	if (err != KErrNone)
       
  1679 	{
       
  1680 		status = m_am_tools->convert_am_error_to_eapol_error(err);
       
  1681 		if (status == eap_status_process_general_error)
       
  1682 		{
       
  1683 			status = eap_status_credential_query_failed;
       
  1684 		}
       
  1685 		send_error_notification(status);
       
  1686 	}
       
  1687 	else
       
  1688 	{
       
  1689 		status = eap_status_pending_request;
       
  1690 	}
       
  1691 #endif //#if !defined (USE_EAP_AKA_INTERFACE)
       
  1692 	
       
  1693 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1694 	
       
  1695 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1696 }
       
  1697 
       
  1698 //--------------------------------------------------
       
  1699 
       
  1700 eap_status_e eap_am_type_aka_symbian_c::complete_AKA_RES_L(
       
  1701 	eap_variable_data_c * const aRES, 
       
  1702 	eap_variable_data_c * const aCK,
       
  1703 	eap_variable_data_c * const aIK,
       
  1704 	eap_variable_data_c * const aAUTS,
       
  1705 	eap_status_e authenticationStatus,
       
  1706 	const eap_status_e completion_status )	
       
  1707 {
       
  1708 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1709 
       
  1710 	eap_status_e status(eap_status_ok);
       
  1711 
       
  1712 #if !defined(USE_EAP_AKA_INTERFACE) || defined(__WINS__)
       
  1713 
       
  1714 	EAP_UNREFERENCED_PARAMETER(aRES);
       
  1715 	EAP_UNREFERENCED_PARAMETER(aCK);
       
  1716 	EAP_UNREFERENCED_PARAMETER(aIK);
       
  1717 	EAP_UNREFERENCED_PARAMETER(aAUTS);
       
  1718 	EAP_UNREFERENCED_PARAMETER(authenticationStatus);
       
  1719 	EAP_UNREFERENCED_PARAMETER(completion_status);
       
  1720 
       
  1721 #else
       
  1722 
       
  1723 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("complete_AKA_RES_L\n")));
       
  1724 
       
  1725 	eap_type_aka_authentication_vector_c  authentication_vector( m_am_tools );
       
  1726 	
       
  1727 	if (completion_status != eap_status_ok)
       
  1728 	{
       
  1729 		// Signal upper layer about the failure.
       
  1730 		status = get_am_partner()->complete_AKA_RES_query( &authentication_vector, completion_status);
       
  1731 		
       
  1732 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1733 		return EAP_STATUS_RETURN(m_am_tools, status);		
       
  1734 	}	
       
  1735 	
       
  1736 	if (aRES == 0 || aRES->get_is_valid() == false ||
       
  1737 		aCK == 0 || aCK->get_is_valid() == false ||
       
  1738 		aIK == 0 || aIK->get_is_valid() == false ||
       
  1739 		aAUTS == 0 || aAUTS->get_is_valid() == false )
       
  1740 	{
       
  1741 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1742 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1743 	}
       
  1744 			
       
  1745 	status = authentication_vector.get_RES()->set_copy_of_buffer( aRES );
       
  1746 	if (status != eap_status_ok)
       
  1747 	{
       
  1748 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1749 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1750 	}
       
  1751 
       
  1752 	status = authentication_vector.get_CK()->set_copy_of_buffer( aCK );
       
  1753 	if (status != eap_status_ok)
       
  1754 	{
       
  1755 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1756 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1757 	}
       
  1758 
       
  1759 	status = authentication_vector.get_IK()->set_copy_of_buffer( aIK );
       
  1760 	if (status != eap_status_ok)
       
  1761 	{
       
  1762 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1763 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1764 	}
       
  1765 	
       
  1766 	status = authentication_vector.get_AUTS()->set_copy_of_buffer( aAUTS );
       
  1767 	if (status != eap_status_ok)
       
  1768 	{
       
  1769 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1770 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1771 	}
       
  1772 	
       
  1773 	// Copy RAND and AUTN also. They are needed in case of synchronization failure.
       
  1774 	
       
  1775 	status = authentication_vector.get_RAND()->set_copy_of_buffer( &m_RAND );
       
  1776 	if (status != eap_status_ok)
       
  1777 	{
       
  1778 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1779 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1780 	}
       
  1781 	
       
  1782 	status = authentication_vector.get_AUTN()->set_copy_of_buffer( &m_AUTN );
       
  1783 	if (status != eap_status_ok)
       
  1784 	{
       
  1785 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1786 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1787 	}	
       
  1788 	
       
  1789 	authentication_vector.set_vector_status(authenticationStatus);
       
  1790 
       
  1791 	// Complete request.
       
  1792 	status = get_am_partner()->complete_AKA_RES_query( &authentication_vector, eap_status_ok);
       
  1793 	
       
  1794 	if (status == eap_status_ok)
       
  1795 	{
       
  1796 		status = eap_status_completed_request;
       
  1797 	}
       
  1798 #endif	
       
  1799 
       
  1800 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1801 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1802 }
       
  1803 
       
  1804 //--------------------------------------------------
       
  1805 
       
  1806 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_AKA_RES_query()
       
  1807 {
       
  1808 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1809 #if defined (USE_EAP_AKA_INTERFACE) && !defined(__WINS__)
       
  1810 	if (m_is_client == true)
       
  1811 	{
       
  1812 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::cancel_AKA_RES_query() - cancelling IF query\n")));
       
  1813 	
       
  1814 		m_aka_if->Cancel();
       
  1815 	}
       
  1816 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1817 	return eap_status_ok;
       
  1818 #else
       
  1819 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1820 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  1821 #endif	
       
  1822 }
       
  1823 
       
  1824 //--------------------------------------------------
       
  1825 
       
  1826 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::handle_aka_notification(
       
  1827 	eap_aka_notification_codes_e aka_notification_code)
       
  1828 {
       
  1829 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1830 
       
  1831 	switch ((aka_notification_code & aka_notification_code_value))
       
  1832 	{
       
  1833 	case eap_aka_notification_no_F_no_P_user_has_not_subscribed_to_the_requested_service:
       
  1834 		send_error_notification(eap_status_user_has_not_subscribed_to_the_requested_service);
       
  1835 		break;
       
  1836 
       
  1837 	case eap_aka_notification_no_F_no_P_users_calls_are_barred:
       
  1838 		send_error_notification(eap_status_users_calls_are_barred);
       
  1839 		break;
       
  1840 
       
  1841 	default:
       
  1842 		// Do nothing
       
  1843 		break;
       
  1844 	}
       
  1845 
       
  1846 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1847 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1848 }
       
  1849 
       
  1850 //--------------------------------------------------
       
  1851 
       
  1852 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_AKA_authentication_vector(
       
  1853 	const eap_variable_data_c * const username, ///< // This is payload AT_IDENTITY. If this is uninitialized then imsi must be initialized.
       
  1854 	const u8_t next_eap_identifier,
       
  1855 	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.
       
  1856 	eap_type_aka_authentication_vector_c * const authentication_vector,
       
  1857 	eap_type_aka_identity_type * const type) 
       
  1858 {
       
  1859 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1860 	
       
  1861 	// NOTE if user needs to use state_selector or imsi after return from query_AKA_authentication_vector()
       
  1862 	// function those parameters MUST be copied using copy() member function of each parameter.
       
  1863 	// For example: saved_imsi = p_imsi_or_pseudonym->copy()
       
  1864 	//              saved_state_selector = state_selector->copy()
       
  1865 
       
  1866 	eap_status_e status = eap_status_process_general_error;	
       
  1867 	
       
  1868 #if defined (USE_EAP_TYPE_SERVER_AKA) 
       
  1869 
       
  1870 	if (username == 0
       
  1871 		|| imsi == 0
       
  1872 		|| authentication_vector == 0
       
  1873 		|| type == 0)
       
  1874 	{
       
  1875 		// Something is really wrong.
       
  1876 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1877 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1878 	}
       
  1879 
       
  1880 	if (username->get_is_valid_data() == false
       
  1881 		&& imsi->get_is_valid_data() == false)
       
  1882 	{
       
  1883 		// Something is really wrong.
       
  1884 		// Only one of these must be set.
       
  1885 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1886 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1887 	}
       
  1888 
       
  1889 	if (username->get_is_valid_data() == true
       
  1890 		&& imsi->get_is_valid_data() == false)
       
  1891 	{
       
  1892 		// We must query IMSI.
       
  1893 
       
  1894 		// This is akaple test.
       
  1895 		query_imsi_from_username_syncronous(
       
  1896 			0u,
       
  1897 			0,
       
  1898 			username,
       
  1899 			imsi,
       
  1900 			type);
       
  1901 
       
  1902 		if (imsi->get_is_valid_data() == false
       
  1903 			|| imsi->get_data_length() != m_am_tools->strlen(TEST_IMSI)
       
  1904 			|| m_am_tools->memcmp(imsi->get_data(imsi->get_data_length()), TEST_IMSI, imsi->get_data_length()) != 0)
       
  1905 		{
       
  1906 			EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: MAC of identity differs.\n")));
       
  1907 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1908 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  1909 		}
       
  1910 	}
       
  1911 	else if (imsi->get_is_valid_data() == true)
       
  1912 	{
       
  1913 		*type = AKA_IDENTITY_TYPE_IMSI_ID;
       
  1914 	}
       
  1915 
       
  1916 	{
       
  1917 		status = m_aka_algorithm->generate_authentication_vector(
       
  1918 			authentication_vector);
       
  1919 		if (status != eap_status_ok)
       
  1920 		{
       
  1921 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1922 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1923 		}
       
  1924 	}
       
  1925 
       
  1926 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("query_AKA_authentication_vector(): Used EAP-Identity type %d.\n"),
       
  1927 		*type));
       
  1928 
       
  1929 	m_next_eap_identifier = next_eap_identifier;
       
  1930 
       
  1931 	m_aka_authentication_vector_status = eap_aka_authentication_vector_status_ok;
       
  1932 
       
  1933 	{
       
  1934 		EAP_TRACE_DEBUG(
       
  1935 			m_am_tools,
       
  1936 			TRACE_FLAGS_DEFAULT,
       
  1937 			(EAPL("AKA: %s: direct_complete_function: complete_AKA_authentication_vector_query()\n"),
       
  1938 			(m_is_client == true ? "client": "server")));
       
  1939 
       
  1940 		status = get_am_partner()->complete_AKA_authentication_vector_query(
       
  1941 			authentication_vector,
       
  1942 			imsi,
       
  1943 			m_aka_authentication_vector_status,
       
  1944 			*type,
       
  1945 			eap_status_ok,
       
  1946 			next_eap_identifier);
       
  1947 		if (status == eap_status_ok)
       
  1948 		{
       
  1949 			status = eap_status_completed_request;
       
  1950 		}
       
  1951 	}
       
  1952 #else
       
  1953 
       
  1954 	EAP_UNREFERENCED_PARAMETER(username);
       
  1955 	EAP_UNREFERENCED_PARAMETER(next_eap_identifier);
       
  1956 	EAP_UNREFERENCED_PARAMETER(imsi);
       
  1957 	EAP_UNREFERENCED_PARAMETER(authentication_vector);
       
  1958 	EAP_UNREFERENCED_PARAMETER(type);	
       
  1959 	
       
  1960 #endif // #if !defined (USE_EAP_TYPE_SERVER_AKA)	
       
  1961 
       
  1962 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1963 	return EAP_STATUS_RETURN(m_am_tools, status);		
       
  1964 }
       
  1965 
       
  1966 //--------------------------------------------------
       
  1967 
       
  1968 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_AKA_authentication_vector_query()
       
  1969 {
       
  1970 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1971 
       
  1972 #if !defined (USE_EAP_TYPE_SERVER_AKA)
       
  1973 
       
  1974 	EAP_TRACE_ERROR(
       
  1975 		m_am_tools,
       
  1976 		TRACE_FLAGS_DEFAULT,
       
  1977 		(EAPL("cancel_AKA_authentication_vector_query()\n")));
       
  1978 
       
  1979 	delete m_authentication_vector;
       
  1980 	m_authentication_vector = 0;
       
  1981 
       
  1982 #endif // #if !defined (USE_EAP_TYPE_SERVER_AKA)	
       
  1983 
       
  1984 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1985 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1986 }
       
  1987 
       
  1988 //--------------------------------------------------
       
  1989 
       
  1990 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::generate_encryption_IV(
       
  1991 	eap_variable_data_c * const encryption_IV,
       
  1992 	const u32_t IV_length)
       
  1993 {
       
  1994 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1995 	
       
  1996 	eap_status_e status = eap_status_process_general_error;
       
  1997 	
       
  1998 	status = encryption_IV->init(IV_length);
       
  1999 	if (status != eap_status_ok)
       
  2000 	{
       
  2001 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2002 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2003 	}
       
  2004 
       
  2005 	encryption_IV->set_is_valid();
       
  2006 	encryption_IV->set_data_length(IV_length);
       
  2007 
       
  2008 	m_am_tools->get_crypto()->add_rand_seed_hw_ticks();
       
  2009 
       
  2010 	status = m_am_tools->get_crypto()->get_rand_bytes(
       
  2011 		encryption_IV->get_data(encryption_IV->get_data_length()),
       
  2012 		encryption_IV->get_data_length());
       
  2013 		
       
  2014 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2015 	return EAP_STATUS_RETURN(m_am_tools, status);	
       
  2016 }
       
  2017 
       
  2018 //--------------------------------------------------
       
  2019 
       
  2020 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::generate_pseudonym_id(
       
  2021 	const eap_am_network_id_c * const send_network_id,
       
  2022 	const eap_variable_data_c * const imsi,
       
  2023 	eap_variable_data_c * const pseudonym_identity,
       
  2024 	const u32_t maximum_pseudonym_length)
       
  2025 {
       
  2026 
       
  2027 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2028 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2029 
       
  2030 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
  2031 	
       
  2032 	// From AKA simulator code.
       
  2033 	// This is an example.
       
  2034 
       
  2035 	return generate_identity(
       
  2036 		AKA_IDENTITY_TYPE_PSEUDONYM_ID,
       
  2037 		imsi,
       
  2038 		pseudonym_identity,
       
  2039 		maximum_pseudonym_length);
       
  2040 #else
       
  2041 
       
  2042 	EAP_UNREFERENCED_PARAMETER(send_network_id);
       
  2043 	EAP_UNREFERENCED_PARAMETER(imsi);
       
  2044 	EAP_UNREFERENCED_PARAMETER(pseudonym_identity);
       
  2045 	EAP_UNREFERENCED_PARAMETER(maximum_pseudonym_length);	
       
  2046 
       
  2047 	// This function shouldn't be called for other than server.
       
  2048 	return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);	
       
  2049 	
       
  2050 #endif // #if defined (USE_EAP_TYPE_SERVER_AKA)		
       
  2051 		
       
  2052 }
       
  2053 
       
  2054 //--------------------------------------------------
       
  2055 
       
  2056 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
  2057 	// These functions are used only for server side.
       
  2058 
       
  2059 eap_status_e eap_am_type_aka_symbian_c::generate_identity(
       
  2060 	const eap_type_aka_identity_type identity_type,
       
  2061 	const eap_variable_data_c * const imsi,
       
  2062 	eap_variable_data_c * const pseudonym,
       
  2063 	const u32_t maximum_pseudonym_length)
       
  2064 {
       
  2065 
       
  2066 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2067 
       
  2068 	// From AKA simulator code.
       
  2069 	
       
  2070 	// This is an example.
       
  2071 
       
  2072 	eap_status_e status = eap_status_process_general_error;
       
  2073 
       
  2074 	//return eap_status_not_supported; // This will disable pseudonym and re-authentication idetities.
       
  2075 
       
  2076 	// Here pseydonym indentity includes encrypted IMSI.
       
  2077 	// This causes the client to be database of it's own pseudonym identity.
       
  2078 	// Server stores only one or more global encryption key.
       
  2079 	// Encryption key is indexed by encryption_key_index attribute of pseudonym.
       
  2080 	// Server could store old keys some time after a new key is changed.
       
  2081 	//                                         
       
  2082 	// --------time------------>               
       
  2083 	//                                         
       
  2084 	// +---Key-1-------+                       
       
  2085 	//       +---Key-2------+                  
       
  2086 	//               +---Key-3------+          
       
  2087 	//                     +---Key-4------+
       
  2088 	//                                         
       
  2089 
       
  2090 	crypto_aes_c aes(m_am_tools);
       
  2091 	crypto_cbc_c cbc_aes(m_am_tools, &aes, false);
       
  2092 
       
  2093 	if (cbc_aes.get_is_valid() == false)
       
  2094 	{
       
  2095 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2096 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2097 	}
       
  2098 
       
  2099 	eap_variable_data_c encryption_IV(m_am_tools);
       
  2100 
       
  2101 	{
       
  2102 		status = generate_encryption_IV(
       
  2103 			&encryption_IV,
       
  2104 			aes.get_block_size());
       
  2105 	}
       
  2106 
       
  2107 	if (status != eap_status_ok)
       
  2108 	{
       
  2109 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2110 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2111 	}
       
  2112 
       
  2113 	eap_variable_data_c tmp_pseudonym(m_am_tools);
       
  2114 	status = tmp_pseudonym.set_buffer_length(sizeof(eap_aka_pseudonym_s));
       
  2115 	if (status != eap_status_ok)
       
  2116 	{
       
  2117 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2118 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2119 	}
       
  2120 	tmp_pseudonym.set_data_length(sizeof(eap_aka_pseudonym_s));
       
  2121 	eap_aka_pseudonym_s * const str_pseudonym 
       
  2122 		= reinterpret_cast<eap_aka_pseudonym_s * const>(tmp_pseudonym.get_data(
       
  2123 			sizeof(eap_aka_pseudonym_s)));
       
  2124 
       
  2125 	m_am_tools->memset(str_pseudonym, 0, sizeof(*str_pseudonym));
       
  2126 
       
  2127 	str_pseudonym->imsi_block.imsi_length = static_cast<u8_t>(imsi->get_data_length());
       
  2128 	if (identity_type == AKA_IDENTITY_TYPE_PSEUDONYM_ID)
       
  2129 	{
       
  2130 		str_pseudonym->imsi_block.id_type = 0;
       
  2131 	}
       
  2132 	else if (identity_type == AKA_IDENTITY_TYPE_RE_AUTH_ID)
       
  2133 	{
       
  2134 		str_pseudonym->imsi_block.id_type = 1;
       
  2135 	}
       
  2136 	else
       
  2137 	{
       
  2138 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2139 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  2140 	}
       
  2141 
       
  2142 	str_pseudonym->encryption_key_index = m_pseudonym_key_index;
       
  2143 
       
  2144 	m_am_tools->memmove(
       
  2145 		str_pseudonym->encryption_IV.IV_8,
       
  2146 		encryption_IV.get_data(aes.get_block_size()),
       
  2147 		sizeof(str_pseudonym->encryption_IV.IV_8));
       
  2148 	m_am_tools->memmove(
       
  2149 		str_pseudonym->imsi_block.imsi_and_padding,
       
  2150 		imsi->get_data(imsi->get_data_length()),
       
  2151 		imsi->get_data_length());
       
  2152 
       
  2153 	u32_t imsi_data_length = sizeof(u8_t)+imsi->get_data_length();
       
  2154 
       
  2155 	u32_t cbc_aes_data_length = 0u;
       
  2156 	if ((imsi_data_length % aes.get_block_size()) != 0u)
       
  2157 	{
       
  2158 		cbc_aes_data_length = imsi_data_length + (aes.get_block_size() - (aes.get_block_size() % imsi_data_length));
       
  2159 	}
       
  2160 	else
       
  2161 	{
       
  2162 		cbc_aes_data_length = imsi_data_length;
       
  2163 	}
       
  2164 
       
  2165 	u32_t padding_bytes_length = cbc_aes_data_length - imsi_data_length;
       
  2166 
       
  2167 	if (padding_bytes_length > 0u)
       
  2168 	{
       
  2169 		cbc_aes.add_padding_bytes(
       
  2170 			&(str_pseudonym->imsi_block.imsi_and_padding[str_pseudonym->imsi_block.imsi_length]),
       
  2171 			padding_bytes_length,
       
  2172 			0ul);
       
  2173 	}
       
  2174 
       
  2175 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym struct"),
       
  2176 		reinterpret_cast<u8_t *>(str_pseudonym),
       
  2177 		sizeof(*str_pseudonym)));
       
  2178 
       
  2179 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym IV"),
       
  2180 		encryption_IV.get_data(encryption_IV.get_data_length()),
       
  2181 		encryption_IV.get_data_length()));
       
  2182 
       
  2183 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym encryption key"),
       
  2184 		m_pseudonym_key.get_data(m_pseudonym_key.get_data_length()),
       
  2185 		m_pseudonym_key.get_data_length()));
       
  2186 
       
  2187 	status = cbc_aes.set_encryption_key(
       
  2188 		encryption_IV.get_data(encryption_IV.get_data_length()),
       
  2189 		encryption_IV.get_data_length(),
       
  2190 		m_pseudonym_key.get_data(m_pseudonym_key.get_data_length()),
       
  2191 		m_pseudonym_key.get_data_length());
       
  2192 	if (status != eap_status_ok)
       
  2193 	{
       
  2194 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2195 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2196 	}
       
  2197 
       
  2198 	status = cbc_aes.encrypt_data(
       
  2199 		&(str_pseudonym->imsi_block),
       
  2200 		sizeof(str_pseudonym->imsi_block));
       
  2201 	if (status != eap_status_ok)
       
  2202 	{
       
  2203 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2204 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2205 	}
       
  2206 
       
  2207 	{
       
  2208 		crypto_sha1_c sha1(m_am_tools);
       
  2209 		crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false);
       
  2210 	  
       
  2211 		if (hmac_sha1.get_is_valid() == false)
       
  2212 	    {
       
  2213 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2214 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2215 	    }
       
  2216 
       
  2217 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym MAC key"),
       
  2218 			m_pseudonym_MAC_key.get_data(m_pseudonym_MAC_key.get_data_length()),
       
  2219 			m_pseudonym_MAC_key.get_data_length()));
       
  2220 
       
  2221 		if (hmac_sha1.hmac_set_key(
       
  2222 			&m_pseudonym_MAC_key
       
  2223 			) != eap_status_ok)
       
  2224 		{
       
  2225 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2226 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2227 		}
       
  2228 
       
  2229 		hmac_sha1.hmac_update(
       
  2230 			reinterpret_cast<u8_t *>(str_pseudonym),
       
  2231 			sizeof(*str_pseudonym)-sizeof(str_pseudonym->MAC));
       
  2232 
       
  2233 		u32_t length = EAP_TYPE_AKA_MAC_SIZE;
       
  2234 
       
  2235 		hmac_sha1.hmac_128_final(
       
  2236 			str_pseudonym->MAC,
       
  2237 			&length);
       
  2238 
       
  2239 		EAP_ASSERT(length == EAP_TYPE_AKA_MAC_SIZE);
       
  2240 	}
       
  2241 
       
  2242 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"),
       
  2243 		tmp_pseudonym.get_data(tmp_pseudonym.get_data_length()),
       
  2244 		tmp_pseudonym.get_data_length()));
       
  2245 
       
  2246 	// NOTE this does not add any security.
       
  2247 	// This will only scramble encryption key index.
       
  2248 	str_pseudonym->encryption_key_index ^= 
       
  2249 		(str_pseudonym->encryption_IV.IV_32[0]
       
  2250 		+ str_pseudonym->encryption_IV.IV_32[1]
       
  2251 		+ str_pseudonym->encryption_IV.IV_32[2]
       
  2252 		+ str_pseudonym->encryption_IV.IV_32[3]
       
  2253 		+ ENCRYPTION_KEY_INDEX_SCRAMBLE_CONST);
       
  2254 
       
  2255 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"),
       
  2256 		tmp_pseudonym.get_data(tmp_pseudonym.get_data_length()),
       
  2257 		tmp_pseudonym.get_data_length()));
       
  2258 
       
  2259 	pseudonym->init(3ul+(sizeof(*str_pseudonym)+1u)*4u/3u);
       
  2260 	pseudonym->set_is_valid();
       
  2261 	pseudonym->set_data_length(pseudonym->get_buffer_length());
       
  2262 
       
  2263 	u32_t pseudonym_length = pseudonym->get_data_length();
       
  2264 
       
  2265 	status = m_am_tools->convert_bytes_to_ascii_armor(
       
  2266 		tmp_pseudonym.get_data_offset(0u, tmp_pseudonym.get_data_length()),
       
  2267 		tmp_pseudonym.get_data_length(),
       
  2268 		pseudonym->get_data_offset(0u, pseudonym->get_data_length()),
       
  2269 		&pseudonym_length);
       
  2270 	if (status != eap_status_ok)
       
  2271 	{
       
  2272 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2273 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2274 	}
       
  2275 
       
  2276 	if (pseudonym_length > maximum_pseudonym_length)
       
  2277 	{
       
  2278 		pseudonym_length = maximum_pseudonym_length;
       
  2279 	}
       
  2280 	pseudonym->set_data_length(pseudonym_length);
       
  2281 
       
  2282 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym"),
       
  2283 		pseudonym->get_data(pseudonym->get_data_length()),
       
  2284 		pseudonym->get_data_length()));
       
  2285 
       
  2286 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2287 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2288 }
       
  2289 
       
  2290 //--------------------------------------------------
       
  2291 
       
  2292 eap_status_e eap_am_type_aka_symbian_c::query_imsi_from_username_syncronous(
       
  2293 	const u8_t next_eap_identifier,
       
  2294 	const eap_am_network_id_c * const network_id,
       
  2295 	const eap_variable_data_c * const username,
       
  2296 	eap_variable_data_c * const imsi,
       
  2297 	eap_type_aka_identity_type * const identity_type)
       
  2298 {
       
  2299 	// Note this is syncronous call.
       
  2300 	if (network_id == 0
       
  2301 		|| username == 0
       
  2302 		|| imsi == 0
       
  2303 		|| identity_type == 0)
       
  2304 	{
       
  2305 		// Something is really wrong.
       
  2306 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2307 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2308 	}
       
  2309 
       
  2310 
       
  2311 	crypto_aes_c aes(m_am_tools);
       
  2312 	crypto_cbc_c cbc_aes(m_am_tools, &aes, false);
       
  2313 
       
  2314 	if (cbc_aes.get_is_valid() == false)
       
  2315 	{
       
  2316 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2317 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2318 	}
       
  2319 
       
  2320 	eap_status_e status = eap_status_process_general_error;
       
  2321 
       
  2322 	const u8_t * const username_prefix = username->get_data_offset(0u, 1u);
       
  2323 
       
  2324 	if (username->get_data_length() <= AKA_IMSI_LENGTH+1u
       
  2325 		&& username->get_data_length() > 1u
       
  2326 		&& username_prefix != 0
       
  2327 		&& *username_prefix == *AKA_IMSI_PREFIX_CHARACTER
       
  2328 		&& check_is_valid_imsi(username) == eap_status_ok)
       
  2329 	{
       
  2330 		// We have IMSI.
       
  2331 		status = imsi->set_copy_of_buffer(
       
  2332 			username->get_data_offset(1u, username->get_data_length()-1u),
       
  2333 			username->get_data_length()-1u);
       
  2334 		if (status != eap_status_ok)
       
  2335 		{
       
  2336 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2337 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2338 		}
       
  2339 
       
  2340 		*identity_type = AKA_IDENTITY_TYPE_IMSI_ID;
       
  2341 
       
  2342 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"),
       
  2343 			imsi->get_data(imsi->get_data_length()),
       
  2344 			imsi->get_data_length()));
       
  2345 
       
  2346 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("query_imsi_from_username(): Used EAP-Identity type %d.\n"),
       
  2347 			*identity_type));
       
  2348 
       
  2349 		status = eap_status_ok;
       
  2350 	}
       
  2351 	else if (username->get_data_length() > aes.get_block_size()
       
  2352 			 && username->get_data_length() > sizeof(eap_aka_pseudonym_s))
       
  2353 	{
       
  2354 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("username"),
       
  2355 			username->get_data(username->get_data_length()),
       
  2356 			username->get_data_length()));
       
  2357 
       
  2358 		// We have pseudonym_identity.
       
  2359 		eap_variable_data_c tmp_imsi(m_am_tools);
       
  2360 		tmp_imsi.set_buffer_length(sizeof(eap_aka_pseudonym_s)+1u);
       
  2361 		tmp_imsi.set_data_length(sizeof(eap_aka_pseudonym_s)+1u);
       
  2362 		u32_t tmp_imsi_length = tmp_imsi.get_data_length();
       
  2363 
       
  2364 		eap_aka_pseudonym_s * const str_pseudonym = reinterpret_cast<eap_aka_pseudonym_s * const>(tmp_imsi.get_data_offset(0u, tmp_imsi.get_data_length()));
       
  2365 		if (str_pseudonym == 0)
       
  2366 		{
       
  2367 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2368 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2369 		}
       
  2370 
       
  2371 		status = m_am_tools->restore_bytes_from_ascii_armor(
       
  2372 			username->get_data_offset(0u, username->get_data_length()),
       
  2373 			username->get_data_length(),
       
  2374 			tmp_imsi.get_data_offset(0u, tmp_imsi.get_data_length()),
       
  2375 			&tmp_imsi_length);
       
  2376 		if (status != eap_status_ok)
       
  2377 		{
       
  2378 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2379 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2380 		}
       
  2381 		tmp_imsi.set_data_length(tmp_imsi_length);
       
  2382 
       
  2383 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"),
       
  2384 			tmp_imsi.get_data(tmp_imsi.get_data_length()),
       
  2385 			tmp_imsi.get_data_length()));
       
  2386 
       
  2387 		// NOTE this does not add any security.
       
  2388 		// This will only scramble encryption key index.
       
  2389 		str_pseudonym->encryption_key_index ^= 
       
  2390 			(str_pseudonym->encryption_IV.IV_32[0]
       
  2391 			+ str_pseudonym->encryption_IV.IV_32[1]
       
  2392 			+ str_pseudonym->encryption_IV.IV_32[2]
       
  2393 			+ str_pseudonym->encryption_IV.IV_32[3]
       
  2394 			+ ENCRYPTION_KEY_INDEX_SCRAMBLE_CONST);
       
  2395 
       
  2396 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym data"),
       
  2397 			tmp_imsi.get_data(tmp_imsi.get_data_length()),
       
  2398 			tmp_imsi.get_data_length()));
       
  2399 
       
  2400 		status = eap_status_illegal_eap_identity;
       
  2401 
       
  2402 		if ((m_pseudonym_key_index == str_pseudonym->encryption_key_index
       
  2403 			|| m_pseudonym_key_index-1u == str_pseudonym->encryption_key_index)
       
  2404 			&& tmp_imsi.get_data_length() == sizeof(eap_aka_pseudonym_s))
       
  2405 		{
       
  2406 			const eap_variable_data_c *test_pseudonym_key = &m_pseudonym_key;
       
  2407 			const eap_variable_data_c *test_pseudonym_MAC_key = &m_pseudonym_MAC_key;
       
  2408 
       
  2409 			if (m_pseudonym_key_index-1u == str_pseudonym->encryption_key_index)
       
  2410 			{
       
  2411 				test_pseudonym_key = &m_prev_pseudonym_key;
       
  2412 				test_pseudonym_MAC_key = &m_prev_pseudonym_MAC_key;
       
  2413 			}
       
  2414 
       
  2415 			{
       
  2416 				crypto_sha1_c sha1(m_am_tools);
       
  2417 				crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false);
       
  2418 
       
  2419 				if (hmac_sha1.get_is_valid() == false)
       
  2420 				{
       
  2421 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2422 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2423 				}
       
  2424 
       
  2425 				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym MAC key"),
       
  2426 					test_pseudonym_MAC_key->get_data(test_pseudonym_MAC_key->get_data_length()),
       
  2427 					test_pseudonym_MAC_key->get_data_length()));
       
  2428 
       
  2429 				if (hmac_sha1.hmac_set_key(
       
  2430 					test_pseudonym_MAC_key
       
  2431 					) != eap_status_ok)
       
  2432 				{
       
  2433 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2434 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2435 				}
       
  2436 
       
  2437 				hmac_sha1.hmac_update(
       
  2438 					reinterpret_cast<u8_t *>(str_pseudonym),
       
  2439 					sizeof(*str_pseudonym)-sizeof(str_pseudonym->MAC));
       
  2440 
       
  2441 				u32_t length = EAP_TYPE_AKA_MAC_SIZE;
       
  2442 				u8_t tmp_MAC[EAP_TYPE_AKA_MAC_SIZE];
       
  2443 
       
  2444 				hmac_sha1.hmac_128_final(
       
  2445 					tmp_MAC,
       
  2446 					&length);
       
  2447 
       
  2448 				EAP_ASSERT(length == EAP_TYPE_AKA_MAC_SIZE);
       
  2449 
       
  2450 				if (m_am_tools->memcmp(tmp_MAC, str_pseudonym->MAC, EAP_TYPE_AKA_MAC_SIZE) != 0)
       
  2451 				{
       
  2452 					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: MAC of identity differs.\n")));
       
  2453 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2454 					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  2455 				}
       
  2456 			}
       
  2457 
       
  2458 			EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym decryption key"),
       
  2459 				test_pseudonym_key->get_data(test_pseudonym_key->get_data_length()),
       
  2460 				test_pseudonym_key->get_data_length()));
       
  2461 
       
  2462 			status = cbc_aes.set_decryption_key(
       
  2463 				str_pseudonym->encryption_IV.IV_8,
       
  2464 				sizeof(str_pseudonym->encryption_IV.IV_8),
       
  2465 				test_pseudonym_key->get_data(test_pseudonym_key->get_data_length()),
       
  2466 				test_pseudonym_key->get_data_length());
       
  2467 			if (status != eap_status_ok)
       
  2468 			{
       
  2469 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2470 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2471 			}
       
  2472 
       
  2473 			status = cbc_aes.decrypt_data(
       
  2474 				&(str_pseudonym->imsi_block),
       
  2475 				sizeof(str_pseudonym->imsi_block));
       
  2476 			if (status != eap_status_ok)
       
  2477 			{
       
  2478 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2479 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2480 			}
       
  2481 
       
  2482 			EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("pseudonym struct"),
       
  2483 				reinterpret_cast<u8_t *>(str_pseudonym),
       
  2484 				sizeof(*str_pseudonym)));
       
  2485 
       
  2486 			u32_t imsi_length = static_cast<u32_t>(str_pseudonym->imsi_block.imsi_length);
       
  2487 
       
  2488 			if (imsi_length < 0u
       
  2489 				|| imsi_length > AKA_IMSI_LENGTH)
       
  2490 			{
       
  2491 				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: IMSI length illegal.\n")));
       
  2492 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2493 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  2494 			}
       
  2495 
       
  2496 			if (str_pseudonym->imsi_block.id_type == 0)
       
  2497 			{
       
  2498 				*identity_type = AKA_IDENTITY_TYPE_PSEUDONYM_ID;
       
  2499 			}
       
  2500 			else if (str_pseudonym->imsi_block.id_type == 1)
       
  2501 			{
       
  2502 				*identity_type = AKA_IDENTITY_TYPE_RE_AUTH_ID;
       
  2503 			}
       
  2504 			else
       
  2505 			{
       
  2506 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2507 				return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  2508 			}
       
  2509 
       
  2510 
       
  2511 
       
  2512 			status = imsi->set_copy_of_buffer(
       
  2513 				str_pseudonym->imsi_block.imsi_and_padding,
       
  2514 				imsi_length);
       
  2515 
       
  2516 			EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"),
       
  2517 				imsi->get_data(imsi->get_data_length()),
       
  2518 				imsi->get_data_length()));
       
  2519 
       
  2520 			EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("query_imsi_from_username(): Used EAP-Identity type %d.\n"),
       
  2521 				*identity_type));
       
  2522 
       
  2523 			if (m_pseudonym_key_use_count < MAX_PSEUDONYM_USE_COUNT+MAX_REAUTH_USE_COUNT)
       
  2524 			{
       
  2525 				++m_pseudonym_key_use_count;
       
  2526 			}
       
  2527 			else
       
  2528 			{
       
  2529 				{
       
  2530 					crypto_aes_c aes(m_am_tools);
       
  2531 
       
  2532 					if (aes.get_is_valid() == false)
       
  2533 					{
       
  2534 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2535 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2536 					}
       
  2537 
       
  2538 					// Note this function generates cryptographically strong random bytes.
       
  2539 					// Here we use those bytes as a secret encryption key.
       
  2540 					eap_status_e status = m_prev_pseudonym_key.set_copy_of_buffer(&m_pseudonym_key);
       
  2541 					if (status != eap_status_ok)
       
  2542 					{
       
  2543 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2544 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2545 					}
       
  2546 					status = generate_encryption_IV(
       
  2547 						&m_pseudonym_key,
       
  2548 						aes.get_block_size());
       
  2549 					if (status == eap_status_ok)
       
  2550 					{
       
  2551 						status = m_prev_pseudonym_MAC_key.set_copy_of_buffer(&m_pseudonym_MAC_key);
       
  2552 						if (status != eap_status_ok)
       
  2553 						{
       
  2554 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2555 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2556 						}
       
  2557 						status = generate_encryption_IV(
       
  2558 							&m_pseudonym_MAC_key,
       
  2559 							aes.get_block_size());
       
  2560 						if (status == eap_status_ok)
       
  2561 						{
       
  2562 						}
       
  2563 					}
       
  2564 					++m_pseudonym_key_index;
       
  2565 					m_pseudonym_key_use_count = 0u;
       
  2566 				}
       
  2567 			}
       
  2568 		}
       
  2569 		else
       
  2570 		{
       
  2571 			if (m_pseudonym_key_index != str_pseudonym->encryption_key_index)
       
  2572 			{
       
  2573 				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: MAC key index differs, %lu != %lu.\n"),
       
  2574 					m_pseudonym_key_index,
       
  2575 					str_pseudonym->encryption_key_index));
       
  2576 			}
       
  2577 			else if (tmp_imsi.get_data_length() == sizeof(eap_aka_pseudonym_s))
       
  2578 			{
       
  2579 				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: pseudonym length differs, %lu != %lu.\n"),
       
  2580 					tmp_imsi.get_data_length(),
       
  2581 					sizeof(eap_aka_pseudonym_s)));
       
  2582 			}
       
  2583 
       
  2584 			status = eap_status_illegal_eap_identity;
       
  2585 
       
  2586 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2587 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2588 		}
       
  2589 	}
       
  2590 	else
       
  2591 	{
       
  2592 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("WARNING: illegal username.\n")));
       
  2593 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2594 		return eap_status_illegal_eap_identity;
       
  2595 	}
       
  2596 
       
  2597 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2598 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2599 }
       
  2600 
       
  2601 #endif // #if defined (USE_EAP_TYPE_SERVER_AKA)		
       
  2602 
       
  2603 //--------------------------------------------------
       
  2604 
       
  2605 eap_status_e eap_am_type_aka_symbian_c::generate_reauthentication_id(
       
  2606 	const eap_am_network_id_c * const send_network_id,
       
  2607 	const eap_variable_data_c * const imsi,
       
  2608 	eap_variable_data_c * const reauthentication_identity,
       
  2609 	const u32_t maximum_reauthentication_identity_length)
       
  2610 {
       
  2611 	// From AKA simulator code.
       
  2612 	
       
  2613 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2614 	
       
  2615 	// This is an example.
       
  2616 
       
  2617 	eap_status_e status = eap_status_process_general_error;
       
  2618 
       
  2619 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
  2620 
       
  2621 	status = generate_identity(
       
  2622 		AKA_IDENTITY_TYPE_RE_AUTH_ID,
       
  2623 		imsi,
       
  2624 		reauthentication_identity,
       
  2625 		maximum_reauthentication_identity_length);
       
  2626 	if (status != eap_status_ok)
       
  2627 	{
       
  2628 		reauthentication_identity->reset();
       
  2629 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2630 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2631 	}
       
  2632 	
       
  2633 	if (m_nai_realm.get_is_valid_data() == true
       
  2634 		&& m_nai_realm.get_data_length() > 0ul)
       
  2635 	{
       
  2636 		status = reauthentication_identity->add_data(reinterpret_cast<const u8_t * const>(AKA_AT_CHARACTER), 1u);
       
  2637 		if (status != eap_status_ok)
       
  2638 		{
       
  2639 			reauthentication_identity->reset();
       
  2640 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2641 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2642 		}
       
  2643 
       
  2644 		status = reauthentication_identity->add_data(&m_nai_realm);
       
  2645 		if (status != eap_status_ok)
       
  2646 		{
       
  2647 			reauthentication_identity->reset();
       
  2648 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2649 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2650 		}
       
  2651 	}
       
  2652 #else
       
  2653 
       
  2654 	EAP_UNREFERENCED_PARAMETER(send_network_id);
       
  2655 	EAP_UNREFERENCED_PARAMETER(imsi);
       
  2656 	EAP_UNREFERENCED_PARAMETER(reauthentication_identity);
       
  2657 	EAP_UNREFERENCED_PARAMETER(maximum_reauthentication_identity_length);	
       
  2658 
       
  2659 #endif // #if defined (USE_EAP_TYPE_SERVER_AKA)
       
  2660 
       
  2661 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2662 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2663 }
       
  2664 	
       
  2665 //--------------------------------------------------
       
  2666 
       
  2667 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_imsi_from_username(
       
  2668 	const u8_t next_eap_identifier,
       
  2669 	const eap_am_network_id_c * const send_network_id,
       
  2670 	const eap_variable_data_c * const username,
       
  2671 	eap_variable_data_c * const imsi,
       
  2672 	eap_type_aka_identity_type * const type,
       
  2673 	const eap_type_aka_complete_e completion_action)
       
  2674 {
       
  2675 	// From AKA simulator code.
       
  2676 
       
  2677 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2678 	
       
  2679 	// Note this is asyncronous call.
       
  2680 	
       
  2681 	eap_status_e status = eap_status_process_general_error;
       
  2682 
       
  2683 #if defined (USE_EAP_TYPE_SERVER_AKA)
       
  2684 
       
  2685 	m_identity_type = AKA_IDENTITY_TYPE_NONE;
       
  2686 	m_next_eap_identifier = 0;
       
  2687 	m_completion_action = eap_type_aka_complete_none;
       
  2688 	m_username.reset();
       
  2689 	m_IMSI.reset();
       
  2690 
       
  2691 	status = query_imsi_from_username_syncronous(
       
  2692 		next_eap_identifier,
       
  2693 		send_network_id,
       
  2694 		username,
       
  2695 		imsi,
       
  2696 		type);
       
  2697 	if (status != eap_status_ok)
       
  2698 	{
       
  2699 		// Do not return immediately.
       
  2700 		// Here we test the asyncronous completion.
       
  2701 	}
       
  2702 
       
  2703 	{
       
  2704 		status = get_am_partner()->complete_imsi_from_username(
       
  2705 			next_eap_identifier,
       
  2706 			send_network_id,
       
  2707 			username,
       
  2708 			imsi,
       
  2709 			*type,
       
  2710 			eap_status_ok,
       
  2711 			completion_action);
       
  2712 
       
  2713 		if (status == eap_status_ok)
       
  2714 		{
       
  2715 			status = eap_status_completed_request;
       
  2716 		}
       
  2717 	}
       
  2718 #else
       
  2719 
       
  2720 	EAP_UNREFERENCED_PARAMETER(next_eap_identifier);
       
  2721 	EAP_UNREFERENCED_PARAMETER(send_network_id);
       
  2722 	EAP_UNREFERENCED_PARAMETER(username);
       
  2723 	EAP_UNREFERENCED_PARAMETER(imsi);
       
  2724 	EAP_UNREFERENCED_PARAMETER(type);	
       
  2725 	EAP_UNREFERENCED_PARAMETER(completion_action);
       
  2726 	
       
  2727 #endif // #if defined (USE_EAP_TYPE_SERVER_AKA)
       
  2728 
       
  2729 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  2730 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2731 }	
       
  2732 
       
  2733 //--------------------------------------------------
       
  2734 
       
  2735 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_re_syncronization(
       
  2736 	const u8_t /*next_eap_identifier*/,
       
  2737 	eap_type_aka_authentication_vector_c * const /*authentication_vector*/
       
  2738 	)
       
  2739 {
       
  2740 	/********** For server.**********/
       
  2741 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  2742 }
       
  2743 
       
  2744 //--------------------------------------------------
       
  2745 
       
  2746 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::cancel_imsi_from_username_query()
       
  2747 {
       
  2748 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2749 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2750 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  2751 }
       
  2752 
       
  2753 //--------------------------------------------------
       
  2754 
       
  2755 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::type_configure_read(
       
  2756 	const eap_configuration_field_c * const field,
       
  2757 	eap_variable_data_c * const data)
       
  2758 {
       
  2759 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2760 	EAP_ASSERT(data != 0);
       
  2761 
       
  2762 	eap_status_e status(eap_status_ok);
       
  2763 	
       
  2764 	// Trap must be set here because the OS independent portion of EAP AKA
       
  2765 	// that calls this function does not know anything about Symbian.	
       
  2766 	TRAPD(err, type_configure_readL(
       
  2767 		field->get_field(),
       
  2768 		field->get_field_length(),
       
  2769 		data));
       
  2770 	if (err != KErrNone)
       
  2771 	{
       
  2772 		EAP_TRACE_DEBUG(
       
  2773 			m_am_tools,
       
  2774 			TRACE_FLAGS_DEFAULT,
       
  2775 			(EAPL("eap_am_type_aka_symbian_c::type_configure_read(): LEAVE from type_configure_readL, error=%d, Reads configuration from partner.\n"),
       
  2776 			err));
       
  2777 	
       
  2778 		status = m_partner->read_configure(
       
  2779 			field,
       
  2780 			data);
       
  2781 	}
       
  2782 
       
  2783 	m_am_tools->trace_configuration(
       
  2784 		status,
       
  2785 		field,
       
  2786 		data);
       
  2787 
       
  2788 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2789 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2790 }
       
  2791 
       
  2792 //--------------------------------------------------
       
  2793 
       
  2794 void eap_am_type_aka_symbian_c::type_configure_readL(
       
  2795 	eap_config_string field,
       
  2796 	const u32_t field_length,
       
  2797 	eap_variable_data_c * const data)
       
  2798 {
       
  2799 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2800 	EAP_UNREFERENCED_PARAMETER(field_length);
       
  2801 	
       
  2802 	// Create a buffer for the ascii strings - initialised with the argument
       
  2803 	HBufC8* asciibuf = HBufC8::NewLC(KMaxDBFieldNameLength);
       
  2804 	TPtr8 asciiString = asciibuf->Des();
       
  2805 	asciiString.Copy(reinterpret_cast<const unsigned char *>(field));
       
  2806 			
       
  2807 	// Buffer for unicode parameter
       
  2808 	HBufC* unicodebuf = HBufC::NewLC(KMaxDBFieldNameLength);
       
  2809 	TPtr unicodeString = unicodebuf->Des();
       
  2810 	
       
  2811 	// Convert to unicode 
       
  2812 	unicodeString.Copy(asciiString);
       
  2813 	
       
  2814 	// Now do the database query
       
  2815 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
  2816 	TPtr sqlStatement = buf->Des();
       
  2817 
       
  2818 	_LIT(KSQLQueryRow, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
  2819 	sqlStatement.Format(KSQLQueryRow, &unicodeString, &KAkaTableName, 
       
  2820 		&KServiceType, m_index_type, &KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
  2821 	
       
  2822 	RDbView view;
       
  2823 	User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited));
       
  2824 	CleanupClosePushL(view);
       
  2825 	User::LeaveIfError(view.EvaluateAll());	
       
  2826 	
       
  2827 	if (view.FirstL())
       
  2828 	{
       
  2829 		eap_status_e status;
       
  2830 		view.GetL();
       
  2831 				
       
  2832 		switch (view.ColType(KDefaultColumnInView_One))
       
  2833 		{
       
  2834 		case EDbColText:
       
  2835 			{
       
  2836 				unicodeString = view.ColDes(KDefaultColumnInView_One);
       
  2837 				// Convert to 8-bit
       
  2838 				asciiString.Copy(unicodeString);
       
  2839 				if (asciiString.Size() > 0)
       
  2840 				{
       
  2841 					status = data->set_copy_of_buffer(asciiString.Ptr(), asciiString.Size());
       
  2842 					if (status != eap_status_ok)
       
  2843 					{
       
  2844 						User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
       
  2845 					}
       
  2846 				} 
       
  2847 				else 
       
  2848 				{
       
  2849 					status = data->init(0);
       
  2850 					if (status != eap_status_ok)
       
  2851 					{
       
  2852 						User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
       
  2853 					}
       
  2854 					data->set_is_valid();					
       
  2855 					break;
       
  2856 				}
       
  2857 			}
       
  2858 			break;
       
  2859 
       
  2860 		case EDbColUint32:
       
  2861 			{
       
  2862 				TUint value;
       
  2863 				value = view.ColUint32(KDefaultColumnInView_One);
       
  2864 				status = data->set_copy_of_buffer(&value, sizeof(value));
       
  2865 				if (status != eap_status_ok)
       
  2866 				{
       
  2867 					User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
       
  2868 				}
       
  2869 			}
       
  2870 			break;
       
  2871 
       
  2872 		default:
       
  2873 			EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Unexpected column type.\n")));
       
  2874 			User::Leave(KErrGeneral);
       
  2875 			break;
       
  2876 		}
       
  2877 	} 
       
  2878 	else 
       
  2879 	{
       
  2880 		// Could not find parameter
       
  2881 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("type_configure_readL: Could not find configuration parameter.\n")));
       
  2882 		User::Leave(KErrArgument);
       
  2883 	}		
       
  2884 	
       
  2885 	CleanupStack::PopAndDestroy(4); // Close view, & 3 strings
       
  2886 
       
  2887 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2888 }
       
  2889 
       
  2890 //--------------------------------------------------
       
  2891 
       
  2892 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::type_configure_write(
       
  2893 	const eap_configuration_field_c * const field,
       
  2894 	eap_variable_data_c * const data)
       
  2895 {
       
  2896 	// NOTE: At the moment this is not called anywhere.
       
  2897 	// NOTE: This is really just for simulation.
       
  2898 	// Write is routed to partner object.
       
  2899 	eap_status_e status = m_partner->write_configure(
       
  2900 			field,
       
  2901 			data);
       
  2902 	return status;
       
  2903 }
       
  2904 
       
  2905 //--------------------------------------------------
       
  2906 
       
  2907 EAP_FUNC_EXPORT void eap_am_type_aka_symbian_c::set_is_valid()
       
  2908 {
       
  2909 	m_is_valid = true;
       
  2910 }
       
  2911 
       
  2912 //--------------------------------------------------
       
  2913 
       
  2914 EAP_FUNC_EXPORT bool eap_am_type_aka_symbian_c::get_is_valid()
       
  2915 {
       
  2916 	return m_is_valid;
       
  2917 }
       
  2918 
       
  2919 //--------------------------------------------------
       
  2920 
       
  2921 #if defined(__WINS__)
       
  2922 
       
  2923 EAP_FUNC_EXPORT eap_status_e eap_am_type_aka_symbian_c::query_SIM_imsi(
       
  2924 	u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length)
       
  2925 {
       
  2926 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2927 
       
  2928 	if (imsi == 0 || imsi_length == 0)
       
  2929 	{
       
  2930 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2931 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2932 	}
       
  2933 
       
  2934 	// This function returns Nokia test SIM IMSI.
       
  2935 	// It is used only when real AKA interface is not used.	
       
  2936 	
       
  2937 	*imsi_length = m_am_tools->strlen(TEST_IMSI);
       
  2938 	if (*imsi_length > max_length)
       
  2939 	{
       
  2940 		// ERROR, too short buffer.
       
  2941 		*imsi_length = 0u;
       
  2942 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2943 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2944 	}
       
  2945 	m_am_tools->memmove(imsi, TEST_IMSI, m_am_tools->strlen(TEST_IMSI));
       
  2946 
       
  2947 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2948 	return eap_status_ok;
       
  2949 }
       
  2950 
       
  2951 #endif //#if defined(__WINS__)
       
  2952 
       
  2953 //--------------------------------------------------
       
  2954 
       
  2955 eap_status_e eap_am_type_aka_symbian_c::check_is_valid_imsi(
       
  2956 	const eap_variable_data_c * const username)
       
  2957 {
       
  2958 	if (username == 0
       
  2959 		|| username->get_is_valid_data() == false)
       
  2960 	{
       
  2961 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2962 	}
       
  2963 
       
  2964 	for (u32_t ind = 0ul; ind < username->get_data_length(); ind++)
       
  2965 	{
       
  2966 		const u8_t * const digit = username->get_data_offset(
       
  2967 			ind,
       
  2968 			sizeof(u8_t));
       
  2969 		if (digit == 0
       
  2970 			|| *digit < '0'
       
  2971 			|| *digit > '9')
       
  2972 		{
       
  2973 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  2974 		}
       
  2975 	}
       
  2976 
       
  2977 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2978 }
       
  2979 
       
  2980 //--------------------------------------------------
       
  2981 
       
  2982 bool eap_am_type_aka_symbian_c::is_session_valid()
       
  2983 {
       
  2984 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2985 	
       
  2986 	bool sessionValidity(false);
       
  2987 	
       
  2988 	TRAPD(err, sessionValidity = is_session_validL());
       
  2989 	if (err != KErrNone) 
       
  2990 	{
       
  2991 		EAP_TRACE_ERROR(m_am_tools, 
       
  2992 			TRACE_FLAGS_DEFAULT, (
       
  2993 			EAPL("eap_am_type_aka_symbian_c::is_session_valid - LEAVE - error=%d, Assuming session is invalid \n"),
       
  2994 			err));
       
  2995 			
       
  2996 		sessionValidity = false;
       
  2997 	}
       
  2998 	 		
       
  2999 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3000 	
       
  3001 	return sessionValidity;
       
  3002 }
       
  3003 
       
  3004 //--------------------------------------------------
       
  3005 
       
  3006 bool eap_am_type_aka_symbian_c::is_session_validL()
       
  3007 {
       
  3008 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3009 
       
  3010 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::is_session_valid - start \n")));
       
  3011 
       
  3012 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
  3013 	TPtr sqlStatement = buf->Des();
       
  3014 	
       
  3015 	// Query all the relevant parameters
       
  3016 	_LIT(KSQLQuery, "SELECT %S, %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
  3017 	sqlStatement.Format(KSQLQuery, &cf_str_EAP_AKA_max_session_validity_time_literal,
       
  3018 						&KAKALastFullAuthTime, &KAkaTableName,
       
  3019 						&KServiceType, m_index_type, 
       
  3020 						&KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
  3021 
       
  3022 	RDbView view;
       
  3023 	// Evaluate view
       
  3024 	User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement)));
       
  3025 	CleanupClosePushL(view);
       
  3026 	User::LeaveIfError(view.EvaluateAll());
       
  3027 	
       
  3028 	// Get the first (and only) row
       
  3029 	view.FirstL();
       
  3030 	view.GetL();
       
  3031 	
       
  3032 	// Get column set so we get the correct column numbers
       
  3033 	CDbColSet* colSet = view.ColSetL();
       
  3034 	CleanupStack::PushL(colSet);
       
  3035 		
       
  3036 	TInt64 maxSessionTime = view.ColInt64(colSet->ColNo(cf_str_EAP_AKA_max_session_validity_time_literal));
       
  3037 	TInt64 fullAuthTime = view.ColInt64(colSet->ColNo(KAKALastFullAuthTime));
       
  3038 
       
  3039 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
  3040 	CleanupStack::PopAndDestroy(&view); // Close view.
       
  3041 	CleanupStack::PopAndDestroy(buf); // Delete buf.
       
  3042 	
       
  3043 	// If the max session time from DB is zero then we use the 
       
  3044 	// one read from configuration file.
       
  3045 	
       
  3046 	if( maxSessionTime == 0)
       
  3047 	{
       
  3048 		EAP_TRACE_DEBUG(m_am_tools, 
       
  3049 			TRACE_FLAGS_DEFAULT, (
       
  3050 			EAPL("Session Validity - Using max session validity time from config file\n")));
       
  3051 	
       
  3052 		maxSessionTime = m_max_session_time; // value from configuration file.
       
  3053 	}
       
  3054 	
       
  3055 	// Get the current time.
       
  3056 	TTime currentTime;
       
  3057 	currentTime.UniversalTime();
       
  3058 	
       
  3059 	TTime lastFullAuthTime(fullAuthTime);
       
  3060 	
       
  3061 #if defined(_DEBUG) || defined(DEBUG)	
       
  3062 	
       
  3063 	TDateTime currentDateTime = currentTime.DateTime();
       
  3064 		
       
  3065 	TDateTime fullAuthDateTime = lastFullAuthTime.DateTime();
       
  3066 
       
  3067 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  3068 	(EAPL("Session Validity - Current Time,        %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), 
       
  3069 	currentDateTime.Day()+1, currentDateTime.Month()+1, currentDateTime.Year(), currentDateTime.Hour(),
       
  3070 	currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond()));
       
  3071 
       
  3072 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  3073 	(EAPL("Session Validity - Last Full Auth Time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), 
       
  3074 	fullAuthDateTime.Day()+1, fullAuthDateTime.Month()+1, fullAuthDateTime.Year(), fullAuthDateTime.Hour(),
       
  3075 	fullAuthDateTime.Minute(), fullAuthDateTime.Second(), fullAuthDateTime.MicroSecond()));
       
  3076 
       
  3077 #endif
       
  3078 
       
  3079 	TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(lastFullAuthTime);
       
  3080 		
       
  3081 	EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("eap_am_type_aka_symbian_c::is_session_valid:interval in microseconds:"),
       
  3082 			&(interval.Int64()),
       
  3083 			sizeof(interval.Int64()) ) );
       
  3084 			
       
  3085 	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:"),
       
  3086 			&(maxSessionTime),
       
  3087 			sizeof(maxSessionTime) ) );
       
  3088 			
       
  3089 	
       
  3090 #if defined(_DEBUG) || defined(DEBUG)
       
  3091 
       
  3092 	TTimeIntervalMinutes intervalMins;
       
  3093 	TInt error = currentTime.MinutesFrom(lastFullAuthTime, intervalMins);
       
  3094 	
       
  3095 	if(error == KErrNone)
       
  3096 	{
       
  3097 		EAP_TRACE_DEBUG(
       
  3098 			m_am_tools,
       
  3099 			TRACE_FLAGS_DEFAULT,
       
  3100 			(EAPL("eap_am_type_aka_symbian_c::is_session_validL()")
       
  3101 			 EAPL("interval in Minutes =%d\n"),
       
  3102 			 intervalMins.Int()));
       
  3103 	}
       
  3104 	
       
  3105 #endif
       
  3106 
       
  3107 
       
  3108 	if( maxSessionTime >= interval.Int64() )
       
  3109 	{
       
  3110 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::is_session_valid - Session Valid \n")));
       
  3111 
       
  3112 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);			
       
  3113 
       
  3114 		return true;	
       
  3115 	}
       
  3116 	else
       
  3117 	{
       
  3118 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::is_session_valid - Session NOT Valid \n")));
       
  3119 
       
  3120 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);			
       
  3121 		
       
  3122 		return false;	
       
  3123 	}
       
  3124 }
       
  3125 
       
  3126 //--------------------------------------------------
       
  3127 
       
  3128 void eap_am_type_aka_symbian_c::store_authentication_timeL()
       
  3129 {
       
  3130 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3131 	
       
  3132 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_type_aka_symbian_c::store_authentication_timeL - start \n")));	
       
  3133 
       
  3134 	HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
       
  3135 	TPtr sqlStatement = buf->Des();
       
  3136 	
       
  3137 	// Query all the relevant parameters
       
  3138 	_LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d AND %S=%d AND %S=%d");
       
  3139 	sqlStatement.Format(KSQLQuery, &KAKALastFullAuthTime, &KAkaTableName,
       
  3140 						&KServiceType, m_index_type, 
       
  3141 						&KServiceIndex, m_index, &KTunnelingType, m_tunneling_vendor_type);
       
  3142 
       
  3143 	RDbView view;
       
  3144 	// Evaluate view
       
  3145 	User::LeaveIfError(view.Prepare(m_database, TDbQuery(sqlStatement), TDbWindow::EUnlimited));
       
  3146 	CleanupClosePushL(view);
       
  3147 	User::LeaveIfError(view.EvaluateAll());
       
  3148 	
       
  3149 	// Get the first (and only) row for updation.
       
  3150 	view.FirstL();
       
  3151 	view.UpdateL();
       
  3152 	
       
  3153 	// Get column set so we get the correct column numbers
       
  3154 	CDbColSet* colSet = view.ColSetL();
       
  3155 	CleanupStack::PushL(colSet);
       
  3156 
       
  3157 	// Get the current universal time.
       
  3158 	TTime currentTime;
       
  3159 	currentTime.UniversalTime();
       
  3160 		
       
  3161 #if defined(_DEBUG) || defined(DEBUG)	
       
  3162 	
       
  3163 	TDateTime currentDateTime = currentTime.DateTime();
       
  3164 	
       
  3165 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  3166 	(EAPL("eap_am_type_aka_symbian_c::store_authentication_time, %2d-%2d-%4d : %2d-%2d-%2d-%d\n"), 
       
  3167 	currentDateTime.Day()+1, currentDateTime.Month()+1,currentDateTime.Year(), currentDateTime.Hour(),
       
  3168 	currentDateTime.Minute(), currentDateTime.Second(), currentDateTime.MicroSecond()));
       
  3169 
       
  3170 #endif
       
  3171 
       
  3172 	TInt64 fullAuthTime = currentTime.Int64();
       
  3173 	
       
  3174 	view.SetColL(colSet->ColNo(KAKALastFullAuthTime), fullAuthTime);
       
  3175 
       
  3176 	view.PutL();	
       
  3177 
       
  3178 	CleanupStack::PopAndDestroy(colSet); // Delete colSet.
       
  3179 	CleanupStack::PopAndDestroy(&view); // Close view.
       
  3180 	CleanupStack::PopAndDestroy(buf); // Delete buf.
       
  3181 
       
  3182 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);			
       
  3183 }
       
  3184 
       
  3185 //--------------------------------------------------
       
  3186 
       
  3187 //  End of File