eapol/eapol_framework/wapi_common/src/ec_certificate_store.cpp
changeset 17 8840d3e38314
equal deleted inserted replaced
2:1c7bc153c08e 17:8840d3e38314
       
     1 /*
       
     2 * ============================================================================
       
     3 *  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_certificate_store.cpp
       
     4 *  Part of     : WAPI / WAPI       *** Info from the SWAD
       
     5 *  Description : WAPI authentication
       
     6 *  Version     : %version: 109 % << Don't touch! Updated by Synergy at check-out.
       
     7 *
       
     8 *  Copyright © 2001-2009 Nokia.  All rights reserved.
       
     9 *  This material, including documentation and any related computer
       
    10 *  programs, is protected by copyright controlled by Nokia.  All
       
    11 *  rights are reserved.  Copying, including reproducing, storing,
       
    12 *  adapting or translating, any or all of this material requires the
       
    13 *  prior written consent of Nokia.  This material also contains
       
    14 *  confidential information which may not be disclosed to others
       
    15 *  without the prior written consent of Nokia.
       
    16 * ============================================================================
       
    17 * Template version: 4.1.1
       
    18 */
       
    19 
       
    20 // This is enumeration of WAPI source code.
       
    21 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    22 	#undef EAP_FILE_NUMBER_ENUM
       
    23 	#define EAP_FILE_NUMBER_ENUM 701 
       
    24 	#undef EAP_FILE_NUMBER_DATE 
       
    25 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    26 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    27 
       
    28 
       
    29 #if defined(USE_WAPI_CORE)
       
    30 
       
    31 #include "eap_automatic_variable.h"
       
    32 #include "ec_certificate_store.h"
       
    33 #include "ec_cs_types.h"
       
    34 #include "ec_cs_strings.h"
       
    35 #include "abs_ec_certificate_store.h"
       
    36 #include "abs_eap_am_file_input.h"
       
    37 #include "asn1_der_type.h"
       
    38 #include "ec_am_base_algorithms.h"
       
    39 #include "wapi_asn1_der_parser.h"
       
    40 #include "ec_am_base_certificate_store.h"
       
    41 #include "ec_cs_tlv.h"
       
    42 #include "ec_cs_tlv_payloads.h"
       
    43 #include "eap_protocol_layer.h"
       
    44 #include "eap_state_notification.h"
       
    45 #include "ec_cs_compare_certificate_id.h"
       
    46 #include "wapi_certificate_asn1_der_parser.h"
       
    47 #include "ec_cs_compare_certificate_issuer_name.h"
       
    48 #include "ec_cs_compare_certificate_reference.h"
       
    49 #include "ec_cs_compare_reference_id.h"
       
    50 #include "ec_cs_compare_reference.h"
       
    51 #include "ec_cs_compare_reference_issuer_name.h"
       
    52 #include "eap_tlv_message_data.h"
       
    53 #include "eap_crypto_api.h"
       
    54 
       
    55 //----------------------------------------------------------------------------
       
    56 
       
    57 EAP_FUNC_EXPORT ec_certificate_store_c::~ec_certificate_store_c()
       
    58 {
       
    59 	EAP_TRACE_DEBUG(
       
    60 		m_am_tools,
       
    61 		TRACE_FLAGS_DEFAULT,
       
    62 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::~ec_certificate_store_c():\n"),
       
    63 		 this,
       
    64 		 (m_is_client == true ? "client": "server")));
       
    65 
       
    66 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::~ec_certificate_store_c()");
       
    67 
       
    68 	delete m_ec_algorithms;
       
    69 	m_ec_algorithms = 0;
       
    70 
       
    71 }
       
    72 
       
    73 //----------------------------------------------------------------------------
       
    74 
       
    75 EAP_FUNC_EXPORT ec_certificate_store_c::ec_certificate_store_c(
       
    76 	abs_eap_am_tools_c * const tools,
       
    77 	abs_ec_certificate_store_c * const partner,
       
    78 	ec_am_base_certificate_store_c * const am_certificate_store,
       
    79 	const bool is_client_when_true)
       
    80 	: m_am_tools(tools)
       
    81 	, m_partner(partner)
       
    82 	, m_ec_algorithms(0)
       
    83 	, m_am_certificate_store(am_certificate_store)
       
    84 	, m_receive_network_id(tools)
       
    85 	, m_master_key_changed(false)
       
    86 	, m_PAC_store_master_key(tools)
       
    87 	, m_PAC_store_password(tools)
       
    88 	, m_PAC_store_device_seed(tools)
       
    89 	, m_completion_queue(tools)
       
    90 	, m_pending_operation(ec_cs_pending_operation_none)
       
    91 	, m_queried_issuer_ID(tools)
       
    92 	, m_imported_certificate_wapi_id(tools)
       
    93 	, m_imported_certificate_file_data(tools)
       
    94 	, m_imported_certificate_filename(tools)
       
    95 	, m_imported_certificate_data(tools)
       
    96 	, m_imported_private_key_data(tools)
       
    97 	, m_ec_cs_completion_status(eap_status_process_general_error)
       
    98 	, m_ae_certificate(tools)
       
    99 
       
   100 	, m_selected_ca_id(tools)
       
   101 	, m_selected_client_id(tools)
       
   102 
       
   103 	, m_broken_cs_data_list(tools)
       
   104 	, m_ca_asu_id_list(tools)
       
   105 	, m_read_ca_asu_id_list(false)
       
   106 	, m_client_asu_id_list(tools)
       
   107 	, m_read_client_asu_id_list(false)
       
   108 	, m_ca_certificates(tools)
       
   109 	, m_client_certificates(tools)
       
   110 	, m_client_private_keys(tools)
       
   111 
       
   112 	, m_peer_identity(tools)
       
   113 	, m_signature(tools)
       
   114 
       
   115 	, m_hash_of_message(tools)
       
   116 	, m_id_of_own_certificate(tools)
       
   117 
       
   118 	, m_dummy_test_asu_certificate(tools)
       
   119 	, m_dummy_test_asu_private_key(tools)
       
   120 	, m_dummy_test_peer_certificate(tools)
       
   121 	, m_dummy_test_own_certificate(tools)
       
   122 	, m_dummy_test_own_private_key(tools)
       
   123 
       
   124 	, m_is_client(is_client_when_true)
       
   125 	, m_is_valid(false)
       
   126 	, m_shutdown_was_called(false)
       
   127 	, m_reference_counter_read(false)
       
   128 	, m_reference_counter_changed(false)
       
   129 	, m_reference_counter(0ul)
       
   130 	, m_PAC_store_key_timeout_ms(EAP_FAST_PAC_STORE_DEFAULT_KEY_CACHE_TIMEOUT)
       
   131 	, m_already_in_completion_action_check(false)
       
   132 	, m_pending_read_ec_cs_data(false)
       
   133 	, m_complete_start_certificate_import(false)
       
   134 	, m_certificate_store_initialized(false)
       
   135 	, m_allow_use_of_ae_certificate(false)
       
   136 {
       
   137 	EAP_TRACE_DEBUG(
       
   138 		m_am_tools,
       
   139 		TRACE_FLAGS_DEFAULT,
       
   140 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::ec_certificate_store_c():\n"),
       
   141 		 this,
       
   142 		 (m_is_client == true ? "client": "server")));
       
   143 
       
   144 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::ec_certificate_store_c()");
       
   145 
       
   146 	if (partner == 0
       
   147 		|| am_certificate_store == 0)
       
   148 	{
       
   149 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   150 		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   151 		return;
       
   152 	}
       
   153 
       
   154 	m_ec_algorithms = ec_am_base_algorithms_c::new_ec_base_algorithms_c(
       
   155 		tools,
       
   156 		this,
       
   157 		is_client_when_true);
       
   158 	if (m_ec_algorithms == 0
       
   159 		|| m_ec_algorithms->get_is_valid() == false)
       
   160 	{
       
   161 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   162 		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   163 		return;
       
   164 	}
       
   165 
       
   166 	am_certificate_store->set_am_certificate_store_partner(this);
       
   167 
       
   168 	m_is_valid = true;
       
   169 }
       
   170 
       
   171 //----------------------------------------------------------------------------
       
   172 
       
   173 EAP_FUNC_EXPORT bool ec_certificate_store_c::get_is_valid() const
       
   174 {
       
   175 	return m_is_valid;
       
   176 }
       
   177 
       
   178 //--------------------------------------------------
       
   179 
       
   180 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::read_configure(
       
   181 	const eap_configuration_field_c * const field,
       
   182 	eap_variable_data_c * const data)
       
   183 {
       
   184 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   185 
       
   186 	const eap_status_e status = m_partner->read_configure(field, data);
       
   187 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   188 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   189 }
       
   190 
       
   191 //----------------------------------------------------------------------------
       
   192 
       
   193 #if defined(USE_WAPI_CORE_SERVER) || !defined(WAPI_USE_CERTIFICATE_STORE)
       
   194 
       
   195 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::read_test_certificate(
       
   196 	const eap_configuration_field_c * const field,
       
   197 	eap_variable_data_c * const data)
       
   198 {
       
   199 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   200 
       
   201 	EAP_TRACE_DEBUG(
       
   202 		m_am_tools,
       
   203 		TRACE_FLAGS_DEFAULT,
       
   204 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_test_certificate():\n"),
       
   205 		 this,
       
   206 		 (m_is_client == true ? "client": "server")));
       
   207 
       
   208 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_test_certificate()");
       
   209 
       
   210 	eap_status_e status(eap_status_not_supported);
       
   211 
       
   212 	{
       
   213 		eap_variable_data_c name(m_am_tools);
       
   214 		if (name.get_is_valid() == false)
       
   215 		{
       
   216 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   217 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   218 		}
       
   219 
       
   220 		status = m_partner->read_configure(
       
   221 			field,
       
   222 			&name);
       
   223 		if (status == eap_status_ok
       
   224 			&& name.get_is_valid_data() == true)
       
   225 		{
       
   226 			// OK test certificate configured.
       
   227 
       
   228 			abs_eap_am_file_input_c * const file_input = abs_eap_am_file_input_c::new_abs_eap_am_file_input_c(m_am_tools);
       
   229 
       
   230 			eap_automatic_variable_c<abs_eap_am_file_input_c> automatic_file_input(m_am_tools, file_input);
       
   231 
       
   232 			if (file_input == 0
       
   233 				|| file_input->get_is_valid() == false)
       
   234 			{
       
   235 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   236 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   237 			}
       
   238 
       
   239 			status = file_input->file_open(&name, eap_file_io_direction_read);
       
   240 			if (status != eap_status_ok)
       
   241 			{
       
   242 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   243 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   244 			}
       
   245 
       
   246 			u32_t file_size = file_input->file_size();
       
   247 
       
   248 			status = data->set_buffer_length(file_size);
       
   249 			if (status != eap_status_ok)
       
   250 			{
       
   251 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   252 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   253 			}
       
   254 
       
   255 			status = file_input->file_read(data);
       
   256 			if (status != eap_status_ok)
       
   257 			{
       
   258 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   259 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   260 			}
       
   261 		}
       
   262 		else
       
   263 		{
       
   264 			// Here we ignore missing configuration data.
       
   265 			status = eap_status_ok;
       
   266 		}
       
   267 	}
       
   268 
       
   269 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   270 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   271 }
       
   272 
       
   273 #endif //#if defined(USE_WAPI_CORE_SERVER) || !defined(WAPI_USE_CERTIFICATE_STORE)
       
   274 
       
   275 //----------------------------------------------------------------------------
       
   276 
       
   277 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::configure()
       
   278 {
       
   279 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   280 
       
   281 	EAP_TRACE_DEBUG(
       
   282 		m_am_tools,
       
   283 		TRACE_FLAGS_DEFAULT,
       
   284 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::configure():\n"),
       
   285 		 this,
       
   286 		 (m_is_client == true ? "client": "server")));
       
   287 
       
   288 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::configure()");
       
   289 
       
   290 	eap_status_e status(eap_status_not_supported);
       
   291 
       
   292 
       
   293 	{
       
   294 		eap_variable_data_c EAP_FAST_PAC_store_key_timeout_ms(m_am_tools);
       
   295 
       
   296 		eap_status_e status = m_partner->read_configure(
       
   297 			cf_str_EAP_FAST_PAC_store_key_timeout_ms.get_field(),
       
   298 			&EAP_FAST_PAC_store_key_timeout_ms);
       
   299 		if (status == eap_status_ok
       
   300 			&& EAP_FAST_PAC_store_key_timeout_ms.get_is_valid_data() == true)
       
   301 		{
       
   302 			u32_t *timeout_ms = reinterpret_cast<u32_t *>(
       
   303 				EAP_FAST_PAC_store_key_timeout_ms.get_data(sizeof(u32_t)));
       
   304 			if (timeout_ms != 0)
       
   305 			{
       
   306 				m_PAC_store_key_timeout_ms = *timeout_ms;
       
   307 			}
       
   308 		}
       
   309 	}
       
   310 
       
   311 
       
   312 	{
       
   313 		// Read CS store password from memory store if such exists.
       
   314 		eap_variable_data_c key(m_am_tools);
       
   315 
       
   316 		status = key.set_copy_of_buffer(
       
   317 			WAPI_CS_MEMORY_STORE_KEY,
       
   318 			sizeof(WAPI_CS_MEMORY_STORE_KEY));
       
   319 		if (status != eap_status_ok)
       
   320 		{
       
   321 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   322 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   323 		}
       
   324 
       
   325 		eap_tlv_message_data_c tlv_data(m_am_tools);
       
   326 
       
   327 		status = m_am_tools->memory_store_get_data(
       
   328 			&key,
       
   329 			&tlv_data);
       
   330 		if (status != eap_status_ok)
       
   331 		{
       
   332 			EAP_TRACE_DEBUG(
       
   333 				m_am_tools,
       
   334 				TRACE_FLAGS_DEFAULT,
       
   335 				(EAPL("ec_certificate_store_c::configure(): cannot get credentials\n")));
       
   336 
       
   337 			// Ignore the error.
       
   338 			status = eap_status_ok;
       
   339 		}
       
   340 		else
       
   341 		{
       
   342 			EAP_TRACE_DEBUG(
       
   343 				m_am_tools,
       
   344 				TRACE_FLAGS_DEFAULT,
       
   345 				(EAPL("ec_certificate_store_c::configure(): credentials found\n")));
       
   346 
       
   347 			// Parse read data.
       
   348 			eap_array_c<eap_tlv_header_c> tlv_blocks(m_am_tools);
       
   349 				
       
   350 			status = tlv_data.parse_message_data(&tlv_blocks);
       
   351 			if (status != eap_status_ok)
       
   352 			{
       
   353 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   354 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   355 			}
       
   356 
       
   357 			for (u32_t ind = 0ul; ind < tlv_blocks.get_object_count(); ind++)
       
   358 			{
       
   359 				eap_tlv_header_c * const tlv = tlv_blocks.get_object(ind);
       
   360 				if (tlv != 0)
       
   361 				{
       
   362 					if (tlv->get_type() == ec_cs_data_type_password)
       
   363 					{
       
   364 						status = m_PAC_store_password.set_copy_of_buffer(
       
   365 							tlv->get_value(tlv->get_value_length()),
       
   366 							tlv->get_value_length());
       
   367 						if (status != eap_status_ok)
       
   368 						{
       
   369 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   370 							return EAP_STATUS_RETURN(m_am_tools, status);
       
   371 						}
       
   372 
       
   373 						EAP_TRACE_DATA_DEBUG(
       
   374 							m_am_tools,
       
   375 							TRACE_FLAGS_DEFAULT,
       
   376 							(EAPL("CS store password"),
       
   377 							 m_PAC_store_password.get_data(),
       
   378 							 m_PAC_store_password.get_data_length()));
       
   379 					}
       
   380 					else if (tlv->get_type() == ec_cs_data_type_device_seed)
       
   381 					{
       
   382 						status = m_PAC_store_device_seed.set_copy_of_buffer(
       
   383 							tlv->get_value(tlv->get_value_length()),
       
   384 							tlv->get_value_length());
       
   385 						if (status != eap_status_ok)
       
   386 						{
       
   387 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   388 							return EAP_STATUS_RETURN(m_am_tools, status);
       
   389 						}
       
   390 
       
   391 						EAP_TRACE_DATA_DEBUG(
       
   392 							m_am_tools,
       
   393 							TRACE_FLAGS_DEFAULT,
       
   394 							(EAPL("CS store device seed"),
       
   395 							 m_PAC_store_device_seed.get_data(),
       
   396 							 m_PAC_store_device_seed.get_data_length()));
       
   397 					}
       
   398 					else if (tlv->get_type() == ec_cs_data_type_master_key)
       
   399 					{
       
   400 						status = m_PAC_store_master_key.set_copy_of_buffer(
       
   401 							tlv->get_value(tlv->get_value_length()),
       
   402 							tlv->get_value_length());
       
   403 						if (status != eap_status_ok)
       
   404 						{
       
   405 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   406 							return EAP_STATUS_RETURN(m_am_tools, status);
       
   407 						}
       
   408 
       
   409 						EAP_TRACE_DATA_DEBUG(
       
   410 							m_am_tools,
       
   411 							TRACE_FLAGS_DEFAULT,
       
   412 							(EAPL("CS store master key"),
       
   413 							 m_PAC_store_master_key.get_data(),
       
   414 							 m_PAC_store_master_key.get_data_length()));
       
   415 					}
       
   416 					else if (tlv->get_type() == ec_cs_data_type_reference_counter)
       
   417 					{
       
   418 						u32_t * data = reinterpret_cast<u32_t *>(tlv->get_value(sizeof(m_reference_counter)));
       
   419 						if (data != 0)
       
   420 						{
       
   421 							m_reference_counter = eap_read_u32_t_network_order(
       
   422 								data,
       
   423 								sizeof(m_reference_counter));
       
   424 						}
       
   425 					}
       
   426 					else
       
   427 					{
       
   428 						EAP_TRACE_DEBUG(
       
   429 							m_am_tools,
       
   430 							TRACE_FLAGS_DEFAULT,
       
   431 							(EAPL("ec_certificate_store_c::configure(): unknown credential type %d, length %d\n"),
       
   432 							 tlv->get_type(),
       
   433 							 tlv->get_value_length()));
       
   434 					}
       
   435 				}
       
   436 			} // for()
       
   437 
       
   438 			status = m_am_tools->memory_store_remove_data(&key);
       
   439 			if (status != eap_status_ok)
       
   440 			{
       
   441 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   442 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   443 			}
       
   444 
       
   445 			EAP_TRACE_DEBUG(
       
   446 				m_am_tools,
       
   447 				TRACE_FLAGS_DEFAULT,
       
   448 				(EAPL("ec_certificate_store_c::configure(): credentials removed from eapol\n")));
       
   449 		}
       
   450 	}
       
   451 
       
   452 
       
   453 #if !defined(WAPI_USE_CERTIFICATE_STORE)
       
   454 	if (m_is_client == true)
       
   455 	{
       
   456 		status = read_test_certificate(
       
   457 			cf_str_WAPI_ASU_certificate_file.get_field(),
       
   458 			&m_dummy_test_asu_certificate);
       
   459 		if (status != eap_status_ok)
       
   460 		{
       
   461 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   462 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   463 		}
       
   464 
       
   465 		status = read_test_certificate(
       
   466 			cf_str_WAPI_ASUE_certificate_file.get_field(),
       
   467 			&m_dummy_test_own_certificate);
       
   468 		if (status != eap_status_ok)
       
   469 		{
       
   470 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   471 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   472 		}
       
   473 
       
   474 		status = read_test_certificate(
       
   475 			cf_str_WAPI_ASUE_private_key_file.get_field(),
       
   476 			&m_dummy_test_own_private_key);
       
   477 		if (status != eap_status_ok)
       
   478 		{
       
   479 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   480 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   481 		}
       
   482 
       
   483 		status = read_test_certificate(
       
   484 			cf_str_WAPI_AE_certificate_file.get_field(),
       
   485 			&m_dummy_test_peer_certificate);
       
   486 		if (status != eap_status_ok)
       
   487 		{
       
   488 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   489 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   490 		}
       
   491 	}
       
   492 	else
       
   493 #endif //#if !defined(WAPI_USE_CERTIFICATE_STORE)
       
   494 #if defined(USE_WAPI_CORE_SERVER)
       
   495 
       
   496 	if (m_is_client == false)
       
   497 	{
       
   498 		status = read_test_certificate(
       
   499 			cf_str_WAPI_ASU_certificate_file.get_field(),
       
   500 			&m_dummy_test_asu_certificate);
       
   501 		if (status != eap_status_ok)
       
   502 		{
       
   503 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   504 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   505 		}
       
   506 
       
   507 		status = read_test_certificate(
       
   508 			cf_str_WAPI_AE_certificate_file.get_field(),
       
   509 			&m_dummy_test_own_certificate);
       
   510 		if (status != eap_status_ok)
       
   511 		{
       
   512 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   513 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   514 		}
       
   515 
       
   516 		status = read_test_certificate(
       
   517 			cf_str_WAPI_AE_private_key_file.get_field(),
       
   518 			&m_dummy_test_own_private_key);
       
   519 		if (status != eap_status_ok)
       
   520 		{
       
   521 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   522 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   523 		}
       
   524 
       
   525 		status = read_test_certificate(
       
   526 			cf_str_WAPI_ASU_private_key_file.get_field(),
       
   527 			&m_dummy_test_asu_private_key);
       
   528 		if (status != eap_status_ok)
       
   529 		{
       
   530 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   531 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   532 		}
       
   533 
       
   534 		status = read_test_certificate(
       
   535 			cf_str_WAPI_ASUE_certificate_file.get_field(),
       
   536 			&m_dummy_test_peer_certificate);
       
   537 		if (status != eap_status_ok)
       
   538 		{
       
   539 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   540 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   541 		}
       
   542 	}
       
   543 	else
       
   544 #endif //#if defined(USE_WAPI_CORE_SERVER)
       
   545 	{
       
   546 		status = eap_status_ok;
       
   547 	}
       
   548 
       
   549 	{
       
   550 		// Adds timer to delete CS store Key from member variable.
       
   551 
       
   552 		EAP_TRACE_DEBUG(
       
   553 			m_am_tools,
       
   554 			TRACE_FLAGS_DEFAULT,
       
   555 			(EAPL("ec_certificate_store_c::configure(): am_set_timer(): WAPI_CS_KEY_TIMER_ID\n")));
       
   556 
       
   557 		status = m_am_tools->am_set_timer(
       
   558 			this,
       
   559 			WAPI_CS_KEY_TIMER_ID,
       
   560 			0,
       
   561 			m_PAC_store_key_timeout_ms);
       
   562 		if (status != eap_status_ok)
       
   563 		{
       
   564 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   565 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   566 		}
       
   567 	}
       
   568 
       
   569 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   570 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   571 }
       
   572 
       
   573 //------------------------------------------------------------------------------
       
   574 
       
   575 eap_status_e ec_certificate_store_c::cancel_operations()
       
   576 {
       
   577 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   578 
       
   579 	EAP_TRACE_DEBUG(
       
   580 		m_am_tools,
       
   581 		TRACE_FLAGS_DEFAULT,
       
   582 		(EAPL("WAPI_Core: ec_certificate_store_c::cancel_operations()\n")));
       
   583 
       
   584 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::cancel_operations()");
       
   585 
       
   586 	eap_status_e status(eap_status_ok);
       
   587 
       
   588 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
   589 
       
   590 	status = m_am_certificate_store->cancel_certificate_store_store_operations();
       
   591 
       
   592 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
   593 
       
   594 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   595 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   596 }
       
   597 
       
   598 
       
   599 //--------------------------------------------------
       
   600 
       
   601 eap_status_e ec_certificate_store_c::save_data_to_permanent_store()
       
   602 {
       
   603 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   604 
       
   605 	EAP_TRACE_DEBUG(
       
   606 		m_am_tools,
       
   607 		TRACE_FLAGS_DEFAULT,
       
   608 		(EAPL("WAPI_Core: this = 0x%08x, %s, ec_certificate_store_c::save_data_to_permanent_store()\n"),
       
   609 		this,
       
   610 		(m_is_client == true ? "client": "server")));
       
   611 
       
   612 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_data_to_permanent_store()");
       
   613 
       
   614 	eap_status_e status(eap_status_ok);
       
   615 
       
   616 	if (m_is_client == true)
       
   617 	{
       
   618 		if (m_certificate_store_initialized == true)
       
   619 		{
       
   620 			// Save all data to permanent store.
       
   621 
       
   622 			eap_array_c<ec_cs_data_c> data_references(m_am_tools);
       
   623 
       
   624 			if (m_reference_counter_changed == true)
       
   625 			{
       
   626 				/*
       
   627 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
   628 				 * | Type=Referene counter TLV     |           Length=4            |  |
       
   629 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
       
   630 				 * |                    reference counter (4 octets)               |  |
       
   631 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
   632 				 * | Type=CS-MAC TLV               |           Length=32           |  |
       
   633 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
       
   634 				 * |                              MAC (32 octets)                  |  |
       
   635 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
   636 				 */
       
   637 
       
   638 				ec_cs_data_c * const refence_counter = new ec_cs_data_c(m_am_tools);
       
   639 
       
   640 				eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, refence_counter);
       
   641 
       
   642 				if (refence_counter == 0
       
   643 					|| refence_counter->get_is_valid() == false)
       
   644 				{
       
   645 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   646 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   647 				}
       
   648 
       
   649 				EAP_TRACE_DEBUG(
       
   650 					m_am_tools,
       
   651 					TRACE_FLAGS_DEFAULT,
       
   652 					(EAPL("Wrote reference counter = 0x%08x\n"),
       
   653 					 m_reference_counter));
       
   654 
       
   655 				refence_counter->set_type(ec_cs_data_type_reference_counter);
       
   656 
       
   657 				status = refence_counter->get_writable_reference()->set_copy_of_buffer(
       
   658 					EC_CS_ZERO_REFERENCE,
       
   659 					sizeof(EC_CS_ZERO_REFERENCE));
       
   660 				if (status != eap_status_ok)
       
   661 				{
       
   662 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   663 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   664 				}
       
   665 
       
   666 				eap_variable_data_c reference_counter_MAC_key(m_am_tools);
       
   667 				if (reference_counter_MAC_key.get_is_valid() == false)
       
   668 				{
       
   669 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   670 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   671 				}
       
   672 
       
   673 				ec_cs_tlv_c pac_tlv_handler(m_am_tools, true);
       
   674 				if (pac_tlv_handler.get_is_valid() == false)
       
   675 				{
       
   676 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   677 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   678 				}
       
   679 
       
   680 				status = pac_tlv_handler.generate_data_key(
       
   681 					false,
       
   682 					ec_cs_data_type_reference_counter,
       
   683 					&reference_counter_MAC_key,
       
   684 					&m_PAC_store_master_key,
       
   685 					refence_counter->get_reference(),
       
   686 					&m_PAC_store_device_seed);
       
   687 				if (status != eap_status_ok)
       
   688 				{
       
   689 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   690 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   691 				}
       
   692 
       
   693 				ec_cs_variable_data_c reference_counter_tlv(m_am_tools);
       
   694 				if (reference_counter_tlv.get_is_valid() == false)
       
   695 				{
       
   696 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   697 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   698 				}
       
   699 
       
   700 				status = pac_tlv_handler.create_u32_t_tlv(
       
   701 					&reference_counter_tlv,
       
   702 					ec_cs_tlv_type_CS_reference_counter,
       
   703 					m_reference_counter);
       
   704 				if (status != eap_status_ok)
       
   705 				{
       
   706 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   707 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   708 				}
       
   709 
       
   710 				status = pac_tlv_handler.create_data_with_MAC(
       
   711 					&reference_counter_MAC_key,
       
   712 					reference_counter_tlv.get_full_tlv_buffer(),
       
   713 					refence_counter->get_writable_data());
       
   714 				if (status != eap_status_ok)
       
   715 				{
       
   716 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   717 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   718 				}
       
   719 
       
   720 				EAP_TRACE_DATA_DEBUG(
       
   721 					m_am_tools,
       
   722 					TRACE_FLAGS_DEFAULT,
       
   723 					(EAPL("New reference counter data"),
       
   724 					 refence_counter->get_data()->get_data(),
       
   725 					 refence_counter->get_data()->get_data_length()));
       
   726 
       
   727 				refence_counter->set_change_status(ec_cs_data_change_status_new);
       
   728 
       
   729 				status = data_references.add_object(refence_counter->copy(), true);
       
   730 				if (status != eap_status_ok)
       
   731 				{
       
   732 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   733 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   734 				}
       
   735 
       
   736 			}
       
   737 
       
   738 			if (m_master_key_changed == true)
       
   739 			{
       
   740 				// Create encrypted Master key data block.
       
   741 				// NOTE this is the only data encrypted with CS store password.
       
   742 
       
   743 				/*
       
   744 				 * Master key data
       
   745 				 *
       
   746  				 * 0                   1                   2                   3   
       
   747 				 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
   748 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    -+ -+
       
   749 				 * | Type=CS-Encrypted block TLV   |     Length=4+16+4+n+4+m       |     |  |
       
   750 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
       
   751 				 * | Type=CS-Encryption IV TLV     |           Length=16           |  |  |  | plain text
       
   752 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  |
       
   753 				 * |                              IV (16 octets)                   |  |  |  |
       
   754 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
       
   755 				 * | Type=CS-Encrypted data TLV    |           Length=n+4+m        |  |  |  |
       
   756 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  | -+
       
   757 				 * |                          Master key TLV (n octets)            |  |  |  |
       
   758 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | encrypted
       
   759 				 * | Type=CS-padding TLV           |           Length=m            |  |  |  | multiple of
       
   760 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | 16 octets
       
   761 				 * |                           padding (m octets)                  |  |  |  |
       
   762 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
       
   763 				 * | Type=CS-MAC TLV               |           Length=32           |  |
       
   764 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
       
   765 				 * |                              MAC (32 octets)                  |  |
       
   766 				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
   767 				 */
       
   768 
       
   769 				ec_cs_data_c * const master_key = new ec_cs_data_c(m_am_tools);
       
   770 
       
   771 				eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, master_key);
       
   772 
       
   773 				if (master_key == 0
       
   774 					|| master_key->get_is_valid() == false)
       
   775 				{
       
   776 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   777 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   778 				}
       
   779 
       
   780 				master_key->set_type(ec_cs_data_type_master_key);
       
   781 
       
   782 				status = master_key->get_writable_reference()->set_copy_of_buffer(
       
   783 					EC_CS_ZERO_REFERENCE,
       
   784 					sizeof(EC_CS_ZERO_REFERENCE));
       
   785 				if (status != eap_status_ok)
       
   786 				{
       
   787 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   788 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   789 				}
       
   790 
       
   791 				ec_cs_tlv_c pac_tlv_handler(m_am_tools, true);
       
   792 				if (pac_tlv_handler.get_is_valid() == false)
       
   793 				{
       
   794 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   795 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   796 				}
       
   797 
       
   798 				status = pac_tlv_handler.create_master_key_data(
       
   799 					&m_PAC_store_password,
       
   800 					&m_PAC_store_device_seed,
       
   801 					&m_PAC_store_master_key,
       
   802 					master_key->get_reference(),
       
   803 					master_key->get_writable_data());
       
   804 				if (status != eap_status_ok)
       
   805 				{
       
   806 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   807 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   808 				}
       
   809 
       
   810 				master_key->set_change_status(ec_cs_data_change_status_new);
       
   811 
       
   812 				status = data_references.add_object(master_key->copy(), true);
       
   813 				if (status != eap_status_ok)
       
   814 				{
       
   815 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   816 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   817 				}
       
   818 			}
       
   819 
       
   820 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   821 
       
   822 			status = copy<ec_cs_data_c>(
       
   823 				&m_ca_certificates,
       
   824 				&data_references,
       
   825 				m_am_tools,
       
   826 				true);
       
   827 			if (status != eap_status_ok)
       
   828 			{
       
   829 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   830 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   831 			}
       
   832 
       
   833 			status = copy<ec_cs_data_c>(
       
   834 				&m_client_certificates,
       
   835 				&data_references,
       
   836 				m_am_tools,
       
   837 				true);
       
   838 			if (status != eap_status_ok)
       
   839 			{
       
   840 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   841 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   842 			}
       
   843 
       
   844 			status = copy<ec_cs_data_c>(
       
   845 				&m_client_private_keys,
       
   846 				&data_references,
       
   847 				m_am_tools,
       
   848 				true);
       
   849 			if (status != eap_status_ok)
       
   850 			{
       
   851 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   852 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   853 			}
       
   854 
       
   855 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   856 
       
   857 			status = add_asu_id_list(
       
   858 				&m_ca_asu_id_list,
       
   859 				&data_references);
       
   860 			if (status != eap_status_ok)
       
   861 			{
       
   862 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   863 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   864 			}
       
   865 
       
   866 			status = add_asu_id_list(
       
   867 				&m_client_asu_id_list,
       
   868 				&data_references);
       
   869 			if (status != eap_status_ok)
       
   870 			{
       
   871 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   872 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   873 			}
       
   874 
       
   875 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   876 
       
   877 			status = copy<ec_cs_data_c>(
       
   878 				&m_broken_cs_data_list,
       
   879 				&data_references,
       
   880 				m_am_tools,
       
   881 				true);
       
   882 			if (status != eap_status_ok)
       
   883 			{
       
   884 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   885 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   886 			}
       
   887 
       
   888 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   889 
       
   890 			EAP_TRACE_DEBUG(
       
   891 				m_am_tools,
       
   892 				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
   893 				(EAPL("calls: ec_certificate_store_c::save_data_to_permanent_store(): m_am_pac_store_services->write_PAC_store_data(): %d.\n"),
       
   894 				__LINE__));
       
   895 
       
   896 			status = m_am_certificate_store->write_certificate_store_data(
       
   897 				true,
       
   898 				ec_cs_pending_operation_none,
       
   899 				&data_references);
       
   900 			if (status != eap_status_ok)
       
   901 			{
       
   902 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   903 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   904 			}
       
   905 		}
       
   906 		else
       
   907 		{
       
   908 			EAP_TRACE_DEBUG(
       
   909 				m_am_tools,
       
   910 				TRACE_FLAGS_DEFAULT,
       
   911 				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s, ec_certificate_store_c::save_data_to_permanent_store(): Certificate store NOT initialized. Do not save data.\n"),
       
   912 				this,
       
   913 				(m_is_client == true ? "client": "server")));
       
   914 		}
       
   915 	}
       
   916 
       
   917 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   918 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   919 }
       
   920 
       
   921 //--------------------------------------------------
       
   922 
       
   923 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::shutdown()
       
   924 {
       
   925 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   926 
       
   927 	EAP_TRACE_DEBUG(
       
   928 		m_am_tools,
       
   929 		TRACE_FLAGS_DEFAULT,
       
   930 		(EAPL("WAPI_Core: this = 0x%08x, %s, ec_certificate_store_c::shutdown()\n"),
       
   931 		this,
       
   932 		(m_is_client == true ? "client": "server")));
       
   933 
       
   934 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::shutdown()");
       
   935 
       
   936 	eap_status_e status(eap_status_process_general_error);
       
   937 
       
   938 	if (m_shutdown_was_called == true)
       
   939 	{
       
   940 		// Shutdown function was called already.
       
   941 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   942 	}
       
   943 	m_shutdown_was_called = true;
       
   944 
       
   945 	(void) m_am_tools->am_cancel_timer(
       
   946 			this,
       
   947 			WAPI_CS_KEY_TIMER_ID);
       
   948 
       
   949 	(void) cancel_operations();
       
   950 
       
   951 	(void) save_data_to_permanent_store();
       
   952 
       
   953 	(void) completion_action_clenup();
       
   954 
       
   955 	{
       
   956 		// Save the CS store password.
       
   957 		eap_variable_data_c key(m_am_tools);
       
   958 
       
   959 		status = key.set_copy_of_buffer(
       
   960 			WAPI_CS_MEMORY_STORE_KEY,
       
   961 			sizeof(WAPI_CS_MEMORY_STORE_KEY));
       
   962 		if (status != eap_status_ok)
       
   963 		{
       
   964 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   965 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   966 		}
       
   967 
       
   968 		(void) m_am_tools->memory_store_remove_data(&key);
       
   969 
       
   970 		eap_tlv_message_data_c tlv_data(m_am_tools);
       
   971 
       
   972 		if (m_PAC_store_password.get_is_valid_data() == true)
       
   973 		{
       
   974 			status = tlv_data.add_message_data(
       
   975 				ec_cs_data_type_password,
       
   976 				m_PAC_store_password.get_data_length(),
       
   977 				m_PAC_store_password.get_data());
       
   978 			if (status != eap_status_ok)
       
   979 			{
       
   980 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   981 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   982 			}
       
   983 		}
       
   984 
       
   985 		if (m_PAC_store_device_seed.get_is_valid_data() == true)
       
   986 		{
       
   987 			status = tlv_data.add_message_data(
       
   988 				ec_cs_data_type_device_seed,
       
   989 				m_PAC_store_device_seed.get_data_length(),
       
   990 				m_PAC_store_device_seed.get_data());
       
   991 			if (status != eap_status_ok)
       
   992 			{
       
   993 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   994 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   995 			}
       
   996 		}
       
   997 
       
   998 		if (m_PAC_store_master_key.get_is_valid_data() == true)
       
   999 		{
       
  1000 			status = tlv_data.add_message_data(
       
  1001 				ec_cs_data_type_master_key,
       
  1002 				m_PAC_store_master_key.get_data_length(),
       
  1003 				m_PAC_store_master_key.get_data());
       
  1004 			if (status != eap_status_ok)
       
  1005 			{
       
  1006 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1007 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1008 			}
       
  1009 		}
       
  1010 
       
  1011 		{
       
  1012 			u32_t network_order_reference_counter = eap_htonl(m_reference_counter);
       
  1013 
       
  1014 			status = tlv_data.add_message_data(
       
  1015 				ec_cs_data_type_reference_counter,
       
  1016 				sizeof(network_order_reference_counter),
       
  1017 				&network_order_reference_counter);
       
  1018 			if (status != eap_status_ok)
       
  1019 			{
       
  1020 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1021 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1022 			}
       
  1023 		}
       
  1024 
       
  1025 		status = m_am_tools->memory_store_add_data(
       
  1026 			&key,
       
  1027 			&tlv_data,
       
  1028 			m_PAC_store_key_timeout_ms);
       
  1029 		if (status != eap_status_ok)
       
  1030 		{
       
  1031 			EAP_TRACE_DEBUG(
       
  1032 				m_am_tools,
       
  1033 				TRACE_FLAGS_DEFAULT,
       
  1034 				(EAPL("ec_certificate_store_c::shutdown(): cannot store credentials\n")));
       
  1035 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1036 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1037 		}
       
  1038 	}
       
  1039 
       
  1040 
       
  1041 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1042 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1043 }
       
  1044 
       
  1045 //--------------------------------------------------
       
  1046 
       
  1047 eap_status_e ec_certificate_store_c::add_asu_id_list(
       
  1048 	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const asu_id_list,
       
  1049 	eap_array_c<ec_cs_data_c> * const data_references)
       
  1050 {
       
  1051 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1052 
       
  1053 	EAP_TRACE_DEBUG(
       
  1054 		m_am_tools,
       
  1055 		TRACE_FLAGS_DEFAULT,
       
  1056 		(EAPL("WAPI_Core: ec_certificate_store_c::add_asu_id_list()\n")));
       
  1057 
       
  1058 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_asu_id_list()");
       
  1059 
       
  1060 	eap_status_e status(eap_status_ok);
       
  1061 
       
  1062 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1063 
       
  1064 	for (u32_t index = 0ul; index < asu_id_list->get_object_count(); ++index)
       
  1065 	{
       
  1066 		const ec_cs_data_c * const data = asu_id_list->get_object(index);
       
  1067 		if (data != 0)
       
  1068 		{
       
  1069 			ec_cs_data_c * const new_ec_cd_data = data->copy();
       
  1070 			if (new_ec_cd_data != 0)
       
  1071 			{
       
  1072 				status = data_references->add_object(new_ec_cd_data, true);
       
  1073 				if (status != eap_status_ok)
       
  1074 				{
       
  1075 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1076 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  1077 				}
       
  1078 			}
       
  1079 		}
       
  1080 	}
       
  1081 
       
  1082 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1083 	
       
  1084 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1085 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1086 }
       
  1087 
       
  1088 //--------------------------------------------------
       
  1089 
       
  1090 eap_status_e ec_certificate_store_c::create_unique_reference(
       
  1091 	ec_cs_data_c * const out_reference)
       
  1092 {
       
  1093 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1094 
       
  1095 	EAP_TRACE_DEBUG(
       
  1096 		m_am_tools,
       
  1097 		TRACE_FLAGS_DEFAULT,
       
  1098 		(EAPL("WAPI_Core: ec_certificate_store_c::create_unique_reference()\n")));
       
  1099 
       
  1100 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_unique_reference()");
       
  1101 
       
  1102 	eap_status_e status(eap_status_process_general_error);
       
  1103 
       
  1104 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1105 
       
  1106 	++m_reference_counter;
       
  1107 
       
  1108 	EAP_TRACE_DEBUG(
       
  1109 		m_am_tools,
       
  1110 		TRACE_FLAGS_DEFAULT,
       
  1111 		(EAPL("Increased reference counter = 0x%08x\n"),
       
  1112 		 m_reference_counter));
       
  1113 
       
  1114 	m_reference_counter_changed = true;
       
  1115 
       
  1116 	u32_t network_order_counter = eap_htonl(m_reference_counter);
       
  1117 
       
  1118 	status = out_reference->get_writable_reference()->set_copy_of_buffer(
       
  1119 		&network_order_counter,
       
  1120 		sizeof(network_order_counter));
       
  1121 
       
  1122 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1123 
       
  1124 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1125 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1126 }
       
  1127 
       
  1128 //----------------------------------------------------------------------------
       
  1129 
       
  1130 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::initialize_certificate_store()
       
  1131 {
       
  1132 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1133 
       
  1134 	EAP_TRACE_DEBUG(
       
  1135 		m_am_tools,
       
  1136 		TRACE_FLAGS_DEFAULT,
       
  1137 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::initialize_certificate_store():\n"),
       
  1138 		 this,
       
  1139 		 (m_is_client == true ? "client": "server")));
       
  1140 
       
  1141 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::initialize_certificate_store()");
       
  1142 
       
  1143 	eap_status_e status(eap_status_not_supported);
       
  1144 
       
  1145 	status = m_am_certificate_store->initialize_certificate_store(wapi_completion_operation_continue_certificate_authentication);
       
  1146 
       
  1147 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1148 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1149 }
       
  1150 
       
  1151 //----------------------------------------------------------------------------
       
  1152 
       
  1153 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::query_asu_id()
       
  1154 {
       
  1155 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1156 
       
  1157 	EAP_TRACE_DEBUG(
       
  1158 		m_am_tools,
       
  1159 		TRACE_FLAGS_DEFAULT,
       
  1160 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::query_asu_id():\n"),
       
  1161 		 this,
       
  1162 		 (m_is_client == true ? "client": "server")));
       
  1163 
       
  1164 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::query_asu_id()");
       
  1165 
       
  1166 	eap_variable_data_c asn1_der_subject_name(m_am_tools);
       
  1167 	eap_variable_data_c asn1_der_issuer_name(m_am_tools);
       
  1168 	eap_variable_data_c asn1_der_sequence_number(m_am_tools);
       
  1169 
       
  1170 	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
       
  1171 	if (parser.get_is_valid() == false)
       
  1172 	{
       
  1173 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1174 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1175 	}
       
  1176 
       
  1177 	eap_status_e status(eap_status_ok);
       
  1178 
       
  1179 	if (m_selected_ca_id.get_is_valid_data() == true)
       
  1180 	{
       
  1181 		wapi_asn1_der_parser_c asn1_der_parser(m_am_tools);
       
  1182 		if (asn1_der_parser.get_is_valid() == false)
       
  1183 		{
       
  1184 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1185 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1186 		}
       
  1187 
       
  1188 		status = asn1_der_parser.decode(&m_selected_ca_id);
       
  1189 		if (status != eap_status_ok)
       
  1190 		{
       
  1191 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1192 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1193 		}
       
  1194 
       
  1195 		status = asn1_der_parser.get_wapi_identity(
       
  1196 			&asn1_der_subject_name,
       
  1197 			&asn1_der_issuer_name,
       
  1198 			&asn1_der_sequence_number);
       
  1199 		if (status != eap_status_ok)
       
  1200 		{
       
  1201 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1202 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1203 		}
       
  1204 	}
       
  1205 	else
       
  1206 	{
       
  1207 		status = parser.decode(&m_dummy_test_asu_certificate);
       
  1208 		if (status != eap_status_ok)
       
  1209 		{
       
  1210 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1211 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1212 		}
       
  1213 
       
  1214 		status = parser.read_certificate_id(
       
  1215 			&asn1_der_subject_name,
       
  1216 			&asn1_der_issuer_name,
       
  1217 			&asn1_der_sequence_number);
       
  1218 		if (status != eap_status_ok)
       
  1219 		{
       
  1220 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1221 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1222 		}
       
  1223 	}
       
  1224 
       
  1225 	status = m_partner->complete_query_asu_id(
       
  1226 		&asn1_der_subject_name,
       
  1227 		&asn1_der_issuer_name,
       
  1228 		&asn1_der_sequence_number,
       
  1229 		status);
       
  1230 
       
  1231 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1232 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1233 }
       
  1234 
       
  1235 //----------------------------------------------------------------------------
       
  1236 
       
  1237 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::compare_id_and_certificate(
       
  1238 	const eap_variable_data_c * const ID,
       
  1239 	const eap_variable_data_c * const certificate)
       
  1240 {
       
  1241 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1242 
       
  1243 	EAP_TRACE_DEBUG(
       
  1244 		m_am_tools,
       
  1245 		TRACE_FLAGS_DEFAULT,
       
  1246 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::compare_id_and_certificate():\n"),
       
  1247 		 this,
       
  1248 		 (m_is_client == true ? "client": "server")));
       
  1249 
       
  1250 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::compare_id_and_certificate()");
       
  1251 
       
  1252 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1253 
       
  1254 	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
       
  1255 	if (parser.get_is_valid() == false)
       
  1256 	{
       
  1257 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1258 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1259 	}
       
  1260 
       
  1261 	eap_status_e status = parser.decode(certificate);
       
  1262 	if (status != eap_status_ok)
       
  1263 	{
       
  1264 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1265 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1266 	}
       
  1267 
       
  1268 	eap_variable_data_c certificate_id(m_am_tools);
       
  1269 	if (certificate_id.get_is_valid() == false)
       
  1270 	{
       
  1271 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1272 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1273 	}
       
  1274 
       
  1275 	status = parser.read_certificate_id(
       
  1276 		&certificate_id);
       
  1277 	if (status != eap_status_ok)
       
  1278 	{
       
  1279 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1280 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1281 	}
       
  1282 
       
  1283 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1284 
       
  1285 	if (certificate_id.compare(ID) == 0)
       
  1286 	{
       
  1287 		EAP_TRACE_DATA_DEBUG(
       
  1288 			m_am_tools,
       
  1289 			TRACE_FLAGS_DEFAULT,
       
  1290 			(EAPL("OK: compare_id_and_certificate(): match certificate_id"),
       
  1291 			certificate_id.get_data(),
       
  1292 			certificate_id.get_data_length()));
       
  1293 
       
  1294 		EAP_TRACE_DATA_DEBUG(
       
  1295 			m_am_tools,
       
  1296 			TRACE_FLAGS_DEFAULT,
       
  1297 			(EAPL("OK: compare_id_and_certificate(): match ID"),
       
  1298 			ID->get_data(),
       
  1299 			ID->get_data_length()));
       
  1300 
       
  1301 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1302 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1303 	}
       
  1304 	else
       
  1305 	{
       
  1306 		EAP_TRACE_DATA_DEBUG(
       
  1307 			m_am_tools,
       
  1308 			TRACE_FLAGS_DEFAULT,
       
  1309 			(EAPL("INFO: compare_id_and_certificate(): mismatch certificate_id"),
       
  1310 			certificate_id.get_data(),
       
  1311 			certificate_id.get_data_length()));
       
  1312 
       
  1313 		EAP_TRACE_DATA_DEBUG(
       
  1314 			m_am_tools,
       
  1315 			TRACE_FLAGS_DEFAULT,
       
  1316 			(EAPL("INFO: compare_id_and_certificate(): mismatch ID"),
       
  1317 			ID->get_data(),
       
  1318 			ID->get_data_length()));
       
  1319 
       
  1320 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1321 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_match);
       
  1322 	}
       
  1323 }
       
  1324 
       
  1325 //----------------------------------------------------------------------------
       
  1326 
       
  1327 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::compare_issuer_name_of_id_and_certificate(
       
  1328 	const eap_variable_data_c * const issuer_ID,
       
  1329 	const eap_variable_data_c * const certificate)
       
  1330 {
       
  1331 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1332 
       
  1333 	EAP_TRACE_DEBUG(
       
  1334 		m_am_tools,
       
  1335 		TRACE_FLAGS_DEFAULT,
       
  1336 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::compare_issuer_name_of_id_and_certificate():\n"),
       
  1337 		 this,
       
  1338 		 (m_is_client == true ? "client": "server")));
       
  1339 
       
  1340 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::compare_issuer_name_of_id_and_certificate()");
       
  1341 
       
  1342 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1343 
       
  1344 	eap_variable_data_c issuer_ID_subject_name(m_am_tools);
       
  1345 	eap_variable_data_c issuer_ID_issuer_name(m_am_tools);
       
  1346 	eap_variable_data_c issuer_ID_sequence_number(m_am_tools);
       
  1347 
       
  1348 	wapi_asn1_der_parser_c asn1_der_parser(m_am_tools);
       
  1349 	if (asn1_der_parser.get_is_valid() == false)
       
  1350 	{
       
  1351 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1352 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1353 	}
       
  1354 
       
  1355 	eap_status_e status = asn1_der_parser.decode(issuer_ID);
       
  1356 	if (status != eap_status_ok)
       
  1357 	{
       
  1358 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1359 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1360 	}
       
  1361 
       
  1362 	status = asn1_der_parser.get_wapi_identity(
       
  1363 		&issuer_ID_subject_name,
       
  1364 		&issuer_ID_issuer_name,
       
  1365 		&issuer_ID_sequence_number);
       
  1366 	if (status != eap_status_ok)
       
  1367 	{
       
  1368 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1369 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1370 	}
       
  1371 
       
  1372 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1373 
       
  1374 	eap_variable_data_c certificate_subject_name(m_am_tools);
       
  1375 	eap_variable_data_c certificate_issuer_name(m_am_tools);
       
  1376 	eap_variable_data_c certificate_sequence_number(m_am_tools);
       
  1377 
       
  1378 	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
       
  1379 	if (parser.get_is_valid() == false)
       
  1380 	{
       
  1381 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1382 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1383 	}
       
  1384 
       
  1385 	status = parser.decode(certificate);
       
  1386 	if (status != eap_status_ok)
       
  1387 	{
       
  1388 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1389 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1390 	}
       
  1391 
       
  1392 	status = parser.read_certificate_id(
       
  1393 		&certificate_subject_name,
       
  1394 		&certificate_issuer_name,
       
  1395 		&certificate_sequence_number);
       
  1396 	if (status != eap_status_ok)
       
  1397 	{
       
  1398 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1399 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1400 	}
       
  1401 
       
  1402 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1403 
       
  1404 	if (certificate_issuer_name.compare(&issuer_ID_issuer_name) == 0)
       
  1405 	{
       
  1406 		EAP_TRACE_DATA_DEBUG(
       
  1407 			m_am_tools,
       
  1408 			TRACE_FLAGS_DEFAULT,
       
  1409 			(EAPL("OK: compare_issuer_name_of_id_and_certificate(): match certificate_issuer_name"),
       
  1410 			certificate_issuer_name.get_data(),
       
  1411 			certificate_issuer_name.get_data_length()));
       
  1412 
       
  1413 		EAP_TRACE_DATA_DEBUG(
       
  1414 			m_am_tools,
       
  1415 			TRACE_FLAGS_DEFAULT,
       
  1416 			(EAPL("OK: compare_issuer_name_of_id_and_certificate(): match issuer_ID_issuer_name"),
       
  1417 			issuer_ID_issuer_name.get_data(),
       
  1418 			issuer_ID_issuer_name.get_data_length()));
       
  1419 
       
  1420 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1421 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1422 	}
       
  1423 	else
       
  1424 	{
       
  1425 		EAP_TRACE_DATA_DEBUG(
       
  1426 			m_am_tools,
       
  1427 			TRACE_FLAGS_DEFAULT,
       
  1428 			(EAPL("INFO: compare_issuer_name_of_id_and_certificate(): mismatch certificate_issuer_name"),
       
  1429 			certificate_issuer_name.get_data(),
       
  1430 			certificate_issuer_name.get_data_length()));
       
  1431 
       
  1432 		EAP_TRACE_DATA_DEBUG(
       
  1433 			m_am_tools,
       
  1434 			TRACE_FLAGS_DEFAULT,
       
  1435 			(EAPL("INFO: compare_issuer_name_of_id_and_certificate(): mismatch issuer_ID_issuer_name"),
       
  1436 			issuer_ID_issuer_name.get_data(),
       
  1437 			issuer_ID_issuer_name.get_data_length()));
       
  1438 
       
  1439 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1440 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_match);
       
  1441 	}
       
  1442 }
       
  1443 
       
  1444 //----------------------------------------------------------------------------
       
  1445 
       
  1446 eap_status_e ec_certificate_store_c::compare_issuer_common_name_and_certificate(
       
  1447 	const eap_variable_data_c * const certificate,
       
  1448 	const eap_variable_data_c * const subject_common_name)
       
  1449 {
       
  1450 	eap_variable_data_c certificate_subject_name(m_am_tools);
       
  1451 	eap_variable_data_c certificate_issuer_name(m_am_tools);
       
  1452 	eap_variable_data_c certificate_sequence_number(m_am_tools);
       
  1453 
       
  1454 	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
       
  1455 	if (parser.get_is_valid() == false)
       
  1456 	{
       
  1457 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1458 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1459 	}
       
  1460 
       
  1461 	eap_status_e status = parser.decode(certificate);
       
  1462 	if (status != eap_status_ok)
       
  1463 	{
       
  1464 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1465 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1466 	}
       
  1467 
       
  1468 	status = parser.read_certificate_id(
       
  1469 		&certificate_subject_name,
       
  1470 		&certificate_issuer_name,
       
  1471 		&certificate_sequence_number);
       
  1472 	if (status != eap_status_ok)
       
  1473 	{
       
  1474 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1475 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1476 	}
       
  1477 
       
  1478 	wapi_asn1_der_parser_c parse_subject_name(m_am_tools);
       
  1479 	if (parse_subject_name.get_is_valid() == false)
       
  1480 	{
       
  1481 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1482 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1483 	}
       
  1484 
       
  1485 	eap_variable_data_c subject_name(m_am_tools);
       
  1486 
       
  1487 	status = parse_subject_name.get_decoded_subject_name(
       
  1488 		&certificate_subject_name,
       
  1489 		&subject_name);
       
  1490 	if (status != eap_status_ok)
       
  1491 	{
       
  1492 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1493 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1494 	}
       
  1495 
       
  1496 	if (subject_common_name->compare(&subject_name) == 0)
       
  1497 	{
       
  1498 		EAP_TRACE_DATA_DEBUG(
       
  1499 			m_am_tools,
       
  1500 			TRACE_FLAGS_DEFAULT,
       
  1501 			(EAPL("OK: compare_issuer_common_name_and_certificate(): match subject_common_name"),
       
  1502 			subject_common_name->get_data(),
       
  1503 			subject_common_name->get_data_length()));
       
  1504 
       
  1505 		EAP_TRACE_DATA_DEBUG(
       
  1506 			m_am_tools,
       
  1507 			TRACE_FLAGS_DEFAULT,
       
  1508 			(EAPL("OK: compare_issuer_common_name_and_certificate(): match subject_name"),
       
  1509 			subject_name.get_data(),
       
  1510 			subject_name.get_data_length()));
       
  1511 	}
       
  1512 	else
       
  1513 	{
       
  1514 		EAP_TRACE_DATA_DEBUG(
       
  1515 			m_am_tools,
       
  1516 			TRACE_FLAGS_DEFAULT,
       
  1517 			(EAPL("INFO: compare_issuer_common_name_and_certificate(): mismatch subject_common_name"),
       
  1518 			subject_common_name->get_data(),
       
  1519 			subject_common_name->get_data_length()));
       
  1520 
       
  1521 		EAP_TRACE_DATA_DEBUG(
       
  1522 			m_am_tools,
       
  1523 			TRACE_FLAGS_DEFAULT,
       
  1524 			(EAPL("INFO: compare_issuer_common_name_and_certificate(): mismatch subject_name"),
       
  1525 			subject_name.get_data(),
       
  1526 			subject_name.get_data_length()));
       
  1527 
       
  1528 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1529 		return EAP_STATUS_RETURN(m_am_tools, eap_status_user_certificate_unknown);
       
  1530 	}
       
  1531 
       
  1532 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1533 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1534 }
       
  1535 
       
  1536 //----------------------------------------------------------------------------
       
  1537 
       
  1538 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::get_own_certificate()
       
  1539 {
       
  1540 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1541 
       
  1542 	EAP_TRACE_DEBUG(
       
  1543 		m_am_tools,
       
  1544 		TRACE_FLAGS_DEFAULT,
       
  1545 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::get_own_certificate():\n"),
       
  1546 		 this,
       
  1547 		 (m_is_client == true ? "client": "server")));
       
  1548 
       
  1549 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::get_own_certificate()");
       
  1550 
       
  1551 	eap_status_e status = m_partner->complete_get_own_certificate(&m_dummy_test_own_certificate);
       
  1552 
       
  1553 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1554 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1555 }
       
  1556 
       
  1557 //----------------------------------------------------------------------------
       
  1558 
       
  1559 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::set_ae_certificate(
       
  1560 	const eap_variable_data_c * const ae_certificate)
       
  1561 {
       
  1562 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1563 
       
  1564 	EAP_TRACE_DEBUG(
       
  1565 		m_am_tools,
       
  1566 		TRACE_FLAGS_DEFAULT,
       
  1567 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::set_ae_certificate():\n"),
       
  1568 		 this,
       
  1569 		 (m_is_client == true ? "client": "server")));
       
  1570 
       
  1571 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::set_ae_certificate()");
       
  1572 
       
  1573 	eap_status_e status = m_ae_certificate.set_copy_of_buffer(ae_certificate);
       
  1574 
       
  1575 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1576 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1577 }
       
  1578 
       
  1579 //----------------------------------------------------------------------------
       
  1580 
       
  1581 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::select_certificate(
       
  1582 	const eap_variable_data_c * const issuer_ID)
       
  1583 {
       
  1584 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1585 
       
  1586 	EAP_TRACE_DEBUG(
       
  1587 		m_am_tools,
       
  1588 		TRACE_FLAGS_DEFAULT,
       
  1589 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::select_certificate():\n"),
       
  1590 		 this,
       
  1591 		 (m_is_client == true ? "client": "server")));
       
  1592 
       
  1593 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::select_certificate()");
       
  1594 
       
  1595 	EAP_TRACE_DATA_DEBUG(
       
  1596 		m_am_tools, 
       
  1597 		TRACE_FLAGS_DEFAULT, 
       
  1598 		(EAPL("issuer_ID"),
       
  1599 		 issuer_ID->get_data(),
       
  1600 		 issuer_ID->get_data_length()));
       
  1601 
       
  1602 	if (m_pending_operation != ec_cs_pending_operation_none)
       
  1603 	{
       
  1604 		// Some operation is already pending. Try again later.
       
  1605 		return EAP_STATUS_RETURN(m_am_tools, eap_status_device_busy);
       
  1606 	}
       
  1607 
       
  1608 #if defined(WAPI_USE_CERTIFICATE_STORE)
       
  1609 
       
  1610 	eap_status_e status = m_queried_issuer_ID.set_copy_of_buffer(issuer_ID);
       
  1611 	if (status != eap_status_ok)
       
  1612 	{
       
  1613 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1614 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1615 	}
       
  1616 
       
  1617 	status = completion_action_push(ec_cs_completion_internal_select_certificate);
       
  1618 	if (status != eap_status_ok)
       
  1619 	{
       
  1620 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1621 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1622 	}
       
  1623 
       
  1624 	status = completion_action_push(ec_cs_completion_internal_select_certificate_with_identity);
       
  1625 	if (status != eap_status_ok)
       
  1626 	{
       
  1627 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1628 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1629 	}
       
  1630 
       
  1631 	status = completion_action_push(ec_cs_completion_query_PAC_store_password);
       
  1632 	if (status != eap_status_ok)
       
  1633 	{
       
  1634 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1635 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1636 	}
       
  1637 
       
  1638 	status = initialize_certificate_store();
       
  1639 	if (status != eap_status_ok)
       
  1640 	{
       
  1641 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1642 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1643 	}
       
  1644 
       
  1645 	status = completion_action_check();
       
  1646 
       
  1647 #else
       
  1648 
       
  1649 	(void) EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  1650 
       
  1651 	eap_variable_data_c * selected_certificate = 0;
       
  1652 
       
  1653 	eap_variable_data_c certificate_id(m_am_tools);
       
  1654 	if (certificate_id.get_is_valid() == false)
       
  1655 	{
       
  1656 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1657 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1658 	}
       
  1659 
       
  1660 	eap_status_e status = compare_issuer_name_of_id_and_certificate(issuer_ID, &m_dummy_test_own_certificate);
       
  1661 	if (status == eap_status_ok)
       
  1662 	{
       
  1663 		selected_certificate = &m_dummy_test_own_certificate;
       
  1664 
       
  1665 		wapi_certificate_asn1_der_parser_c parser(m_am_tools);
       
  1666 		if (parser.get_is_valid() == false)
       
  1667 		{
       
  1668 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1669 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1670 		}
       
  1671 
       
  1672 		eap_status_e status = parser.decode(&m_dummy_test_asu_certificate);
       
  1673 		if (status != eap_status_ok)
       
  1674 		{
       
  1675 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1676 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1677 		}
       
  1678 
       
  1679 		status = parser.read_certificate_id(
       
  1680 			&certificate_id);
       
  1681 		if (status != eap_status_ok)
       
  1682 		{
       
  1683 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1684 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1685 		}
       
  1686 	}
       
  1687 
       
  1688 	status = m_partner->complete_select_certificate(
       
  1689 		issuer_ID,
       
  1690 		&certificate_id,
       
  1691 		selected_certificate);
       
  1692 
       
  1693 #endif
       
  1694 
       
  1695 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1696 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1697 }
       
  1698 
       
  1699 //----------------------------------------------------------------------------
       
  1700 
       
  1701 eap_status_e ec_certificate_store_c::internal_select_certificate_with_identity(
       
  1702 	const eap_variable_data_c * const user_certificate_id)
       
  1703 {
       
  1704 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1705 
       
  1706 	EAP_TRACE_DEBUG(
       
  1707 		m_am_tools,
       
  1708 		TRACE_FLAGS_DEFAULT,
       
  1709 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity():\n"),
       
  1710 		 this,
       
  1711 		 (m_is_client == true ? "client": "server")));
       
  1712 
       
  1713 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_select_certificate_with_identity()");
       
  1714 
       
  1715 	EAP_TRACE_DATA_DEBUG(
       
  1716 		m_am_tools, 
       
  1717 		TRACE_FLAGS_DEFAULT, 
       
  1718 		(EAPL("user_certificate_id"),
       
  1719 		 user_certificate_id->get_data(),
       
  1720 		 user_certificate_id->get_data_length()));
       
  1721 
       
  1722 	ec_cs_data_c search_id(m_am_tools);
       
  1723 
       
  1724 	eap_status_e status = search_id.get_writable_data()->set_buffer(
       
  1725 		user_certificate_id);
       
  1726 	if (status != eap_status_ok)
       
  1727 	{
       
  1728 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1729 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1730 	}
       
  1731 
       
  1732 	eap_variable_data_c certificate_reference(m_am_tools);
       
  1733 
       
  1734 	ec_cs_data_type_e certificate_type(ec_cs_data_type_none);
       
  1735 
       
  1736 	const ec_cs_data_c * reference_tlv = 0;
       
  1737 
       
  1738 	if (reference_tlv == 0
       
  1739 		&& m_read_client_asu_id_list == true)
       
  1740 	{
       
  1741 		// Search client certificate that is selected by UI.
       
  1742 
       
  1743 		ec_cs_compare_reference_id_c compare_certificate_id(m_am_tools);
       
  1744 
       
  1745 		ec_cs_data_c search_user_certificate_id(m_am_tools);
       
  1746 
       
  1747 		status = search_user_certificate_id.get_writable_data()->set_buffer(
       
  1748 			user_certificate_id);
       
  1749 		if (status != eap_status_ok)
       
  1750 		{
       
  1751 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1752 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1753 		}
       
  1754 
       
  1755 		EAP_TRACE_DEBUG(
       
  1756 			m_am_tools,
       
  1757 			TRACE_FLAGS_DEFAULT,
       
  1758 			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity(): count of m_client_asu_id_list = %d.\n"),
       
  1759 			 this,
       
  1760 			 (m_is_client == true ? "client": "server"),
       
  1761 			 m_client_asu_id_list.get_object_count()));
       
  1762 
       
  1763 		// Search Certificate-reference with the issuer ID.
       
  1764 		i32_t index = find_with_compare<ec_cs_data_c>(
       
  1765 			&compare_certificate_id,
       
  1766 			&m_client_asu_id_list,
       
  1767 			&search_user_certificate_id,
       
  1768 			m_am_tools);
       
  1769 		if (index >= 0)
       
  1770 		{
       
  1771 			// Match.
       
  1772 			EAP_TRACE_DEBUG(
       
  1773 				m_am_tools,
       
  1774 				TRACE_FLAGS_DEFAULT,
       
  1775 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity(): Certificate match.\n"),
       
  1776 				 this,
       
  1777 				 (m_is_client == true ? "client": "server")));
       
  1778 
       
  1779 			reference_tlv = m_client_asu_id_list.get_object(index);
       
  1780 			certificate_type = ec_cs_data_type_client_certificate_data;
       
  1781 		}
       
  1782 		else
       
  1783 		{
       
  1784 			EAP_TRACE_DEBUG(
       
  1785 				m_am_tools,
       
  1786 				TRACE_FLAGS_DEFAULT,
       
  1787 				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity(): No certificate match.\n"),
       
  1788 				 this,
       
  1789 				 (m_is_client == true ? "client": "server")));
       
  1790 		}
       
  1791 	}
       
  1792 
       
  1793 
       
  1794 	if (reference_tlv != 0)
       
  1795 	{
       
  1796 		status = read_certificate_reference(reference_tlv, &certificate_reference);
       
  1797 		if (status != eap_status_ok)
       
  1798 		{
       
  1799 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1800 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1801 		}
       
  1802 
       
  1803 		// Read the certificate from database.
       
  1804 		status = read_certificate(
       
  1805 			ec_cs_pending_operation_select_client_certificate,
       
  1806 			certificate_type,
       
  1807 			&certificate_reference);
       
  1808 		if (status != eap_status_ok)
       
  1809 		{
       
  1810 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1811 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1812 		}
       
  1813 	}
       
  1814 
       
  1815 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1816 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1817 }
       
  1818 
       
  1819 //----------------------------------------------------------------------------
       
  1820 
       
  1821 eap_status_e ec_certificate_store_c::internal_select_own_certificate_with_issuer_name()
       
  1822 {
       
  1823 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1824 
       
  1825 	EAP_TRACE_DEBUG(
       
  1826 		m_am_tools,
       
  1827 		TRACE_FLAGS_DEFAULT,
       
  1828 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name():\n"),
       
  1829 		 this,
       
  1830 		 (m_is_client == true ? "client": "server")));
       
  1831 
       
  1832 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name()");
       
  1833 
       
  1834 	EAP_TRACE_DATA_DEBUG(
       
  1835 		m_am_tools, 
       
  1836 		TRACE_FLAGS_DEFAULT, 
       
  1837 		(EAPL("m_id_of_own_certificate"),
       
  1838 		 m_id_of_own_certificate.get_data(),
       
  1839 		 m_id_of_own_certificate.get_data_length()));
       
  1840 
       
  1841 	eap_status_e status(eap_status_process_general_error);
       
  1842 
       
  1843 	ec_cs_data_c search_id(m_am_tools);
       
  1844 
       
  1845 	{
       
  1846 		wapi_asn1_der_parser_c parser(m_am_tools);
       
  1847 		if (parser.get_is_valid() == false)
       
  1848 		{
       
  1849 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1850 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1851 		}
       
  1852 
       
  1853 		status = parser.decode(&m_id_of_own_certificate);
       
  1854 		if (status != eap_status_ok)
       
  1855 		{
       
  1856 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1857 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1858 		}
       
  1859 
       
  1860 		eap_variable_data_c subject_name(m_am_tools);
       
  1861 		eap_variable_data_c issuer_name(m_am_tools);
       
  1862 		eap_variable_data_c sequence_number(m_am_tools);
       
  1863 
       
  1864 		status = parser.get_wapi_identity(
       
  1865 			&subject_name,
       
  1866 			&issuer_name,
       
  1867 			&sequence_number);
       
  1868 		if (status != eap_status_ok)
       
  1869 		{
       
  1870 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1871 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1872 		}
       
  1873 
       
  1874 		status = search_id.get_writable_data()->set_copy_of_buffer(
       
  1875 			&issuer_name);
       
  1876 		if (status != eap_status_ok)
       
  1877 		{
       
  1878 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1879 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1880 		}
       
  1881 	}
       
  1882 
       
  1883 
       
  1884 	eap_variable_data_c certificate_reference(m_am_tools);
       
  1885 
       
  1886 	ec_cs_compare_reference_issuer_name_c compare_reference_issuer_name(m_am_tools);
       
  1887 
       
  1888 	ec_cs_data_type_e certificate_type(ec_cs_data_type_none);
       
  1889 
       
  1890 	const ec_cs_data_c * reference_tlv = 0;
       
  1891 
       
  1892 	EAP_TRACE_DEBUG(
       
  1893 		m_am_tools,
       
  1894 		TRACE_FLAGS_DEFAULT,
       
  1895 		(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name(): count of m_client_asu_id_list = %d.\n"),
       
  1896 		 this,
       
  1897 		 (m_is_client == true ? "client": "server"),
       
  1898 		 m_client_asu_id_list.get_object_count()));
       
  1899 
       
  1900 	if (reference_tlv == 0
       
  1901 		&& m_read_client_asu_id_list == true)
       
  1902 	{
       
  1903 		// Search Certificate-reference with the issuer ID.
       
  1904 		i32_t index = find_with_compare<ec_cs_data_c>(
       
  1905 			&compare_reference_issuer_name,
       
  1906 			&m_client_asu_id_list,
       
  1907 			&search_id,
       
  1908 			m_am_tools);
       
  1909 		if (index >= 0)
       
  1910 		{
       
  1911 			// Match.
       
  1912 			EAP_TRACE_DEBUG(
       
  1913 				m_am_tools,
       
  1914 				TRACE_FLAGS_DEFAULT,
       
  1915 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name(): Certificate match.\n"),
       
  1916 				 this,
       
  1917 				 (m_is_client == true ? "client": "server")));
       
  1918 
       
  1919 			reference_tlv = m_client_asu_id_list.get_object(index);
       
  1920 			certificate_type = ec_cs_data_type_client_certificate_data;
       
  1921 		}
       
  1922 		else
       
  1923 		{
       
  1924 			EAP_TRACE_DEBUG(
       
  1925 				m_am_tools,
       
  1926 				TRACE_FLAGS_DEFAULT,
       
  1927 				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name(): No certificate match.\n"),
       
  1928 				 this,
       
  1929 				 (m_is_client == true ? "client": "server")));
       
  1930 		}
       
  1931 	}
       
  1932 
       
  1933 
       
  1934 	if (reference_tlv != 0)
       
  1935 	{
       
  1936 		status = read_certificate_reference(reference_tlv, &certificate_reference);
       
  1937 		if (status != eap_status_ok)
       
  1938 		{
       
  1939 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1940 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1941 		}
       
  1942 
       
  1943 		// Read the certificate from database.
       
  1944 		status = read_certificate(
       
  1945 			ec_cs_pending_operation_select_client_certificate,
       
  1946 			certificate_type,
       
  1947 			&certificate_reference);
       
  1948 		if (status != eap_status_ok)
       
  1949 		{
       
  1950 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1951 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1952 		}
       
  1953 	}
       
  1954 
       
  1955 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1956 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1957 }
       
  1958 
       
  1959 //----------------------------------------------------------------------------
       
  1960 
       
  1961 eap_status_e ec_certificate_store_c::internal_select_certificate()
       
  1962 {
       
  1963 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1964 
       
  1965 	EAP_TRACE_DEBUG(
       
  1966 		m_am_tools,
       
  1967 		TRACE_FLAGS_DEFAULT,
       
  1968 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate():\n"),
       
  1969 		 this,
       
  1970 		 (m_is_client == true ? "client": "server")));
       
  1971 
       
  1972 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_select_certificate()");
       
  1973 
       
  1974 	EAP_TRACE_DATA_DEBUG(
       
  1975 		m_am_tools, 
       
  1976 		TRACE_FLAGS_DEFAULT, 
       
  1977 		(EAPL("m_queried_issuer_ID"),
       
  1978 		 m_queried_issuer_ID.get_data(),
       
  1979 		 m_queried_issuer_ID.get_data_length()));
       
  1980 
       
  1981 	if (m_pending_operation != ec_cs_pending_operation_none)
       
  1982 	{
       
  1983 		// Some operation is already pending. Try again later.
       
  1984 		return EAP_STATUS_RETURN(m_am_tools, eap_status_device_busy);
       
  1985 	}
       
  1986 
       
  1987 	eap_status_e status(eap_status_not_supported);
       
  1988 
       
  1989 	ec_cs_compare_certificate_id_c compare_certificate_id(
       
  1990 		m_am_tools,
       
  1991 		&m_PAC_store_master_key,
       
  1992 		&m_PAC_store_device_seed);
       
  1993 
       
  1994 	const ec_cs_data_c * match_certificate_data = 0;
       
  1995 
       
  1996 	ec_cs_data_c search_id(m_am_tools);
       
  1997 
       
  1998 	status = search_id.get_writable_data()->set_buffer(
       
  1999 		&m_queried_issuer_ID);
       
  2000 	if (status != eap_status_ok)
       
  2001 	{
       
  2002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2003 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2004 	}
       
  2005 
       
  2006 	i32_t index(-1);
       
  2007 
       
  2008 	EAP_TRACE_DEBUG(
       
  2009 		m_am_tools,
       
  2010 		TRACE_FLAGS_DEFAULT,
       
  2011 		(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): count of m_ca_certificates = %d.\n"),
       
  2012 		 this,
       
  2013 		 (m_is_client == true ? "client": "server"),
       
  2014 		 m_ca_certificates.get_object_count()));
       
  2015 
       
  2016 	if (m_is_client == false)
       
  2017 	{
       
  2018 		// Search certificate with the issuer ID from CA-certificates.
       
  2019 		index = find_with_compare<ec_cs_data_c>(
       
  2020 			&compare_certificate_id,
       
  2021 			&m_ca_certificates,
       
  2022 			&search_id,
       
  2023 			m_am_tools);
       
  2024 	}
       
  2025 
       
  2026 	if (index >= 0)
       
  2027 	{
       
  2028 		// Match.
       
  2029 		EAP_TRACE_DEBUG(
       
  2030 			m_am_tools,
       
  2031 			TRACE_FLAGS_DEFAULT,
       
  2032 			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): CA certificate match.\n"),
       
  2033 			 this,
       
  2034 			 (m_is_client == true ? "client": "server")));
       
  2035 
       
  2036 		match_certificate_data = m_ca_certificates.get_object(index);
       
  2037 	}
       
  2038 	else
       
  2039 	{
       
  2040 		EAP_TRACE_DEBUG(
       
  2041 			m_am_tools,
       
  2042 			TRACE_FLAGS_DEFAULT,
       
  2043 			(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): No CA certificate match.\n"),
       
  2044 			 this,
       
  2045 			 (m_is_client == true ? "client": "server")));
       
  2046 
       
  2047 		eap_variable_data_c issuer_name(m_am_tools);
       
  2048 
       
  2049 		{
       
  2050 			wapi_asn1_der_parser_c parser(m_am_tools);
       
  2051 			if (parser.get_is_valid() == false)
       
  2052 			{
       
  2053 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2054 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2055 			}
       
  2056 
       
  2057 			eap_status_e status = parser.decode(&m_queried_issuer_ID);
       
  2058 			if (status != eap_status_ok)
       
  2059 			{
       
  2060 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2061 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2062 			}
       
  2063 
       
  2064 			eap_variable_data_c subject_name(m_am_tools);
       
  2065 			eap_variable_data_c sequence_number(m_am_tools);
       
  2066 
       
  2067 			status = parser.get_wapi_identity(
       
  2068 				&subject_name,
       
  2069 				&issuer_name,
       
  2070 				&sequence_number);
       
  2071 			if (status != eap_status_ok)
       
  2072 			{
       
  2073 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2074 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2075 			}
       
  2076 		}
       
  2077 
       
  2078 		ec_cs_compare_certificate_id_c compare_certificate_id(
       
  2079 			m_am_tools,
       
  2080 			&m_PAC_store_master_key,
       
  2081 			&m_PAC_store_device_seed);
       
  2082 
       
  2083 		ec_cs_data_c search_certificate_id(m_am_tools);
       
  2084 
       
  2085 		status = search_certificate_id.get_writable_data()->set_buffer(
       
  2086 			&m_selected_client_id);
       
  2087 
       
  2088 		if (status != eap_status_ok)
       
  2089 		{
       
  2090 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2091 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2092 		}
       
  2093 
       
  2094 		EAP_TRACE_DEBUG(
       
  2095 			m_am_tools,
       
  2096 			TRACE_FLAGS_DEFAULT,
       
  2097 			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): count of m_client_certificates = %d.\n"),
       
  2098 			 this,
       
  2099 			 (m_is_client == true ? "client": "server"),
       
  2100 			 m_client_certificates.get_object_count()));
       
  2101 
       
  2102 		// Search certificate with the issuer ID from client certificates.
       
  2103 		index = find_with_compare<ec_cs_data_c>(
       
  2104 			&compare_certificate_id,
       
  2105 			&m_client_certificates,
       
  2106 			&search_certificate_id,
       
  2107 			m_am_tools);
       
  2108 		if (index >= 0)
       
  2109 		{
       
  2110 			// Match.
       
  2111 			EAP_TRACE_DEBUG(
       
  2112 				m_am_tools,
       
  2113 				TRACE_FLAGS_DEFAULT,
       
  2114 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): Client certificate match.\n"),
       
  2115 				 this,
       
  2116 				 (m_is_client == true ? "client": "server")));
       
  2117 
       
  2118 			match_certificate_data = m_client_certificates.get_object(index);
       
  2119 		}
       
  2120 		else if (m_read_ca_asu_id_list == true
       
  2121 				 && m_read_client_asu_id_list == true)
       
  2122 		{
       
  2123 			// Both certificate lists are already read, cannot continue.
       
  2124 			EAP_TRACE_DEBUG(
       
  2125 				m_am_tools,
       
  2126 				TRACE_FLAGS_DEFAULT,
       
  2127 				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): No client certificate match.\n"),
       
  2128 				 this,
       
  2129 				 (m_is_client == true ? "client": "server")));
       
  2130 
       
  2131 			(void) m_partner->set_session_timeout(0ul);
       
  2132 
       
  2133 			if (m_is_client == false)
       
  2134 			{
       
  2135 				status = eap_status_ca_certificate_unknown;
       
  2136 			}
       
  2137 			else
       
  2138 			{
       
  2139 				status = eap_status_user_certificate_unknown;
       
  2140 			}
       
  2141 
       
  2142 			(void) send_error_notification(status);
       
  2143 
       
  2144 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2145 			return EAP_STATUS_RETURN(m_am_tools, eap_status_no_match);
       
  2146 		}
       
  2147 		else
       
  2148 		{
       
  2149 			status = completion_action_push(ec_cs_completion_internal_select_certificate);
       
  2150 			if (status != eap_status_ok)
       
  2151 			{
       
  2152 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2153 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2154 			}
       
  2155 
       
  2156 			status = completion_action_push(ec_cs_completion_internal_select_certificate_with_identity);
       
  2157 			if (status != eap_status_ok)
       
  2158 			{
       
  2159 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2160 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2161 			}
       
  2162 
       
  2163 			// This function call must be asyncronous.
       
  2164 			status = read_both_certificate_lists(ec_cs_pending_operation_select_client_certificate);
       
  2165 			if (status != eap_status_ok)
       
  2166 			{
       
  2167 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2168 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2169 			}
       
  2170 		}
       
  2171 	}
       
  2172 
       
  2173 	const eap_variable_data_c * certificate_data = 0;
       
  2174 
       
  2175 	eap_variable_data_c certificate_data_buffer(m_am_tools);
       
  2176 	eap_variable_data_c certificate_ID(m_am_tools);
       
  2177 
       
  2178 	if (certificate_data_buffer.get_is_valid() == false
       
  2179 		|| certificate_ID.get_is_valid() == false)
       
  2180 	{
       
  2181 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2182 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2183 	}
       
  2184 
       
  2185 	if (match_certificate_data != 0)
       
  2186 	{
       
  2187 		ec_cs_tlv_c handler(m_am_tools, true);
       
  2188 		if (handler.get_is_valid() == false)
       
  2189 		{
       
  2190 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2191 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2192 		}
       
  2193 
       
  2194 		eap_variable_data_c certificate_reference(m_am_tools);
       
  2195 		if (certificate_reference.get_is_valid() == false)
       
  2196 		{
       
  2197 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2198 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2199 		}
       
  2200 
       
  2201 		status = handler.parse_encrypted_certificate(
       
  2202 			match_certificate_data->get_type(),
       
  2203 			&m_PAC_store_master_key,
       
  2204 			match_certificate_data->get_reference(),
       
  2205 			&m_PAC_store_device_seed,
       
  2206 			match_certificate_data->get_data(),
       
  2207 			&certificate_reference);
       
  2208 		if (status != eap_status_ok)
       
  2209 		{
       
  2210 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2211 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2212 		}
       
  2213 
       
  2214 		const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
       
  2215 		if (certificate_data_tlv == 0)
       
  2216 		{
       
  2217 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2218 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2219 		}
       
  2220 
       
  2221 		status = certificate_data_buffer.set_copy_of_buffer(
       
  2222 			certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
       
  2223 			certificate_data_tlv->get_data_length());
       
  2224 		if (status != eap_status_ok)
       
  2225 		{
       
  2226 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2227 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2228 		}
       
  2229 
       
  2230 		certificate_data = &certificate_data_buffer;
       
  2231 
       
  2232 		// Read the certificate ID.
       
  2233 		{
       
  2234 			wapi_certificate_asn1_der_parser_c parser(m_am_tools);
       
  2235 			if (parser.get_is_valid() == false)
       
  2236 			{
       
  2237 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2238 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2239 			}
       
  2240 
       
  2241 			eap_status_e status = parser.decode(certificate_data);
       
  2242 			if (status != eap_status_ok)
       
  2243 			{
       
  2244 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2245 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2246 			}
       
  2247 
       
  2248 			status = parser.read_certificate_id(
       
  2249 				&certificate_ID);
       
  2250 			if (status != eap_status_ok)
       
  2251 			{
       
  2252 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2253 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2254 			}
       
  2255 		}
       
  2256 	}
       
  2257 
       
  2258 	status = m_partner->complete_select_certificate(
       
  2259 		&m_queried_issuer_ID,
       
  2260 		&certificate_ID,
       
  2261 		certificate_data);
       
  2262 
       
  2263 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2264 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2265 }
       
  2266 
       
  2267 //----------------------------------------------------------------------------
       
  2268 
       
  2269 eap_status_e ec_certificate_store_c::internal_create_signature_with_private_key()
       
  2270 {
       
  2271 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2272 
       
  2273 	EAP_TRACE_DEBUG(
       
  2274 		m_am_tools,
       
  2275 		TRACE_FLAGS_DEFAULT,
       
  2276 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key():\n"),
       
  2277 		 this,
       
  2278 		 (m_is_client == true ? "client": "server")));
       
  2279 
       
  2280 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_create_signature_with_private_key()");
       
  2281 
       
  2282 	EAP_TRACE_DATA_DEBUG(
       
  2283 		m_am_tools,
       
  2284 		TRACE_FLAGS_DEFAULT,
       
  2285 		(EAPL("m_id_of_own_certificate"),
       
  2286 		m_id_of_own_certificate.get_data(),
       
  2287 		m_id_of_own_certificate.get_data_length()));
       
  2288 
       
  2289 	const ec_cs_data_c * selected_private_key = 0;
       
  2290 	const eap_variable_data_c * selected_private_key_data = 0;
       
  2291 
       
  2292 	eap_variable_data_c private_key_buffer(m_am_tools);
       
  2293 
       
  2294 	eap_status_e status(eap_status_not_supported);
       
  2295 
       
  2296 
       
  2297 	if (m_is_client == true)
       
  2298 	{
       
  2299 
       
  2300 #if defined(WAPI_USE_CERTIFICATE_STORE)
       
  2301 
       
  2302 		// Search client certificate that is issued by id_of_certificate,
       
  2303 		// then read the private key with Certificate-Reference.
       
  2304 
       
  2305 		eap_variable_data_c issuer_name(m_am_tools);
       
  2306 
       
  2307 		{
       
  2308 			wapi_asn1_der_parser_c parser(m_am_tools);
       
  2309 			if (parser.get_is_valid() == false)
       
  2310 			{
       
  2311 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2312 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2313 			}
       
  2314 
       
  2315 			eap_status_e status = parser.decode(&m_id_of_own_certificate);
       
  2316 			if (status != eap_status_ok)
       
  2317 			{
       
  2318 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2319 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2320 			}
       
  2321 
       
  2322 			eap_variable_data_c subject_name(m_am_tools);
       
  2323 			eap_variable_data_c sequence_number(m_am_tools);
       
  2324 
       
  2325 			status = parser.get_wapi_identity(
       
  2326 				&subject_name,
       
  2327 				&issuer_name,
       
  2328 				&sequence_number);
       
  2329 			if (status != eap_status_ok)
       
  2330 			{
       
  2331 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2332 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2333 			}
       
  2334 		}
       
  2335 
       
  2336 		ec_cs_compare_certificate_id_c compare_user_certificate_id(
       
  2337 			m_am_tools,
       
  2338 			&m_PAC_store_master_key,
       
  2339 			&m_PAC_store_device_seed);
       
  2340 
       
  2341 		ec_cs_data_c search_user_certificate_id(m_am_tools);
       
  2342 
       
  2343 		status = search_user_certificate_id.get_writable_data()->set_buffer(
       
  2344 			&m_id_of_own_certificate);
       
  2345 		if (status != eap_status_ok)
       
  2346 		{
       
  2347 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2348 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2349 		}
       
  2350 
       
  2351 		EAP_TRACE_DEBUG(
       
  2352 			m_am_tools,
       
  2353 			TRACE_FLAGS_DEFAULT,
       
  2354 			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): count of m_client_certificates = %d.\n"),
       
  2355 			 this,
       
  2356 			 (m_is_client == true ? "client": "server"),
       
  2357 			 m_client_certificates.get_object_count()));
       
  2358 
       
  2359 		// Search certificate with the issuer name from client-certificates.
       
  2360 		i32_t index = find_with_compare<ec_cs_data_c>(
       
  2361 			&compare_user_certificate_id,
       
  2362 			&m_client_certificates,
       
  2363 			&search_user_certificate_id,
       
  2364 			m_am_tools);
       
  2365 
       
  2366 		if (index >= 0)
       
  2367 		{
       
  2368 			// Match.
       
  2369 			EAP_TRACE_DEBUG(
       
  2370 				m_am_tools,
       
  2371 				TRACE_FLAGS_DEFAULT,
       
  2372 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): Client certificate match.\n"),
       
  2373 				 this,
       
  2374 				 (m_is_client == true ? "client": "server")));
       
  2375 
       
  2376 			const ec_cs_data_c * const selected_certificate = m_client_certificates.get_object(index);
       
  2377 
       
  2378 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2379 
       
  2380 			// Read the Certificate-Reference.
       
  2381 
       
  2382 			ec_cs_tlv_c handler(m_am_tools, true);
       
  2383 			if (handler.get_is_valid() == false)
       
  2384 			{
       
  2385 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2386 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2387 			}
       
  2388 
       
  2389 			eap_variable_data_c certificate_reference(m_am_tools);
       
  2390 			if (certificate_reference.get_is_valid() == false)
       
  2391 			{
       
  2392 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2393 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2394 			}
       
  2395 
       
  2396 			status = handler.parse_encrypted_certificate(
       
  2397 				selected_certificate->get_type(),
       
  2398 				&m_PAC_store_master_key,
       
  2399 				selected_certificate->get_reference(),
       
  2400 				&m_PAC_store_device_seed,
       
  2401 				selected_certificate->get_data(),
       
  2402 				&certificate_reference);
       
  2403 			if (status != eap_status_ok)
       
  2404 			{
       
  2405 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2406 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2407 			}
       
  2408 
       
  2409 			if (certificate_reference.get_is_valid_data() == false)
       
  2410 			{
       
  2411 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2412 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2413 			}
       
  2414 
       
  2415 			const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
       
  2416 			if (certificate_data_tlv == 0)
       
  2417 			{
       
  2418 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2419 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2420 			}
       
  2421 
       
  2422 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2423 
       
  2424 			{
       
  2425 				eap_variable_data_c certificate(
       
  2426 					m_am_tools,
       
  2427 					certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
       
  2428 					certificate_data_tlv->get_data_length(),
       
  2429 					false,
       
  2430 					false);
       
  2431 				if (certificate.get_is_valid() == false)
       
  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 				status = compare_id_and_certificate(
       
  2438 					&m_selected_client_id,
       
  2439 					&certificate);
       
  2440 				if (status != eap_status_ok)
       
  2441 				{
       
  2442 					// Certificate selected by host does not match the certificate peer uses.
       
  2443 					(void) m_partner->set_session_timeout(0ul);
       
  2444 
       
  2445 					if (m_is_client == false)
       
  2446 					{
       
  2447 						status = eap_status_ca_certificate_unknown;
       
  2448 					}
       
  2449 					else
       
  2450 					{
       
  2451 						status = eap_status_user_certificate_unknown;
       
  2452 					}
       
  2453 
       
  2454 					(void) send_error_notification(status);
       
  2455 
       
  2456 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2457 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2458 				}
       
  2459 			}
       
  2460 
       
  2461 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2462 
       
  2463 			ec_cs_compare_certificate_reference_c compare_certificate_reference(m_am_tools);
       
  2464 
       
  2465 			ec_cs_data_c search_reference(m_am_tools);
       
  2466 
       
  2467 			status = search_reference.get_writable_data()->set_buffer(
       
  2468 				&certificate_reference);
       
  2469 			if (status != eap_status_ok)
       
  2470 			{
       
  2471 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2472 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2473 			}
       
  2474 
       
  2475 			EAP_TRACE_DEBUG(
       
  2476 				m_am_tools,
       
  2477 				TRACE_FLAGS_DEFAULT,
       
  2478 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): count of m_client_private_keys = %d.\n"),
       
  2479 				 this,
       
  2480 				 (m_is_client == true ? "client": "server"),
       
  2481 				 m_client_private_keys.get_object_count()));
       
  2482 
       
  2483 			// Search private key with the Certificate-Reference.
       
  2484 			i32_t index = find_with_compare<ec_cs_data_c>(
       
  2485 				&compare_certificate_reference,
       
  2486 				&m_client_private_keys,
       
  2487 				&search_reference,
       
  2488 				m_am_tools);
       
  2489 
       
  2490 			if (index >= 0)
       
  2491 			{
       
  2492 				// Match.
       
  2493 				EAP_TRACE_DEBUG(
       
  2494 					m_am_tools,
       
  2495 					TRACE_FLAGS_DEFAULT,
       
  2496 					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): Client certificate match.\n"),
       
  2497 					 this,
       
  2498 					 (m_is_client == true ? "client": "server")));
       
  2499 
       
  2500 				selected_private_key = m_client_private_keys.get_object(index);
       
  2501 
       
  2502 				if (selected_private_key == 0)
       
  2503 				{
       
  2504 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2505 					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
       
  2506 				}
       
  2507 
       
  2508 				ec_cs_tlv_c handler(m_am_tools, true);
       
  2509 				if (handler.get_is_valid() == false)
       
  2510 				{
       
  2511 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2512 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2513 				}
       
  2514 
       
  2515 				eap_variable_data_c certificate_reference(m_am_tools);
       
  2516 				if (certificate_reference.get_is_valid() == false)
       
  2517 				{
       
  2518 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2519 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2520 				}
       
  2521 
       
  2522 				status = handler.parse_encrypted_certificate(
       
  2523 					selected_private_key->get_type(),
       
  2524 					&m_PAC_store_master_key,
       
  2525 					selected_private_key->get_reference(),
       
  2526 					&m_PAC_store_device_seed,
       
  2527 					selected_private_key->get_data(),
       
  2528 					&certificate_reference);
       
  2529 				if (status != eap_status_ok)
       
  2530 				{
       
  2531 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2532 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2533 				}
       
  2534 
       
  2535 				const ec_cs_variable_data_c * const private_key_data = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_private_key_data);
       
  2536 				if (private_key_data == 0)
       
  2537 				{
       
  2538 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2539 					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2540 				}
       
  2541 
       
  2542 				status = private_key_buffer.set_copy_of_buffer(
       
  2543 					private_key_data->get_data(private_key_data->get_data_length()),
       
  2544 					private_key_data->get_data_length());
       
  2545 				if (status != eap_status_ok)
       
  2546 				{
       
  2547 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2548 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2549 				}
       
  2550 
       
  2551 				selected_private_key_data = &private_key_buffer;
       
  2552 			}
       
  2553 			else
       
  2554 			{
       
  2555 				EAP_TRACE_DEBUG(
       
  2556 					m_am_tools,
       
  2557 					TRACE_FLAGS_DEFAULT,
       
  2558 					(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): No client certificate match.\n"),
       
  2559 					 this,
       
  2560 					 (m_is_client == true ? "client": "server")));
       
  2561 			}
       
  2562 		}
       
  2563 		else
       
  2564 		{
       
  2565 			EAP_TRACE_DEBUG(
       
  2566 				m_am_tools,
       
  2567 				TRACE_FLAGS_DEFAULT,
       
  2568 				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): No client certificate match.\n"),
       
  2569 				 this,
       
  2570 				 (m_is_client == true ? "client": "server")));
       
  2571 
       
  2572 			status = completion_action_push(ec_cs_completion_internal_create_signature_with_private_key);
       
  2573 			if (status != eap_status_ok)
       
  2574 			{
       
  2575 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2576 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2577 			}
       
  2578 
       
  2579 			status = internal_select_own_certificate_with_issuer_name();
       
  2580 			if (status != eap_status_ok)
       
  2581 			{
       
  2582 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2583 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2584 			}
       
  2585 		}
       
  2586 
       
  2587 #else
       
  2588 
       
  2589 		if (selected_private_key_data == 0)
       
  2590 		{
       
  2591 			status = compare_id_and_certificate(&m_id_of_own_certificate, &m_dummy_test_own_certificate);
       
  2592 			if (status == eap_status_ok)
       
  2593 			{
       
  2594 				selected_private_key_data = &m_dummy_test_own_private_key;
       
  2595 			}
       
  2596 		}
       
  2597 
       
  2598 #endif //#if defined(WAPI_USE_CERTIFICATE_STORE)
       
  2599 
       
  2600 	}
       
  2601 
       
  2602 	if (m_is_client == false)
       
  2603 	{
       
  2604 		if (selected_private_key_data == 0)
       
  2605 		{
       
  2606 			status = compare_id_and_certificate(&m_id_of_own_certificate, &m_dummy_test_asu_certificate);
       
  2607 			if (status == eap_status_ok)
       
  2608 			{
       
  2609 				selected_private_key_data = &m_dummy_test_asu_private_key;
       
  2610 			}
       
  2611 		}
       
  2612 
       
  2613 		if (selected_private_key_data == 0)
       
  2614 		{
       
  2615 			status = compare_id_and_certificate(&m_id_of_own_certificate, &m_dummy_test_own_certificate);
       
  2616 			if (status == eap_status_ok)
       
  2617 			{
       
  2618 				selected_private_key_data = &m_dummy_test_own_private_key;
       
  2619 			}
       
  2620 		}
       
  2621 	}
       
  2622 
       
  2623 	status = m_ec_algorithms->create_signature_with_private_key(&m_hash_of_message, selected_private_key_data);
       
  2624 
       
  2625 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2626 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2627 }
       
  2628 
       
  2629 //----------------------------------------------------------------------------
       
  2630 
       
  2631 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::create_signature_with_private_key(
       
  2632 	const eap_variable_data_c * const hash_of_message,
       
  2633 	const eap_variable_data_c * const id_of_certificate)
       
  2634 {
       
  2635 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2636 
       
  2637 	EAP_TRACE_DEBUG(
       
  2638 		m_am_tools,
       
  2639 		TRACE_FLAGS_DEFAULT,
       
  2640 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::create_signature_with_private_key():\n"),
       
  2641 		 this,
       
  2642 		 (m_is_client == true ? "client": "server")));
       
  2643 
       
  2644 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_signature_with_private_key()");
       
  2645 
       
  2646 	EAP_TRACE_DATA_DEBUG(
       
  2647 		m_am_tools,
       
  2648 		TRACE_FLAGS_DEFAULT,
       
  2649 		(EAPL("id_of_certificate"),
       
  2650 		id_of_certificate->get_data(),
       
  2651 		id_of_certificate->get_data_length()));
       
  2652 
       
  2653 	eap_variable_data_c private_key_buffer(m_am_tools);
       
  2654 
       
  2655 	eap_status_e status(eap_status_not_supported);
       
  2656 
       
  2657 	status = m_hash_of_message.set_copy_of_buffer(hash_of_message);
       
  2658 	if (status != eap_status_ok)
       
  2659 	{
       
  2660 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2661 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2662 	}
       
  2663 
       
  2664 	status = m_id_of_own_certificate.set_copy_of_buffer(id_of_certificate);
       
  2665 	if (status != eap_status_ok)
       
  2666 	{
       
  2667 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2668 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2669 	}
       
  2670 
       
  2671 	status = internal_create_signature_with_private_key();
       
  2672 
       
  2673 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2674 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2675 }
       
  2676 
       
  2677 //----------------------------------------------------------------------------
       
  2678 
       
  2679 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::verify_signature_with_public_key(
       
  2680 	const eap_variable_data_c * const peer_identity,
       
  2681 	const eap_variable_data_c * const hash_of_message,
       
  2682 	const eap_variable_data_c * const signature,
       
  2683 	const bool allow_use_of_ae_certificate)
       
  2684 {
       
  2685 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2686 
       
  2687 	EAP_TRACE_DEBUG(
       
  2688 		m_am_tools,
       
  2689 		TRACE_FLAGS_DEFAULT,
       
  2690 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key():\n"),
       
  2691 		 this,
       
  2692 		 (m_is_client == true ? "client": "server")));
       
  2693 
       
  2694 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::verify_signature_with_public_key()");
       
  2695 
       
  2696 	eap_status_e status(eap_status_not_supported);
       
  2697 
       
  2698 	eap_variable_data_c used_certificate_id(m_am_tools);
       
  2699 
       
  2700 	if (allow_use_of_ae_certificate == false
       
  2701 		&& m_selected_ca_id.get_is_valid_data() == true)
       
  2702 	{
       
  2703 		status = used_certificate_id.set_copy_of_buffer(&m_selected_ca_id);
       
  2704 	}
       
  2705 	else
       
  2706 	{
       
  2707 		status = used_certificate_id.set_copy_of_buffer(peer_identity);
       
  2708 	}
       
  2709 
       
  2710 	if (status != eap_status_ok)
       
  2711 	{
       
  2712 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2713 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2714 	}
       
  2715 
       
  2716 
       
  2717 	EAP_TRACE_DATA_DEBUG(
       
  2718 		m_am_tools,
       
  2719 		TRACE_FLAGS_DEFAULT,
       
  2720 		(EAPL("used_certificate_id"),
       
  2721 		used_certificate_id.get_data(),
       
  2722 		used_certificate_id.get_data_length()));
       
  2723 
       
  2724 	eap_variable_data_c * selected_certificate = 0;
       
  2725 	eap_variable_data_c selected_certificate_buffer(m_am_tools);
       
  2726 
       
  2727 
       
  2728 	if (selected_certificate == 0
       
  2729 		&& m_ae_certificate.get_is_valid_data() == true
       
  2730 		&& allow_use_of_ae_certificate == true)
       
  2731 	{
       
  2732 		status = compare_id_and_certificate(&used_certificate_id, &m_ae_certificate);
       
  2733 		if (status == eap_status_ok)
       
  2734 		{
       
  2735 			selected_certificate = &m_ae_certificate;
       
  2736 		}
       
  2737 	}
       
  2738 
       
  2739 	if (m_is_client == true
       
  2740 		&& selected_certificate == 0)
       
  2741 	{
       
  2742 
       
  2743 #if defined(WAPI_USE_CERTIFICATE_STORE)
       
  2744 
       
  2745 		ec_cs_compare_certificate_id_c compare_certificate_id(
       
  2746 			m_am_tools,
       
  2747 			&m_PAC_store_master_key,
       
  2748 			&m_PAC_store_device_seed);
       
  2749 
       
  2750 		const ec_cs_data_c * match_certificate_data = 0;
       
  2751 
       
  2752 		ec_cs_data_c search_peer_identity(m_am_tools);
       
  2753 
       
  2754 		status = search_peer_identity.get_writable_data()->set_buffer(
       
  2755 			&used_certificate_id);
       
  2756 		if (status != eap_status_ok)
       
  2757 		{
       
  2758 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2759 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2760 		}
       
  2761 
       
  2762 		EAP_TRACE_DEBUG(
       
  2763 			m_am_tools,
       
  2764 			TRACE_FLAGS_DEFAULT,
       
  2765 			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): count of m_ca_certificates = %d.\n"),
       
  2766 			 this,
       
  2767 			 (m_is_client == true ? "client": "server"),
       
  2768 			 m_ca_certificates.get_object_count()));
       
  2769 
       
  2770 		// Search certificate with the issuer ID from CA-certificates.
       
  2771 		i32_t index = find_with_compare<ec_cs_data_c>(
       
  2772 			&compare_certificate_id,
       
  2773 			&m_ca_certificates,
       
  2774 			&search_peer_identity,
       
  2775 			m_am_tools);
       
  2776 
       
  2777 		if (index >= 0)
       
  2778 		{
       
  2779 			// Match.
       
  2780 			EAP_TRACE_DEBUG(
       
  2781 				m_am_tools,
       
  2782 				TRACE_FLAGS_DEFAULT,
       
  2783 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): CA certificate match.\n"),
       
  2784 				 this,
       
  2785 				 (m_is_client == true ? "client": "server")));
       
  2786 
       
  2787 			match_certificate_data = m_ca_certificates.get_object(index);
       
  2788 		}
       
  2789 		else
       
  2790 		{
       
  2791 			EAP_TRACE_DEBUG(
       
  2792 				m_am_tools,
       
  2793 				TRACE_FLAGS_DEFAULT,
       
  2794 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): count of m_client_certificates = %d.\n"),
       
  2795 				 this,
       
  2796 				 (m_is_client == true ? "client": "server"),
       
  2797 				 m_client_certificates.get_object_count()));
       
  2798 
       
  2799 			// Search certificate with the issuer ID from client certificates.
       
  2800 			index = find_with_compare<ec_cs_data_c>(
       
  2801 				&compare_certificate_id,
       
  2802 				&m_client_certificates,
       
  2803 				&search_peer_identity,
       
  2804 				m_am_tools);
       
  2805 			if (index >= 0)
       
  2806 			{
       
  2807 				// Match.
       
  2808 				EAP_TRACE_DEBUG(
       
  2809 					m_am_tools,
       
  2810 					TRACE_FLAGS_DEFAULT,
       
  2811 					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): Client certificate match.\n"),
       
  2812 					 this,
       
  2813 					 (m_is_client == true ? "client": "server")));
       
  2814 
       
  2815 				match_certificate_data = m_client_certificates.get_object(index);
       
  2816 			}
       
  2817 			else
       
  2818 			{
       
  2819 				EAP_TRACE_DEBUG(
       
  2820 					m_am_tools,
       
  2821 					TRACE_FLAGS_DEFAULT,
       
  2822 					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): No CA neither client certificate match.\n"),
       
  2823 					 this,
       
  2824 					 (m_is_client == true ? "client": "server")));
       
  2825 			}
       
  2826 		}
       
  2827 
       
  2828 		if (match_certificate_data != 0)
       
  2829 		{
       
  2830 			ec_cs_tlv_c handler(m_am_tools, true);
       
  2831 			if (handler.get_is_valid() == false)
       
  2832 			{
       
  2833 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2834 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2835 			}
       
  2836 
       
  2837 			eap_variable_data_c certificate_reference(m_am_tools);
       
  2838 			if (certificate_reference.get_is_valid() == false)
       
  2839 			{
       
  2840 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2841 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2842 			}
       
  2843 
       
  2844 			status = handler.parse_encrypted_certificate(
       
  2845 				match_certificate_data->get_type(),
       
  2846 				&m_PAC_store_master_key,
       
  2847 				match_certificate_data->get_reference(),
       
  2848 				&m_PAC_store_device_seed,
       
  2849 				match_certificate_data->get_data(),
       
  2850 				&certificate_reference);
       
  2851 			if (status != eap_status_ok)
       
  2852 			{
       
  2853 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2854 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2855 			}
       
  2856 
       
  2857 			const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
       
  2858 			if (certificate_data_tlv == 0)
       
  2859 			{
       
  2860 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2861 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2862 			}
       
  2863 
       
  2864 			{
       
  2865 				eap_variable_data_c certificate(
       
  2866 					m_am_tools,
       
  2867 					certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
       
  2868 					certificate_data_tlv->get_data_length(),
       
  2869 					false,
       
  2870 					false);
       
  2871 				if (certificate.get_is_valid() == false)
       
  2872 				{
       
  2873 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2874 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2875 				}
       
  2876 
       
  2877 				status = compare_id_and_certificate(
       
  2878 					&m_selected_ca_id,
       
  2879 					&certificate);
       
  2880 				if (status != eap_status_ok)
       
  2881 				{
       
  2882 					// Certificate selected by host does not match the certificate peer uses.
       
  2883 					(void) m_partner->set_session_timeout(0ul);
       
  2884 
       
  2885 					if (m_is_client == false)
       
  2886 					{
       
  2887 						status = eap_status_ca_certificate_unknown;
       
  2888 					}
       
  2889 					else
       
  2890 					{
       
  2891 						status = eap_status_user_certificate_unknown;
       
  2892 					}
       
  2893 
       
  2894 					(void) send_error_notification(status);
       
  2895 
       
  2896 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2897 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2898 				}
       
  2899 			}
       
  2900 
       
  2901 			status = selected_certificate_buffer.set_copy_of_buffer(
       
  2902 				certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
       
  2903 				certificate_data_tlv->get_data_length());
       
  2904 			if (status != eap_status_ok)
       
  2905 			{
       
  2906 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2907 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2908 			}
       
  2909 
       
  2910 			selected_certificate = &selected_certificate_buffer;
       
  2911 		}
       
  2912 		else
       
  2913 		{
       
  2914 			if (m_ca_certificates.get_object_count() == 0)
       
  2915 			{
       
  2916 				ec_cs_data_c search_id(m_am_tools);
       
  2917 
       
  2918 				eap_status_e status = search_id.get_writable_data()->set_buffer(
       
  2919 					&used_certificate_id);
       
  2920 				if (status != eap_status_ok)
       
  2921 				{
       
  2922 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2923 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2924 				}
       
  2925 
       
  2926 				eap_variable_data_c certificate_reference(m_am_tools);
       
  2927 
       
  2928 				ec_cs_compare_reference_id_c compare_reference_id(m_am_tools);
       
  2929 
       
  2930 				ec_cs_data_type_e certificate_type(ec_cs_data_type_none);
       
  2931 
       
  2932 				const ec_cs_data_c * reference_tlv = 0;
       
  2933 
       
  2934 				if (m_read_ca_asu_id_list == true)
       
  2935 				{
       
  2936 					EAP_TRACE_DEBUG(
       
  2937 						m_am_tools,
       
  2938 						TRACE_FLAGS_DEFAULT,
       
  2939 						(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): count of m_ca_asu_id_list = %d.\n"),
       
  2940 						 this,
       
  2941 						 (m_is_client == true ? "client": "server"),
       
  2942 						 m_ca_asu_id_list.get_object_count()));
       
  2943 
       
  2944 					// Search Certificate-reference with the issuer ID.
       
  2945 					i32_t index = find_with_compare<ec_cs_data_c>(
       
  2946 						&compare_reference_id,
       
  2947 						&m_ca_asu_id_list,
       
  2948 						&search_id,
       
  2949 						m_am_tools);
       
  2950 					if (index >= 0)
       
  2951 					{
       
  2952 						// Match.
       
  2953 						EAP_TRACE_DEBUG(
       
  2954 							m_am_tools,
       
  2955 							TRACE_FLAGS_DEFAULT,
       
  2956 							(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): CA certificate ID list match.\n"),
       
  2957 							 this,
       
  2958 							 (m_is_client == true ? "client": "server")));
       
  2959 
       
  2960 						reference_tlv = m_ca_asu_id_list.get_object(index);
       
  2961 						certificate_type = ec_cs_data_type_ca_certificate_data;
       
  2962 					}
       
  2963 					else
       
  2964 					{
       
  2965 						EAP_TRACE_DEBUG(
       
  2966 							m_am_tools,
       
  2967 							TRACE_FLAGS_DEFAULT,
       
  2968 							(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): NO CA certificate ID list match.\n"),
       
  2969 							 this,
       
  2970 							 (m_is_client == true ? "client": "server")));
       
  2971 					}
       
  2972 
       
  2973 					if (reference_tlv != 0)
       
  2974 					{
       
  2975 						status = read_certificate_reference(reference_tlv, &certificate_reference);
       
  2976 						if (status != eap_status_ok)
       
  2977 						{
       
  2978 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2979 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2980 						}
       
  2981 
       
  2982 						status = m_peer_identity.set_copy_of_buffer(&used_certificate_id);
       
  2983 						if (status != eap_status_ok)
       
  2984 						{
       
  2985 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2986 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2987 						}
       
  2988 
       
  2989 						status = m_hash_of_message.set_copy_of_buffer(hash_of_message);
       
  2990 						if (status != eap_status_ok)
       
  2991 						{
       
  2992 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2993 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2994 						}
       
  2995 
       
  2996 						status = m_signature.set_copy_of_buffer(signature);
       
  2997 						if (status != eap_status_ok)
       
  2998 						{
       
  2999 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3000 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  3001 						}
       
  3002 
       
  3003 						m_allow_use_of_ae_certificate = allow_use_of_ae_certificate;
       
  3004 
       
  3005 						status = completion_action_push(ec_cs_completion_internal_verify_signature_with_public_key);
       
  3006 						if (status != eap_status_ok)
       
  3007 						{
       
  3008 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3009 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  3010 						}
       
  3011 
       
  3012 						// Read the certificate from database.
       
  3013 						status = read_certificate(
       
  3014 							ec_cs_pending_operation_verify_signature_with_public_key,
       
  3015 							certificate_type,
       
  3016 							&certificate_reference);
       
  3017 						if (status != eap_status_ok)
       
  3018 						{
       
  3019 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3020 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  3021 						}
       
  3022 					}
       
  3023 				}
       
  3024 			}
       
  3025 			else
       
  3026 			{
       
  3027 				// No certificate found. Cannot continue.
       
  3028 				(void) m_partner->set_session_timeout(0ul);
       
  3029 
       
  3030 				if (m_is_client == false)
       
  3031 				{
       
  3032 					status = eap_status_ca_certificate_unknown;
       
  3033 				}
       
  3034 				else
       
  3035 				{
       
  3036 					status = eap_status_user_certificate_unknown;
       
  3037 				}
       
  3038 
       
  3039 				(void) send_error_notification(status);
       
  3040 
       
  3041 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3042 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3043 			}
       
  3044 		}
       
  3045 
       
  3046 #else
       
  3047 
       
  3048 		if (selected_certificate == 0)
       
  3049 		{
       
  3050 			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_asu_certificate);
       
  3051 			if (status == eap_status_ok)
       
  3052 			{
       
  3053 				selected_certificate = &m_dummy_test_asu_certificate;
       
  3054 			}
       
  3055 		}
       
  3056 
       
  3057 		if (selected_certificate == 0)
       
  3058 		{
       
  3059 			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_own_certificate);
       
  3060 			if (status == eap_status_ok)
       
  3061 			{
       
  3062 				selected_certificate = &m_dummy_test_own_certificate;
       
  3063 			}
       
  3064 		}
       
  3065 
       
  3066 #endif //#if defined(WAPI_USE_CERTIFICATE_STORE)
       
  3067 
       
  3068 	}
       
  3069 
       
  3070 
       
  3071 	if (m_is_client == false)
       
  3072 	{
       
  3073 		if (selected_certificate == 0)
       
  3074 		{
       
  3075 			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_asu_certificate);
       
  3076 			if (status == eap_status_ok)
       
  3077 			{
       
  3078 				selected_certificate = &m_dummy_test_asu_certificate;
       
  3079 			}
       
  3080 		}
       
  3081 
       
  3082 		if (selected_certificate == 0)
       
  3083 		{
       
  3084 			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_own_certificate);
       
  3085 			if (status == eap_status_ok)
       
  3086 			{
       
  3087 				selected_certificate = &m_dummy_test_own_certificate;
       
  3088 			}
       
  3089 		}
       
  3090 
       
  3091 		if (m_is_client == false // Only test server could have this certificate.
       
  3092 			&& selected_certificate == 0)
       
  3093 		{
       
  3094 			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_peer_certificate);
       
  3095 			if (status == eap_status_ok)
       
  3096 			{
       
  3097 				selected_certificate = &m_dummy_test_peer_certificate;
       
  3098 			}
       
  3099 		}
       
  3100 	}
       
  3101 
       
  3102 	status = m_ec_algorithms->verify_signature_with_public_key(
       
  3103 		selected_certificate,
       
  3104 		hash_of_message,
       
  3105 		signature);
       
  3106 
       
  3107 
       
  3108 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3109 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3110 }
       
  3111 
       
  3112 
       
  3113 //----------------------------------------------------------------------------
       
  3114 
       
  3115 eap_status_e ec_certificate_store_c::read_certificate_wapi_identity(
       
  3116 	const eap_variable_data_c * const certificate,
       
  3117 	eap_variable_data_c * const certificate_wapi_identity)
       
  3118 {
       
  3119 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3120 
       
  3121 	EAP_TRACE_DEBUG(
       
  3122 		m_am_tools,
       
  3123 		TRACE_FLAGS_DEFAULT,
       
  3124 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate_wapi_identity():\n"),
       
  3125 		 this,
       
  3126 		 (m_is_client == true ? "client": "server")));
       
  3127 
       
  3128 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate_wapi_identity()");
       
  3129 
       
  3130 	if (certificate_wapi_identity == 0
       
  3131 		|| certificate_wapi_identity->get_is_valid() == false)
       
  3132 	{
       
  3133 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3134 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3135 	}
       
  3136 
       
  3137 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3138 
       
  3139 	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
       
  3140 	if (parser.get_is_valid() == false)
       
  3141 	{
       
  3142 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3143 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3144 	}
       
  3145 
       
  3146 	eap_status_e status = parser.decode(certificate);
       
  3147 	if (status != eap_status_ok)
       
  3148 	{
       
  3149 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3150 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3151 	}
       
  3152 
       
  3153 	status = parser.read_certificate_id(
       
  3154 		certificate_wapi_identity);
       
  3155 	if (status != eap_status_ok)
       
  3156 	{
       
  3157 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3158 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3159 	}
       
  3160 
       
  3161 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3162 
       
  3163 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3164 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3165 }
       
  3166 
       
  3167 //----------------------------------------------------------------------------
       
  3168 
       
  3169 eap_status_e ec_certificate_store_c::copy_certificate_wapi_identities(
       
  3170 	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const certificates_id_list,
       
  3171 	eap_array_c<eap_variable_data_c> * const wapi_identities_list)
       
  3172 {
       
  3173 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3174 
       
  3175 	EAP_TRACE_DEBUG(
       
  3176 		m_am_tools,
       
  3177 		TRACE_FLAGS_DEFAULT,
       
  3178 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::copy_certificate_wapi_identities():\n"),
       
  3179 		 this,
       
  3180 		 (m_is_client == true ? "client": "server")));
       
  3181 
       
  3182 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::copy_certificate_wapi_identities()");
       
  3183 
       
  3184 	eap_status_e status(eap_status_ok);
       
  3185 
       
  3186 	if (certificates_id_list == 0
       
  3187 		|| wapi_identities_list == 0)
       
  3188 	{
       
  3189 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3190 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3191 	}
       
  3192 
       
  3193 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3194 
       
  3195 	ec_cs_tlv_c master_key_handler(m_am_tools, true);
       
  3196 	if (master_key_handler.get_is_valid() == false)
       
  3197 	{
       
  3198 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3199 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3200 	}
       
  3201 
       
  3202 	for (u32_t ind = 0; ind < certificates_id_list->get_object_count(); ++ind)
       
  3203 	{
       
  3204 		eap_variable_data_c * const certificate_wapi_identity = new eap_variable_data_c(m_am_tools);
       
  3205 
       
  3206 		eap_automatic_variable_c<eap_variable_data_c> automatic_certificate_wapi_identity(m_am_tools, certificate_wapi_identity);
       
  3207 
       
  3208 		if (certificate_wapi_identity == 0
       
  3209 			|| certificate_wapi_identity->get_is_valid() == false)
       
  3210 		{
       
  3211 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3212 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3213 		}
       
  3214 
       
  3215 		const ec_cs_data_c * const id_reference = certificates_id_list->get_object(ind);
       
  3216 
       
  3217 		if (id_reference != 0
       
  3218 			&& id_reference->get_is_valid() == true)
       
  3219 		{
       
  3220 			ec_cs_tlv_payloads_c parser(
       
  3221 				m_am_tools,
       
  3222 				true);
       
  3223 			if (parser.get_is_valid() == false)
       
  3224 			{
       
  3225 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3226 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3227 			}
       
  3228 
       
  3229 			eap_variable_data_c id_reference_MAC_key(m_am_tools);
       
  3230 			if (id_reference_MAC_key.get_is_valid() == false)
       
  3231 			{
       
  3232 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3233 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3234 			}
       
  3235 
       
  3236 			status = master_key_handler.generate_data_key(
       
  3237 				false,
       
  3238 				id_reference->get_type(),
       
  3239 				&id_reference_MAC_key,
       
  3240 				&m_PAC_store_master_key,
       
  3241 				id_reference->get_reference(),
       
  3242 				&m_PAC_store_device_seed);
       
  3243 			if (status != eap_status_ok)
       
  3244 			{
       
  3245 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3246 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3247 			}
       
  3248 
       
  3249 			status = master_key_handler.parse_data_with_MAC(
       
  3250 				&id_reference_MAC_key,
       
  3251 				id_reference->get_data() ///< This is the start of the message buffer.
       
  3252 				);
       
  3253 			if (status != eap_status_ok)
       
  3254 			{
       
  3255 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3256 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3257 			}
       
  3258 
       
  3259 			const ec_cs_variable_data_c * const ID_reference_data_tlv = master_key_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_ID_reference);
       
  3260 			if (ID_reference_data_tlv == 0)
       
  3261 			{
       
  3262 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3263 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3264 			}
       
  3265 
       
  3266 			ec_cs_tlv_payloads_c id_parser(
       
  3267 				m_am_tools,
       
  3268 				true);
       
  3269 			if (id_parser.get_is_valid() == false)
       
  3270 			{
       
  3271 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3272 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3273 			}
       
  3274 
       
  3275 			{
       
  3276 				u32_t length(ID_reference_data_tlv->get_header()->get_data_length());
       
  3277 				u32_t padding_length(0ul);
       
  3278 
       
  3279 				status = id_parser.parse_ec_cs_payloads(
       
  3280 					ID_reference_data_tlv->get_header()->get_data(ID_reference_data_tlv->get_data_length()), ///< This is the start of the message buffer.
       
  3281 					&length, ///< This is the length of the buffer. This must match with the length of all payloads.
       
  3282 					&padding_length ///< Length of possible padding is set to this variable.
       
  3283 					);
       
  3284 				if (status != eap_status_ok)
       
  3285 				{
       
  3286 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3287 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  3288 				}
       
  3289 			}
       
  3290 
       
  3291 
       
  3292 			const ec_cs_variable_data_c * const asu_id_data_tlv = id_parser.get_tlv_pointer(ec_cs_tlv_type_CS_ASU_ID);
       
  3293 			if (asu_id_data_tlv == 0)
       
  3294 			{
       
  3295 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3296 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3297 			}
       
  3298 
       
  3299 			status = certificate_wapi_identity->set_copy_of_buffer(
       
  3300 				asu_id_data_tlv->get_data(asu_id_data_tlv->get_data_length()),
       
  3301 				asu_id_data_tlv->get_data_length());
       
  3302 			if (status != eap_status_ok)
       
  3303 			{
       
  3304 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3305 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3306 			}
       
  3307 
       
  3308 			EAP_TRACE_DATA_DEBUG(
       
  3309 				m_am_tools,
       
  3310 				TRACE_FLAGS_DEFAULT,
       
  3311 				(EAPL("certificate_wapi_identity"),
       
  3312 				certificate_wapi_identity->get_data(),
       
  3313 				certificate_wapi_identity->get_data_length()));
       
  3314 
       
  3315 			automatic_certificate_wapi_identity.do_not_free_variable();
       
  3316 
       
  3317 			status = wapi_identities_list->add_object(certificate_wapi_identity, true);
       
  3318 			if (status != eap_status_ok)
       
  3319 			{
       
  3320 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3321 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3322 			}
       
  3323 		}
       
  3324 	}
       
  3325 
       
  3326 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3327 
       
  3328 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3329 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3330 }
       
  3331 
       
  3332 //----------------------------------------------------------------------------
       
  3333 
       
  3334 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::read_id_of_certificate(
       
  3335 	const eap_variable_data_c * const certificate)
       
  3336 {
       
  3337 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3338 
       
  3339 	EAP_TRACE_DEBUG(
       
  3340 		m_am_tools,
       
  3341 		TRACE_FLAGS_DEFAULT,
       
  3342 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_id_of_certificate():\n"),
       
  3343 		 this,
       
  3344 		 (m_is_client == true ? "client": "server")));
       
  3345 
       
  3346 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_id_of_certificate()");
       
  3347 
       
  3348 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3349 
       
  3350 	eap_variable_data_c certificate_wapi_id(m_am_tools);
       
  3351 	if (certificate_wapi_id.get_is_valid() == false)
       
  3352 	{
       
  3353 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3354 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3355 	}
       
  3356 
       
  3357 	eap_status_e status = read_certificate_wapi_identity(
       
  3358 		certificate,
       
  3359 		&certificate_wapi_id);
       
  3360 	if (status != eap_status_ok)
       
  3361 	{
       
  3362 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3363 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3364 	}
       
  3365 
       
  3366 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3367 
       
  3368 	status = m_partner->complete_read_id_of_certificate(&certificate_wapi_id);
       
  3369 
       
  3370 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3371 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3372 }
       
  3373 
       
  3374 //----------------------------------------------------------------------------
       
  3375 
       
  3376 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::create_ecdh_temporary_keys()
       
  3377 {
       
  3378 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3379 
       
  3380 	EAP_TRACE_DEBUG(
       
  3381 		m_am_tools,
       
  3382 		TRACE_FLAGS_DEFAULT,
       
  3383 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::create_ecdh_temporary_keys():\n"),
       
  3384 		 this,
       
  3385 		 (m_is_client == true ? "client": "server")));
       
  3386 
       
  3387 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_ecdh_temporary_keys()");
       
  3388 
       
  3389 	eap_status_e status = m_ec_algorithms->create_ecdh_temporary_keys();
       
  3390 
       
  3391 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3392 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3393 }
       
  3394 
       
  3395 //----------------------------------------------------------------------------
       
  3396 
       
  3397 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::create_ecdh(
       
  3398 	const eap_variable_data_c * const own_private_key_d,
       
  3399 	const eap_variable_data_c * const peer_public_key_x,
       
  3400 	const eap_variable_data_c * const peer_public_key_y)
       
  3401 {
       
  3402 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3403 
       
  3404 	EAP_TRACE_DEBUG(
       
  3405 		m_am_tools,
       
  3406 		TRACE_FLAGS_DEFAULT,
       
  3407 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::create_ecdh():\n"),
       
  3408 		 this,
       
  3409 		 (m_is_client == true ? "client": "server")));
       
  3410 
       
  3411 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_ecdh()");
       
  3412 
       
  3413 	eap_status_e status = m_ec_algorithms->create_ecdh(
       
  3414 		own_private_key_d,
       
  3415 		peer_public_key_x,
       
  3416 		peer_public_key_y);
       
  3417 
       
  3418 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3419 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3420 }
       
  3421 
       
  3422 //----------------------------------------------------------------------------
       
  3423 
       
  3424 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_create_signature_with_private_key(
       
  3425 	const eap_variable_data_c * const signature,
       
  3426 	const eap_status_e signature_status)
       
  3427 {
       
  3428 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3429 
       
  3430 	EAP_TRACE_DEBUG(
       
  3431 		m_am_tools,
       
  3432 		TRACE_FLAGS_DEFAULT,
       
  3433 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_create_signature_with_private_key():\n"),
       
  3434 		 this,
       
  3435 		 (m_is_client == true ? "client": "server")));
       
  3436 
       
  3437 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_create_signature_with_private_key()");
       
  3438 
       
  3439 	eap_status_e status = m_partner->complete_create_signature_with_private_key(signature, signature_status);
       
  3440 
       
  3441 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3442 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3443 }
       
  3444 
       
  3445 //----------------------------------------------------------------------------
       
  3446 
       
  3447 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_verify_signature_with_public_key(
       
  3448 	const eap_status_e verification_status)
       
  3449 {
       
  3450 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3451 
       
  3452 	EAP_TRACE_DEBUG(
       
  3453 		m_am_tools,
       
  3454 		TRACE_FLAGS_DEFAULT,
       
  3455 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_verify_signature_with_public_key():\n"),
       
  3456 		 this,
       
  3457 		 (m_is_client == true ? "client": "server")));
       
  3458 
       
  3459 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_verify_signature_with_public_key()");
       
  3460 
       
  3461 	eap_status_e status = m_partner->complete_verify_signature_with_public_key(verification_status);
       
  3462 
       
  3463 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3464 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3465 }
       
  3466 
       
  3467 //----------------------------------------------------------------------------
       
  3468 
       
  3469 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_create_ecdh_temporary_keys(
       
  3470 	const eap_variable_data_c * const private_key_d,
       
  3471 	const eap_variable_data_c * const public_key_x,
       
  3472 	const eap_variable_data_c * const public_key_y)
       
  3473 {
       
  3474 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3475 
       
  3476 	EAP_TRACE_DEBUG(
       
  3477 		m_am_tools,
       
  3478 		TRACE_FLAGS_DEFAULT,
       
  3479 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_create_ecdh_temporary_keys():\n"),
       
  3480 		 this,
       
  3481 		 (m_is_client == true ? "client": "server")));
       
  3482 
       
  3483 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_create_ecdh_temporary_keys()");
       
  3484 
       
  3485 	eap_status_e status = m_partner->complete_create_ecdh_temporary_keys(private_key_d, public_key_x, public_key_y);
       
  3486 
       
  3487 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3488 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3489 }
       
  3490 
       
  3491 //----------------------------------------------------------------------------
       
  3492 
       
  3493 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_create_ecdh(
       
  3494 	const eap_variable_data_c * const K_AB_x4,
       
  3495 	const eap_variable_data_c * const K_AB_y4)
       
  3496 {
       
  3497 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3498 
       
  3499 	EAP_TRACE_DEBUG(
       
  3500 		m_am_tools,
       
  3501 		TRACE_FLAGS_DEFAULT,
       
  3502 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_create_ecdh():\n"),
       
  3503 		 this,
       
  3504 		 (m_is_client == true ? "client": "server")));
       
  3505 
       
  3506 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_create_ecdh()");
       
  3507 
       
  3508 	eap_status_e status = m_partner->complete_create_ecdh(K_AB_x4, K_AB_y4);
       
  3509 
       
  3510 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3511 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3512 }
       
  3513 
       
  3514 //----------------------------------------------------------------------------
       
  3515 
       
  3516 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_initialize_certificate_store(
       
  3517 	const wapi_completion_operation_e completion_operation)
       
  3518 {
       
  3519 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3520 
       
  3521 	EAP_TRACE_DEBUG(
       
  3522 		m_am_tools,
       
  3523 		TRACE_FLAGS_DEFAULT,
       
  3524 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_initialize_certificate_store():\n"),
       
  3525 		 this,
       
  3526 		 (m_is_client == true ? "client": "server")));
       
  3527 
       
  3528 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_initialize_certificate_store()");
       
  3529 
       
  3530 	eap_status_e status(eap_status_ok);
       
  3531 
       
  3532 	m_certificate_store_initialized = true;
       
  3533 
       
  3534 	if (m_complete_start_certificate_import == true)
       
  3535 	{
       
  3536 		set_pending_operation(ec_cs_pending_operation_none);
       
  3537 
       
  3538 		EAP_TRACE_DEBUG(
       
  3539 			m_am_tools,
       
  3540 			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  3541 			(EAPL("calls: ec_certificate_store_c::complete_initialize_certificate_store(): %d.\n"),
       
  3542 			__LINE__));
       
  3543 
       
  3544 		status = m_am_certificate_store->complete_start_certificate_import();
       
  3545 		if (status != eap_status_ok)
       
  3546 		{
       
  3547 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3548 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3549 		}
       
  3550 	}
       
  3551 
       
  3552 	status = completion_action_check();
       
  3553 
       
  3554 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3555 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3556 }
       
  3557 
       
  3558 //----------------------------------------------------------------------------
       
  3559 
       
  3560 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::remove_cached_certificate_store_data()
       
  3561 {
       
  3562 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3563 
       
  3564 	EAP_TRACE_DEBUG(
       
  3565 		m_am_tools,
       
  3566 		TRACE_FLAGS_DEFAULT,
       
  3567 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::remove_cached_certificate_store_data():\n"),
       
  3568 		 this,
       
  3569 		 (m_is_client == true ? "client": "server")));
       
  3570 
       
  3571 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::remove_cached_certificate_store_data()");
       
  3572 
       
  3573 	eap_status_e status(eap_status_ok);
       
  3574 
       
  3575 	save_data_to_permanent_store();
       
  3576 
       
  3577 	m_certificate_store_initialized = false;
       
  3578 
       
  3579 	m_master_key_changed = false;
       
  3580 
       
  3581 	m_PAC_store_master_key.reset();
       
  3582 
       
  3583 	m_PAC_store_password.reset();
       
  3584 
       
  3585 	m_PAC_store_device_seed.reset();
       
  3586 
       
  3587 	eap_variable_data_c key(m_am_tools);
       
  3588 
       
  3589 	status = key.set_copy_of_buffer(
       
  3590 		WAPI_CS_MEMORY_STORE_KEY,
       
  3591 		sizeof(WAPI_CS_MEMORY_STORE_KEY));
       
  3592 	if (status != eap_status_ok)
       
  3593 	{
       
  3594 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3595 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3596 	}
       
  3597 
       
  3598 	(void) m_am_tools->memory_store_remove_data(&key);
       
  3599 
       
  3600 	status = m_imported_certificate_wapi_id.reset();
       
  3601 	if (status != eap_status_ok)
       
  3602 	{
       
  3603 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3604 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3605 	}
       
  3606 
       
  3607 	status = m_imported_certificate_data.reset();
       
  3608 	if (status != eap_status_ok)
       
  3609 	{
       
  3610 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3611 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3612 	}
       
  3613 
       
  3614 	status = m_imported_certificate_file_data.reset();
       
  3615 	if (status != eap_status_ok)
       
  3616 	{
       
  3617 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3618 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3619 	}
       
  3620 
       
  3621 	status = m_imported_certificate_filename.reset();
       
  3622 	if (status != eap_status_ok)
       
  3623 	{
       
  3624 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3625 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3626 	}
       
  3627 
       
  3628 
       
  3629 	status = m_imported_private_key_data.reset();
       
  3630 	if (status != eap_status_ok)
       
  3631 	{
       
  3632 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3633 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3634 	}
       
  3635 
       
  3636 
       
  3637 	status = m_ae_certificate.reset();
       
  3638 	if (status != eap_status_ok)
       
  3639 	{
       
  3640 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3641 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3642 	}
       
  3643 
       
  3644 
       
  3645 	status = m_selected_ca_id.reset();
       
  3646 	if (status != eap_status_ok)
       
  3647 	{
       
  3648 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3649 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3650 	}
       
  3651 
       
  3652 	status = m_selected_client_id.reset();
       
  3653 	if (status != eap_status_ok)
       
  3654 	{
       
  3655 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3656 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3657 	}
       
  3658 
       
  3659 
       
  3660 	status = m_ca_asu_id_list.reset();
       
  3661 	if (status != eap_status_ok)
       
  3662 	{
       
  3663 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3664 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3665 	}
       
  3666 
       
  3667 	m_read_ca_asu_id_list = false;
       
  3668 
       
  3669 	status = m_client_asu_id_list.reset();
       
  3670 	if (status != eap_status_ok)
       
  3671 	{
       
  3672 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3673 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3674 	}
       
  3675 
       
  3676 	m_read_client_asu_id_list = false;
       
  3677 
       
  3678 	status = m_ca_certificates.reset();
       
  3679 	if (status != eap_status_ok)
       
  3680 	{
       
  3681 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3682 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3683 	}
       
  3684 
       
  3685 	status = m_client_certificates.reset();
       
  3686 	if (status != eap_status_ok)
       
  3687 	{
       
  3688 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3689 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3690 	}
       
  3691 
       
  3692 	status = m_client_private_keys.reset();
       
  3693 	if (status != eap_status_ok)
       
  3694 	{
       
  3695 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3696 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3697 	}
       
  3698 
       
  3699 	status = m_broken_cs_data_list.reset();
       
  3700 	if (status != eap_status_ok)
       
  3701 	{
       
  3702 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3703 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3704 	}
       
  3705 
       
  3706 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3707 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3708 }
       
  3709 
       
  3710 //----------------------------------------------------------------------------
       
  3711 
       
  3712 eap_status_e ec_certificate_store_c::read_PEM_data_line(
       
  3713 	const eap_variable_data_c * const in_imported_certificate_file_data,
       
  3714 	u32_t * const offset,
       
  3715 	eap_variable_data_c * const line)
       
  3716 {
       
  3717 	if (in_imported_certificate_file_data == 0
       
  3718 		|| offset == 0
       
  3719 		|| in_imported_certificate_file_data->get_data_length() < *offset)
       
  3720 	{
       
  3721 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3722 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3723 	}
       
  3724 
       
  3725 	if (*offset >= in_imported_certificate_file_data->get_data_length())
       
  3726 	{
       
  3727 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3728 		return EAP_STATUS_RETURN(m_am_tools, eap_status_end_of_file);
       
  3729 	}
       
  3730 
       
  3731 	u32_t remain_data_size(in_imported_certificate_file_data->get_data_length() - *offset);
       
  3732 
       
  3733 	const u8_t * const start = in_imported_certificate_file_data->get_data_offset(*offset, remain_data_size);
       
  3734 	if (start == 0)
       
  3735 	{
       
  3736 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3737 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3738 	}
       
  3739 
       
  3740 	const u8_t * data = start;
       
  3741 	if (data == 0)
       
  3742 	{
       
  3743 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3744 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3745 	}
       
  3746 
       
  3747 
       
  3748 	const u8_t * const end = start + remain_data_size;
       
  3749 	if (end == 0)
       
  3750 	{
       
  3751 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3752 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3753 	}
       
  3754 
       
  3755 	while (data < end && *data != '\n' && *data != '\r')
       
  3756 	{
       
  3757 		++data;
       
  3758 	}
       
  3759 
       
  3760 	eap_status_e status = line->set_buffer(start, (data - start), false, false);
       
  3761 	if (status != eap_status_ok)
       
  3762 	{
       
  3763 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3764 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3765 	}
       
  3766 
       
  3767 	if (data < end)
       
  3768 	{
       
  3769 		if (*data == '\r')
       
  3770 		{
       
  3771 			++data;
       
  3772 		}
       
  3773 
       
  3774 		if (*data == '\n')
       
  3775 		{
       
  3776 			++data;
       
  3777 		}
       
  3778 	}
       
  3779 
       
  3780 	*offset += (data - start);
       
  3781 
       
  3782 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3783 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3784 }
       
  3785 
       
  3786 //----------------------------------------------------------------------------
       
  3787 
       
  3788 eap_status_e ec_certificate_store_c::convert_PEM_to_DER(
       
  3789 	const wapi_pem_data_type_e key_type,
       
  3790 	const eap_variable_data_c * const pem_data,
       
  3791 	eap_array_c<ec_cs_data_c> * const der_data)
       
  3792 {
       
  3793 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3794 
       
  3795 	EAP_TRACE_DEBUG(
       
  3796 		m_am_tools,
       
  3797 		TRACE_FLAGS_DEFAULT,
       
  3798 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::convert_PEM_to_DER():\n"),
       
  3799 		 this,
       
  3800 		 (m_is_client == true ? "client": "server")));
       
  3801 
       
  3802 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::convert_PEM_to_DER()");
       
  3803 
       
  3804 	ec_cs_data_c data(m_am_tools);
       
  3805 	if (data.get_is_valid() == false)
       
  3806 	{
       
  3807 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3808 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3809 	}
       
  3810 
       
  3811 	eap_status_e status = data.get_writable_data()->set_buffer_length(pem_data->get_data_length());
       
  3812 	if (status != eap_status_ok)
       
  3813 	{
       
  3814 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3815 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3816 	}
       
  3817 
       
  3818 	status = data.get_writable_data()->set_data_length(data.get_writable_data()->get_buffer_length());
       
  3819 	if (status != eap_status_ok)
       
  3820 	{
       
  3821 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3822 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3823 	}
       
  3824 
       
  3825 	u32_t der_data_length(data.get_writable_data()->get_data_length());
       
  3826 
       
  3827 	status = m_am_tools->restore_bytes_from_ascii_armor(
       
  3828 		pem_data->get_data(),
       
  3829 		pem_data->get_data_length(),
       
  3830 		data.get_writable_data()->get_data(der_data_length),
       
  3831 		&der_data_length);
       
  3832 	if (status != eap_status_ok)
       
  3833 	{
       
  3834 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3835 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3836 	}
       
  3837 
       
  3838 	status = data.get_writable_data()->set_data_length(der_data_length);
       
  3839 	if (status != eap_status_ok)
       
  3840 	{
       
  3841 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3842 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3843 	}
       
  3844 
       
  3845 	EAP_TRACE_DATA_DEBUG(
       
  3846 		m_am_tools,
       
  3847 		TRACE_FLAGS_DEFAULT,
       
  3848 		(EAPL("data"),
       
  3849 		data.get_writable_data()->get_data(),
       
  3850 		data.get_writable_data()->get_data_length()));
       
  3851 
       
  3852 	if (key_type == wapi_pem_data_type_certificate)
       
  3853 	{
       
  3854 		eap_variable_data_c certificate_wapi_id(m_am_tools);
       
  3855 		if (certificate_wapi_id.get_is_valid() == false)
       
  3856 		{
       
  3857 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3858 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3859 		}
       
  3860 
       
  3861 		status = read_certificate_wapi_identity(
       
  3862 			data.get_data(),
       
  3863 			&certificate_wapi_id);
       
  3864 		if (status != eap_status_ok)
       
  3865 		{
       
  3866 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3867 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3868 		}
       
  3869 
       
  3870 		EAP_TRACE_DATA_DEBUG(
       
  3871 			m_am_tools,
       
  3872 			TRACE_FLAGS_DEFAULT,
       
  3873 			(EAPL("certificate_wapi_id"),
       
  3874 			certificate_wapi_id.get_data(),
       
  3875 			certificate_wapi_id.get_data_length()));
       
  3876 
       
  3877 		ec_cs_data_type_e data_type(ec_cs_data_type_none);
       
  3878 
       
  3879 		status = read_certificate_type(&certificate_wapi_id, &data_type);
       
  3880 		if (status != eap_status_ok)
       
  3881 		{
       
  3882 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3883 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3884 		}
       
  3885 
       
  3886 		data.set_type(data_type);
       
  3887 	}
       
  3888 	else if (key_type == wapi_pem_data_type_private_key)
       
  3889 	{
       
  3890 		data.set_type(ec_cs_data_type_private_key_data);
       
  3891 	}
       
  3892 	else
       
  3893 	{
       
  3894 		EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
       
  3895 	}
       
  3896 
       
  3897 	status = der_data->add_object(data.copy(), true);
       
  3898 	if (status != eap_status_ok)
       
  3899 	{
       
  3900 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3901 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3902 	}
       
  3903 
       
  3904 
       
  3905 #if defined(USE_WAPI_PEM_TO_DER_TEST)
       
  3906 
       
  3907 	{
       
  3908 		// This is test code for PEM decode/encode.
       
  3909 
       
  3910 		eap_variable_data_c pem_data_2(m_am_tools);
       
  3911 		if (pem_data_2.get_is_valid() == false)
       
  3912 		{
       
  3913 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3914 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3915 		}
       
  3916 
       
  3917 		status = pem_data_2.set_buffer_length(3ul + data.get_data()->get_data_length() * 8 / 6);
       
  3918 		if (status != eap_status_ok)
       
  3919 		{
       
  3920 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3921 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3922 		}
       
  3923 
       
  3924 		status = pem_data_2.set_data_length(pem_data_2.get_buffer_length());
       
  3925 		if (status != eap_status_ok)
       
  3926 		{
       
  3927 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3928 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3929 		}
       
  3930 
       
  3931 		u32_t pem_data_length(pem_data->get_data_length());
       
  3932 
       
  3933 		status = m_am_tools->convert_bytes_to_ascii_armor(
       
  3934 			data.get_data()->get_data(),
       
  3935 			data.get_data()->get_data_length(),
       
  3936 			pem_data_2.get_data(der_data_length),
       
  3937 			&pem_data_length);
       
  3938 		if (status != eap_status_ok)
       
  3939 		{
       
  3940 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3941 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3942 		}
       
  3943 
       
  3944 		status = pem_data_2.set_data_length(pem_data_length);
       
  3945 		if (status != eap_status_ok)
       
  3946 		{
       
  3947 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3948 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3949 		}
       
  3950 
       
  3951 		EAP_TRACE_DATA_DEBUG(
       
  3952 			m_am_tools,
       
  3953 			TRACE_FLAGS_DEFAULT,
       
  3954 			(EAPL("pem_data_2"),
       
  3955 			pem_data_2.get_data(),
       
  3956 			pem_data_2.get_data_length()));
       
  3957 
       
  3958 		if (pem_data->compare(&pem_data_2) != 0)
       
  3959 		{
       
  3960 			EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
       
  3961 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3962 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
  3963 		}
       
  3964 	}
       
  3965 
       
  3966 #endif //#if defined(USE_WAPI_PEM_TO_DER_TEST)
       
  3967 
       
  3968 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3969 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3970 }
       
  3971 
       
  3972 //----------------------------------------------------------------------------
       
  3973 
       
  3974 eap_status_e ec_certificate_store_c::parse_PEM_file_data(
       
  3975 	const eap_variable_data_c * const in_imported_certificate_file_data,
       
  3976 	eap_array_c<ec_cs_data_c> * const der_data)
       
  3977 {
       
  3978 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3979 
       
  3980 	EAP_TRACE_DEBUG(
       
  3981 		m_am_tools,
       
  3982 		TRACE_FLAGS_DEFAULT,
       
  3983 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::parse_PEM_file_data():\n"),
       
  3984 		 this,
       
  3985 		 (m_is_client == true ? "client": "server")));
       
  3986 
       
  3987 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::parse_PEM_file_data()");
       
  3988 
       
  3989 	eap_status_e status(eap_status_not_supported);
       
  3990 
       
  3991 	u32_t offset(0ul);
       
  3992 
       
  3993 	eap_variable_data_c line(m_am_tools);
       
  3994 	if (line.get_is_valid() == false)
       
  3995 	{
       
  3996 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3997 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3998 	}
       
  3999 
       
  4000 	eap_variable_data_c pem_data(m_am_tools);
       
  4001 	if (pem_data.get_is_valid() == false)
       
  4002 	{
       
  4003 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4004 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4005 	}
       
  4006 
       
  4007 	wapi_pem_data_type_e data_type(wapi_pem_data_type_none);
       
  4008 	wapi_pem_read_state_e state(wapi_pem_read_state_header);
       
  4009 
       
  4010 	do
       
  4011 	{
       
  4012 		status = read_PEM_data_line(in_imported_certificate_file_data, &offset, &line);
       
  4013 		if (status == eap_status_end_of_file)
       
  4014 		{
       
  4015 			// In the end of file status is eap_status_end_of_file. We change that to OK status.
       
  4016 			status = eap_status_ok;
       
  4017 			break;
       
  4018 		}
       
  4019 		else if (status != eap_status_ok)
       
  4020 		{
       
  4021 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4022 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4023 		}
       
  4024 
       
  4025 		if (state == wapi_pem_read_state_header)
       
  4026 		{
       
  4027 			if (wapi_pem_certificate_begin.get_field()->compare(
       
  4028 					m_am_tools,
       
  4029 					&line) == true)
       
  4030 			{
       
  4031 				state = wapi_pem_read_state_data;
       
  4032 				data_type = wapi_pem_data_type_certificate;
       
  4033 			}
       
  4034 			else if (wapi_pem_ec_private_key_begin.get_field()->compare(
       
  4035 					m_am_tools,
       
  4036 					&line) == true)
       
  4037 			{
       
  4038 				state = wapi_pem_read_state_data;
       
  4039 				data_type = wapi_pem_data_type_private_key;
       
  4040 			}
       
  4041 		}
       
  4042 		else if (state == wapi_pem_read_state_data)
       
  4043 		{
       
  4044 			if (data_type == wapi_pem_data_type_certificate
       
  4045 				&& wapi_pem_certificate_end.get_field()->compare(
       
  4046 					m_am_tools,
       
  4047 					&line) == true)
       
  4048 			{
       
  4049 				status = convert_PEM_to_DER(
       
  4050 					data_type,
       
  4051 					&pem_data,
       
  4052 					der_data);
       
  4053 				if (status != eap_status_ok)
       
  4054 				{
       
  4055 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4056 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4057 				}
       
  4058 
       
  4059 				pem_data.reset_start_offset_and_data_length();
       
  4060 
       
  4061 				state = wapi_pem_read_state_header;
       
  4062 			}
       
  4063 			else if (data_type == wapi_pem_data_type_private_key
       
  4064 				&& wapi_pem_ec_private_key_end.get_field()->compare(
       
  4065 					m_am_tools,
       
  4066 					&line) == true)
       
  4067 			{
       
  4068 				status = convert_PEM_to_DER(
       
  4069 					data_type,
       
  4070 					&pem_data,
       
  4071 					der_data);
       
  4072 				if (status != eap_status_ok)
       
  4073 				{
       
  4074 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4075 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4076 				}
       
  4077 
       
  4078 				pem_data.reset_start_offset_and_data_length();
       
  4079 
       
  4080 				state = wapi_pem_read_state_header;
       
  4081 			}
       
  4082 			else
       
  4083 			{
       
  4084 				status = pem_data.add_data(&line);
       
  4085 				if (status != eap_status_ok)
       
  4086 				{
       
  4087 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4088 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4089 				}
       
  4090 			}
       
  4091 		}
       
  4092 	}
       
  4093 	while(status == eap_status_ok);
       
  4094 
       
  4095 
       
  4096 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4097 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4098 }
       
  4099 
       
  4100 //----------------------------------------------------------------------------
       
  4101 
       
  4102 eap_status_e ec_certificate_store_c::read_certificate_type(
       
  4103 	const eap_variable_data_c * const imported_certificate_wapi_id,
       
  4104 	ec_cs_data_type_e * const data_type)
       
  4105 {
       
  4106 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4107 
       
  4108 	EAP_TRACE_DEBUG(
       
  4109 		m_am_tools,
       
  4110 		TRACE_FLAGS_DEFAULT,
       
  4111 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate_type():\n"),
       
  4112 		 this,
       
  4113 		 (m_is_client == true ? "client": "server")));
       
  4114 
       
  4115 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate_type()");
       
  4116 
       
  4117 	eap_status_e status(eap_status_not_supported);
       
  4118 
       
  4119 
       
  4120 	wapi_asn1_der_parser_c wapi_asn1_der_parser(m_am_tools);
       
  4121 
       
  4122 	if (wapi_asn1_der_parser.get_is_valid() == false)
       
  4123 	{
       
  4124 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4125 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4126 	}
       
  4127 
       
  4128 	status = wapi_asn1_der_parser.decode(imported_certificate_wapi_id);
       
  4129 	if (status != eap_status_ok)
       
  4130 	{
       
  4131 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4132 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4133 	}
       
  4134 
       
  4135 	eap_variable_data_c asn1_der_subject_name(m_am_tools);
       
  4136 	eap_variable_data_c asn1_der_issuer_name(m_am_tools);
       
  4137 	eap_variable_data_c asn1_der_sequence_number(m_am_tools);
       
  4138 
       
  4139 	status = wapi_asn1_der_parser.get_wapi_identity(
       
  4140 		&asn1_der_subject_name,
       
  4141 		&asn1_der_issuer_name,
       
  4142 		&asn1_der_sequence_number);
       
  4143 	if (status != eap_status_ok)
       
  4144 	{
       
  4145 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4146 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4147 	}
       
  4148 
       
  4149 	if (asn1_der_subject_name.compare(&asn1_der_issuer_name) == 0)
       
  4150 	{
       
  4151 		*data_type = ec_cs_data_type_ca_certificate_data;
       
  4152 	}
       
  4153 	else
       
  4154 	{
       
  4155 		*data_type = ec_cs_data_type_client_certificate_data;
       
  4156 	}
       
  4157 
       
  4158 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4159 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4160 }
       
  4161 
       
  4162 //----------------------------------------------------------------------------
       
  4163 
       
  4164 eap_status_e ec_certificate_store_c::read_certificate_reference(
       
  4165 	const ec_cs_data_c * const reference_tlv,
       
  4166 	eap_variable_data_c * const certificate_reference)
       
  4167 {
       
  4168 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4169 
       
  4170 	EAP_TRACE_DEBUG(
       
  4171 		m_am_tools,
       
  4172 		TRACE_FLAGS_DEFAULT,
       
  4173 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate_reference():\n"),
       
  4174 		 this,
       
  4175 		 (m_is_client == true ? "client": "server")));
       
  4176 
       
  4177 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate_reference()");
       
  4178 
       
  4179 	eap_status_e status(eap_status_not_supported);
       
  4180 
       
  4181 	ec_cs_tlv_header_c id_reference_tlv(
       
  4182 		m_am_tools,
       
  4183 		reference_tlv->get_data()->get_data(),
       
  4184 		reference_tlv->get_data()->get_data_length());
       
  4185 	if (id_reference_tlv.get_is_valid() == false)
       
  4186 	{
       
  4187 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4188 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4189 	}
       
  4190 
       
  4191 	ec_cs_tlv_payloads_c parser(
       
  4192 		m_am_tools,
       
  4193 		true);
       
  4194 	if (parser.get_is_valid() == false)
       
  4195 	{
       
  4196 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4197 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4198 	}
       
  4199 
       
  4200 	u32_t length(id_reference_tlv.get_data_length());
       
  4201 	u32_t padding_length(0ul);
       
  4202 
       
  4203 	status = parser.parse_ec_cs_payloads(
       
  4204 		id_reference_tlv.get_data(length), ///< This is the start of the message buffer.
       
  4205 		&length, ///< This is the length of the buffer. This must match with the length of all payloads.
       
  4206 		&padding_length ///< Length of possible padding is set to this variable.
       
  4207 		);
       
  4208 	if (status != eap_status_ok)
       
  4209 	{
       
  4210 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4211 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4212 	}
       
  4213 
       
  4214 	const ec_cs_variable_data_c * const certificate_reference_tlv = parser.get_tlv_pointer(ec_cs_tlv_type_CS_certificate_reference);
       
  4215 	if (certificate_reference_tlv == 0)
       
  4216 	{
       
  4217 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4218 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4219 	}
       
  4220 
       
  4221 	status = certificate_reference->set_copy_of_buffer(
       
  4222 		certificate_reference_tlv->get_data(certificate_reference_tlv->get_data_length()),
       
  4223 		certificate_reference_tlv->get_data_length());
       
  4224 	if (status != eap_status_ok)
       
  4225 	{
       
  4226 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4227 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4228 	}
       
  4229 
       
  4230 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4231 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4232 }
       
  4233 
       
  4234 //----------------------------------------------------------------------------
       
  4235 
       
  4236 eap_status_e ec_certificate_store_c::read_certificate(
       
  4237 	const ec_cs_pending_operation_e pending_operation,
       
  4238 	const ec_cs_data_type_e certificate_type,
       
  4239 	const eap_variable_data_c * certificate_reference)
       
  4240 {
       
  4241 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4242 
       
  4243 	EAP_TRACE_DEBUG(
       
  4244 		m_am_tools,
       
  4245 		TRACE_FLAGS_DEFAULT,
       
  4246 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate():\n"),
       
  4247 		 this,
       
  4248 		 (m_is_client == true ? "client": "server")));
       
  4249 
       
  4250 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate()");
       
  4251 
       
  4252 	eap_status_e status(eap_status_not_supported);
       
  4253 
       
  4254 	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
       
  4255 
       
  4256 	{
       
  4257 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  4258 
       
  4259 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  4260 
       
  4261 		if (data == 0
       
  4262 			|| data->get_is_valid() == false)
       
  4263 		{
       
  4264 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4265 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4266 		}
       
  4267 
       
  4268 		status = data->get_writable_reference()->set_copy_of_buffer(certificate_reference);
       
  4269 		if (status != eap_status_ok)
       
  4270 		{
       
  4271 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4272 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4273 		}
       
  4274 
       
  4275 		data->set_type(certificate_type);
       
  4276 
       
  4277 		automatic_data.do_not_free_variable();
       
  4278 
       
  4279 		status = in_references.add_object(data, true);
       
  4280 		if (status != eap_status_ok)
       
  4281 		{
       
  4282 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4283 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4284 		}
       
  4285 	}
       
  4286 
       
  4287 
       
  4288 	if (certificate_type == ec_cs_data_type_client_certificate_data)
       
  4289 	{
       
  4290 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  4291 
       
  4292 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  4293 
       
  4294 		if (data == 0
       
  4295 			|| data->get_is_valid() == false)
       
  4296 		{
       
  4297 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4298 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4299 		}
       
  4300 
       
  4301 		status = data->get_writable_reference()->set_copy_of_buffer(certificate_reference);
       
  4302 		if (status != eap_status_ok)
       
  4303 		{
       
  4304 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4305 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4306 		}
       
  4307 
       
  4308 		data->set_type(ec_cs_data_type_private_key_data);
       
  4309 
       
  4310 		automatic_data.do_not_free_variable();
       
  4311 
       
  4312 		status = in_references.add_object(data, true);
       
  4313 		if (status != eap_status_ok)
       
  4314 		{
       
  4315 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4316 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4317 		}
       
  4318 	}
       
  4319 
       
  4320 	status = m_am_certificate_store->read_certificate_store_data(
       
  4321 		pending_operation,
       
  4322 		&in_references);
       
  4323 
       
  4324 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4325 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4326 }
       
  4327 
       
  4328 //----------------------------------------------------------------------------
       
  4329 
       
  4330 eap_status_e ec_certificate_store_c::read_both_certificate_lists(
       
  4331 	const ec_cs_pending_operation_e pending_operation)
       
  4332 {
       
  4333 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4334 
       
  4335 	EAP_TRACE_DEBUG(
       
  4336 		m_am_tools,
       
  4337 		TRACE_FLAGS_DEFAULT,
       
  4338 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_both_certificate_lists():\n"),
       
  4339 		 this,
       
  4340 		 (m_is_client == true ? "client": "server")));
       
  4341 
       
  4342 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_both_certificate_lists()");
       
  4343 
       
  4344 	eap_status_e status(eap_status_not_supported);
       
  4345 
       
  4346 	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
       
  4347 
       
  4348 	status = add_password_qyery(&in_references);
       
  4349 	if (status != eap_status_ok)
       
  4350 	{
       
  4351 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4352 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4353 	}
       
  4354 
       
  4355 	if (m_read_ca_asu_id_list == false)
       
  4356 	{
       
  4357 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  4358 
       
  4359 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  4360 
       
  4361 		if (data == 0
       
  4362 			|| data->get_is_valid() == false)
       
  4363 		{
       
  4364 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4365 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4366 		}
       
  4367 
       
  4368 		data->set_type(ec_cs_data_type_ca_asu_id_list);
       
  4369 
       
  4370 		automatic_data.do_not_free_variable();
       
  4371 
       
  4372 		status = in_references.add_object(data, true);
       
  4373 		if (status != eap_status_ok)
       
  4374 		{
       
  4375 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4376 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4377 		}
       
  4378 
       
  4379 	}
       
  4380 	else
       
  4381 	{
       
  4382 		status = eap_status_ok;
       
  4383 	}
       
  4384 
       
  4385 	if (m_read_client_asu_id_list == false)
       
  4386 	{
       
  4387 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  4388 
       
  4389 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  4390 
       
  4391 		if (data == 0
       
  4392 			|| data->get_is_valid() == false)
       
  4393 		{
       
  4394 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4395 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4396 		}
       
  4397 
       
  4398 		data->set_type(ec_cs_data_type_client_asu_id_list);
       
  4399 
       
  4400 		automatic_data.do_not_free_variable();
       
  4401 
       
  4402 		status = in_references.add_object(data, true);
       
  4403 		if (status != eap_status_ok)
       
  4404 		{
       
  4405 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4406 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4407 		}
       
  4408 	}
       
  4409 	else
       
  4410 	{
       
  4411 		status = eap_status_ok;
       
  4412 	}
       
  4413 
       
  4414 	if (in_references.get_object_count() > 0ul)
       
  4415 	{
       
  4416 		m_read_ca_asu_id_list = true;
       
  4417 		m_read_client_asu_id_list = true;
       
  4418 
       
  4419 		status = m_am_certificate_store->read_certificate_store_data(
       
  4420 			pending_operation,
       
  4421 			&in_references);
       
  4422 	}
       
  4423 
       
  4424 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4425 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4426 }
       
  4427 
       
  4428 //----------------------------------------------------------------------------
       
  4429 
       
  4430 eap_status_e ec_certificate_store_c::read_ca_certificate_list(
       
  4431 	const ec_cs_pending_operation_e pending_operation)
       
  4432 {
       
  4433 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4434 
       
  4435 	EAP_TRACE_DEBUG(
       
  4436 		m_am_tools,
       
  4437 		TRACE_FLAGS_DEFAULT,
       
  4438 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_ca_certificate_list():\n"),
       
  4439 		 this,
       
  4440 		 (m_is_client == true ? "client": "server")));
       
  4441 
       
  4442 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_ca_certificate_list()");
       
  4443 
       
  4444 	eap_status_e status(eap_status_not_supported);
       
  4445 
       
  4446 	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
       
  4447 
       
  4448 	status = add_password_qyery(&in_references);
       
  4449 	if (status != eap_status_ok)
       
  4450 	{
       
  4451 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4452 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4453 	}
       
  4454 
       
  4455 	if (m_read_ca_asu_id_list == false)
       
  4456 	{
       
  4457 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  4458 
       
  4459 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  4460 
       
  4461 		if (data == 0
       
  4462 			|| data->get_is_valid() == false)
       
  4463 		{
       
  4464 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4465 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4466 		}
       
  4467 
       
  4468 		data->set_type(ec_cs_data_type_ca_asu_id_list);
       
  4469 
       
  4470 		automatic_data.do_not_free_variable();
       
  4471 
       
  4472 		status = in_references.add_object(data, true);
       
  4473 		if (status != eap_status_ok)
       
  4474 		{
       
  4475 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4476 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4477 		}
       
  4478 	}
       
  4479 	else
       
  4480 	{
       
  4481 		status = eap_status_ok;
       
  4482 	}
       
  4483 
       
  4484 	if (in_references.get_object_count() > 0ul)
       
  4485 	{
       
  4486 		status = m_am_certificate_store->read_certificate_store_data(
       
  4487 			pending_operation,
       
  4488 			&in_references);
       
  4489 	}
       
  4490 
       
  4491 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4492 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4493 }
       
  4494 
       
  4495 //----------------------------------------------------------------------------
       
  4496 
       
  4497 eap_status_e ec_certificate_store_c::read_client_certificate_list(
       
  4498 	const ec_cs_pending_operation_e pending_operation)
       
  4499 {
       
  4500 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4501 
       
  4502 	EAP_TRACE_DEBUG(
       
  4503 		m_am_tools,
       
  4504 		TRACE_FLAGS_DEFAULT,
       
  4505 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_client_certificate_list():\n"),
       
  4506 		 this,
       
  4507 		 (m_is_client == true ? "client": "server")));
       
  4508 
       
  4509 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_client_certificate_list()");
       
  4510 
       
  4511 	eap_status_e status(eap_status_not_supported);
       
  4512 
       
  4513 	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
       
  4514 
       
  4515 	status = add_password_qyery(&in_references);
       
  4516 	if (status != eap_status_ok)
       
  4517 	{
       
  4518 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4519 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4520 	}
       
  4521 
       
  4522 	if (m_read_client_asu_id_list == false)
       
  4523 	{
       
  4524 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  4525 
       
  4526 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  4527 
       
  4528 		if (data == 0
       
  4529 			|| data->get_is_valid() == false)
       
  4530 		{
       
  4531 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4532 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4533 		}
       
  4534 
       
  4535 		data->set_type(ec_cs_data_type_client_asu_id_list);
       
  4536 
       
  4537 		automatic_data.do_not_free_variable();
       
  4538 
       
  4539 		status = in_references.add_object(data, true);
       
  4540 		if (status != eap_status_ok)
       
  4541 		{
       
  4542 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4543 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4544 		}
       
  4545 	}
       
  4546 	else
       
  4547 	{
       
  4548 		status = eap_status_ok;
       
  4549 	}
       
  4550 
       
  4551 
       
  4552 	if (in_references.get_object_count() > 0ul)
       
  4553 	{
       
  4554 		status = m_am_certificate_store->read_certificate_store_data(
       
  4555 			pending_operation,
       
  4556 			&in_references);
       
  4557 	}
       
  4558 
       
  4559 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4560 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4561 }
       
  4562 
       
  4563 //----------------------------------------------------------------------------
       
  4564 
       
  4565 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::add_imported_certificate_file(
       
  4566 	const eap_variable_data_c * const in_imported_certificate_file_data,
       
  4567 	const eap_variable_data_c * const in_imported_certificate_filename)
       
  4568 {
       
  4569 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4570 
       
  4571 	EAP_TRACE_DEBUG(
       
  4572 		m_am_tools,
       
  4573 		TRACE_FLAGS_DEFAULT,
       
  4574 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::add_imported_certificate_file():\n"),
       
  4575 		 this,
       
  4576 		 (m_is_client == true ? "client": "server")));
       
  4577 
       
  4578 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_imported_certificate_file()");
       
  4579 
       
  4580 	eap_status_e status(eap_status_not_supported);
       
  4581 
       
  4582 	if (in_imported_certificate_file_data == 0
       
  4583 		|| in_imported_certificate_file_data->get_is_valid() == false)
       
  4584 	{
       
  4585 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4586 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4587 	}
       
  4588 
       
  4589 	if (in_imported_certificate_filename == 0
       
  4590 		|| in_imported_certificate_filename->get_is_valid() == false)
       
  4591 	{
       
  4592 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4593 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4594 	}
       
  4595 
       
  4596 	EAP_TRACE_DATA_DEBUG(
       
  4597 		m_am_tools,
       
  4598 		TRACE_FLAGS_DEFAULT,
       
  4599 		(EAPL("in_imported_certificate_filename"),
       
  4600 		in_imported_certificate_filename->get_data(),
       
  4601 		in_imported_certificate_filename->get_data_length()));
       
  4602 
       
  4603 	EAP_TRACE_DATA_DEBUG(
       
  4604 		m_am_tools,
       
  4605 		TRACE_FLAGS_DEFAULT,
       
  4606 		(EAPL("in_imported_certificate_file_data"),
       
  4607 		in_imported_certificate_file_data->get_data(),
       
  4608 		in_imported_certificate_file_data->get_data_length()));
       
  4609 
       
  4610 	eap_array_c<ec_cs_data_c> der_data(m_am_tools);
       
  4611 
       
  4612 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4613 
       
  4614 	status = m_imported_certificate_file_data.set_copy_of_buffer(in_imported_certificate_file_data);
       
  4615 	if (status != eap_status_ok)
       
  4616 	{
       
  4617 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4618 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4619 	}
       
  4620 
       
  4621 	status = m_imported_certificate_filename.set_copy_of_buffer(in_imported_certificate_filename);
       
  4622 	if (status != eap_status_ok)
       
  4623 	{
       
  4624 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4625 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4626 	}
       
  4627 
       
  4628 	status = m_imported_certificate_data.reset_start_offset_and_data_length();
       
  4629 	if (status != eap_status_ok)
       
  4630 	{
       
  4631 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4632 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4633 	}
       
  4634 
       
  4635 	status = m_imported_private_key_data.reset_start_offset_and_data_length();
       
  4636 	if (status != eap_status_ok)
       
  4637 	{
       
  4638 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4639 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4640 	}
       
  4641 
       
  4642 	status = completion_action_push(ec_cs_completion_complete_add_imported_certificate_file);
       
  4643 	if (status != eap_status_ok)
       
  4644 	{
       
  4645 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4646 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4647 	}
       
  4648 
       
  4649 	if (m_PAC_store_master_key.get_is_valid_data() == true
       
  4650 		&& m_PAC_store_password.get_is_valid_data() == true
       
  4651 		&& m_PAC_store_device_seed.get_is_valid_data() == true)
       
  4652 	{
       
  4653 		status = internal_complete_add_imported_certificate_file();
       
  4654 		if (status != eap_status_ok)
       
  4655 		{
       
  4656 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4657 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4658 		}
       
  4659 	}
       
  4660 	else
       
  4661 	{
       
  4662 		status = completion_action_push(ec_cs_completion_internal_complete_add_imported_certificate_file);
       
  4663 		if (status != eap_status_ok)
       
  4664 		{
       
  4665 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4666 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4667 		}
       
  4668 
       
  4669 		status = completion_action_push(ec_cs_completion_query_PAC_store_password);
       
  4670 		if (status != eap_status_ok)
       
  4671 		{
       
  4672 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4673 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4674 		}
       
  4675 	}
       
  4676 
       
  4677 	// If there were no asyncronous calls operations continue here.
       
  4678 	status = completion_action_check();
       
  4679 
       
  4680 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4681 
       
  4682 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4683 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4684 }
       
  4685 
       
  4686 //----------------------------------------------------------------------------
       
  4687 
       
  4688 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::internal_complete_add_imported_certificate_file()
       
  4689 {
       
  4690 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4691 
       
  4692 	EAP_TRACE_DEBUG(
       
  4693 		m_am_tools,
       
  4694 		TRACE_FLAGS_DEFAULT,
       
  4695 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_complete_add_imported_certificate_file():\n"),
       
  4696 		 this,
       
  4697 		 (m_is_client == true ? "client": "server")));
       
  4698 
       
  4699 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_complete_add_imported_certificate_file()");
       
  4700 
       
  4701 	eap_status_e status(eap_status_not_supported);
       
  4702 
       
  4703 	if (m_imported_certificate_file_data.get_is_valid() == false)
       
  4704 	{
       
  4705 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4706 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4707 	}
       
  4708 
       
  4709 	if (m_imported_certificate_filename.get_is_valid() == false)
       
  4710 	{
       
  4711 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4712 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4713 	}
       
  4714 
       
  4715 	EAP_TRACE_DATA_DEBUG(
       
  4716 		m_am_tools,
       
  4717 		TRACE_FLAGS_DEFAULT,
       
  4718 		(EAPL("m_imported_certificate_filename"),
       
  4719 		m_imported_certificate_filename.get_data(),
       
  4720 		m_imported_certificate_filename.get_data_length()));
       
  4721 
       
  4722 	EAP_TRACE_DATA_DEBUG(
       
  4723 		m_am_tools,
       
  4724 		TRACE_FLAGS_DEFAULT,
       
  4725 		(EAPL("m_imported_certificate_file_data"),
       
  4726 		m_imported_certificate_file_data.get_data(),
       
  4727 		m_imported_certificate_file_data.get_data_length()));
       
  4728 
       
  4729 	eap_array_c<ec_cs_data_c> der_data(m_am_tools);
       
  4730 
       
  4731 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4732 
       
  4733 	status = parse_PEM_file_data(&m_imported_certificate_file_data, &der_data);
       
  4734 	if (status != eap_status_ok)
       
  4735 	{
       
  4736 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4737 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4738 	}
       
  4739 
       
  4740 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4741 
       
  4742 	ec_cs_data_type_e data_type(ec_cs_data_type_none);
       
  4743 
       
  4744 	for (u32_t index = 0ul; index < der_data.get_object_count(); ++index)
       
  4745 	{
       
  4746 		ec_cs_data_c * const data = der_data.get_object(index);
       
  4747 		if (data == 0)
       
  4748 		{
       
  4749 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4750 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
       
  4751 		}
       
  4752 
       
  4753 		if (data->get_type() == ec_cs_data_type_ca_certificate_data
       
  4754 			|| data->get_type() == ec_cs_data_type_client_certificate_data)
       
  4755 		{
       
  4756 			data_type = data->get_type();
       
  4757 
       
  4758 			status = read_certificate_wapi_identity(
       
  4759 				data->get_data(),
       
  4760 				&m_imported_certificate_wapi_id);
       
  4761 			if (status != eap_status_ok)
       
  4762 			{
       
  4763 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4764 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4765 			}
       
  4766 
       
  4767 			EAP_TRACE_DATA_DEBUG(
       
  4768 				m_am_tools,
       
  4769 				TRACE_FLAGS_DEFAULT,
       
  4770 				(EAPL("m_imported_certificate_wapi_id"),
       
  4771 				m_imported_certificate_wapi_id.get_data(),
       
  4772 				m_imported_certificate_wapi_id.get_data_length()));
       
  4773 
       
  4774 			status = m_imported_certificate_data.set_copy_of_buffer(data->get_data());
       
  4775 			if (status != eap_status_ok)
       
  4776 			{
       
  4777 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4778 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4779 			}
       
  4780 		}
       
  4781 		else if (data->get_type() == ec_cs_data_type_private_key_data)
       
  4782 		{
       
  4783 			status = m_imported_private_key_data.set_copy_of_buffer(data->get_data());
       
  4784 			if (status != eap_status_ok)
       
  4785 			{
       
  4786 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4787 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4788 			}
       
  4789 		}
       
  4790 
       
  4791 	} // for()
       
  4792 
       
  4793 
       
  4794 	if (data_type == ec_cs_data_type_ca_certificate_data)
       
  4795 	{
       
  4796 		status = completion_action_push(ec_cs_completion_add_imported_ca_certificate);
       
  4797 		if (status != eap_status_ok)
       
  4798 		{
       
  4799 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4800 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4801 		}
       
  4802 
       
  4803 		status = read_ca_certificate_list(ec_cs_pending_operation_import_ca_certificate_file);
       
  4804 		if (status != eap_status_ok)
       
  4805 		{
       
  4806 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4807 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4808 		}
       
  4809 	}
       
  4810 	else //if (data_type == ec_cs_data_type_client_certificate_data)
       
  4811 	{
       
  4812 		status = completion_action_push(ec_cs_completion_add_imported_client_certificate);
       
  4813 		if (status != eap_status_ok)
       
  4814 		{
       
  4815 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4816 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4817 		}
       
  4818 
       
  4819 		status = read_client_certificate_list(ec_cs_pending_operation_import_client_certificate_file);
       
  4820 		if (status != eap_status_ok)
       
  4821 		{
       
  4822 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4823 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4824 		}
       
  4825 	}
       
  4826 
       
  4827 	// If there were no asyncronous calls operations continue here.
       
  4828 	status = completion_action_check();
       
  4829 
       
  4830 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4831 
       
  4832 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4833 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4834 }
       
  4835 
       
  4836 //--------------------------------------------------
       
  4837 
       
  4838 eap_status_e ec_certificate_store_c::save_to_broken_cs_data_list(
       
  4839 	const ec_cs_data_c * const ref_and_data)
       
  4840 {
       
  4841 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4842 
       
  4843 	EAP_TRACE_DEBUG(
       
  4844 		m_am_tools,
       
  4845 		TRACE_FLAGS_DEFAULT,
       
  4846 		(EAPL("WAPI_Core: ec_certificate_store_c::save_to_broken_cs_data_list():\n")));
       
  4847 
       
  4848 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_to_broken_cs_data_list()");
       
  4849 
       
  4850 	eap_status_e status(eap_status_ok);
       
  4851 
       
  4852 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4853 
       
  4854 	if (ref_and_data != 0)
       
  4855 	{
       
  4856 		ec_cs_data_c * const new_ec_cd_data = ref_and_data->copy();
       
  4857 		if (new_ec_cd_data != 0)
       
  4858 		{
       
  4859 			new_ec_cd_data->set_change_status(ec_cs_data_change_status_delete);
       
  4860 
       
  4861 			status = m_broken_cs_data_list.add_object(new_ec_cd_data, true);
       
  4862 			if (status != eap_status_ok)
       
  4863 			{
       
  4864 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4865 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4866 			}
       
  4867 		}
       
  4868 
       
  4869 		if (ref_and_data->get_type() == ec_cs_data_type_ca_certificate_data)
       
  4870 		{
       
  4871 			// We must remove the broken ID-Reference too.
       
  4872 			ec_cs_data_c search_id(m_am_tools);
       
  4873 
       
  4874 			eap_status_e status = search_id.get_writable_data()->set_buffer(
       
  4875 				ref_and_data->get_reference());
       
  4876 			if (status != eap_status_ok)
       
  4877 			{
       
  4878 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4879 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4880 			}
       
  4881 
       
  4882 			eap_variable_data_c certificate_reference(m_am_tools);
       
  4883 
       
  4884 			ec_cs_compare_reference_c compare_reference(m_am_tools);
       
  4885 
       
  4886 			const ec_cs_data_c * identity_reference_tlv = 0;
       
  4887 
       
  4888 			EAP_TRACE_DEBUG(
       
  4889 				m_am_tools,
       
  4890 				TRACE_FLAGS_DEFAULT,
       
  4891 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): count of m_ca_asu_id_list = %d.\n"),
       
  4892 				 this,
       
  4893 				 (m_is_client == true ? "client": "server"),
       
  4894 				 m_ca_asu_id_list.get_object_count()));
       
  4895 
       
  4896 			// Search CA-Certificate identity.
       
  4897 			i32_t index = find_with_compare<ec_cs_data_c>(
       
  4898 				&compare_reference,
       
  4899 				&m_ca_asu_id_list,
       
  4900 				&search_id,
       
  4901 				m_am_tools);
       
  4902 			if (index >= 0)
       
  4903 			{
       
  4904 				// Match.
       
  4905 				EAP_TRACE_DEBUG(
       
  4906 					m_am_tools,
       
  4907 					TRACE_FLAGS_DEFAULT,
       
  4908 					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): CA certificate ID list match.\n"),
       
  4909 					 this,
       
  4910 					 (m_is_client == true ? "client": "server")));
       
  4911 
       
  4912 				identity_reference_tlv = m_ca_asu_id_list.get_object(index);
       
  4913 
       
  4914 				if (identity_reference_tlv != 0)
       
  4915 				{
       
  4916 					ec_cs_data_c * const new_ec_cd_data = identity_reference_tlv->copy();
       
  4917 					if (new_ec_cd_data != 0)
       
  4918 					{
       
  4919 						new_ec_cd_data->set_change_status(ec_cs_data_change_status_delete);
       
  4920 
       
  4921 						status = m_broken_cs_data_list.add_object(new_ec_cd_data, true);
       
  4922 						if (status != eap_status_ok)
       
  4923 						{
       
  4924 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4925 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  4926 						}
       
  4927 					}
       
  4928 				}
       
  4929 			}
       
  4930 		}
       
  4931 		else if (ref_and_data->get_type() == ec_cs_data_type_client_certificate_data
       
  4932 			|| ref_and_data->get_type() == ec_cs_data_type_private_key_data)
       
  4933 		{
       
  4934 			// We must remove the broken ID-Reference too.
       
  4935 			ec_cs_data_c search_id(m_am_tools);
       
  4936 
       
  4937 			eap_status_e status = search_id.get_writable_data()->set_buffer(
       
  4938 				ref_and_data->get_reference());
       
  4939 			if (status != eap_status_ok)
       
  4940 			{
       
  4941 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4942 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4943 			}
       
  4944 
       
  4945 			eap_variable_data_c certificate_reference(m_am_tools);
       
  4946 
       
  4947 			ec_cs_compare_reference_c compare_reference(m_am_tools);
       
  4948 
       
  4949 			const ec_cs_data_c * identity_reference_tlv = 0;
       
  4950 
       
  4951 			EAP_TRACE_DEBUG(
       
  4952 				m_am_tools,
       
  4953 				TRACE_FLAGS_DEFAULT,
       
  4954 				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): count of m_client_asu_id_list = %d.\n"),
       
  4955 				 this,
       
  4956 				 (m_is_client == true ? "client": "server"),
       
  4957 				 m_client_asu_id_list.get_object_count()));
       
  4958 
       
  4959 			// Search CA-Certificate identity.
       
  4960 			i32_t index = find_with_compare<ec_cs_data_c>(
       
  4961 				&compare_reference,
       
  4962 				&m_client_asu_id_list,
       
  4963 				&search_id,
       
  4964 				m_am_tools);
       
  4965 			if (index >= 0)
       
  4966 			{
       
  4967 				// Match.
       
  4968 				EAP_TRACE_DEBUG(
       
  4969 					m_am_tools,
       
  4970 					TRACE_FLAGS_DEFAULT,
       
  4971 					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): CA certificate ID list match.\n"),
       
  4972 					 this,
       
  4973 					 (m_is_client == true ? "client": "server")));
       
  4974 
       
  4975 				identity_reference_tlv = m_client_asu_id_list.get_object(index);
       
  4976 
       
  4977 				if (identity_reference_tlv != 0)
       
  4978 				{
       
  4979 					ec_cs_data_c * const new_ec_cd_data = identity_reference_tlv->copy();
       
  4980 					if (new_ec_cd_data != 0)
       
  4981 					{
       
  4982 						new_ec_cd_data->set_change_status(ec_cs_data_change_status_delete);
       
  4983 
       
  4984 						status = m_broken_cs_data_list.add_object(new_ec_cd_data, true);
       
  4985 						if (status != eap_status_ok)
       
  4986 						{
       
  4987 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4988 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  4989 						}
       
  4990 					}
       
  4991 				}
       
  4992 			}
       
  4993 		}
       
  4994 	}
       
  4995 
       
  4996 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4997 
       
  4998 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4999 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5000 }
       
  5001 
       
  5002 //--------------------------------------------------
       
  5003 
       
  5004 eap_status_e ec_certificate_store_c::save_to_ec_cs_list(
       
  5005 	eap_array_c<ec_cs_data_c> * const ec_cs_list,
       
  5006 	const ec_cs_data_c * const ref_and_data)
       
  5007 {
       
  5008 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5009 
       
  5010 	EAP_TRACE_DEBUG(
       
  5011 		m_am_tools,
       
  5012 		TRACE_FLAGS_DEFAULT,
       
  5013 		(EAPL("WAPI_Core: ec_certificate_store_c::save_to_ec_cs_list():\n")));
       
  5014 
       
  5015 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_to_ec_cs_list()");
       
  5016 
       
  5017 	eap_status_e status(eap_status_ok);
       
  5018 
       
  5019 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  5020 
       
  5021 	if (ref_and_data != 0)
       
  5022 	{
       
  5023 		ec_cs_data_c * const new_ec_cd_data = ref_and_data->copy();
       
  5024 		if (new_ec_cd_data != 0)
       
  5025 		{
       
  5026 			status = ec_cs_list->add_object(new_ec_cd_data, true);
       
  5027 			if (status != eap_status_ok)
       
  5028 			{
       
  5029 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5030 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5031 			}
       
  5032 		}
       
  5033 	}
       
  5034 
       
  5035 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  5036 
       
  5037 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5038 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5039 }
       
  5040 
       
  5041 //--------------------------------------------------
       
  5042 
       
  5043 eap_status_e ec_certificate_store_c::save_ec_cs_data(
       
  5044 	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks)
       
  5045 {
       
  5046 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5047 
       
  5048 	EAP_TRACE_DEBUG(
       
  5049 		m_am_tools,
       
  5050 		TRACE_FLAGS_DEFAULT,
       
  5051 		(EAPL("WAPI_Core: ec_certificate_store_c::save_ec_cs_data(): data_block_count %d\n"),
       
  5052 		in_references_and_data_blocks->get_object_count()));
       
  5053 
       
  5054 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_ec_cs_data()");
       
  5055 
       
  5056 	eap_status_e status(eap_status_ok);
       
  5057 
       
  5058 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5059 
       
  5060 	ec_cs_tlv_c handler(m_am_tools, true);
       
  5061 
       
  5062 	for (u32_t ind = 0ul; ind < in_references_and_data_blocks->get_object_count(); ++ind)
       
  5063 	{
       
  5064 		const ec_cs_data_c * const ref_and_data = in_references_and_data_blocks->get_object(ind);
       
  5065 
       
  5066 		EAP_TRACE_DEBUG(
       
  5067 			m_am_tools,
       
  5068 			TRACE_FLAGS_DEFAULT,
       
  5069 			(EAPL("WAPI_Core: ec_certificate_store_c::save_ec_cs_data(): ref_and_data=0x%08x\n"),
       
  5070 			ref_and_data));
       
  5071 
       
  5072 		if (ref_and_data != 0)
       
  5073 		{
       
  5074 			EAP_TRACE_DEBUG(
       
  5075 				m_am_tools,
       
  5076 				TRACE_FLAGS_DEFAULT,
       
  5077 				(EAPL("reference 0x%08x: type %d=%s, change status %d=%s\n"),
       
  5078 				ref_and_data,
       
  5079 				ref_and_data->get_type(),
       
  5080 				ec_cs_strings_c::get_ec_cs_store_data_string(ref_and_data->get_type()),
       
  5081 				ref_and_data->get_change_status(),
       
  5082 				ec_cs_strings_c::get_ec_cs_store_data_change_status_string(ref_and_data->get_change_status())));
       
  5083 
       
  5084 			EAP_TRACE_DATA_DEBUG(
       
  5085 				m_am_tools,
       
  5086 				TRACE_FLAGS_DEFAULT,
       
  5087 				(EAPL("reference"),
       
  5088 				 ref_and_data->get_reference()->get_data(),
       
  5089 				 ref_and_data->get_reference()->get_data_length()));
       
  5090 
       
  5091 			EAP_TRACE_DATA_DEBUG(
       
  5092 				m_am_tools,
       
  5093 				TRACE_FLAGS_DEFAULT,
       
  5094 				(EAPL("data"),
       
  5095 				 ref_and_data->get_data()->get_data(),
       
  5096 				 ref_and_data->get_data()->get_data_length()));
       
  5097 		}
       
  5098 
       
  5099 		if (ref_and_data != 0
       
  5100 			&& ref_and_data->get_is_valid() == true)
       
  5101 		{
       
  5102 			EAP_TRACE_DEBUG(
       
  5103 				m_am_tools,
       
  5104 				TRACE_FLAGS_DEFAULT,
       
  5105 				(EAPL("reference 0x%08x: type %d=%s, change status %d=%s\n"),
       
  5106 				ref_and_data,
       
  5107 				ref_and_data->get_type(),
       
  5108 				ec_cs_strings_c::get_ec_cs_store_data_string(ref_and_data->get_type()),
       
  5109 				ref_and_data->get_change_status(),
       
  5110 				ec_cs_strings_c::get_ec_cs_store_data_change_status_string(ref_and_data->get_change_status())));
       
  5111 
       
  5112 			EAP_TRACE_DATA_DEBUG(
       
  5113 				m_am_tools,
       
  5114 				TRACE_FLAGS_DEFAULT,
       
  5115 				(EAPL("reference"),
       
  5116 				 ref_and_data->get_reference()->get_data(),
       
  5117 				 ref_and_data->get_reference()->get_data_length()));
       
  5118 
       
  5119 			EAP_TRACE_DATA_DEBUG(
       
  5120 				m_am_tools,
       
  5121 				TRACE_FLAGS_DEFAULT,
       
  5122 				(EAPL("data"),
       
  5123 				 ref_and_data->get_data()->get_data(),
       
  5124 				 ref_and_data->get_data()->get_data_length()));
       
  5125 
       
  5126 			if (ref_and_data->get_type() == ec_cs_data_type_ca_asu_id)
       
  5127 			{
       
  5128 				if (ref_and_data->get_data() != 0
       
  5129 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5130 					&& ref_and_data->get_data()->get_data_length() > 0ul)
       
  5131 				{
       
  5132 					status = handler.verify_data_with_MAC(
       
  5133 						&m_PAC_store_master_key,
       
  5134 						&m_PAC_store_device_seed,
       
  5135 						ref_and_data);
       
  5136 					if (status != eap_status_ok)
       
  5137 					{
       
  5138 						status = save_to_broken_cs_data_list(ref_and_data);
       
  5139 						if (status != eap_status_ok)
       
  5140 						{
       
  5141 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5142 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5143 						}
       
  5144 
       
  5145 						continue;
       
  5146 					}
       
  5147 
       
  5148 					status = save_to_ec_cs_list(&m_ca_asu_id_list, ref_and_data);
       
  5149 					if (status != eap_status_ok)
       
  5150 					{
       
  5151 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5152 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5153 					}
       
  5154 				}
       
  5155 
       
  5156 				m_read_ca_asu_id_list = true;
       
  5157 			}
       
  5158 			else if (ref_and_data->get_type() == ec_cs_data_type_client_asu_id)
       
  5159 			{
       
  5160 				if (ref_and_data->get_data() != 0
       
  5161 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5162 					&& ref_and_data->get_data()->get_data_length() > 0ul)
       
  5163 				{
       
  5164 					status = handler.verify_data_with_MAC(
       
  5165 						&m_PAC_store_master_key,
       
  5166 						&m_PAC_store_device_seed,
       
  5167 						ref_and_data);
       
  5168 					if (status != eap_status_ok)
       
  5169 					{
       
  5170 						status = save_to_broken_cs_data_list(ref_and_data);
       
  5171 						if (status != eap_status_ok)
       
  5172 						{
       
  5173 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5174 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5175 						}
       
  5176 
       
  5177 						continue;
       
  5178 					}
       
  5179 
       
  5180 					status = save_to_ec_cs_list(&m_client_asu_id_list, ref_and_data);
       
  5181 					if (status != eap_status_ok)
       
  5182 					{
       
  5183 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5184 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5185 					}
       
  5186 				}
       
  5187 
       
  5188 				m_read_client_asu_id_list = true;
       
  5189 			}
       
  5190 
       
  5191 			else if (ref_and_data->get_type() == ec_cs_data_type_reference_counter)
       
  5192 			{
       
  5193 				if (ref_and_data->get_data() != 0
       
  5194 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5195 					&& ref_and_data->get_reference()->get_is_valid_data() == true
       
  5196 					&& ref_and_data->get_data()->get_data_length() > 0ul
       
  5197 					&& ref_and_data->get_reference()->get_data_length() > 0ul)
       
  5198 				{
       
  5199 					/*
       
  5200 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
  5201 					 * | Type=Referene counter TLV     |           Length=4            |  |
       
  5202 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
       
  5203 					 * |                    reference counter (4 octets)               |  |
       
  5204 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
  5205 					 * | Type=CS-MAC TLV               |           Length=32           |  |
       
  5206 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
       
  5207 					 * |                              MAC (32 octets)                  |  |
       
  5208 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
  5209 					 */
       
  5210 
       
  5211 					ec_cs_tlv_c master_key_handler(m_am_tools, true);
       
  5212 					if (master_key_handler.get_is_valid() == false)
       
  5213 					{
       
  5214 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5215 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5216 					}
       
  5217 
       
  5218 					eap_variable_data_c MAC_key(m_am_tools);
       
  5219 					if (MAC_key.get_is_valid() == false)
       
  5220 					{
       
  5221 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5222 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5223 					}
       
  5224 
       
  5225 					status = master_key_handler.generate_data_key(
       
  5226 						false,
       
  5227 						ec_cs_data_type_reference_counter,
       
  5228 						&MAC_key,
       
  5229 						&m_PAC_store_master_key,
       
  5230 						ref_and_data->get_reference(),
       
  5231 						&m_PAC_store_device_seed);
       
  5232 					if (status != eap_status_ok)
       
  5233 					{
       
  5234 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5235 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5236 					}
       
  5237 
       
  5238 					status = master_key_handler.parse_data_with_MAC(
       
  5239 						&MAC_key,
       
  5240 						ref_and_data->get_data());
       
  5241 					if (status != eap_status_ok)
       
  5242 					{
       
  5243 						// Cannot continue, terminate authentication.
       
  5244 						(void) m_partner->set_session_timeout(0ul);
       
  5245 						(void) send_error_notification(eap_status_pac_store_corrupted);
       
  5246 
       
  5247 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5248 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5249 					}
       
  5250 
       
  5251 					const ec_cs_variable_data_c * const master_key_encrypted_block_tlv
       
  5252 						= master_key_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_reference_counter);
       
  5253 					if (master_key_encrypted_block_tlv == 0)
       
  5254 					{
       
  5255 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5256 						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5257 					}
       
  5258 
       
  5259 					void * const network_order_counter = master_key_encrypted_block_tlv->get_data(sizeof(m_reference_counter));
       
  5260 
       
  5261 					if (network_order_counter != 0)
       
  5262 					{
       
  5263 						m_reference_counter = eap_read_u32_t_network_order(
       
  5264 							network_order_counter,
       
  5265 							sizeof(m_reference_counter));
       
  5266 
       
  5267 						status = eap_status_ok;
       
  5268 					}
       
  5269 				}
       
  5270 				else
       
  5271 				{
       
  5272 					// No data.
       
  5273 					status = eap_status_ok;
       
  5274 				}
       
  5275 
       
  5276 				EAP_TRACE_DEBUG(
       
  5277 					m_am_tools,
       
  5278 					TRACE_FLAGS_DEFAULT,
       
  5279 					(EAPL("Read reference counter = 0x%08x\n"),
       
  5280 					 m_reference_counter));
       
  5281 
       
  5282 				m_reference_counter_read = true;
       
  5283 			}
       
  5284 			else if (ref_and_data->get_type() == ec_cs_data_type_master_key)
       
  5285 			{
       
  5286 				if (ref_and_data->get_data() != 0
       
  5287 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5288 					&& ref_and_data->get_reference()->get_is_valid_data() == true
       
  5289 					&& ref_and_data->get_data()->get_data_length() > 0ul
       
  5290 					&& ref_and_data->get_reference()->get_data_length() > 0ul)
       
  5291 				{
       
  5292 					EAP_TRACE_DEBUG(
       
  5293 						m_am_tools,
       
  5294 						TRACE_FLAGS_DEFAULT,
       
  5295 						(EAPL("ec_certificate_store_c::save_ec_cs_data(): Read master key from database.\n")));
       
  5296 
       
  5297 					/*
       
  5298 					 * Master key data
       
  5299 					 *
       
  5300  					 * 0                   1                   2                   3   
       
  5301 					 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
  5302 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    -+ -+
       
  5303 					 * | Type=CS-Encrypted block TLV   |     Length=4+16+4+n+4+m       |     |  |
       
  5304 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
       
  5305 					 * | Type=CS-Encryption IV TLV     |           Length=16           |  |  |  | plain text
       
  5306 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  |
       
  5307 					 * |                              IV (16 octets)                   |  |  |  |
       
  5308 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
       
  5309 					 * | Type=CS-Encrypted data TLV    |           Length=n+4+m        |  |  |  |
       
  5310 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  | -+
       
  5311 					 * |                          Master key TLV (n octets)            |  |  |  |
       
  5312 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | encrypted
       
  5313 					 * | Type=CS-padding TLV           |           Length=m            |  |  |  | multiple of
       
  5314 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | 16 octets
       
  5315 					 * |                           padding (m octets)                  |  |  |  |
       
  5316 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
       
  5317 					 * | Type=CS-MAC TLV               |           Length=32           |  |
       
  5318 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
       
  5319 					 * |                              MAC (32 octets)                  |  |
       
  5320 					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
       
  5321 					 */
       
  5322 
       
  5323 					ec_cs_tlv_c master_key_handler(m_am_tools, true);
       
  5324 					if (master_key_handler.get_is_valid() == false)
       
  5325 					{
       
  5326 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5327 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5328 					}
       
  5329 
       
  5330 					eap_variable_data_c MAC_key(m_am_tools);
       
  5331 					if (MAC_key.get_is_valid() == false)
       
  5332 					{
       
  5333 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5334 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5335 					}
       
  5336 
       
  5337 					status = master_key_handler.generate_data_key(
       
  5338 						false,
       
  5339 						ec_cs_data_type_master_key,
       
  5340 						&MAC_key,
       
  5341 						&m_PAC_store_password,
       
  5342 						ref_and_data->get_reference(),
       
  5343 						&m_PAC_store_device_seed);
       
  5344 					if (status != eap_status_ok)
       
  5345 					{
       
  5346 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5347 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5348 					}
       
  5349 
       
  5350 					status = master_key_handler.parse_data_with_MAC(
       
  5351 						&MAC_key,
       
  5352 						ref_and_data->get_data());
       
  5353 					if (status == eap_status_authentication_failure)
       
  5354 					{
       
  5355 						// Ask password again.
       
  5356 						(void) m_PAC_store_password.reset();
       
  5357 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5358 						return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5359 					}
       
  5360 					else if (status != eap_status_ok)
       
  5361 					{
       
  5362 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5363 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5364 					}
       
  5365 
       
  5366 					const ec_cs_variable_data_c * const master_key_encrypted_block_tlv
       
  5367 						= master_key_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_encrypted_block);
       
  5368 					if (master_key_encrypted_block_tlv == 0)
       
  5369 					{
       
  5370 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5371 						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5372 					}
       
  5373 
       
  5374 					ec_cs_variable_data_c master_key_plain_data_tlv(m_am_tools);
       
  5375 					if (master_key_plain_data_tlv.get_is_valid() == false)
       
  5376 					{
       
  5377 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5378 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5379 					}
       
  5380 
       
  5381 					eap_variable_data_c master_key_decryption_key(m_am_tools);
       
  5382 					if (master_key_decryption_key.get_is_valid() == false)
       
  5383 					{
       
  5384 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5385 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5386 					}
       
  5387 
       
  5388 					status = master_key_handler.generate_data_key(
       
  5389 						true,
       
  5390 						ec_cs_data_type_master_key,
       
  5391 						&master_key_decryption_key,
       
  5392 						&m_PAC_store_password,
       
  5393 						ref_and_data->get_reference(),
       
  5394 						&m_PAC_store_device_seed);
       
  5395 					if (status != eap_status_ok)
       
  5396 					{
       
  5397 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5398 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5399 					}
       
  5400 
       
  5401 					ec_cs_tlv_c decrypt_handler(m_am_tools, true);
       
  5402 					if (decrypt_handler.get_is_valid() == false)
       
  5403 					{
       
  5404 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5405 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5406 					}
       
  5407 
       
  5408 					status = decrypt_handler.parse_encrypted_tlv(
       
  5409 						&master_key_decryption_key,
       
  5410 						master_key_encrypted_block_tlv,
       
  5411 						&master_key_plain_data_tlv);
       
  5412 					if (status != eap_status_ok)
       
  5413 					{
       
  5414 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5415 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5416 					}
       
  5417 
       
  5418 					status = decrypt_handler.parse_cs_tlv(
       
  5419 						&master_key_plain_data_tlv);
       
  5420 					if (status != eap_status_ok)
       
  5421 					{
       
  5422 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5423 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5424 					}
       
  5425 
       
  5426 					const ec_cs_variable_data_c * const master_key_tlv
       
  5427 						= decrypt_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_master_key);
       
  5428 					if (master_key_tlv == 0)
       
  5429 					{
       
  5430 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5431 						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5432 					}
       
  5433 
       
  5434 					status = m_PAC_store_master_key.set_copy_of_buffer(
       
  5435 						master_key_tlv->get_data(master_key_tlv->get_data_length()),
       
  5436 						master_key_tlv->get_data_length());
       
  5437 				}
       
  5438 				else
       
  5439 				{
       
  5440 					EAP_TRACE_DEBUG(
       
  5441 						m_am_tools,
       
  5442 						TRACE_FLAGS_DEFAULT,
       
  5443 						(EAPL("ec_certificate_store_c::save_ec_cs_data(): Creates new master key.\n")));
       
  5444 
       
  5445 					// Create a new master key.
       
  5446 					crypto_random_c rand(m_am_tools);
       
  5447 
       
  5448 					if (rand.get_is_valid() == false)
       
  5449 					{
       
  5450 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5451 					}
       
  5452 
       
  5453 					status = m_PAC_store_master_key.set_buffer_length(EAP_FAST_PAC_STORE_MASTER_KEY_SIZE);
       
  5454 					if (status != eap_status_ok)
       
  5455 					{
       
  5456 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5457 					}
       
  5458 
       
  5459 					status = m_PAC_store_master_key.set_data_length(EAP_FAST_PAC_STORE_MASTER_KEY_SIZE);
       
  5460 					if (status != eap_status_ok)
       
  5461 					{
       
  5462 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5463 					}
       
  5464 
       
  5465 					status = rand.get_rand_bytes(
       
  5466 						m_PAC_store_master_key.get_data(
       
  5467 							m_PAC_store_master_key.get_data_length()),
       
  5468 						m_PAC_store_master_key.get_data_length());
       
  5469 					if (status != eap_status_ok)
       
  5470 					{
       
  5471 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5472 					}
       
  5473 
       
  5474 					m_master_key_changed = true;
       
  5475 				}
       
  5476 
       
  5477 				EAP_TRACE_DATA_DEBUG(
       
  5478 					m_am_tools,
       
  5479 					TRACE_FLAGS_DEFAULT,
       
  5480 					(EAPL("CS store master key"),
       
  5481 					 m_PAC_store_master_key.get_data(),
       
  5482 					 m_PAC_store_master_key.get_data_length()));
       
  5483 			}
       
  5484 			else if (ref_and_data->get_type() == ec_cs_data_type_password)
       
  5485 			{
       
  5486 				if (ref_and_data->get_data() != 0
       
  5487 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5488 					&& ref_and_data->get_data()->get_data_length() > 0ul)
       
  5489 				{
       
  5490 					status = m_PAC_store_password.set_copy_of_buffer(ref_and_data->get_data());
       
  5491 				}
       
  5492 
       
  5493 				EAP_TRACE_DATA_DEBUG(
       
  5494 					m_am_tools,
       
  5495 					TRACE_FLAGS_DEFAULT,
       
  5496 					(EAPL("Read CS store password"),
       
  5497 					 m_PAC_store_password.get_data(),
       
  5498 					 m_PAC_store_password.get_data_length()));
       
  5499 			}
       
  5500 			else if (ref_and_data->get_type() == ec_cs_data_type_device_seed)
       
  5501 			{
       
  5502 				if (ref_and_data->get_data() != 0
       
  5503 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5504 					&& ref_and_data->get_data()->get_data_length() > 0ul)
       
  5505 				{
       
  5506 					status = m_PAC_store_device_seed.set_copy_of_buffer(ref_and_data->get_data());
       
  5507 				}
       
  5508 
       
  5509 				EAP_TRACE_DATA_DEBUG(
       
  5510 					m_am_tools,
       
  5511 					TRACE_FLAGS_DEFAULT,
       
  5512 					(EAPL("Read CS store device seed"),
       
  5513 					 m_PAC_store_device_seed.get_data(),
       
  5514 					 m_PAC_store_device_seed.get_data_length()));
       
  5515 			}
       
  5516 			else if (ref_and_data->get_type() == ec_cs_data_type_ca_certificate_data)
       
  5517 			{
       
  5518 				if (ref_and_data->get_data() != 0
       
  5519 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5520 					&& ref_and_data->get_data()->get_data_length() > 0ul)
       
  5521 				{
       
  5522 					status = handler.verify_data_with_MAC(
       
  5523 						&m_PAC_store_master_key,
       
  5524 						&m_PAC_store_device_seed,
       
  5525 						ref_and_data);
       
  5526 					if (status != eap_status_ok)
       
  5527 					{
       
  5528 						status = save_to_broken_cs_data_list(ref_and_data);
       
  5529 						if (status != eap_status_ok)
       
  5530 						{
       
  5531 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5532 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5533 						}
       
  5534 
       
  5535 						continue;
       
  5536 					}
       
  5537 
       
  5538 					status = m_ca_certificates.add_object(ref_and_data->copy(), true);
       
  5539 					if (status != eap_status_ok)
       
  5540 					{
       
  5541 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5542 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5543 					}
       
  5544 				}
       
  5545 			}
       
  5546 			else if (ref_and_data->get_type() == ec_cs_data_type_client_certificate_data)
       
  5547 			{
       
  5548 				if (ref_and_data->get_data() != 0
       
  5549 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5550 					&& ref_and_data->get_data()->get_data_length() > 0ul)
       
  5551 				{
       
  5552 					status = handler.verify_data_with_MAC(
       
  5553 						&m_PAC_store_master_key,
       
  5554 						&m_PAC_store_device_seed,
       
  5555 						ref_and_data);
       
  5556 					if (status != eap_status_ok)
       
  5557 					{
       
  5558 						status = save_to_broken_cs_data_list(ref_and_data);
       
  5559 						if (status != eap_status_ok)
       
  5560 						{
       
  5561 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5562 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5563 						}
       
  5564 
       
  5565 						continue;
       
  5566 					}
       
  5567 
       
  5568 					status = m_client_certificates.add_object(ref_and_data->copy(), true);
       
  5569 					if (status != eap_status_ok)
       
  5570 					{
       
  5571 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5572 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5573 					}
       
  5574 				}
       
  5575 			}
       
  5576 			else if (ref_and_data->get_type() == ec_cs_data_type_private_key_data)
       
  5577 			{
       
  5578 				if (ref_and_data->get_data() != 0
       
  5579 					&& ref_and_data->get_data()->get_is_valid_data() == true
       
  5580 					&& ref_and_data->get_data()->get_data_length() > 0ul)
       
  5581 				{
       
  5582 					status = handler.verify_data_with_MAC(
       
  5583 						&m_PAC_store_master_key,
       
  5584 						&m_PAC_store_device_seed,
       
  5585 						ref_and_data);
       
  5586 					if (status != eap_status_ok)
       
  5587 					{
       
  5588 						status = save_to_broken_cs_data_list(ref_and_data);
       
  5589 						if (status != eap_status_ok)
       
  5590 						{
       
  5591 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5592 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5593 						}
       
  5594 
       
  5595 						continue;
       
  5596 					}
       
  5597 
       
  5598 					status = m_client_private_keys.add_object(ref_and_data->copy(), true);
       
  5599 					if (status != eap_status_ok)
       
  5600 					{
       
  5601 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5602 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  5603 					}
       
  5604 				}
       
  5605 			}
       
  5606 			else if (ref_and_data->get_type() == ec_cs_data_type_selected_ca_id)
       
  5607 			{
       
  5608 				status = m_selected_ca_id.set_copy_of_buffer(ref_and_data->get_data());
       
  5609 				if (status != eap_status_ok)
       
  5610 				{
       
  5611 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5612 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5613 				}
       
  5614 
       
  5615 				EAP_TRACE_DATA_DEBUG(
       
  5616 					m_am_tools,
       
  5617 					TRACE_FLAGS_DEFAULT,
       
  5618 					(EAPL("m_selected_ca_id"),
       
  5619 					 m_selected_ca_id.get_data(),
       
  5620 					 m_selected_ca_id.get_data_length()));
       
  5621 			}
       
  5622 			else if (ref_and_data->get_type() == ec_cs_data_type_selected_client_id)
       
  5623 			{
       
  5624 				status = m_selected_client_id.set_copy_of_buffer(ref_and_data->get_data());
       
  5625 				if (status != eap_status_ok)
       
  5626 				{
       
  5627 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5628 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5629 				}
       
  5630 
       
  5631 				EAP_TRACE_DATA_DEBUG(
       
  5632 					m_am_tools,
       
  5633 					TRACE_FLAGS_DEFAULT,
       
  5634 					(EAPL("m_selected_client_id"),
       
  5635 					 m_selected_client_id.get_data(),
       
  5636 					 m_selected_client_id.get_data_length()));
       
  5637 			}
       
  5638 			else
       
  5639 			{
       
  5640 				status = eap_status_illegal_data_payload;
       
  5641 				(void) EAP_STATUS_RETURN(m_am_tools, status);
       
  5642 				EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
       
  5643 			}
       
  5644 
       
  5645 			if (status != eap_status_ok)
       
  5646 			{
       
  5647 				EAP_TRACE_DEBUG(
       
  5648 					m_am_tools,
       
  5649 					TRACE_FLAGS_DEFAULT,
       
  5650 					(EAPL("WARNING: WAPI_Core: ec_certificate_store_c::save_ec_cs_data(): ignored broken data.\n")));
       
  5651 				status = eap_status_ok;
       
  5652 			}
       
  5653 
       
  5654 		}
       
  5655 	} // for()
       
  5656 
       
  5657 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5658 
       
  5659 	status = completion_action_check();
       
  5660 
       
  5661 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5662 
       
  5663 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5664 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5665 }
       
  5666 
       
  5667 //----------------------------------------------------------------------------
       
  5668 
       
  5669 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_read_certificate_store_data(
       
  5670 	const eap_status_e in_completion_status,
       
  5671 	const ec_cs_pending_operation_e in_pending_operation,
       
  5672 	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks)
       
  5673 {
       
  5674 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5675 
       
  5676 	EAP_TRACE_DEBUG(
       
  5677 		m_am_tools,
       
  5678 		TRACE_FLAGS_DEFAULT,
       
  5679 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_read_certificate_store_data():\n"),
       
  5680 		 this,
       
  5681 		 (m_is_client == true ? "client": "server")));
       
  5682 
       
  5683 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_read_certificate_store_data()");
       
  5684 
       
  5685 	eap_status_e status(eap_status_not_supported);
       
  5686 
       
  5687 	m_pending_read_ec_cs_data = false;
       
  5688 
       
  5689 	if (in_completion_status == eap_status_ok
       
  5690 		&& in_references_and_data_blocks != 0)
       
  5691 	{
       
  5692 		status = save_ec_cs_data(in_references_and_data_blocks);
       
  5693 		if (status != eap_status_ok)
       
  5694 		{
       
  5695 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5696 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5697 		}
       
  5698 	}
       
  5699 	else if (in_completion_status != eap_status_ok)
       
  5700 	{
       
  5701 		// Cannot continue, terminate authentication.
       
  5702 		(void) m_partner->set_session_timeout(0ul);
       
  5703 
       
  5704 		(void) send_error_notification(in_completion_status);
       
  5705 
       
  5706 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5707 	}
       
  5708 
       
  5709 	status = completion_action_check();
       
  5710 
       
  5711 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5712 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5713 }
       
  5714 
       
  5715 //----------------------------------------------------------------------------
       
  5716 
       
  5717 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_write_certificate_store_data(
       
  5718 	const eap_status_e in_completion_status,
       
  5719 	const ec_cs_pending_operation_e in_pending_operation)
       
  5720 {
       
  5721 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5722 
       
  5723 	EAP_TRACE_DEBUG(
       
  5724 		m_am_tools,
       
  5725 		TRACE_FLAGS_DEFAULT,
       
  5726 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_write_certificate_store_data():\n"),
       
  5727 		 this,
       
  5728 		 (m_is_client == true ? "client": "server")));
       
  5729 
       
  5730 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_write_certificate_store_data()");
       
  5731 
       
  5732 	// Here we do nothing. Return still OK status that caller does not disturb.
       
  5733 	eap_status_e status(eap_status_ok);
       
  5734 
       
  5735 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5736 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5737 }
       
  5738 
       
  5739 //----------------------------------------------------------------------------
       
  5740 
       
  5741 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::query_certificate_list()
       
  5742 {
       
  5743 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5744 
       
  5745 	EAP_TRACE_DEBUG(
       
  5746 		m_am_tools,
       
  5747 		TRACE_FLAGS_DEFAULT,
       
  5748 		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::query_certificate_list():\n"),
       
  5749 		 this,
       
  5750 		 (m_is_client == true ? "client": "server")));
       
  5751 
       
  5752 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::query_certificate_list()");
       
  5753 
       
  5754 	eap_status_e status(eap_status_not_supported);
       
  5755 
       
  5756 	status = completion_action_push(ec_cs_completion_complete_query_certificate_list);
       
  5757 	if (status != eap_status_ok)
       
  5758 	{
       
  5759 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5760 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5761 	}
       
  5762 
       
  5763 	status = read_both_certificate_lists(ec_cs_pending_operation_query_certificate_list);
       
  5764 	if (status != eap_status_ok)
       
  5765 	{
       
  5766 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5767 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5768 	}
       
  5769 
       
  5770 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5771 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5772 }
       
  5773 
       
  5774 //--------------------------------------------------
       
  5775 
       
  5776 eap_status_e ec_certificate_store_c::query_PAC_store_password(
       
  5777 	const ec_cs_pending_operation_e in_pending_operation)
       
  5778 {
       
  5779 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5780 
       
  5781 	EAP_TRACE_DEBUG(
       
  5782 		m_am_tools,
       
  5783 		TRACE_FLAGS_DEFAULT,
       
  5784 		(EAPL("EAP-FAST: ec_certificate_store_c::query_PAC_store_password()\n")));
       
  5785 
       
  5786 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::query_PAC_store_password()");
       
  5787 
       
  5788 	eap_status_e status(eap_status_process_general_error);
       
  5789 
       
  5790 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5791 
       
  5792 	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
       
  5793 
       
  5794 	status = add_password_qyery(&in_references);
       
  5795 	if (status != eap_status_ok)
       
  5796 	{
       
  5797 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5798 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5799 	}
       
  5800 
       
  5801 	if (in_references.get_object_count() > 0ul)
       
  5802 	{
       
  5803 		EAP_TRACE_DEBUG(
       
  5804 			m_am_tools,
       
  5805 			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  5806 			(EAPL("calls: ec_certificate_store_c::query_PAC_store_password(): m_am_pac_store_services->read_PAC_store_data(): %d.\n"),
       
  5807 			__LINE__));
       
  5808 
       
  5809 		m_pending_read_ec_cs_data = true;
       
  5810 
       
  5811 		status = m_am_certificate_store->read_certificate_store_data(
       
  5812 			in_pending_operation,
       
  5813 			&in_references);
       
  5814 	}
       
  5815 	else
       
  5816 	{
       
  5817 		EAP_TRACE_DEBUG(
       
  5818 			m_am_tools,
       
  5819 			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  5820 			(EAPL("WARNING: ec_certificate_store_c::query_PAC_store_password(): Skips m_am_pac_store_services->read_PAC_store_data(): %d.\n"),
       
  5821 			__LINE__));
       
  5822 	}
       
  5823 
       
  5824 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5825 
       
  5826 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5827 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5828 }
       
  5829 
       
  5830 //--------------------------------------------------
       
  5831 
       
  5832 eap_status_e ec_certificate_store_c::add_password_qyery(
       
  5833 	eap_array_c<ec_cs_data_c> * const in_references)
       
  5834 {
       
  5835 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5836 
       
  5837 	EAP_TRACE_DEBUG(
       
  5838 		m_am_tools,
       
  5839 		TRACE_FLAGS_DEFAULT,
       
  5840 		(EAPL("EAP-FAST: ec_certificate_store_c::add_password_qyery()\n")));
       
  5841 
       
  5842 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_password_qyery()");
       
  5843 
       
  5844 	eap_status_e status(eap_status_ok);
       
  5845 
       
  5846 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5847 
       
  5848 	if (m_PAC_store_password.get_is_valid_data() == false)
       
  5849 	{
       
  5850 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  5851 
       
  5852 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  5853 
       
  5854 		if (data == 0
       
  5855 			|| data->get_is_valid() == false)
       
  5856 		{
       
  5857 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5858 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5859 		}
       
  5860 
       
  5861 		data->set_type(ec_cs_data_type_password);
       
  5862 
       
  5863 		status = data->get_writable_reference()->set_copy_of_buffer(
       
  5864 			EC_CS_ZERO_REFERENCE,
       
  5865 			sizeof(EC_CS_ZERO_REFERENCE));
       
  5866 		if (status != eap_status_ok)
       
  5867 		{
       
  5868 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5869 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5870 		}
       
  5871 
       
  5872 		automatic_data.do_not_free_variable();
       
  5873 
       
  5874 		status = in_references->add_object(data, true);
       
  5875 		if (status != eap_status_ok)
       
  5876 		{
       
  5877 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5878 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5879 		}
       
  5880 	}
       
  5881 
       
  5882 	if (m_PAC_store_device_seed.get_is_valid_data() == false)
       
  5883 	{
       
  5884 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  5885 
       
  5886 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  5887 
       
  5888 		if (data == 0
       
  5889 			|| data->get_is_valid() == false)
       
  5890 		{
       
  5891 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5892 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5893 		}
       
  5894 
       
  5895 		data->set_type(ec_cs_data_type_device_seed);
       
  5896 
       
  5897 		status = data->get_writable_reference()->set_copy_of_buffer(
       
  5898 			EC_CS_ZERO_REFERENCE,
       
  5899 			sizeof(EC_CS_ZERO_REFERENCE));
       
  5900 		if (status != eap_status_ok)
       
  5901 		{
       
  5902 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5903 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5904 		}
       
  5905 
       
  5906 		automatic_data.do_not_free_variable();
       
  5907 
       
  5908 		status = in_references->add_object(data, true);
       
  5909 		if (status != eap_status_ok)
       
  5910 		{
       
  5911 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5912 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5913 		}
       
  5914 	}
       
  5915 
       
  5916 	if (m_PAC_store_master_key.get_is_valid_data() == false)
       
  5917 	{
       
  5918 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  5919 
       
  5920 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  5921 
       
  5922 		if (data == 0
       
  5923 			|| data->get_is_valid() == false)
       
  5924 		{
       
  5925 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5926 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5927 		}
       
  5928 
       
  5929 		status = data->get_writable_reference()->set_copy_of_buffer(
       
  5930 			EC_CS_ZERO_REFERENCE,
       
  5931 			sizeof(EC_CS_ZERO_REFERENCE));
       
  5932 		if (status != eap_status_ok)
       
  5933 		{
       
  5934 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5935 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5936 		}
       
  5937 
       
  5938 		data->set_type(ec_cs_data_type_master_key);
       
  5939 
       
  5940 		automatic_data.do_not_free_variable();
       
  5941 
       
  5942 		status = in_references->add_object(data, true);
       
  5943 		if (status != eap_status_ok)
       
  5944 		{
       
  5945 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5946 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5947 		}
       
  5948 	}
       
  5949 
       
  5950 
       
  5951 	if (m_reference_counter_read == false)
       
  5952 	{
       
  5953 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  5954 
       
  5955 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  5956 
       
  5957 		if (data == 0
       
  5958 			|| data->get_is_valid() == false)
       
  5959 		{
       
  5960 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5961 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5962 		}
       
  5963 
       
  5964 		data->set_type(ec_cs_data_type_reference_counter);
       
  5965 
       
  5966 		status = data->get_writable_reference()->set_copy_of_buffer(
       
  5967 			EC_CS_ZERO_REFERENCE,
       
  5968 			sizeof(EC_CS_ZERO_REFERENCE));
       
  5969 		if (status != eap_status_ok)
       
  5970 		{
       
  5971 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5972 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5973 		}
       
  5974 
       
  5975 		automatic_data.do_not_free_variable();
       
  5976 
       
  5977 		status = in_references->add_object(data, true);
       
  5978 		if (status != eap_status_ok)
       
  5979 		{
       
  5980 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5981 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5982 		}
       
  5983 	}
       
  5984 
       
  5985 	if (m_selected_client_id.get_is_valid_data() == false)
       
  5986 	{
       
  5987 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  5988 
       
  5989 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  5990 
       
  5991 		if (data == 0
       
  5992 			|| data->get_is_valid() == false)
       
  5993 		{
       
  5994 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5995 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5996 		}
       
  5997 
       
  5998 		data->set_type(ec_cs_data_type_selected_client_id);
       
  5999 
       
  6000 		automatic_data.do_not_free_variable();
       
  6001 
       
  6002 		status = in_references->add_object(data, true);
       
  6003 		if (status != eap_status_ok)
       
  6004 		{
       
  6005 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6006 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6007 		}
       
  6008 
       
  6009 	}
       
  6010 
       
  6011 	if (m_selected_ca_id.get_is_valid_data() == false)
       
  6012 	{
       
  6013 		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
       
  6014 
       
  6015 		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
       
  6016 
       
  6017 		if (data == 0
       
  6018 			|| data->get_is_valid() == false)
       
  6019 		{
       
  6020 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6021 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6022 		}
       
  6023 
       
  6024 		data->set_type(ec_cs_data_type_selected_ca_id);
       
  6025 
       
  6026 		automatic_data.do_not_free_variable();
       
  6027 
       
  6028 		status = in_references->add_object(data, true);
       
  6029 		if (status != eap_status_ok)
       
  6030 		{
       
  6031 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6032 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6033 		}
       
  6034 
       
  6035 	}
       
  6036 
       
  6037 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  6038 
       
  6039 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6040 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6041 }
       
  6042 
       
  6043 //----------------------------------------------------------------------------
       
  6044 
       
  6045 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::start_certificate_import()
       
  6046 {
       
  6047     EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6048 
       
  6049      EAP_TRACE_DEBUG(
       
  6050          m_am_tools,
       
  6051          TRACE_FLAGS_DEFAULT,
       
  6052          (EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::start_certificate_import():\n"),
       
  6053           this,
       
  6054           (m_is_client == true ? "client": "server")));
       
  6055 
       
  6056      EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::start_certificate_import()");
       
  6057 
       
  6058      eap_status_e status(eap_status_not_supported);
       
  6059 
       
  6060 	if (m_pending_operation != ec_cs_pending_operation_none)
       
  6061 	{
       
  6062 		// Some operation is already pending. Try again later.
       
  6063 		return EAP_STATUS_RETURN(m_am_tools, eap_status_device_busy);
       
  6064 	}
       
  6065 
       
  6066 #if defined(WAPI_USE_CERTIFICATE_STORE)
       
  6067 
       
  6068 	m_complete_start_certificate_import = true;
       
  6069 
       
  6070 	status = initialize_certificate_store();
       
  6071 
       
  6072 #endif //#if defined(WAPI_USE_CERTIFICATE_STORE)
       
  6073 
       
  6074      EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6075      return EAP_STATUS_RETURN(m_am_tools, status);
       
  6076    
       
  6077 }
       
  6078 
       
  6079 //------------------------------------------------------------------------------
       
  6080 
       
  6081 EAP_FUNC_EXPORT void ec_certificate_store_c::set_pending_operation(const ec_cs_pending_operation_e operation)
       
  6082 {
       
  6083 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6084 
       
  6085 	EAP_TRACE_DEBUG(
       
  6086 		m_am_tools,
       
  6087 		TRACE_FLAGS_DEFAULT,
       
  6088 		(EAPL("WAPI_Core: ec_certificate_store_c::set_pending_operation(): %s => %s\n"),
       
  6089 		ec_cs_strings_c::get_ec_cs_store_data_string(m_pending_operation),
       
  6090 		ec_cs_strings_c::get_ec_cs_store_data_string(operation)));
       
  6091 
       
  6092 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::set_pending_operation()");
       
  6093 
       
  6094 
       
  6095 	m_pending_operation = operation;
       
  6096 }
       
  6097 
       
  6098 //--------------------------------------------------
       
  6099 
       
  6100 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::are_pending_queries_completed()
       
  6101 {
       
  6102 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6103 
       
  6104 	eap_status_e status = eap_status_pending_request;
       
  6105 
       
  6106 	eap_status_string_c status_string;
       
  6107 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6108 	EAP_TRACE_DEBUG(
       
  6109 		m_am_tools,
       
  6110 		TRACE_FLAGS_DEFAULT,
       
  6111 		(EAPL("WAPI_Core: pending_function: starts: ec_certificate_store_c::are_pending_queries_completed(): %s\n"),
       
  6112 		status_string.get_status_string(status)));
       
  6113 
       
  6114 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::are_pending_queries_completed()");
       
  6115 
       
  6116 	if (m_pending_read_ec_cs_data == false)
       
  6117 	{
       
  6118 		status = eap_status_ok;
       
  6119 	}
       
  6120 
       
  6121 	EAP_TRACE_DEBUG(
       
  6122 		m_am_tools,
       
  6123 		TRACE_FLAGS_DEFAULT,
       
  6124 		(EAPL("WAPI_Core: pending_function: are_pending_queries_completed(): %s\n"),
       
  6125 		status_string.get_status_string(status)));
       
  6126 
       
  6127 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6128 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6129 }
       
  6130 
       
  6131 //--------------------------------------------------
       
  6132 
       
  6133 //
       
  6134 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_pop()
       
  6135 {
       
  6136 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6137 
       
  6138 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6139 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6140 					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_pop()\n")));
       
  6141 
       
  6142 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_pop()");
       
  6143 
       
  6144 	const ec_cs_completion_c * const removed_completion_action = m_completion_queue.get_object(0ul);
       
  6145 
       
  6146 	EAP_TRACE_DEBUG(
       
  6147 		m_am_tools,
       
  6148 		TRACE_FLAGS_DEFAULT,
       
  6149 		(EAPL("WAPI_Core: encrypt_function: starts: ec_certificate_store_c::completion_action_pop(): removes action[%d] %s=%d\n"),
       
  6150 		0ul,
       
  6151 		removed_completion_action->get_completion_action_string(removed_completion_action->get_completion_action()),
       
  6152 		removed_completion_action->get_completion_action()));
       
  6153 
       
  6154 	eap_status_e remove_status = m_completion_queue.remove_object(0ul);
       
  6155 	if (remove_status != eap_status_ok)
       
  6156 	{
       
  6157 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6158 		return EAP_STATUS_RETURN(m_am_tools, remove_status);
       
  6159 	}
       
  6160 
       
  6161 	completion_action_trace();
       
  6162 
       
  6163 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6164 	return EAP_STATUS_RETURN(m_am_tools, remove_status);
       
  6165 }
       
  6166 
       
  6167 //--------------------------------------------------
       
  6168 
       
  6169 //
       
  6170 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_push(
       
  6171 	ec_cs_completion_e action)
       
  6172 {
       
  6173 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6174 
       
  6175 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6176 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6177 					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_push()\n")));
       
  6178 
       
  6179 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_push()");
       
  6180 
       
  6181 	ec_cs_completion_c *completion_action = new ec_cs_completion_c(
       
  6182 		m_am_tools,
       
  6183 		action);
       
  6184 
       
  6185 	if (completion_action == 0
       
  6186 		|| completion_action->get_is_valid() == false)
       
  6187 	{
       
  6188 		delete completion_action;
       
  6189 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6190 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6191 	}
       
  6192 
       
  6193 	// add_object_to_begin() will delete completion_action if operation fails.
       
  6194 	eap_status_e status = m_completion_queue.add_object_to_begin(completion_action, true);
       
  6195 
       
  6196 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6197 					(EAPL("WAPI EC CS DB: send_function: completion_action_push(): action %s\n"),
       
  6198 					 completion_action->get_completion_action_string(completion_action->get_completion_action())));
       
  6199 
       
  6200 	completion_action_trace();
       
  6201 
       
  6202 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6203 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6204 }
       
  6205 
       
  6206 //--------------------------------------------------
       
  6207 
       
  6208 //
       
  6209 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_add(
       
  6210 	ec_cs_completion_e action)
       
  6211 {
       
  6212 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6213 
       
  6214 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6215 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6216 					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_add()\n")));
       
  6217 
       
  6218 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_add()");
       
  6219 
       
  6220 	ec_cs_completion_c *completion_action = new ec_cs_completion_c(
       
  6221 		m_am_tools,
       
  6222 		action);
       
  6223 
       
  6224 	if (completion_action == 0
       
  6225 		|| completion_action->get_is_valid() == false)
       
  6226 	{
       
  6227 		delete completion_action;
       
  6228 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6229 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6230 	}
       
  6231 
       
  6232 	// add_object() will delete completion_action if operation fails.
       
  6233 	eap_status_e status = m_completion_queue.add_object(completion_action, true);
       
  6234 
       
  6235 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6236 					(EAPL("WAPI EC CS DB: send_function: completion_action_add(): action %s\n"),
       
  6237 					 completion_action->get_completion_action_string(completion_action->get_completion_action())));
       
  6238 
       
  6239 	completion_action_trace();
       
  6240 
       
  6241 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6242 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6243 }
       
  6244 
       
  6245 //--------------------------------------------------
       
  6246 
       
  6247 //
       
  6248 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_clenup()
       
  6249 {
       
  6250 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6251 
       
  6252 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6253 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6254 					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_clenup()\n")));
       
  6255 
       
  6256 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_clenup()");
       
  6257 
       
  6258 	eap_status_e final_status = eap_status_ok;
       
  6259 	u32_t counter = 0ul;
       
  6260 
       
  6261 	while(m_completion_queue.get_object_count() > 0ul)
       
  6262 	{
       
  6263 		ec_cs_completion_c * const completion_action = m_completion_queue.get_object(0ul);
       
  6264 		EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace.
       
  6265 
       
  6266 		EAP_TRACE_DEBUG(
       
  6267 			m_am_tools,
       
  6268 			TRACE_FLAGS_DEFAULT,
       
  6269 			(EAPL("ERROR: WAPI EC CS DB: send_function: completion_action_clenup(): ")
       
  6270 			 EAPL("action[%u] %s not completed.\n"),
       
  6271 			 counter,
       
  6272 			 completion_action->get_completion_action_string(completion_action->get_completion_action())));
       
  6273 
       
  6274 		final_status = m_completion_queue.remove_object(0ul);
       
  6275 		if (final_status != eap_status_ok)
       
  6276 		{
       
  6277 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6278 			return EAP_STATUS_RETURN(m_am_tools, final_status);
       
  6279 		}
       
  6280 
       
  6281 		++counter;
       
  6282 
       
  6283 	} // while()
       
  6284 
       
  6285 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6286 	return EAP_STATUS_RETURN(m_am_tools, final_status);
       
  6287 }
       
  6288 
       
  6289 //--------------------------------------------------
       
  6290 
       
  6291 //
       
  6292 EAP_FUNC_EXPORT void ec_certificate_store_c::completion_action_trace()
       
  6293 {
       
  6294 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6295 
       
  6296 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6297 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6298 					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_trace()\n")));
       
  6299 
       
  6300 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_trace()");
       
  6301 
       
  6302 	for (u32_t trace_ind = 0ul; trace_ind < m_completion_queue.get_object_count(); ++trace_ind)
       
  6303 	{
       
  6304 		ec_cs_completion_c * const completion_action = m_completion_queue.get_object(trace_ind);
       
  6305 
       
  6306 		EAP_TRACE_DEBUG(
       
  6307 			m_am_tools,
       
  6308 			TRACE_FLAGS_DEFAULT,
       
  6309 			(EAPL("WAPI EC CS DB: send_function: completion_action_trace(): pending action[%d] %s=%d\n"),
       
  6310 			 trace_ind,
       
  6311 			 completion_action->get_completion_action_string(completion_action->get_completion_action()),
       
  6312 			 completion_action->get_completion_action()));
       
  6313 	} // for()
       
  6314 }
       
  6315 
       
  6316 //--------------------------------------------------
       
  6317 
       
  6318 //
       
  6319 eap_status_e ec_certificate_store_c::add_imported_certificate(
       
  6320 	const ec_cs_data_type_e certificate_type,
       
  6321 	const eap_variable_data_c * const in_imported_certificate_wapi_id,
       
  6322 	const eap_variable_data_c * const in_imported_certificate_file_data,
       
  6323 	const eap_variable_data_c * const in_imported_certificate_filename,
       
  6324 	eap_array_c<ec_cs_data_c> * const out_asu_id_list,
       
  6325 	eap_array_c<ec_cs_data_c> * const out_certificates,
       
  6326 	ec_cs_variable_data_c * const out_certificate_reference)
       
  6327 {
       
  6328 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6329 
       
  6330 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6331 	EAP_TRACE_DEBUG(
       
  6332 		m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6333 		(EAPL("WAPI_Core: send_function: starts: ec_certificate_store_c::add_imported_certificate()\n")));
       
  6334 
       
  6335 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_imported_certificate()");
       
  6336 
       
  6337 	eap_status_e status(eap_status_not_supported);
       
  6338 
       
  6339 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6340 
       
  6341 	if (in_imported_certificate_filename->get_is_valid_data() == true)
       
  6342 	{
       
  6343 		EAP_TRACE_DATA_DEBUG(
       
  6344 			m_am_tools,
       
  6345 			TRACE_FLAGS_DEFAULT,
       
  6346 			(EAPL("filename"),
       
  6347 			 in_imported_certificate_filename->get_data(),
       
  6348 			 in_imported_certificate_filename->get_data_length()));
       
  6349 	}
       
  6350 
       
  6351 	if (in_imported_certificate_file_data->get_is_valid_data() == false
       
  6352 		|| in_imported_certificate_file_data->get_data_length() == 0ul)
       
  6353 	{
       
  6354 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6355 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
  6356 	}
       
  6357 
       
  6358 	// First check this is unique certificate.
       
  6359 
       
  6360 	ec_cs_compare_reference_id_c compare_reference_id(m_am_tools);
       
  6361 
       
  6362 	ec_cs_data_c search_id(m_am_tools);
       
  6363 
       
  6364 	status = search_id.get_writable_data()->set_buffer(
       
  6365 		in_imported_certificate_wapi_id);
       
  6366 	if (status != eap_status_ok)
       
  6367 	{
       
  6368 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6369 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6370 	}
       
  6371 
       
  6372 	EAP_TRACE_DEBUG(
       
  6373 		m_am_tools,
       
  6374 		TRACE_FLAGS_DEFAULT,
       
  6375 		(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::add_imported_certificate(): count of out_certificates = %d.\n"),
       
  6376 		 this,
       
  6377 		 (m_is_client == true ? "client": "server"),
       
  6378 		 out_asu_id_list->get_object_count()));
       
  6379 
       
  6380 	// Search certificate with the issuer ID from CA-certificates.
       
  6381 	i32_t index = find_with_compare<ec_cs_data_c>(
       
  6382 		&compare_reference_id,
       
  6383 		out_asu_id_list,
       
  6384 		&search_id,
       
  6385 		m_am_tools);
       
  6386 
       
  6387 	if (index >= 0)
       
  6388 	{
       
  6389 		// Match, do not add a copy.
       
  6390 		EAP_TRACE_DEBUG(
       
  6391 			m_am_tools,
       
  6392 			TRACE_FLAGS_DEFAULT,
       
  6393 			(EAPL("WARNING: WAPI_Core: CERTIFICATE IMPORT: this = 0x%08x, %s: ec_certificate_store_c::add_imported_certificate(): Certificate alredy installed.\n"),
       
  6394 			 this,
       
  6395 			 (m_is_client == true ? "client": "server")));
       
  6396 
       
  6397 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6398 		return EAP_STATUS_RETURN(m_am_tools, eap_status_already_exists);
       
  6399 	}
       
  6400 
       
  6401 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6402 
       
  6403 	ec_cs_data_type_e id_reference_type(ec_cs_data_type_none);
       
  6404 
       
  6405 	if (certificate_type == ec_cs_data_type_ca_certificate_data)
       
  6406 	{
       
  6407 		id_reference_type = ec_cs_data_type_ca_asu_id;
       
  6408 	}
       
  6409 	else if (certificate_type == ec_cs_data_type_client_certificate_data)
       
  6410 	{
       
  6411 		id_reference_type = ec_cs_data_type_client_asu_id;
       
  6412 	}
       
  6413 	else
       
  6414 	{
       
  6415 		EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
       
  6416 	}
       
  6417 
       
  6418 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6419 
       
  6420 	ec_cs_data_c certificate_reference(m_am_tools);
       
  6421 	if (certificate_reference.get_is_valid() == false)
       
  6422 	{
       
  6423 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6424 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6425 	}
       
  6426 
       
  6427 	{
       
  6428 		status = create_unique_reference(&certificate_reference);
       
  6429 		if (status != eap_status_ok)
       
  6430 		{
       
  6431 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6432 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6433 		}
       
  6434 
       
  6435 		certificate_reference.set_type(ec_cs_data_type_certificate_reference);
       
  6436 
       
  6437 		status = out_certificate_reference->set_copy_of_buffer(
       
  6438 			ec_cs_tlv_type_CS_certificate_reference,
       
  6439 			certificate_reference.get_reference()->get_data(),
       
  6440 			certificate_reference.get_reference()->get_data_length());
       
  6441 		if (status != eap_status_ok)
       
  6442 		{
       
  6443 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6444 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6445 		}
       
  6446 
       
  6447 		EAP_TRACE_DATA_DEBUG(
       
  6448 			m_am_tools,
       
  6449 			TRACE_FLAGS_DEFAULT,
       
  6450 			(EAPL("out_certificate_reference"),
       
  6451 			 out_certificate_reference->get_full_tlv_buffer()->get_data(),
       
  6452 			 out_certificate_reference->get_full_tlv_buffer()->get_data_length()));
       
  6453 	}
       
  6454 
       
  6455 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6456 
       
  6457 	{
       
  6458 		ec_cs_variable_data_c * const id_reference = new ec_cs_variable_data_c(m_am_tools);
       
  6459 
       
  6460 		eap_automatic_variable_c<ec_cs_variable_data_c> automatic_id_reference(m_am_tools, id_reference);
       
  6461 
       
  6462 		if (id_reference == 0
       
  6463 			|| id_reference->get_is_valid() == false)
       
  6464 		{
       
  6465 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6466 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6467 		}
       
  6468 
       
  6469 		status = id_reference->init_header(
       
  6470 			ec_cs_tlv_type_CS_ID_reference,
       
  6471 			0ul);
       
  6472 		if (status != eap_status_ok)
       
  6473 		{
       
  6474 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6475 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6476 		}
       
  6477 
       
  6478 		{
       
  6479 			ec_cs_variable_data_c asu_id(m_am_tools);
       
  6480 
       
  6481 			if (asu_id.get_is_valid() == false)
       
  6482 			{
       
  6483 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6484 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6485 			}
       
  6486 
       
  6487 			status = asu_id.set_copy_of_buffer(
       
  6488 				ec_cs_tlv_type_CS_ASU_ID,
       
  6489 				in_imported_certificate_wapi_id->get_data(),
       
  6490 				in_imported_certificate_wapi_id->get_data_length());
       
  6491 			if (status != eap_status_ok)
       
  6492 			{
       
  6493 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6494 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6495 			}
       
  6496 
       
  6497 			status = id_reference->add_data(&asu_id);
       
  6498 			if (status != eap_status_ok)
       
  6499 			{
       
  6500 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6501 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6502 			}
       
  6503 
       
  6504 			EC_CS_TLV_TRACE_PAYLOAD("add_imported_certificate()", id_reference->get_header(), m_is_client);
       
  6505 		}
       
  6506 
       
  6507 		{
       
  6508 			status = id_reference->add_data(out_certificate_reference);
       
  6509 			if (status != eap_status_ok)
       
  6510 			{
       
  6511 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6512 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6513 			}
       
  6514 
       
  6515 			EC_CS_TLV_TRACE_PAYLOAD("add_imported_certificate()", id_reference->get_header(), m_is_client);
       
  6516 		}
       
  6517 
       
  6518 		ec_cs_data_c reference_data(m_am_tools);
       
  6519 
       
  6520 		status = reference_data.get_writable_data()->set_copy_of_buffer(id_reference->get_full_tlv_buffer());
       
  6521 		if (status != eap_status_ok)
       
  6522 		{
       
  6523 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6524 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6525 		}
       
  6526 
       
  6527 		status = reference_data.get_writable_reference()->set_copy_of_buffer(certificate_reference.get_reference());
       
  6528 		if (status != eap_status_ok)
       
  6529 		{
       
  6530 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6531 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6532 		}
       
  6533 
       
  6534 		reference_data.set_type(id_reference_type);
       
  6535 
       
  6536 		{
       
  6537 			eap_variable_data_c id_reference_MAC_key(m_am_tools);
       
  6538 			if (id_reference_MAC_key.get_is_valid() == false)
       
  6539 			{
       
  6540 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6541 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6542 			}
       
  6543 
       
  6544 			ec_cs_tlv_c pac_tlv_handler(m_am_tools, true);
       
  6545 			if (pac_tlv_handler.get_is_valid() == false)
       
  6546 			{
       
  6547 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6548 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6549 			}
       
  6550 
       
  6551 			status = pac_tlv_handler.generate_data_key(
       
  6552 				false,
       
  6553 				id_reference_type,
       
  6554 				&id_reference_MAC_key,
       
  6555 				&m_PAC_store_master_key,
       
  6556 				certificate_reference.get_reference(),
       
  6557 				&m_PAC_store_device_seed);
       
  6558 			if (status != eap_status_ok)
       
  6559 			{
       
  6560 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6561 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6562 			}
       
  6563 
       
  6564 			status = pac_tlv_handler.create_data_with_MAC(
       
  6565 				&id_reference_MAC_key,
       
  6566 				id_reference->get_full_tlv_buffer(),
       
  6567 				reference_data.get_writable_data());
       
  6568 			if (status != eap_status_ok)
       
  6569 			{
       
  6570 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6571 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6572 			}
       
  6573 
       
  6574 			EAP_TRACE_DATA_DEBUG(
       
  6575 				m_am_tools,
       
  6576 				TRACE_FLAGS_DEFAULT,
       
  6577 				(EAPL("New reference data"),
       
  6578 				 reference_data.get_data()->get_data(),
       
  6579 				 reference_data.get_data()->get_data_length()));
       
  6580 		}
       
  6581 
       
  6582 		reference_data.set_change_status(ec_cs_data_change_status_new);
       
  6583 
       
  6584 		status = out_asu_id_list->add_object(reference_data.copy(), true);
       
  6585 		if (status != eap_status_ok)
       
  6586 		{
       
  6587 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6588 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6589 		}
       
  6590 	}
       
  6591 
       
  6592 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6593 
       
  6594 	{
       
  6595 		eap_variable_data_c certificate(m_am_tools);
       
  6596 
       
  6597 		if (certificate.get_is_valid() == false)
       
  6598 		{
       
  6599 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6600 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6601 		}
       
  6602 
       
  6603 		ec_cs_tlv_c handler(m_am_tools, true);
       
  6604 		if (handler.get_is_valid() == false)
       
  6605 		{
       
  6606 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6607 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6608 		}
       
  6609 
       
  6610 		status = handler.create_encrypted_certificate(
       
  6611 			certificate_type,
       
  6612 			&m_PAC_store_master_key,
       
  6613 			certificate_reference.get_reference(),
       
  6614 			&m_PAC_store_device_seed,
       
  6615 			certificate_reference.get_reference(),
       
  6616 			ec_cs_tlv_type_CS_certificate_data,
       
  6617 			in_imported_certificate_file_data,
       
  6618 			&certificate);
       
  6619 		if (status != eap_status_ok)
       
  6620 		{
       
  6621 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6622 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6623 		}
       
  6624 
       
  6625 		ec_cs_data_c certificate_data(m_am_tools);
       
  6626 
       
  6627 		status = certificate_data.get_writable_data()->set_copy_of_buffer(&certificate);
       
  6628 		if (status != eap_status_ok)
       
  6629 		{
       
  6630 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6631 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6632 		}
       
  6633 
       
  6634 		status = certificate_data.get_writable_reference()->set_copy_of_buffer(certificate_reference.get_reference());
       
  6635 		if (status != eap_status_ok)
       
  6636 		{
       
  6637 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6638 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6639 		}
       
  6640 
       
  6641 		certificate_data.set_type(certificate_type);
       
  6642 
       
  6643 		certificate_data.set_change_status(ec_cs_data_change_status_new);
       
  6644 
       
  6645 		status = out_certificates->add_object(certificate_data.copy(), true);
       
  6646 		if (status != eap_status_ok)
       
  6647 		{
       
  6648 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6649 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6650 		}
       
  6651 	}
       
  6652 
       
  6653 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6654 
       
  6655 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6656 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6657 }
       
  6658 
       
  6659 //--------------------------------------------------
       
  6660 
       
  6661 //
       
  6662 eap_status_e ec_certificate_store_c::add_imported_private_key(
       
  6663 	const ec_cs_data_type_e private_key_type,
       
  6664 	const eap_variable_data_c * const in_imported_private_key_file_data,
       
  6665 	const eap_variable_data_c * const in_imported_private_key_filename,
       
  6666 	const ec_cs_variable_data_c * const in_certificate_reference,
       
  6667 	eap_array_c<ec_cs_data_c> * const out_private_keys)
       
  6668 {
       
  6669 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6670 
       
  6671 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6672 	EAP_TRACE_DEBUG(
       
  6673 		m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6674 		(EAPL("WAPI_Core: send_function: starts: ec_certificate_store_c::add_imported_private_key()\n")));
       
  6675 
       
  6676 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_imported_private_key()");
       
  6677 
       
  6678 	eap_status_e status(eap_status_not_supported);
       
  6679 
       
  6680 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6681 
       
  6682 	ec_cs_data_c certificate_reference(m_am_tools);
       
  6683 	if (certificate_reference.get_is_valid() == false)
       
  6684 	{
       
  6685 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6686 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6687 	}
       
  6688 
       
  6689 	{
       
  6690 		status = certificate_reference.get_writable_reference()->set_copy_of_buffer(
       
  6691 			in_certificate_reference->get_data(in_certificate_reference->get_data_length()),
       
  6692 			in_certificate_reference->get_data_length());
       
  6693 		if (status != eap_status_ok)
       
  6694 		{
       
  6695 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6696 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6697 		}
       
  6698 	}
       
  6699 
       
  6700 	{
       
  6701 		eap_variable_data_c private_key(m_am_tools);
       
  6702 
       
  6703 		if (private_key.get_is_valid() == false)
       
  6704 		{
       
  6705 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6706 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6707 		}
       
  6708 
       
  6709 		ec_cs_tlv_c handler(m_am_tools, true);
       
  6710 		if (handler.get_is_valid() == false)
       
  6711 		{
       
  6712 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6713 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6714 		}
       
  6715 
       
  6716 		status = handler.create_encrypted_certificate(
       
  6717 			private_key_type,
       
  6718 			&m_PAC_store_master_key,
       
  6719 			certificate_reference.get_reference(),
       
  6720 			&m_PAC_store_device_seed,
       
  6721 			certificate_reference.get_reference(),
       
  6722 			ec_cs_tlv_type_CS_private_key_data,
       
  6723 			in_imported_private_key_file_data,
       
  6724 			&private_key);
       
  6725 		if (status != eap_status_ok)
       
  6726 		{
       
  6727 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6728 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6729 		}
       
  6730 
       
  6731 		ec_cs_data_c private_key_data(m_am_tools);
       
  6732 
       
  6733 		status = private_key_data.get_writable_data()->set_copy_of_buffer(&private_key);
       
  6734 		if (status != eap_status_ok)
       
  6735 		{
       
  6736 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6737 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6738 		}
       
  6739 
       
  6740 		status = private_key_data.get_writable_reference()->set_copy_of_buffer(certificate_reference.get_reference());
       
  6741 		if (status != eap_status_ok)
       
  6742 		{
       
  6743 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6744 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6745 		}
       
  6746 
       
  6747 		private_key_data.set_type(private_key_type);
       
  6748 
       
  6749 		private_key_data.set_change_status(ec_cs_data_change_status_new);
       
  6750 
       
  6751 		status = out_private_keys->add_object(private_key_data.copy(), true);
       
  6752 		if (status != eap_status_ok)
       
  6753 		{
       
  6754 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6755 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6756 		}
       
  6757 	}
       
  6758 
       
  6759 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6760 
       
  6761 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6762 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6763 }
       
  6764 
       
  6765 //--------------------------------------------------
       
  6766 
       
  6767 //
       
  6768 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_check()
       
  6769 {
       
  6770 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6771 
       
  6772 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6773 	EAP_TRACE_DEBUG(
       
  6774 		m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6775 		(EAPL("WAPI_Core: send_function: starts: ec_certificate_store_c::completion_action_check()\n")));
       
  6776 
       
  6777 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_check()");
       
  6778 
       
  6779 	if (m_already_in_completion_action_check == true)
       
  6780 	{
       
  6781 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6782 		// This is recursive call of completion_action_check().
       
  6783 		// This MUST return eap_status_ok. Other return values will skip
       
  6784 		// further prosessing of completion action list.
       
  6785 		EAP_TRACE_DEBUG(
       
  6786 			m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6787 			(EAPL("WAPI EC CS DB: send_function: completion_action_check(): skip recursion\n")));
       
  6788 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6789 	}
       
  6790 	m_already_in_completion_action_check = true;
       
  6791 
       
  6792 	eap_automatic_simple_value_c<bool> restore_already_in_completion_action_check(
       
  6793 		m_am_tools,
       
  6794 		&m_already_in_completion_action_check,
       
  6795 		false);
       
  6796 
       
  6797 
       
  6798 	eap_status_e status = are_pending_queries_completed();
       
  6799 
       
  6800 	if (status != eap_status_ok)
       
  6801 	{
       
  6802 		EAP_TRACE_DEBUG(
       
  6803 			m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6804 			(EAPL("WAPI_Core: are_pending_queries_completed(): still pending\n")));
       
  6805 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6806 	}
       
  6807 
       
  6808 	bool continue_with_next_action = true;
       
  6809 	u32_t counter = 0ul;
       
  6810 
       
  6811 	completion_action_trace();
       
  6812 
       
  6813 	while(continue_with_next_action == true
       
  6814 		&& m_completion_queue.get_object_count() > 0ul)
       
  6815 	{
       
  6816 		status = eap_status_ok;
       
  6817 
       
  6818 		ec_cs_completion_c * const completion_action = m_completion_queue.get_object(0ul);
       
  6819 
       
  6820 		EAP_TRACE_DEBUG(
       
  6821 			m_am_tools,
       
  6822 			TRACE_FLAGS_DEFAULT,
       
  6823 			(EAPL("WAPI EC CS DB: send_function: completion_action_check(): action[%d] %s=%d\n"),
       
  6824 			 counter,
       
  6825 			 completion_action->get_completion_action_string(completion_action->get_completion_action()),
       
  6826 			 completion_action->get_completion_action()));
       
  6827 
       
  6828 		ec_cs_completion_e current_action = completion_action->get_completion_action();
       
  6829 
       
  6830 		// This will remove the current completion action.
       
  6831 		status = completion_action_pop();
       
  6832 		if (status != eap_status_ok)
       
  6833 		{
       
  6834 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6835 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6836 		}
       
  6837 
       
  6838 		switch(current_action)
       
  6839 		{
       
  6840 		case ec_cs_completion_none:
       
  6841 			break;
       
  6842 		case ec_cs_completion_complete_add_imported_certificate_file:
       
  6843 			{
       
  6844 				set_pending_operation(ec_cs_pending_operation_none);
       
  6845 
       
  6846 				EAP_TRACE_DEBUG(
       
  6847 					m_am_tools,
       
  6848 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6849 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): m_am_pac_store_services->complete_add_imported_certificate_file(): %d.\n"),
       
  6850 					__LINE__));
       
  6851 
       
  6852 				status = m_am_certificate_store->complete_add_imported_certificate_file(
       
  6853 					m_ec_cs_completion_status,
       
  6854 					&m_imported_certificate_filename);
       
  6855 				if (status != eap_status_ok)
       
  6856 				{
       
  6857 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6858 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  6859 				}
       
  6860 			}
       
  6861 			break;
       
  6862 		case ec_cs_completion_add_imported_ca_certificate:
       
  6863 			{
       
  6864 				set_pending_operation(ec_cs_pending_operation_none);
       
  6865 
       
  6866 				EAP_TRACE_DEBUG(
       
  6867 					m_am_tools,
       
  6868 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6869 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): add_imported_ca_certificate_file(): %d.\n"),
       
  6870 					__LINE__));
       
  6871 
       
  6872 				ec_cs_variable_data_c certificate_reference(m_am_tools);
       
  6873 				if (certificate_reference.get_is_valid() == false)
       
  6874 				{
       
  6875 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6876 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6877 				}
       
  6878 
       
  6879 				status = add_imported_certificate(
       
  6880 					ec_cs_data_type_ca_certificate_data,
       
  6881 					&m_imported_certificate_wapi_id,
       
  6882 					&m_imported_certificate_data,
       
  6883 					&m_imported_certificate_filename,
       
  6884 					&m_ca_asu_id_list,
       
  6885 					&m_ca_certificates,
       
  6886 					&certificate_reference);
       
  6887 
       
  6888 				m_ec_cs_completion_status = status;
       
  6889 
       
  6890 				if (status != eap_status_ok)
       
  6891 				{
       
  6892 					EAP_TRACE_DEBUG(
       
  6893 						m_am_tools,
       
  6894 						TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6895 						(EAPL("ERROR: ec_certificate_store_c::completion_action_check(): add_imported_ca_certificate_file(): Failed status = %d.\n"),
       
  6896 						status));
       
  6897 					status = eap_status_ok;
       
  6898 				}
       
  6899 			}
       
  6900 			break;
       
  6901 		case ec_cs_completion_add_imported_client_certificate:
       
  6902 			{
       
  6903 				set_pending_operation(ec_cs_pending_operation_none);
       
  6904 
       
  6905 				EAP_TRACE_DEBUG(
       
  6906 					m_am_tools,
       
  6907 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6908 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): add_imported_ca_certificate_file(): %d.\n"),
       
  6909 					__LINE__));
       
  6910 
       
  6911 				ec_cs_variable_data_c certificate_reference(m_am_tools);
       
  6912 				if (certificate_reference.get_is_valid() == false)
       
  6913 				{
       
  6914 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6915 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6916 				}
       
  6917 
       
  6918 				status = add_imported_certificate(
       
  6919 					ec_cs_data_type_client_certificate_data,
       
  6920 					&m_imported_certificate_wapi_id,
       
  6921 					&m_imported_certificate_data,
       
  6922 					&m_imported_certificate_filename,
       
  6923 					&m_client_asu_id_list,
       
  6924 					&m_client_certificates,
       
  6925 					&certificate_reference);
       
  6926 
       
  6927 				m_ec_cs_completion_status = status;
       
  6928 
       
  6929 				if (status != eap_status_ok)
       
  6930 				{
       
  6931 					EAP_TRACE_DEBUG(
       
  6932 						m_am_tools,
       
  6933 						TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6934 						(EAPL("ERROR: ec_certificate_store_c::completion_action_check(): add_imported_certificate(): Failed status = %d.\n"),
       
  6935 						status));
       
  6936 					status = eap_status_ok;
       
  6937 				}
       
  6938 				else 
       
  6939 				{
       
  6940 					status = add_imported_private_key(
       
  6941 						ec_cs_data_type_private_key_data,
       
  6942 						&m_imported_private_key_data,
       
  6943 						&m_imported_certificate_filename,
       
  6944 						&certificate_reference,
       
  6945 						&m_client_private_keys);
       
  6946 					if (status != eap_status_ok)
       
  6947 					{
       
  6948 						EAP_TRACE_DEBUG(
       
  6949 							m_am_tools,
       
  6950 							TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6951 							(EAPL("ERROR: ec_certificate_store_c::completion_action_check(): add_imported_private_key(): Failed status = %d.\n"),
       
  6952 							status));
       
  6953 						status = eap_status_ok;
       
  6954 					}
       
  6955 				}
       
  6956 			}
       
  6957 			break;
       
  6958 		case ec_cs_completion_internal_select_certificate:
       
  6959 			{
       
  6960 				set_pending_operation(ec_cs_pending_operation_none);
       
  6961 
       
  6962 				EAP_TRACE_DEBUG(
       
  6963 					m_am_tools,
       
  6964 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6965 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_select_certificate(): %d.\n"),
       
  6966 					__LINE__));
       
  6967 
       
  6968 				status = internal_select_certificate();
       
  6969 				if (status != eap_status_ok)
       
  6970 				{
       
  6971 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6972 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  6973 				}
       
  6974 			}
       
  6975 			break;
       
  6976 		case ec_cs_completion_internal_select_certificate_with_identity:
       
  6977 			{
       
  6978 				set_pending_operation(ec_cs_pending_operation_none);
       
  6979 
       
  6980 				EAP_TRACE_DEBUG(
       
  6981 					m_am_tools,
       
  6982 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  6983 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_select_certificate_with_identity(): %d.\n"),
       
  6984 					__LINE__));
       
  6985 
       
  6986 				status = internal_select_certificate_with_identity(&m_selected_client_id);
       
  6987 				if (status != eap_status_ok)
       
  6988 				{
       
  6989 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6990 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  6991 				}
       
  6992 			}
       
  6993 			break;
       
  6994 		case ec_cs_completion_internal_create_signature_with_private_key:
       
  6995 			{
       
  6996 				set_pending_operation(ec_cs_pending_operation_none);
       
  6997 
       
  6998 				EAP_TRACE_DEBUG(
       
  6999 					m_am_tools,
       
  7000 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  7001 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_create_signature_with_private_key(): %d.\n"),
       
  7002 					__LINE__));
       
  7003 
       
  7004 				status = internal_create_signature_with_private_key();
       
  7005 				if (status != eap_status_ok)
       
  7006 				{
       
  7007 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7008 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7009 				}
       
  7010 			}
       
  7011 			break;
       
  7012 		case ec_cs_completion_complete_query_certificate_list:
       
  7013 			{
       
  7014 				set_pending_operation(ec_cs_pending_operation_none);
       
  7015 
       
  7016 				EAP_TRACE_DEBUG(
       
  7017 					m_am_tools,
       
  7018 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  7019 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): complete_query_certificate_list(): %d.\n"),
       
  7020 					__LINE__));
       
  7021 
       
  7022 				eap_array_c<eap_variable_data_c> ca_certificates_identities(m_am_tools);
       
  7023 				eap_array_c<eap_variable_data_c> user_certificates_identities(m_am_tools);
       
  7024 
       
  7025 				status = copy_certificate_wapi_identities(
       
  7026 					&m_ca_asu_id_list,
       
  7027 					&ca_certificates_identities);
       
  7028 				if (status != eap_status_ok)
       
  7029 				{
       
  7030 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7031 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7032 				}
       
  7033 
       
  7034 				status = copy_certificate_wapi_identities(
       
  7035 					&m_client_asu_id_list,
       
  7036 					&user_certificates_identities);
       
  7037 				if (status != eap_status_ok)
       
  7038 				{
       
  7039 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7040 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7041 				}
       
  7042 
       
  7043 				status = m_am_certificate_store->complete_query_certificate_list(
       
  7044 					&ca_certificates_identities,
       
  7045 					&user_certificates_identities);
       
  7046 				if (status != eap_status_ok)
       
  7047 				{
       
  7048 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7049 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7050 				}
       
  7051 			}
       
  7052 			break;
       
  7053 
       
  7054 		case ec_cs_completion_internal_verify_signature_with_public_key:
       
  7055 			{
       
  7056 				set_pending_operation(ec_cs_pending_operation_none);
       
  7057 
       
  7058 				EAP_TRACE_DEBUG(
       
  7059 					m_am_tools,
       
  7060 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  7061 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): verify_signature_with_public_key(): %d.\n"),
       
  7062 					__LINE__));
       
  7063 
       
  7064 				status = verify_signature_with_public_key(
       
  7065 					&m_peer_identity,
       
  7066 					&m_hash_of_message,
       
  7067 					&m_signature,
       
  7068 					m_allow_use_of_ae_certificate);
       
  7069 				if (status != eap_status_ok)
       
  7070 				{
       
  7071 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7072 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7073 				}
       
  7074 			}
       
  7075 			break;
       
  7076 
       
  7077 		case ec_cs_completion_internal_complete_add_imported_certificate_file:
       
  7078 			{
       
  7079 				set_pending_operation(ec_cs_pending_operation_none);
       
  7080 
       
  7081 				EAP_TRACE_DEBUG(
       
  7082 					m_am_tools,
       
  7083 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  7084 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_complete_add_imported_certificate_file(): %d.\n"),
       
  7085 					__LINE__));
       
  7086 
       
  7087 				status = internal_complete_add_imported_certificate_file();
       
  7088 				if (status != eap_status_ok)
       
  7089 				{
       
  7090 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7091 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7092 				}
       
  7093 			}
       
  7094 			break;
       
  7095 
       
  7096 		case ec_cs_completion_query_PAC_store_password:
       
  7097 			{
       
  7098 				set_pending_operation(ec_cs_pending_operation_none);
       
  7099 
       
  7100 				EAP_TRACE_DEBUG(
       
  7101 					m_am_tools,
       
  7102 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
       
  7103 					(EAPL("calls: ec_certificate_store_c::completion_action_check(): query_PAC_store_password(): %d.\n"),
       
  7104 					__LINE__));
       
  7105 
       
  7106 				status = query_PAC_store_password(m_pending_operation);
       
  7107 				if (status == eap_status_pending_request)
       
  7108 				{
       
  7109 					// Cannot continue yet.
       
  7110 					continue_with_next_action = false;
       
  7111 				}
       
  7112 			}
       
  7113 			break;
       
  7114 
       
  7115 		default:
       
  7116 			{
       
  7117 				EAP_TRACE_DEBUG(
       
  7118 					m_am_tools,
       
  7119 					TRACE_FLAGS_DEFAULT,
       
  7120 					(EAPL("EROR: WAPI EC CS DB: send_function: completion_action_check(): unknown action[%d] %s=%d\n"),
       
  7121 					 counter,
       
  7122 					 ec_cs_completion_c::get_completion_action_string(current_action),
       
  7123 					 current_action));
       
  7124 			}
       
  7125 			break;
       
  7126 		} // switch()
       
  7127 
       
  7128 		if (status == eap_status_user_cancel_authentication)
       
  7129 		{
       
  7130 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7131 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7132 		}
       
  7133 
       
  7134 		++counter;
       
  7135 
       
  7136 	} // while()
       
  7137 
       
  7138 	if (continue_with_next_action == false)
       
  7139 	{
       
  7140 		status = eap_status_pending_request;
       
  7141 	}
       
  7142 
       
  7143 	completion_action_trace();
       
  7144 
       
  7145 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7146 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7147 }
       
  7148 
       
  7149 //--------------------------------------------------
       
  7150 
       
  7151 //
       
  7152 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::timer_expired(
       
  7153 	const u32_t id,
       
  7154 	void * data)
       
  7155 {
       
  7156 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7157 	EAP_TRACE_DEBUG(
       
  7158 		m_am_tools,
       
  7159 		TRACE_FLAGS_DEFAULT,
       
  7160 		(EAPL("eapol calls: ec_certificate_store_c::timer_expired(): id = %d, data = 0x%08x.\n"),
       
  7161 		id,
       
  7162 		data));
       
  7163 
       
  7164 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::timer_expired()");
       
  7165 
       
  7166 	switch (id)
       
  7167 	{
       
  7168 	case WAPI_CS_KEY_TIMER_ID:
       
  7169 		{
       
  7170 			EAP_TRACE_DEBUG(
       
  7171 				m_am_tools,
       
  7172 				TRACE_FLAGS_DEFAULT,
       
  7173 				(EAPL("WAPI_CS_KEY_TIMER_ID elapsed\n")));
       
  7174 
       
  7175 			m_PAC_store_password.reset();
       
  7176 			m_PAC_store_device_seed.reset();
       
  7177 			m_PAC_store_master_key.reset();
       
  7178 		}
       
  7179 		break;
       
  7180 	
       
  7181 	default:
       
  7182 		break;
       
  7183 	}
       
  7184 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7185 }
       
  7186 
       
  7187 //--------------------------------------------------
       
  7188 
       
  7189 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::timer_delete_data(
       
  7190 	const u32_t id,
       
  7191 	void *data)
       
  7192 {
       
  7193 	EAP_TRACE_DEBUG(
       
  7194 		m_am_tools,
       
  7195 		TRACE_FLAGS_DEFAULT,
       
  7196 		(EAPL("eapol calls: ec_certificate_store_c::timer_delete_data(): id = %d, data = 0x%08x.\n"),
       
  7197 		id,
       
  7198 		data));
       
  7199 
       
  7200 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::timer_delete_data()");
       
  7201 
       
  7202 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7203 }
       
  7204 
       
  7205 //--------------------------------------------------
       
  7206 
       
  7207 void ec_certificate_store_c::send_error_notification(const eap_status_e error)
       
  7208 {
       
  7209 	// Notifies the lower level of an authentication error.
       
  7210 
       
  7211 	eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error);
       
  7212 
       
  7213 	if (error == eap_status_user_cancel_authentication)
       
  7214 	{
       
  7215 		general_state_variable = eap_general_state_authentication_cancelled;
       
  7216 	}
       
  7217 
       
  7218 	// Here we swap the addresses.
       
  7219 	eap_am_network_id_c send_network_id(m_am_tools,
       
  7220 		m_receive_network_id.get_destination_id(),
       
  7221 		m_receive_network_id.get_source_id(),
       
  7222 		m_receive_network_id.get_type());
       
  7223 
       
  7224 	eap_state_notification_c notification(
       
  7225 		m_am_tools,
       
  7226 		&send_network_id,
       
  7227 		true,
       
  7228 		eap_state_notification_eap,
       
  7229 		eap_protocol_layer_general,
       
  7230 		eap_type_none,
       
  7231 		eap_state_none,
       
  7232 		general_state_variable,
       
  7233 		0,
       
  7234 		false);
       
  7235 
       
  7236 	notification.set_authentication_error(error);
       
  7237 
       
  7238 	m_partner->state_notification(&notification);
       
  7239 }
       
  7240 
       
  7241 //----------------------------------------------------------------------------
       
  7242 
       
  7243 EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::set_receive_network_id(const eap_am_network_id_c * const receive_network_id)
       
  7244 {
       
  7245 	return m_receive_network_id.set_copy_of_network_id(receive_network_id);
       
  7246 }
       
  7247 
       
  7248 //----------------------------------------------------------------------------
       
  7249 //----------------------------------------------------------------------------
       
  7250 //----------------------------------------------------------------------------
       
  7251 
       
  7252 EAP_FUNC_EXPORT ec_base_certificate_store_c * ec_base_certificate_store_c::new_ec_base_certificate_store_c(
       
  7253 	abs_eap_am_tools_c * const tools,
       
  7254 	abs_ec_certificate_store_c * const partner,
       
  7255 	ec_am_base_certificate_store_c * const am_certificate_store,
       
  7256 	const bool is_client_when_true)
       
  7257 {
       
  7258 	ec_base_certificate_store_c * store = new ec_certificate_store_c(
       
  7259 		tools,
       
  7260 		partner,
       
  7261 		am_certificate_store,
       
  7262 		is_client_when_true);
       
  7263 
       
  7264 	if (store == 0)
       
  7265 	{
       
  7266 		return 0;
       
  7267 	}
       
  7268 
       
  7269 	eap_status_e status(store->configure());
       
  7270 
       
  7271 	if (status != eap_status_ok)
       
  7272 	{
       
  7273 		delete store;
       
  7274 		return 0;
       
  7275 	}
       
  7276 
       
  7277 	return store;
       
  7278 }
       
  7279 
       
  7280 //----------------------------------------------------------------------------
       
  7281 
       
  7282 #endif //#if defined(USE_WAPI_CORE)
       
  7283 
       
  7284 // End.