eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_record.cpp
changeset 0 c8830336c852
child 2 1c7bc153c08e
equal deleted inserted replaced
-1:000000000000 0:c8830336c852
       
     1 /*
       
     2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  EAP and WLAN authentication protocols.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // This is enumeration of EAPOL source code.
       
    20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    21 	#undef EAP_FILE_NUMBER_ENUM
       
    22 	#define EAP_FILE_NUMBER_ENUM 135 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 
       
    28 
       
    29 #include "eap_am_memory.h"
       
    30 #include "eap_am_export.h"
       
    31 #include "eap_am_tools.h"
       
    32 #include "eap_tools.h"
       
    33 #include "eap_crypto_api.h"
       
    34 #include "abs_tls_base_record.h"
       
    35 #include "tls_base_record.h"
       
    36 #include "tls_record.h"
       
    37 #include "tls_am_services.h"
       
    38 #include "tls_handshake_header.h"
       
    39 #include "tls_peap_types.h"
       
    40 #include "tls_message.h"
       
    41 #include "eap_automatic_variable.h"
       
    42 #include "eap_state_notification.h"
       
    43 #include "eap_type_tls_peap_types.h"
       
    44 #include "eap_header_string.h"
       
    45 
       
    46 #if defined(USE_FAST_EAP_TYPE)
       
    47 	#include "eap_fast_tlv_payloads.h"
       
    48 #endif //#if defined(USE_FAST_EAP_TYPE)
       
    49 
       
    50 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
    51 #include "tls_extension.h"
       
    52 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
    53 
       
    54 //--------------------------------------------------
       
    55 
       
    56 #define EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(tools, status) \
       
    57 	EAP_STATUS_RETURN(tools, eap_status_return_and_create_tls_protocol_alert((status)))
       
    58 
       
    59 
       
    60 eap_status_e tls_record_c::eap_status_return_and_create_tls_protocol_alert(
       
    61 	const eap_status_e status)
       
    62 {
       
    63 	if (status != eap_status_ok
       
    64 		&& status != eap_status_success
       
    65 		&& status != eap_status_pending_request
       
    66 		&& status != eap_status_drop_packet_quietly)
       
    67 	{
       
    68 		(void) create_tls_protocol_alert(tls_alert_description_none, tls_alert_level_none, status);
       
    69 	}
       
    70 
       
    71 	return EAP_STATUS_RETURN(m_am_tools, status);
       
    72 }
       
    73 
       
    74 //--------------------------------------------------
       
    75 
       
    76 EAP_FUNC_EXPORT tls_record_c::~tls_record_c()
       
    77 {
       
    78 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    79 
       
    80 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
    81 					(EAPL("this = 0x%08x, %s: function: starts: tls_record_c::~tls_record_c(): m_am_tls_services")
       
    82 					 EAPL(" = 0x%08x (validity %d).\n"),
       
    83 					 this,
       
    84 					 (m_is_client == true ? "client": "server"),
       
    85 					 m_am_tls_services,
       
    86 					 m_am_tls_services->get_is_valid()));
       
    87 
       
    88 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::~tls_record_c()");
       
    89 
       
    90 	EAP_ASSERT(m_shutdown_was_called == true);
       
    91 
       
    92 	completion_action_clenup();
       
    93 
       
    94 	if (m_free_am_tls_services == true)
       
    95 	{
       
    96 		delete m_am_tls_services;
       
    97 	}
       
    98 	m_am_tls_services = 0;
       
    99 
       
   100 	if (m_free_application == true)
       
   101 	{
       
   102 		delete m_application;
       
   103 	}
       
   104 	m_application = 0;
       
   105 
       
   106 	reset_block_ciphers(true);
       
   107 	reset_block_ciphers(false);
       
   108 
       
   109 	reset_stream_ciphers(true);
       
   110 	reset_stream_ciphers(false);
       
   111 
       
   112 	reset_hmac_algorithms(true);
       
   113 	reset_hmac_algorithms(false);
       
   114 
       
   115 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   116 }
       
   117 
       
   118 //--------------------------------------------------
       
   119 
       
   120 #if defined(_WIN32) && !defined(__GNUC__)
       
   121 	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
       
   122 #endif
       
   123 
       
   124 EAP_FUNC_EXPORT tls_record_c::tls_record_c(
       
   125 	abs_eap_am_tools_c * const tools, ///< tools is pointer to the tools class. @see abs_eap_am_tools_c.
       
   126 	tls_am_services_c * const am_tls_services, ///< This is pointer to adaptation module of TLS.
       
   127 	const bool free_am_tls_services,
       
   128 	tls_base_application_c * const application, ///< application is pointer to application object.
       
   129 	const bool free_application,
       
   130 	const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false).
       
   131 	const eap_type_value_e eap_type,
       
   132 	const eap_am_network_id_c * const receive_network_id)
       
   133 	: tls_base_record_c(tools /*, partner */)
       
   134 	, m_am_tools(tools)
       
   135 	, m_am_tls_services(am_tls_services)
       
   136 	, m_free_am_tls_services(free_am_tls_services)
       
   137 	, m_application(application)
       
   138 	, m_free_application(free_application)
       
   139 	, m_completion_queue(tools)
       
   140 	, m_received_tls_message(tools, this, this, this, is_client_when_true)
       
   141 	, m_new_tls_message(tools, this, this, this, is_client_when_true)
       
   142 	, m_message_hash_md5(tools)
       
   143 	, m_message_hash_sha1(tools)
       
   144 	, m_message_hash_md5_certificate_verify(tools)
       
   145 	, m_message_hash_sha1_certificate_verify(tools)
       
   146 	, m_client_message_hash_md5_finished(tools)
       
   147 	, m_client_message_hash_sha1_finished(tools)
       
   148 	, m_server_message_hash_md5_finished(tools)
       
   149 	, m_server_message_hash_sha1_finished(tools)
       
   150 	, m_client_handshake_random_value(tools)
       
   151 	, m_server_handshake_random_value(tools)
       
   152 	, m_session_id(tools)
       
   153 	, m_master_secret(tools)
       
   154 	, m_eap_master_session_key(tools, eap_type)
       
   155 	, m_new_send_mac_key(tools)
       
   156 	, m_new_receive_mac_key(tools)
       
   157 	, m_new_send_encryption_key(tools)
       
   158 	, m_new_receive_encryption_key(tools)
       
   159 	, m_new_send_iv(tools)
       
   160 	, m_new_receive_iv(tools)
       
   161 	, m_send_mac_key(tools)
       
   162 	, m_receive_mac_key(tools)
       
   163 	, m_send_encryption_key(tools)
       
   164 	, m_receive_encryption_key(tools)
       
   165 	, m_send_iv(tools)
       
   166 	, m_receive_iv(tools)
       
   167 	, m_session_key_seed(tools)
       
   168 	, m_mschapv2_challenges(tools)
       
   169 	, m_own_private_dhe_key(tools)
       
   170 	, m_own_public_dhe_key(tools)
       
   171 	, m_peer_public_dhe_key(tools)
       
   172 	, m_shared_dh_key(tools)
       
   173 	, m_dhe_prime(tools)
       
   174 	, m_dhe_group_generator(tools)
       
   175 	, m_signed_message_hash(tools)
       
   176 	, m_premaster_secret(tools)
       
   177 	, m_own_encrypted_premaster_secret(tools)
       
   178 #if defined(USE_FAST_EAP_TYPE)
       
   179 	, m_eap_fast_pac_key(tools)
       
   180 #endif //#if defined(USE_FAST_EAP_TYPE)
       
   181 	, m_proposed_cipher_suites(tools)
       
   182 	, m_proposed_compression_methods(tools)
       
   183 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
   184 	, m_supported_tls_extensions(tools)
       
   185 	, m_received_tls_extensions(tools)
       
   186 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
   187 	, m_NAI_realm(tools)
       
   188 	, m_send_network_id(tools)
       
   189 	, m_own_certificate_chain(tools)
       
   190 	, m_own_certificate_types(tools)
       
   191 	, m_own_certificate_authorities(tools)
       
   192 	, m_peer_certificate_chain(tools)
       
   193 	, m_peer_certificate_chain_result(eap_status_illegal_certificate)
       
   194 	, m_verify_signature(eap_status_authentication_failure)
       
   195 	, m_peer_certificate_types(tools)
       
   196 	, m_peer_certificate_authorities(tools)
       
   197 	, m_resumed_cipher_suite(tls_cipher_suites_none)
       
   198 	, m_selected_cipher_suite(tls_cipher_suites_none)
       
   199 	, m_selected_compression_method(tls_compression_method_none)
       
   200 	, m_receive_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
   201 	, m_receive_compression_method(tls_compression_method_null)
       
   202 	, m_send_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
   203 	, m_send_compression_method(tls_compression_method_null)
       
   204 	, m_send_block_cipher(0)
       
   205 	, m_receive_block_cipher(0)
       
   206 	, m_send_stream_cipher(0)
       
   207 	, m_receive_stream_cipher(0)
       
   208 	, m_send_hmac_algorithm(0)
       
   209 	, m_receive_hmac_algorithm(0)
       
   210 	, m_send_record_sequence_number(0ul)
       
   211 	, m_receive_record_sequence_number(0ul)
       
   212 	, m_tls_peap_state(tls_peap_state_wait_tls_start)
       
   213 	, m_tls_session_type(tls_session_type_none)
       
   214 	, m_eap_type(eap_type)
       
   215 	, m_peap_version(peap_version_none)
       
   216 	, m_tunneled_eap_type_authentication_state(eap_state_none)
       
   217 	, m_is_valid(false)
       
   218 	, m_is_client(is_client_when_true)
       
   219 	, m_allow_message_send(true)
       
   220 	, m_already_in_completion_action_check(false)
       
   221 	, m_already_in_process_tls_records(false)
       
   222 	, m_pending_query_certificate_authorities_and_types(false)
       
   223 	, m_pending_query_certificate_chain(false)
       
   224 	, m_pending_query_cipher_suites_and_previous_session(false)
       
   225 	, m_pending_query_dh_parameters(false)
       
   226 	, m_pending_query_realm(false)
       
   227 	, m_pending_select_cipher_suite_and_check_session_id(false)
       
   228 	, m_pending_verify_certificate_chain(false)
       
   229 	, m_pending_rsa_decrypt_with_private_key(false)
       
   230 	, m_pending_rsa_encrypt_with_public_key(false)
       
   231 	, m_pending_sign_with_private_key(false)
       
   232 	, m_pending_verify_with_public_key(false)
       
   233 	, m_pending_query_tunnel_PAC(false)
       
   234 	, m_tls_peap_test_version(false)
       
   235 	, m_key_material_generated(false)
       
   236 	, m_tls_peap_server_authenticates_client_policy_flag(true)
       
   237 	, m_tls_peap_server_authenticates_client_config_server(true)
       
   238 	, m_tls_peap_server_authenticates_client_action(true)
       
   239 	, m_tls_peap_server_requested_client_certificate(false)
       
   240 	, m_could_send_fatal_alert_message(true)
       
   241 	, m_could_send_warning_alert_message(true)
       
   242 	, m_force_tls_message_send(false)
       
   243 	, m_shutdown_was_called(false)
       
   244 	, m_use_separate_tls_record(true)  // Some vendors seems to use only separate TLS-records. Windows RAS and FreeRadius works too with this.
       
   245 	, m_use_extra_padding_length(false) // It seems that EAP-TLS of Microsoft Windows does not work with extra padding.
       
   246 	, m_client_allows_empty_certificate_authorities_list(false)
       
   247 	, m_server_sends_empty_certificate_authorities_list(false)
       
   248 	, m_use_tppd_tls_peap(true)
       
   249 	, m_use_tppd_peapv1_acknowledge_hack(false)
       
   250 	, m_server_offers_new_session_id(true)
       
   251 	, m_will_receive_new_session_ticket(false)
       
   252 	, m_send_piggypacked_eap_identity_request(true)
       
   253 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
   254 	, m_tls_use_identity_privacy(false)
       
   255 	, m_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_none)
       
   256 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
   257 #if defined(USE_FAST_EAP_TYPE)
       
   258 	, m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP(false)
       
   259 	, m_remove_tunnel_pac(false)
       
   260 #endif //#if defined(USE_FAST_EAP_TYPE)
       
   261 	{
       
   262 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   263 
       
   264 	EAP_TRACE_DEBUG(
       
   265 		m_am_tools,
       
   266 		TRACE_FLAGS_DEFAULT,
       
   267 		(EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::tls_record_c(): "),
       
   268 		 this,
       
   269 		 (m_is_client == true ? "client": "server")));
       
   270 
       
   271 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::tls_record_c()");
       
   272 
       
   273 	if (receive_network_id == 0
       
   274 		|| receive_network_id->get_is_valid_data() == false)
       
   275 	{
       
   276 		// No need to delete anything here because it is done in destructor.
       
   277 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   278 		return;
       
   279 	}
       
   280 
       
   281 	if (m_am_tls_services == 0
       
   282 		|| m_am_tls_services->get_is_valid() == false)
       
   283 	{
       
   284 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_TLS_PEAP_ERROR,
       
   285 						(EAPL("ERROR: %s: function: tls_record_c::tls_record_c() failed,")
       
   286 						 EAPL(" m_am_tls_services = 0x%08x (validity %d) is invalid.\n"),
       
   287 						 (m_is_client == true ? "client": "server"),
       
   288 						 m_am_tls_services, (m_am_tls_services != 0) ? m_am_tls_services->get_is_valid() : false));
       
   289 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   290 		return;
       
   291 	}
       
   292 	m_am_tls_services->set_tls_am_partner(this);
       
   293 
       
   294 	// Here we swap the addresses.
       
   295 	eap_am_network_id_c send_network_id(
       
   296 		m_am_tools,
       
   297 		receive_network_id->get_destination_id(),
       
   298 		receive_network_id->get_source_id(),
       
   299 		receive_network_id->get_type());
       
   300 
       
   301 	eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id);
       
   302 	if (status != eap_status_ok)
       
   303 	{
       
   304 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   305 		return;
       
   306 	}
       
   307 
       
   308 	if (get_is_tunneled_tls() == true
       
   309 		&& m_application == 0)
       
   310 	{
       
   311 		// Application is required in tunneled mode.
       
   312 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   313 		return;
       
   314 	}
       
   315 
       
   316 	if (m_application != 0)
       
   317 	{
       
   318 		m_application->set_application_partner(this);
       
   319 	}
       
   320 
       
   321 	if (m_is_client == false)
       
   322 	{
       
   323 		set_state(tls_peap_state_wait_handshake_type_client_hello);
       
   324 	}
       
   325 
       
   326 	set_is_valid();
       
   327 
       
   328 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   329 }
       
   330 
       
   331 //--------------------------------------------------
       
   332 
       
   333 EAP_FUNC_EXPORT void tls_record_c::reset_block_ciphers(const bool send_when_true)
       
   334 {
       
   335 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   336 
       
   337 	if (send_when_true == true)
       
   338 	{
       
   339 		delete m_send_block_cipher;
       
   340 		m_send_block_cipher = 0;
       
   341 	}
       
   342 	else
       
   343 	{
       
   344 		delete m_receive_block_cipher;
       
   345 		m_receive_block_cipher = 0;
       
   346 	}
       
   347 
       
   348 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   349 }
       
   350 
       
   351 //--------------------------------------------------
       
   352 
       
   353 EAP_FUNC_EXPORT void tls_record_c::reset_stream_ciphers(const bool send_when_true)
       
   354 {
       
   355 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   356 
       
   357 	if (send_when_true == true)
       
   358 	{
       
   359 		delete m_send_stream_cipher;
       
   360 		m_send_stream_cipher = 0;
       
   361 	}
       
   362 	else
       
   363 	{
       
   364 		delete m_receive_stream_cipher;
       
   365 		m_receive_stream_cipher = 0;
       
   366 	}
       
   367 
       
   368 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   369 }
       
   370 
       
   371 //--------------------------------------------------
       
   372 
       
   373 EAP_FUNC_EXPORT void tls_record_c::reset_hmac_algorithms(const bool send_when_true)
       
   374 {
       
   375 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   376 
       
   377 	if (send_when_true == true)
       
   378 	{
       
   379 		delete m_send_hmac_algorithm;
       
   380 		m_send_hmac_algorithm = 0;
       
   381 	}
       
   382 	else
       
   383 	{
       
   384 		delete m_receive_hmac_algorithm;
       
   385 		m_receive_hmac_algorithm = 0;
       
   386 	}
       
   387 
       
   388 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   389 }
       
   390 
       
   391 //--------------------------------------------------
       
   392 
       
   393 EAP_FUNC_EXPORT void tls_record_c::set_state(const tls_peap_state_e state)
       
   394 {
       
   395 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   396 
       
   397 	EAP_TRACE_DEBUG(
       
   398 		m_am_tools,
       
   399 		TRACE_FLAGS_DEFAULT,
       
   400 		(EAPL("TLS: this = 0x%08x, %s: state_function: starts: tls_record_c::set_state() from %s to %s\n"),
       
   401 		 this,
       
   402 		 (m_is_client == true ? "client": "server"),
       
   403 		 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
   404 		 eap_tls_trace_string_c::get_state_string(state)));
       
   405 
       
   406 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_state()");
       
   407 
       
   408 	if (m_tls_peap_state != tls_peap_state_failure)
       
   409 	{
       
   410 		m_tls_peap_state = state;
       
   411 	}
       
   412 
       
   413 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   414 }
       
   415 
       
   416 //--------------------------------------------------
       
   417 
       
   418 EAP_FUNC_EXPORT tls_peap_state_e tls_record_c::get_state() const
       
   419 {
       
   420 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   421 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   422 	return m_tls_peap_state;
       
   423 }
       
   424 
       
   425 //--------------------------------------------------
       
   426 
       
   427 EAP_FUNC_EXPORT bool tls_record_c::verify_state(const tls_peap_state_e state)
       
   428 {
       
   429 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   430 
       
   431 	bool are_equal = false;
       
   432 
       
   433 	EAP_TRACE_DEBUG(
       
   434 		m_am_tools,
       
   435 		TRACE_FLAGS_DEFAULT,
       
   436 		(EAPL("TLS: %s: state_function: starts: tls_record_c::verify_state(): (current state %s) %s (new state %s)\n"),
       
   437 		 (m_is_client == true ? "client": "server"),
       
   438 		 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
   439 		 ((m_tls_peap_state == state) ? "==" : "!="),
       
   440 		 eap_tls_trace_string_c::get_state_string(state)));
       
   441 
       
   442 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::verify_state()");
       
   443 
       
   444 	if (m_tls_peap_state == state)
       
   445 	{
       
   446 		are_equal = true;
       
   447 	}
       
   448 	else
       
   449 	{
       
   450 		are_equal = false;
       
   451 	}
       
   452 
       
   453 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   454 	return are_equal;
       
   455 }
       
   456 
       
   457 //--------------------------------------------------
       
   458 
       
   459 EAP_FUNC_EXPORT void tls_record_c::set_is_valid()
       
   460 {
       
   461 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   462 
       
   463 	m_is_valid = true;
       
   464 
       
   465 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   466 }
       
   467 
       
   468 //--------------------------------------------------
       
   469 
       
   470 EAP_FUNC_EXPORT bool tls_record_c::get_is_tunneled_tls()
       
   471 {
       
   472 	return (
       
   473 		m_eap_type == eap_type_peap
       
   474 		|| m_eap_type == eap_type_ttls
       
   475 #if defined(USE_FAST_EAP_TYPE)
       
   476 		|| m_eap_type == eap_type_fast
       
   477 #endif //#if defined(USE_FAST_EAP_TYPE)
       
   478 		);
       
   479 }
       
   480 
       
   481 //--------------------------------------------------
       
   482 
       
   483 EAP_FUNC_EXPORT void tls_record_c::set_peap_version(
       
   484 	const peap_version_e peap_version,
       
   485 	const bool use_tppd_tls_peap,
       
   486 	const bool use_tppd_peapv1_acknowledge_hack)
       
   487 {
       
   488 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   489 
       
   490 	m_peap_version = peap_version;
       
   491 
       
   492 	m_use_tppd_tls_peap = use_tppd_tls_peap;
       
   493 
       
   494 	m_use_tppd_peapv1_acknowledge_hack = use_tppd_peapv1_acknowledge_hack;
       
   495 
       
   496 	m_am_tls_services->set_peap_version(
       
   497 		peap_version,
       
   498 		use_tppd_tls_peap,
       
   499 		use_tppd_peapv1_acknowledge_hack);
       
   500 
       
   501 	if (m_application != 0)
       
   502 	{
       
   503 		m_application->set_peap_version(
       
   504 			peap_version,
       
   505 			use_tppd_tls_peap,
       
   506 			use_tppd_peapv1_acknowledge_hack);
       
   507 	}
       
   508 
       
   509 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   510 }
       
   511 
       
   512 //--------------------------------------------------
       
   513 
       
   514 EAP_FUNC_EXPORT eap_status_e tls_record_c::configure()
       
   515 {
       
   516 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   517 
       
   518 	EAP_TRACE_DEBUG(
       
   519 		m_am_tools,
       
   520 		TRACE_FLAGS_DEFAULT,
       
   521 		(EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::configure():\n"),
       
   522 		 this,
       
   523 		(m_is_client == true ? "client": "server")));
       
   524 
       
   525 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::configure()");
       
   526 
       
   527 	eap_status_e status = m_am_tls_services->configure();
       
   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 	//----------------------------------------------------------
       
   535 
       
   536 	{
       
   537 		eap_variable_data_c test_version(m_am_tools);
       
   538 
       
   539 		status = get_type_partner()->read_configure(
       
   540 			cf_str_EAP_TLS_test_version.get_field(),
       
   541 			&test_version);
       
   542 		if (status == eap_status_ok
       
   543 			&& test_version.get_is_valid_data() == true
       
   544 			&& test_version.get_data_length() == sizeof(u32_t)
       
   545 			&& test_version.get_data(sizeof(u32_t)) != 0)
       
   546 		{
       
   547 			// This is optional value.
       
   548 			u32_t *flag = reinterpret_cast<u32_t *>(test_version.get_data(sizeof(u32_t)));
       
   549 			if (flag != 0)
       
   550 			{
       
   551 				if (*flag == 0)
       
   552 				{
       
   553 					m_tls_peap_test_version = false;
       
   554 				}
       
   555 				else
       
   556 				{
       
   557 					m_tls_peap_test_version = true;
       
   558 				}
       
   559 			}
       
   560 		}
       
   561 
       
   562 		status = eap_status_ok;
       
   563 	}
       
   564 
       
   565 	//----------------------------------------------------------
       
   566 
       
   567 	{
       
   568 		eap_variable_data_c use_separate_tls_record(m_am_tools);
       
   569 
       
   570 		status = get_type_partner()->read_configure(
       
   571 			cf_str_TLS_use_separate_tls_record.get_field(),
       
   572 			&use_separate_tls_record);
       
   573 		if (status == eap_status_ok
       
   574 			&& use_separate_tls_record.get_is_valid_data() == true
       
   575 			&& use_separate_tls_record.get_data_length() == sizeof(u32_t)
       
   576 			&& use_separate_tls_record.get_data(sizeof(u32_t)) != 0)
       
   577 		{
       
   578 			// This is optional value.
       
   579 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   580 				use_separate_tls_record.get_data(sizeof(u32_t)));
       
   581 			if (flag != 0)
       
   582 			{
       
   583 				if (*flag == 0)
       
   584 				{
       
   585 					m_use_separate_tls_record = false;
       
   586 				}
       
   587 				else
       
   588 				{
       
   589 					m_use_separate_tls_record = true;
       
   590 				}
       
   591 			}
       
   592 		}
       
   593 
       
   594 		status = eap_status_ok;
       
   595 	}
       
   596 
       
   597 	//----------------------------------------------------------
       
   598 
       
   599 	if (m_is_client == false)
       
   600 	{
       
   601 		eap_variable_data_c server_offers_new_session_id(m_am_tools);
       
   602 
       
   603 		status = get_type_partner()->read_configure(
       
   604 			cf_str_TLS_server_offers_new_session_id.get_field(),
       
   605 			&server_offers_new_session_id);
       
   606 		if (status == eap_status_ok
       
   607 			&& server_offers_new_session_id.get_is_valid_data() == true
       
   608 			&& server_offers_new_session_id.get_data_length() == sizeof(u32_t)
       
   609 			&& server_offers_new_session_id.get_data(sizeof(u32_t)) != 0)
       
   610 		{
       
   611 			// This is optional value.
       
   612 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   613 				server_offers_new_session_id.get_data(sizeof(u32_t)));
       
   614 			if (flag != 0)
       
   615 			{
       
   616 				if (*flag == 0)
       
   617 				{
       
   618 					m_server_offers_new_session_id = false;
       
   619 				}
       
   620 				else
       
   621 				{
       
   622 					m_server_offers_new_session_id = true;
       
   623 				}
       
   624 			}
       
   625 		}
       
   626 
       
   627 		status = eap_status_ok;
       
   628 	}
       
   629 
       
   630 	//----------------------------------------------------------
       
   631 
       
   632 	if (get_is_tunneled_tls() == true)
       
   633 	{
       
   634 		// Default function in PEAP and TTLS is only client authenticates server.
       
   635 		m_tls_peap_server_authenticates_client_config_server = false;
       
   636 	}
       
   637 
       
   638 	if (m_is_client == false)
       
   639 	{
       
   640 		eap_variable_data_c server_authenticates_client(m_am_tools);
       
   641 
       
   642 		status = get_type_partner()->read_configure(
       
   643 			cf_str_TLS_server_authenticates_client.get_field(),
       
   644 			&server_authenticates_client);
       
   645 		if (status == eap_status_ok
       
   646 			&& server_authenticates_client.get_is_valid_data() == true
       
   647 			&& server_authenticates_client.get_data_length() == sizeof(u32_t)
       
   648 			&& server_authenticates_client.get_data(sizeof(u32_t)) != 0)
       
   649 		{
       
   650 			// This is optional value.
       
   651 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   652 				server_authenticates_client.get_data(sizeof(u32_t)));
       
   653 			if (flag != 0)
       
   654 			{
       
   655 				if (*flag == 0)
       
   656 				{
       
   657 					m_tls_peap_server_authenticates_client_config_server = false;
       
   658 				}
       
   659 				else
       
   660 				{
       
   661 					m_tls_peap_server_authenticates_client_config_server = true;
       
   662 				}
       
   663 			}
       
   664 		}
       
   665 
       
   666 		if (m_tls_peap_server_authenticates_client_config_server == false)
       
   667 		{
       
   668 			m_tls_peap_server_authenticates_client_action = false;
       
   669 		}
       
   670 
       
   671 		status = eap_status_ok;
       
   672 	}
       
   673 
       
   674 	//----------------------------------------------------------
       
   675 
       
   676 	if (get_is_tunneled_tls() == true)
       
   677 	{
       
   678 		// Default function in PEAP and TTLS is only client authenticates server.
       
   679 		m_tls_peap_server_authenticates_client_policy_flag = false;
       
   680 	}
       
   681 
       
   682 	if (m_is_client == true)
       
   683 	{
       
   684 		eap_variable_data_c server_authenticates_client(m_am_tools);
       
   685 
       
   686 		status = get_type_partner()->read_configure(
       
   687 			cf_str_TLS_server_authenticates_client_policy_in_client.get_field(),
       
   688 			&server_authenticates_client);
       
   689 		if (status == eap_status_ok
       
   690 			&& server_authenticates_client.get_is_valid_data() == true
       
   691 			&& server_authenticates_client.get_data_length() == sizeof(u32_t)
       
   692 			&& server_authenticates_client.get_data(sizeof(u32_t)) != 0)
       
   693 		{
       
   694 			// This is optional value.
       
   695 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   696 				server_authenticates_client.get_data(sizeof(u32_t)));
       
   697 			if (flag != 0)
       
   698 			{
       
   699 				if (*flag == 0)
       
   700 				{
       
   701 					m_tls_peap_server_authenticates_client_policy_flag = false;
       
   702 				}
       
   703 				else
       
   704 				{
       
   705 					m_tls_peap_server_authenticates_client_policy_flag = true;
       
   706 				}
       
   707 			}
       
   708 		}
       
   709 
       
   710 		status = eap_status_ok;
       
   711 	}
       
   712 	else
       
   713 	{
       
   714 		eap_variable_data_c server_authenticates_client(m_am_tools);
       
   715 
       
   716 		status = get_type_partner()->read_configure(
       
   717 			cf_str_TLS_server_authenticates_client_policy_in_server.get_field(),
       
   718 			&server_authenticates_client);
       
   719 		if (status == eap_status_ok
       
   720 			&& server_authenticates_client.get_is_valid_data() == true
       
   721 			&& server_authenticates_client.get_data_length() == sizeof(u32_t)
       
   722 			&& server_authenticates_client.get_data(sizeof(u32_t)) != 0)
       
   723 		{
       
   724 			// This is optional value.
       
   725 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   726 				server_authenticates_client.get_data(sizeof(u32_t)));
       
   727 			if (flag != 0)
       
   728 			{
       
   729 				if (*flag == 0)
       
   730 				{
       
   731 					m_tls_peap_server_authenticates_client_policy_flag = false;
       
   732 				}
       
   733 				else
       
   734 				{
       
   735 					m_tls_peap_server_authenticates_client_policy_flag = true;
       
   736 				}
       
   737 			}
       
   738 		}
       
   739 
       
   740 		status = eap_status_ok;
       
   741 	}
       
   742 
       
   743 	//----------------------------------------------------------
       
   744 
       
   745 	if (m_is_client == true)
       
   746 	{
       
   747 		eap_variable_data_c client_allows_empty_certificate_authorities_list(m_am_tools);
       
   748 
       
   749 		status = get_type_partner()->read_configure(
       
   750 			cf_str_TLS_client_allows_empty_certificate_authorities_list.get_field(),
       
   751 			&client_allows_empty_certificate_authorities_list);
       
   752 		if (status == eap_status_ok
       
   753 			&& client_allows_empty_certificate_authorities_list.get_is_valid_data() == true
       
   754 			&& client_allows_empty_certificate_authorities_list.get_data_length() == sizeof(u32_t)
       
   755 			&& client_allows_empty_certificate_authorities_list.get_data(sizeof(u32_t)) != 0)
       
   756 		{
       
   757 			// This is optional value.
       
   758 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   759 				client_allows_empty_certificate_authorities_list.get_data(sizeof(u32_t)));
       
   760 			if (flag != 0)
       
   761 			{
       
   762 				if (*flag == 0)
       
   763 				{
       
   764 					m_client_allows_empty_certificate_authorities_list = false;
       
   765 				}
       
   766 				else
       
   767 				{
       
   768 					m_client_allows_empty_certificate_authorities_list = true;
       
   769 				}
       
   770 			}
       
   771 		}
       
   772 
       
   773 		status = eap_status_ok;
       
   774 	}
       
   775 	else
       
   776 	{
       
   777 		eap_variable_data_c server_sends_empty_certificate_authorities_list(m_am_tools);
       
   778 
       
   779 		status = get_type_partner()->read_configure(
       
   780 			cf_str_TLS_server_sends_empty_certificate_authorities_list.get_field(),
       
   781 			&server_sends_empty_certificate_authorities_list);
       
   782 		if (status == eap_status_ok
       
   783 			&& server_sends_empty_certificate_authorities_list.get_is_valid_data() == true
       
   784 			&& server_sends_empty_certificate_authorities_list.get_data_length() == sizeof(u32_t)
       
   785 			&& server_sends_empty_certificate_authorities_list.get_data(sizeof(u32_t)) != 0)
       
   786 		{
       
   787 			// This is optional value.
       
   788 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   789 				server_sends_empty_certificate_authorities_list.get_data(sizeof(u32_t)));
       
   790 			if (flag != 0)
       
   791 			{
       
   792 				if (*flag == 0)
       
   793 				{
       
   794 					m_server_sends_empty_certificate_authorities_list = false;
       
   795 				}
       
   796 				else
       
   797 				{
       
   798 					m_server_sends_empty_certificate_authorities_list = true;
       
   799 				}
       
   800 			}
       
   801 		}
       
   802 
       
   803 		status = eap_status_ok;
       
   804 	}
       
   805 
       
   806 	//----------------------------------------------------------
       
   807 
       
   808 	if (m_is_client == false)
       
   809 	{
       
   810 		eap_variable_data_c send_piggypacked_eap_identity_request(m_am_tools);
       
   811 
       
   812 		status = get_type_partner()->read_configure(
       
   813 			cf_str_EAP_FAST_send_piggypacked_eap_identity_request.get_field(),
       
   814 			&send_piggypacked_eap_identity_request);
       
   815 		if (status == eap_status_ok
       
   816 			&& send_piggypacked_eap_identity_request.get_is_valid_data() == true
       
   817 			&& send_piggypacked_eap_identity_request.get_data_length() == sizeof(u32_t)
       
   818 			&& send_piggypacked_eap_identity_request.get_data(sizeof(u32_t)) != 0)
       
   819 		{
       
   820 			// This is optional value.
       
   821 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   822 				send_piggypacked_eap_identity_request.get_data(sizeof(u32_t)));
       
   823 			if (flag != 0)
       
   824 			{
       
   825 				if (*flag == 0)
       
   826 				{
       
   827 					m_send_piggypacked_eap_identity_request = false;
       
   828 				}
       
   829 				else
       
   830 				{
       
   831 					m_send_piggypacked_eap_identity_request = true;
       
   832 				}
       
   833 			}
       
   834 		}
       
   835 
       
   836 		status = eap_status_ok;
       
   837 	}
       
   838 
       
   839 	//----------------------------------------------------------
       
   840 
       
   841 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
   842 
       
   843 	{
       
   844 		eap_variable_data_c tls_use_privacy(m_am_tools);
       
   845 
       
   846 		status = get_type_partner()->read_configure(
       
   847 			cf_str_EAP_TLS_PEAP_use_identity_privacy.get_field(),
       
   848 			&tls_use_privacy);
       
   849 		if (status == eap_status_ok
       
   850 			&& tls_use_privacy.get_is_valid_data() == true
       
   851 			&& tls_use_privacy.get_data_length() == sizeof(u32_t)
       
   852 			&& tls_use_privacy.get_data(sizeof(u32_t)) != 0)
       
   853 		{
       
   854 			// This is optional value.
       
   855 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   856 				tls_use_privacy.get_data(sizeof(u32_t)));
       
   857 			if (flag != 0)
       
   858 			{
       
   859 				if (*flag == 0)
       
   860 				{
       
   861 					m_tls_use_identity_privacy = false;
       
   862 				}
       
   863 				else
       
   864 				{
       
   865 					m_tls_use_identity_privacy = true;
       
   866 				}
       
   867 			}
       
   868 		}
       
   869 
       
   870 		status = eap_status_ok;
       
   871 	}
       
   872 
       
   873 	if (m_is_client == false)
       
   874 	{
       
   875 		eap_variable_data_c tls_server_use_privacy(m_am_tools);
       
   876 
       
   877 		status = get_type_partner()->read_configure(
       
   878 			cf_str_EAP_TLS_PEAP_use_identity_privacy_server.get_field(),
       
   879 			&tls_server_use_privacy);
       
   880 		if (status == eap_status_ok
       
   881 			&& tls_server_use_privacy.get_is_valid_data() == true
       
   882 			&& tls_server_use_privacy.get_data_length() == sizeof(u32_t)
       
   883 			&& tls_server_use_privacy.get_data(sizeof(u32_t)) != 0)
       
   884 		{
       
   885 			// This is optional value.
       
   886 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   887 				tls_server_use_privacy.get_data(sizeof(u32_t)));
       
   888 			if (flag != 0)
       
   889 			{
       
   890 				if (*flag == 0)
       
   891 				{
       
   892 					m_tls_use_identity_privacy = false;
       
   893 				}
       
   894 				else
       
   895 				{
       
   896 					m_tls_use_identity_privacy = true;
       
   897 				}
       
   898 			}
       
   899 		}
       
   900 
       
   901 		status = eap_status_ok;
       
   902 	}
       
   903 
       
   904 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
   905 
       
   906 	//----------------------------------------------------------
       
   907 
       
   908 #if defined(USE_FAST_EAP_TYPE)
       
   909 	if (m_eap_type == eap_type_fast)
       
   910 	{
       
   911 		// Client and server configuration.
       
   912 		{
       
   913 			eap_variable_data_c provisioning(m_am_tools);
       
   914 
       
   915 			status = get_type_partner()->read_configure(
       
   916 				cf_str_EAP_FAST_allow_server_unauthenticated_provisioning_mode_ADHP.get_field(),
       
   917 				&provisioning);
       
   918 			if (status == eap_status_ok
       
   919 				&& provisioning.get_is_valid_data() == true
       
   920 				&& provisioning.get_data_length() == sizeof(u32_t)
       
   921 				&& provisioning.get_data(sizeof(u32_t)) != 0)
       
   922 			{
       
   923 				// This is optional value.
       
   924 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   925 					provisioning.get_data(sizeof(u32_t)));
       
   926 				if (flag != 0)
       
   927 				{
       
   928 					if (*flag == 0)
       
   929 					{
       
   930 						m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP = false;
       
   931 					}
       
   932 					else
       
   933 					{
       
   934 						m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP = true;
       
   935 					}
       
   936 				}
       
   937 			}
       
   938 
       
   939 			status = eap_status_ok;
       
   940 		}
       
   941 
       
   942 		{
       
   943 			eap_variable_data_c allow_server_authenticated_provisioning_mode(m_am_tools);
       
   944 
       
   945 			status = read_configure(
       
   946 				cf_str_EAP_FAST_allow_server_authenticated_provisioning_mode.get_field(),
       
   947 				&allow_server_authenticated_provisioning_mode);
       
   948 			if (status == eap_status_ok
       
   949 				&& allow_server_authenticated_provisioning_mode.get_is_valid_data() == true
       
   950 				&& allow_server_authenticated_provisioning_mode.get_data_length() == sizeof(u32_t)
       
   951 				&& allow_server_authenticated_provisioning_mode.get_data(sizeof(u32_t)) != 0)
       
   952 			{
       
   953 				// This is optional value.
       
   954 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   955 					allow_server_authenticated_provisioning_mode.get_data(sizeof(u32_t)));
       
   956 				if (flag != 0)
       
   957 				{
       
   958 					if (*flag == 0)
       
   959 					{
       
   960 						m_fast_allow_server_authenticated_provisioning_mode = false;
       
   961 					}
       
   962 					else
       
   963 					{
       
   964 						m_fast_allow_server_authenticated_provisioning_mode = true;
       
   965 					}
       
   966 				}
       
   967 			}
       
   968 
       
   969 			status = eap_status_ok;
       
   970 		}
       
   971 
       
   972 	}
       
   973 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
   974 
       
   975 	//----------------------------------------------------------
       
   976 
       
   977 	status = message_hash_init();
       
   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 
       
   986 	if (m_application != 0)
       
   987 	{
       
   988 		status = m_application->configure();
       
   989 	}
       
   990 	else
       
   991 	{
       
   992 		status = eap_status_ok;
       
   993 	}
       
   994 
       
   995 	//----------------------------------------------------------
       
   996 
       
   997 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   998 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   999 }
       
  1000 
       
  1001 //--------------------------------------------------
       
  1002 
       
  1003 EAP_FUNC_EXPORT eap_status_e tls_record_c::shutdown()
       
  1004 {
       
  1005 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1006 
       
  1007 	EAP_TRACE_DEBUG(
       
  1008 		m_am_tools,
       
  1009 		TRACE_FLAGS_DEFAULT,
       
  1010 		(EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::shutdown():\n"),
       
  1011 		 this,
       
  1012 		 (m_is_client == true ? "client": "server")));
       
  1013 
       
  1014 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::shutdown()");
       
  1015 
       
  1016 	if (m_shutdown_was_called == true)
       
  1017 	{
       
  1018 		// Shutdown function was called already.
       
  1019 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1020 	}
       
  1021 	m_shutdown_was_called = true;
       
  1022 
       
  1023 	if (m_tls_peap_state != tls_peap_state_tls_success)
       
  1024 	{
       
  1025 		set_state(tls_peap_state_failure);
       
  1026 	}
       
  1027 
       
  1028 	eap_status_e status = eap_status_ok;
       
  1029 
       
  1030 	if (m_application != 0)
       
  1031 	{
       
  1032 		status = m_application->shutdown();
       
  1033 	}
       
  1034 
       
  1035 
       
  1036 	if (m_pending_query_certificate_authorities_and_types == true)
       
  1037 	{
       
  1038 		EAP_TRACE_DEBUG(
       
  1039 			m_am_tools,
       
  1040 			TRACE_FLAGS_DEFAULT,
       
  1041 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_certificate_authorities_and_types()\n")));
       
  1042 
       
  1043 		m_am_tls_services->cancel_query_certificate_authorities_and_types();
       
  1044 		m_pending_query_certificate_authorities_and_types = false;
       
  1045 	}
       
  1046 
       
  1047 	if (m_pending_query_certificate_chain == true)
       
  1048 	{
       
  1049 		EAP_TRACE_DEBUG(
       
  1050 			m_am_tools,
       
  1051 			TRACE_FLAGS_DEFAULT,
       
  1052 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_certificate_chain()\n")));
       
  1053 
       
  1054 		m_am_tls_services->cancel_query_certificate_chain();
       
  1055 		m_pending_query_certificate_chain = false;
       
  1056 	}
       
  1057 
       
  1058 	if (m_pending_query_cipher_suites_and_previous_session == true)
       
  1059 	{
       
  1060 		EAP_TRACE_DEBUG(
       
  1061 			m_am_tools,
       
  1062 			TRACE_FLAGS_DEFAULT,
       
  1063 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_cipher_suites_and_previous_session()\n")));
       
  1064 
       
  1065 		m_am_tls_services->cancel_query_cipher_suites_and_previous_session();
       
  1066 		m_pending_query_cipher_suites_and_previous_session = false;
       
  1067 	}
       
  1068 
       
  1069 	if (m_pending_query_dh_parameters == true)
       
  1070 	{
       
  1071 		EAP_TRACE_DEBUG(
       
  1072 			m_am_tools,
       
  1073 			TRACE_FLAGS_DEFAULT,
       
  1074 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_dh_parameters()\n")));
       
  1075 
       
  1076 		m_am_tls_services->cancel_query_dh_parameters();
       
  1077 		m_pending_query_dh_parameters = false;
       
  1078 	}
       
  1079 
       
  1080 	if (m_pending_query_realm == true)
       
  1081 	{
       
  1082 		EAP_TRACE_DEBUG(
       
  1083 			m_am_tools,
       
  1084 			TRACE_FLAGS_DEFAULT,
       
  1085 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_realm()\n")));
       
  1086 
       
  1087 		m_am_tls_services->cancel_query_realm();
       
  1088 		m_pending_query_realm = false;
       
  1089 	}
       
  1090 
       
  1091 	if (m_pending_select_cipher_suite_and_check_session_id == true)
       
  1092 	{
       
  1093 		EAP_TRACE_DEBUG(
       
  1094 			m_am_tools,
       
  1095 			TRACE_FLAGS_DEFAULT,
       
  1096 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_select_cipher_suite_and_check_session_id()\n")));
       
  1097 
       
  1098 		m_am_tls_services->cancel_select_cipher_suite_and_check_session_id();
       
  1099 		m_pending_select_cipher_suite_and_check_session_id = false;
       
  1100 	}
       
  1101 
       
  1102 	if (m_pending_verify_certificate_chain == true)
       
  1103 	{
       
  1104 		EAP_TRACE_DEBUG(
       
  1105 			m_am_tools,
       
  1106 			TRACE_FLAGS_DEFAULT,
       
  1107 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_verify_certificate_chain()\n")));
       
  1108 
       
  1109 		m_am_tls_services->cancel_verify_certificate_chain();
       
  1110 		m_pending_verify_certificate_chain = false;
       
  1111 	}
       
  1112 
       
  1113 	if (m_pending_rsa_decrypt_with_private_key == true)
       
  1114 	{
       
  1115 		EAP_TRACE_DEBUG(
       
  1116 			m_am_tools,
       
  1117 			TRACE_FLAGS_DEFAULT,
       
  1118 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_rsa_decrypt_with_private_key()\n")));
       
  1119 
       
  1120 		m_am_tls_services->cancel_rsa_decrypt_with_private_key();
       
  1121 		m_pending_rsa_decrypt_with_private_key = false;
       
  1122 	}
       
  1123 
       
  1124 	if (m_pending_rsa_encrypt_with_public_key == true)
       
  1125 	{
       
  1126 		EAP_TRACE_DEBUG(
       
  1127 			m_am_tools,
       
  1128 			TRACE_FLAGS_DEFAULT,
       
  1129 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_rsa_encrypt_with_public_key()\n")));
       
  1130 
       
  1131 		m_am_tls_services->cancel_rsa_encrypt_with_public_key();
       
  1132 		m_pending_rsa_encrypt_with_public_key = false;
       
  1133 	}
       
  1134 
       
  1135 	if (m_pending_sign_with_private_key == true)
       
  1136 	{
       
  1137 		EAP_TRACE_DEBUG(
       
  1138 			m_am_tools,
       
  1139 			TRACE_FLAGS_DEFAULT,
       
  1140 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_sign_with_private_key()\n")));
       
  1141 
       
  1142 		m_am_tls_services->cancel_sign_with_private_key();
       
  1143 		m_pending_sign_with_private_key = false;
       
  1144 	}
       
  1145 
       
  1146 	if (m_pending_verify_with_public_key == true)
       
  1147 	{
       
  1148 		EAP_TRACE_DEBUG(
       
  1149 			m_am_tools,
       
  1150 			TRACE_FLAGS_DEFAULT,
       
  1151 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_verify_with_public_key()\n")));
       
  1152 
       
  1153 		m_am_tls_services->cancel_verify_with_public_key();
       
  1154 		m_pending_verify_with_public_key = false;
       
  1155 	}
       
  1156 
       
  1157 	if (m_pending_query_tunnel_PAC == true)
       
  1158 	{
       
  1159 		EAP_TRACE_DEBUG(
       
  1160 			m_am_tools,
       
  1161 			TRACE_FLAGS_DEFAULT,
       
  1162 			(EAPL("TLS: function: tls_record_c::shutdown(): calls cancel_query_tunnel_PAC()\n")));
       
  1163 
       
  1164 		if (m_application != 0)
       
  1165 		{
       
  1166 			m_application->cancel_query_tunnel_PAC();
       
  1167 		}
       
  1168 		m_pending_query_tunnel_PAC = false;
       
  1169 	}
       
  1170 
       
  1171 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1172 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1173 }
       
  1174 
       
  1175 //--------------------------------------------------
       
  1176 
       
  1177 EAP_FUNC_EXPORT eap_status_e tls_record_c::set_nai_realm(
       
  1178 	const eap_variable_data_c * const NAI_realm)
       
  1179 {
       
  1180 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1181 
       
  1182 	eap_status_e status = m_NAI_realm.set_copy_of_buffer(NAI_realm);
       
  1183 
       
  1184 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1185 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1186 }
       
  1187 
       
  1188 //--------------------------------------------------
       
  1189 
       
  1190 void tls_record_c::send_error_notification(const eap_status_e error)
       
  1191 {
       
  1192 	// Notifies the lower level of an authentication error.
       
  1193 
       
  1194 	eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error);
       
  1195 
       
  1196 	if (error == eap_status_user_cancel_authentication)
       
  1197 	{
       
  1198 		general_state_variable = eap_general_state_authentication_cancelled;
       
  1199 	}
       
  1200 
       
  1201 	eap_state_notification_c notification(
       
  1202 		m_am_tools,
       
  1203 		&m_send_network_id,
       
  1204 		true,
       
  1205 		eap_state_notification_eap,
       
  1206 		eap_protocol_layer_general,
       
  1207 		m_eap_type,
       
  1208 		eap_state_none,
       
  1209 		general_state_variable,
       
  1210 		0,
       
  1211 		false);
       
  1212 
       
  1213 	notification.set_authentication_error(error);
       
  1214 
       
  1215 	get_type_partner()->state_notification(&notification);
       
  1216 }
       
  1217 
       
  1218 //--------------------------------------------------
       
  1219 
       
  1220 //
       
  1221 EAP_FUNC_EXPORT eap_status_e tls_record_c::completion_action_add(
       
  1222 	tls_completion_action_e action)
       
  1223 {
       
  1224 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1225 
       
  1226 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  1227 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1228 					(EAPL("TLS: %s: send_function: completion_action_add()\n"),
       
  1229 					 (m_is_client == true ? "client": "server")));
       
  1230 
       
  1231 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::completion_action_add()");
       
  1232 
       
  1233 	tls_completion_c *completion_action = new tls_completion_c(
       
  1234 		m_am_tools,
       
  1235 		action);
       
  1236 
       
  1237 	if (completion_action == 0
       
  1238 		|| completion_action->get_is_valid() == false)
       
  1239 	{
       
  1240 		delete completion_action;
       
  1241 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1242 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1243 	}
       
  1244 
       
  1245 	// add_object() will delete completion_action if operation fails.
       
  1246 	eap_status_e status = m_completion_queue.add_object(completion_action, true);
       
  1247 
       
  1248 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1249 					(EAPL("TLS: %s: send_function: completion_action_add(): action %s\n"),
       
  1250 					 (m_is_client == true ? "client": "server"),
       
  1251 					 completion_action->get_completion_action_string()));
       
  1252 
       
  1253 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1254 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1255 }
       
  1256 
       
  1257 //--------------------------------------------------
       
  1258 
       
  1259 //
       
  1260 EAP_FUNC_EXPORT eap_status_e tls_record_c::completion_action_clenup()
       
  1261 {
       
  1262 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1263 
       
  1264 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  1265 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1266 					(EAPL("TLS: %s: send_function: starts: tls_record_c::completion_action_clenup()\n"),
       
  1267 					 (m_is_client == true ? "client": "server")));
       
  1268 
       
  1269 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::completion_action_clenup()");
       
  1270 
       
  1271 	eap_status_e final_status = eap_status_ok;
       
  1272 	u32_t counter = 0ul;
       
  1273 
       
  1274 	while(m_completion_queue.get_object_count() > 0ul)
       
  1275 	{
       
  1276 		tls_completion_c * const completion_action = m_completion_queue.get_object(0ul);
       
  1277 		EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace.
       
  1278 
       
  1279 		EAP_TRACE_DEBUG(
       
  1280 			m_am_tools,
       
  1281 			TRACE_FLAGS_DEFAULT,
       
  1282 			(EAPL("ERROR: TLS: %s: send_function: completion_action_clenup(): ")
       
  1283 			 EAPL("action[%u] %s not completed.\n"),
       
  1284 			 (m_is_client == true ? "client": "server"),
       
  1285 			 counter,
       
  1286 			 completion_action->get_completion_action_string()));
       
  1287 
       
  1288 		final_status = m_completion_queue.remove_object(0ul);
       
  1289 		if (final_status != eap_status_ok)
       
  1290 		{
       
  1291 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1292 			return EAP_STATUS_RETURN(m_am_tools, final_status);
       
  1293 		}
       
  1294 
       
  1295 		++counter;
       
  1296 
       
  1297 	} // while()
       
  1298 
       
  1299 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1300 	return EAP_STATUS_RETURN(m_am_tools, final_status);
       
  1301 }
       
  1302 
       
  1303 //--------------------------------------------------
       
  1304 
       
  1305 //
       
  1306 EAP_FUNC_EXPORT eap_status_e tls_record_c::completion_action_check()
       
  1307 {
       
  1308 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1309 
       
  1310 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  1311 	EAP_TRACE_DEBUG(
       
  1312 		m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1313 		(EAPL("TLS: %s: send_function: starts: tls_record_c::completion_action_check()\n"),
       
  1314 		(m_is_client == true ? "client": "server")));
       
  1315 
       
  1316 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::completion_action_check()");
       
  1317 
       
  1318 	if (m_already_in_completion_action_check == true)
       
  1319 	{
       
  1320 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1321 		// This is recursive call of completion_action_check().
       
  1322 		// This MUST return eap_status_ok. Other return values will skip
       
  1323 		// further prosessing of completion action list.
       
  1324 		EAP_TRACE_DEBUG(
       
  1325 			m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1326 			(EAPL("TLS: %s: send_function: completion_action_check(): skip recursion\n"),
       
  1327 			(m_is_client == true ? "client": "server")));
       
  1328 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1329 	}
       
  1330 	m_already_in_completion_action_check = true;
       
  1331 
       
  1332 	eap_automatic_simple_value_c<bool> restore_already_in_completion_action_check(
       
  1333 		m_am_tools,
       
  1334 		&m_already_in_completion_action_check,
       
  1335 		false);
       
  1336 
       
  1337 	eap_status_e status = eap_status_ok;
       
  1338 	bool continue_with_next_action = true;
       
  1339 	u32_t counter = 0ul;
       
  1340 
       
  1341 	while(continue_with_next_action == true
       
  1342 		&& m_completion_queue.get_object_count() > 0ul)
       
  1343 	{
       
  1344 		status = eap_status_ok;
       
  1345 
       
  1346 		tls_completion_c * const completion_action = m_completion_queue.get_object(0ul);
       
  1347 
       
  1348 		EAP_TRACE_DEBUG(
       
  1349 			m_am_tools,
       
  1350 			TRACE_FLAGS_DEFAULT,
       
  1351 			(EAPL("TLS: %s: send_function: completion_action_check(): action[%d] %s\n"),
       
  1352 			 (m_is_client == true ? "client": "server"),
       
  1353 			 counter,
       
  1354 			 completion_action->get_completion_action_string()));
       
  1355 
       
  1356 		switch(completion_action->get_completion_action())
       
  1357 		{
       
  1358 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  1359 		case tls_completion_action_create_handshake_type_hello_request:
       
  1360 		{
       
  1361 			// We must send Handshake/HelloRequest message.
       
  1362 			eap_status_e status = create_handshake_type_hello_request();
       
  1363 			if (status != eap_status_ok)
       
  1364 			{
       
  1365 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1366 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1367 			}
       
  1368 			break;
       
  1369 		}
       
  1370 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  1371 		case tls_completion_action_query_cipher_suites_and_previous_session:
       
  1372 		{
       
  1373 			m_allow_message_send = false;
       
  1374 
       
  1375 			status = m_am_tls_services->query_cipher_suites_and_previous_session();
       
  1376 
       
  1377 			m_allow_message_send = true;
       
  1378 
       
  1379 			if (status == eap_status_pending_request)
       
  1380 			{
       
  1381 				// This is pending query, that will be completed by
       
  1382 				// complete_query_cipher_suites_and_previous_session() call.
       
  1383 				m_pending_query_cipher_suites_and_previous_session = true;
       
  1384 
       
  1385 				// Cannot complete yet.
       
  1386 				continue_with_next_action = false;
       
  1387 			}
       
  1388 
       
  1389 			break;
       
  1390 		}
       
  1391 		case tls_completion_action_create_handshake_type_client_hello:
       
  1392 		{
       
  1393 			if (m_pending_query_cipher_suites_and_previous_session == false
       
  1394 				&& m_proposed_cipher_suites.get_object_count() > 0ul
       
  1395 				&& m_proposed_compression_methods.get_object_count() > 0ul)
       
  1396 			{
       
  1397 				// We must send Handshake/ClientHello message.
       
  1398 				eap_status_e status = create_handshake_type_client_hello();
       
  1399 				if (status != eap_status_ok)
       
  1400 				{
       
  1401 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1402 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1403 				}
       
  1404 			}
       
  1405 			else
       
  1406 			{
       
  1407 				// Cannot complete yet.
       
  1408 				continue_with_next_action = false;
       
  1409 			}
       
  1410 			break;
       
  1411 		}
       
  1412 		case tls_completion_action_create_handshake_type_server_hello:
       
  1413 		{
       
  1414 			if (m_pending_select_cipher_suite_and_check_session_id == false
       
  1415 				&& m_selected_cipher_suite != tls_cipher_suites_none
       
  1416 				&& m_selected_compression_method != tls_compression_method_none)
       
  1417 			{
       
  1418 				// We must send Handshake/ServerHello message.
       
  1419 				eap_status_e status = create_handshake_type_server_hello(
       
  1420 					static_cast<u8_t>(m_selected_cipher_suite),
       
  1421 					static_cast<u8_t>(m_selected_compression_method));
       
  1422 				if (status != eap_status_ok)
       
  1423 				{
       
  1424 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1425 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1426 				}
       
  1427 			}
       
  1428 			else
       
  1429 			{
       
  1430 				// Cannot complete yet.
       
  1431 				continue_with_next_action = false;
       
  1432 			}
       
  1433 			break;
       
  1434 		}
       
  1435 		case tls_completion_action_create_handshake_type_certificate:
       
  1436 		{
       
  1437 			if (m_pending_query_certificate_chain == false
       
  1438 				&& m_pending_verify_certificate_chain == false)
       
  1439 			{
       
  1440 				// We must send Handshake/Certificate message.
       
  1441 				// NOTE m_own_certificate_chain could be empty.
       
  1442 				status = create_handshake_type_certificate(&m_own_certificate_chain);
       
  1443 				if (status != eap_status_ok)
       
  1444 				{
       
  1445 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1446 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1447 				}
       
  1448 			}
       
  1449 			else
       
  1450 			{
       
  1451 				// Cannot complete yet.
       
  1452 				continue_with_next_action = false;
       
  1453 			}
       
  1454 			break;
       
  1455 		}
       
  1456 		case tls_completion_action_create_handshake_type_server_key_exchange:
       
  1457 		{
       
  1458 			if (m_pending_query_dh_parameters == false)
       
  1459 			{
       
  1460 				if ((cipher_suite_is_TLS_DHE_DSS() == true
       
  1461 					|| cipher_suite_is_TLS_DHE_RSA() == true
       
  1462 #if defined(USE_FAST_EAP_TYPE)
       
  1463 					|| (m_eap_type == eap_type_fast
       
  1464 						&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  1465 						&& cipher_suite_is_TLS_DH_anon() == true)
       
  1466 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  1467 					)
       
  1468 					&& m_dhe_prime.get_is_valid_data() == true
       
  1469 					&& m_dhe_group_generator.get_is_valid_data() == true)
       
  1470 				{
       
  1471 					status = generate_dhe_keys();
       
  1472 					if (status != eap_status_ok)
       
  1473 					{
       
  1474 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1475 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1476 					}
       
  1477 
       
  1478 					// We must send Handshake/ServerKeyExchange.
       
  1479 					status = create_handshake_type_server_key_exchange();
       
  1480 					if (status == eap_status_pending_request)
       
  1481 					{
       
  1482 						// This is pending query, that will be completed by 
       
  1483 						// complete_create_handshake_type_server_key_exchange() call.
       
  1484 					}
       
  1485 					else if (status == eap_status_completed_request)
       
  1486 					{
       
  1487 						// This is already completed by
       
  1488 						// complete_create_handshake_type_server_key_exchange() call.
       
  1489 						status = eap_status_ok;
       
  1490 					}
       
  1491 					else if (status == eap_status_ok)
       
  1492 					{
       
  1493 						// This is also an error case, because this call
       
  1494 						// is always completed on success.
       
  1495 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1496 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1497 							m_am_tools,
       
  1498 							eap_status_process_general_error);
       
  1499 					}
       
  1500 					else // All other status values means error, because this
       
  1501 						// call is always completed on success.
       
  1502 					{
       
  1503 						// This is an error case.
       
  1504 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1505 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1506 					}
       
  1507 				}
       
  1508 				else
       
  1509 				{
       
  1510 					// Cannot complete yet.
       
  1511 					continue_with_next_action = false;
       
  1512 				}
       
  1513 			}
       
  1514 			else
       
  1515 			{
       
  1516 				// Cannot complete yet.
       
  1517 				continue_with_next_action = false;
       
  1518 			}
       
  1519 			break;
       
  1520 		}
       
  1521 		case tls_completion_action_create_handshake_type_certificate_request:
       
  1522 		{
       
  1523 			if (m_pending_query_certificate_authorities_and_types == false
       
  1524 				&& m_own_certificate_types.get_object_count() != 0ul
       
  1525 				&& (m_own_certificate_authorities.get_object_count() != 0ul
       
  1526 					|| m_server_sends_empty_certificate_authorities_list == false))
       
  1527 			{
       
  1528 				// We must send Handshake/CertificateRequest message.
       
  1529 				status = create_handshake_type_certificate_request(
       
  1530 					&m_own_certificate_types,
       
  1531 					&m_own_certificate_authorities);
       
  1532 				if (status != eap_status_ok)
       
  1533 				{
       
  1534 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1535 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1536 				}
       
  1537 			}
       
  1538 			else
       
  1539 			{
       
  1540 				// Cannot complete yet.
       
  1541 				continue_with_next_action = false;
       
  1542 			}
       
  1543 			break;
       
  1544 		}
       
  1545 		case tls_completion_action_create_handshake_type_server_hello_done:
       
  1546 		{
       
  1547 			status = create_handshake_type_server_hello_done();
       
  1548 			if (status != eap_status_ok)
       
  1549 			{
       
  1550 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1551 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1552 			}
       
  1553 
       
  1554 			break;
       
  1555 		}
       
  1556 		case tls_completion_action_create_handshake_type_certificate_verify:
       
  1557 		{
       
  1558 			if (m_pending_query_certificate_chain == false
       
  1559 				&& m_pending_verify_certificate_chain == false
       
  1560 				&& m_own_certificate_chain.get_object_count() > 0ul)
       
  1561 			{
       
  1562 				// We must send Handshake/CertificateVerify.
       
  1563 				status = create_handshake_type_certificate_verify();
       
  1564 				if (status == eap_status_pending_request)
       
  1565 				{
       
  1566 					// This is pending query, that will be completed by
       
  1567 					// complete_create_handshake_type_certificate_verify() call.
       
  1568 				}
       
  1569 				else if (status == eap_status_completed_request)
       
  1570 				{
       
  1571 					// This is already completed by
       
  1572 					// complete_create_handshake_type_certificate_verify() call.
       
  1573 					status = eap_status_ok;
       
  1574 				}
       
  1575 				else if (status == eap_status_ok)
       
  1576 				{
       
  1577 					// This is also an error case, because this
       
  1578 					// call is always completed on success. 
       
  1579 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1580 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1581 						m_am_tools,
       
  1582 						eap_status_process_general_error);
       
  1583 				}
       
  1584 				else // All other status values means error, because this
       
  1585 					// call is always completed on success.
       
  1586 				{
       
  1587 					// This is an error case.
       
  1588 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1589 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1590 				}
       
  1591 			}
       
  1592 			else if (m_pending_query_certificate_chain == false
       
  1593 				&& m_pending_verify_certificate_chain == false
       
  1594 				&& m_own_certificate_chain.get_object_count() == 0ul)
       
  1595 			{
       
  1596 				// No user certificate.
       
  1597 			}
       
  1598 			else
       
  1599 			{
       
  1600 				// Cannot complete yet.
       
  1601 				continue_with_next_action = false;
       
  1602 			}
       
  1603 			break;
       
  1604 		}
       
  1605 		case tls_completion_action_create_handshake_type_client_key_exchange:
       
  1606 		{
       
  1607 			if (m_pending_query_certificate_chain == false
       
  1608 				&& m_pending_verify_certificate_chain == false)
       
  1609 			{
       
  1610 				if (cipher_suite_is_TLS_DHE_DSS() == true
       
  1611 					|| cipher_suite_is_TLS_DHE_RSA() == true
       
  1612 #if defined(USE_FAST_EAP_TYPE)
       
  1613 					|| (m_eap_type == eap_type_fast
       
  1614 						&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  1615 						&& cipher_suite_is_TLS_DH_anon() == true)
       
  1616 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  1617 					)
       
  1618 				{
       
  1619 					// DHE parameters should have been received in ServerKeyExchange message.
       
  1620 
       
  1621 					if (m_dhe_prime.get_is_valid_data() == true
       
  1622 						&& m_dhe_group_generator.get_is_valid_data() == true)
       
  1623 					{
       
  1624 						status = generate_dhe_keys();
       
  1625 						if (status != eap_status_ok)
       
  1626 						{
       
  1627 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1628 							return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1629 								m_am_tools,
       
  1630 								status);
       
  1631 						}
       
  1632 					}
       
  1633 					else
       
  1634 					{
       
  1635 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1636 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1637 							m_am_tools,
       
  1638 							eap_status_authentication_failure);
       
  1639 					}
       
  1640 				}
       
  1641 				else if (cipher_suite_is_TLS_RSA() == true)
       
  1642 				{
       
  1643 					// Do nothing special.
       
  1644 				}
       
  1645 				else
       
  1646 				{
       
  1647 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1648 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1649 						m_am_tools,
       
  1650 						eap_status_not_supported);
       
  1651 				}
       
  1652 			
       
  1653 				// We must generate premaster secret.
       
  1654 				status = generate_premaster_secret();
       
  1655 				if (status != eap_status_ok)
       
  1656 				{
       
  1657 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1658 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1659 				}
       
  1660 				
       
  1661 				// We must generate master secret.
       
  1662 				status = generate_master_secret();
       
  1663 				if (status != eap_status_ok)
       
  1664 				{
       
  1665 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1666 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1667 				}
       
  1668 				
       
  1669 				// We must generate the key material.
       
  1670 				status = generate_key_material();
       
  1671 				if (status != eap_status_ok)
       
  1672 				{
       
  1673 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1674 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1675 				}
       
  1676 
       
  1677 				// We must send Handshake/ClientKeyExchange.
       
  1678 				status = create_handshake_type_client_key_exchange();
       
  1679 				if (status == eap_status_pending_request)
       
  1680 				{
       
  1681 					// This is pending query, that will be completed by
       
  1682 					// complete_create_handshake_type_client_key_exchange() call.
       
  1683 					// Cannot complete yet.
       
  1684 					continue_with_next_action = false;
       
  1685 				}
       
  1686 				else if (status == eap_status_completed_request)
       
  1687 				{
       
  1688 					// This is already completed by
       
  1689 					// complete_create_handshake_type_client_key_exchange() call.
       
  1690 					status = eap_status_ok;
       
  1691 				}
       
  1692 				else if (status == eap_status_ok)
       
  1693 				{
       
  1694 					// NOTE: This is not always an error case. 
       
  1695 					if (cipher_suite_is_TLS_DHE_DSS() == true
       
  1696 						|| cipher_suite_is_TLS_DHE_RSA() == true
       
  1697 #if defined(USE_FAST_EAP_TYPE)
       
  1698 						|| (m_eap_type == eap_type_fast
       
  1699 							&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  1700 							&& cipher_suite_is_TLS_DH_anon() == true)
       
  1701 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  1702 						)
       
  1703 					{
       
  1704 						// Cipher suites cipher_suite_is_TLS_DHE_DSS()
       
  1705 						// and cipher_suite_is_TLS_DHE_RSA() are syncronous.
       
  1706 						// Do nothing special.
       
  1707 					}
       
  1708 					else if (cipher_suite_is_TLS_RSA() == true)
       
  1709 					{
       
  1710 						// Cipher suites cipher_suite_is_TLS_RSA() are asyncronous
       
  1711 						// and they must NOT return eap_status_ok.
       
  1712 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1713 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1714 							m_am_tools,
       
  1715 							eap_status_process_general_error);
       
  1716 					}
       
  1717 					else
       
  1718 					{
       
  1719 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1720 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1721 							m_am_tools,
       
  1722 							eap_status_not_supported);
       
  1723 					}
       
  1724 				}
       
  1725 				else // All other status values means error, because this
       
  1726 					// call is always completed on success.
       
  1727 				{
       
  1728 					// This is an error case.
       
  1729 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1730 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1731 				}
       
  1732 			}
       
  1733 			else
       
  1734 			{
       
  1735 				// Cannot complete yet.
       
  1736 				continue_with_next_action = false;
       
  1737 			}
       
  1738 			break;
       
  1739 		}
       
  1740 		case tls_completion_action_create_handshake_type_finished:
       
  1741 		{
       
  1742 			// We must send Handshake/Finished.
       
  1743 			status = create_handshake_type_finished();
       
  1744 			if (status != eap_status_ok)
       
  1745 			{
       
  1746 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1747 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1748 			}
       
  1749 			break;
       
  1750 		}
       
  1751 		case tls_completion_action_finish_handshake:
       
  1752 		{
       
  1753 			// We must finish the handshake.
       
  1754 			status = finish_handshake();
       
  1755 			if (status != eap_status_ok)
       
  1756 			{
       
  1757 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1758 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1759 			}
       
  1760 			break;
       
  1761 		}
       
  1762 		case tls_completion_action_create_change_cipher_spec_type_change_cipher_spec:
       
  1763 		{
       
  1764 			// We must send ChangeCipherSpec/ChangeCipherSpec.
       
  1765 			status = create_change_cipher_spec_type_change_cipher_spec();
       
  1766 			if (status != eap_status_ok)
       
  1767 			{
       
  1768 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1769 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1770 			}
       
  1771 			break;
       
  1772 		}
       
  1773 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  1774 		case tls_completion_action_create_handshake_type_new_session_ticket:
       
  1775 		{
       
  1776 			// We must send Hanshake/NewSessionTicket.
       
  1777 			status = create_handshake_type_new_session_ticket();
       
  1778 			if (status != eap_status_ok)
       
  1779 			{
       
  1780 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1781 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1782 			}
       
  1783 			break;
       
  1784 		}
       
  1785 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  1786 		case tls_completion_action_query_dh_parameters:
       
  1787 		{
       
  1788 			if (m_selected_cipher_suite != tls_cipher_suites_none)
       
  1789 			{
       
  1790 				EAP_TRACE_DEBUG(
       
  1791 					m_am_tools,
       
  1792 					TRACE_FLAGS_DEFAULT,
       
  1793 					(EAPL("TLS: %s: pki_function: query_dh_parameters()\n"),
       
  1794 					 (m_is_client == true ? "client": "server")));
       
  1795 				// Note, server does not query DH parametrs from certificate chain,
       
  1796 				// instead server should consult it's configuration settings.
       
  1797 				status = m_am_tls_services->query_dh_parameters(0, m_selected_cipher_suite);
       
  1798 				if (status == eap_status_pending_request)
       
  1799 				{
       
  1800 					// This is pending query, that will be completed
       
  1801 					// by complete_query_dh_parameters() call.
       
  1802 					m_pending_query_dh_parameters = true;
       
  1803 				}
       
  1804 				else if (status == eap_status_completed_request)
       
  1805 				{
       
  1806 					// This is already completed by complete_query_dh_parameters() call.
       
  1807 					status = eap_status_ok;
       
  1808 				}
       
  1809 				else if (status == eap_status_ok)
       
  1810 				{
       
  1811 					// This is also an error case, because this call
       
  1812 					// is always completed on success. 
       
  1813 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1814 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1815 						m_am_tools,
       
  1816 						eap_status_process_general_error);
       
  1817 				}
       
  1818 				else // All other status values means error, because this
       
  1819 					// call is always completed on success.
       
  1820 				{
       
  1821 					// This is an error case.
       
  1822 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1823 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1824 				}
       
  1825 			}
       
  1826 			else
       
  1827 			{
       
  1828 				// Cannot complete yet.
       
  1829 				continue_with_next_action = false;
       
  1830 			}
       
  1831 			break;
       
  1832 		}
       
  1833 		case tls_completion_action_process_tls_records:
       
  1834 		{
       
  1835 			if (are_pending_queries_completed() == eap_status_ok)
       
  1836 			{
       
  1837 				status = process_tls_records();
       
  1838 				if (status == eap_status_ok)
       
  1839 				{
       
  1840 					// All pending messages processed.
       
  1841 					// Do nothing special.
       
  1842 				}
       
  1843 				else if (status == eap_status_end_recursion)
       
  1844 				{
       
  1845 					// Break recursion.
       
  1846 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1847 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, eap_status_ok);
       
  1848 				}
       
  1849 				else if (status == eap_status_pending_request)
       
  1850 				{
       
  1851 					// Cannot complete yet.
       
  1852 					continue_with_next_action = false;
       
  1853 				}
       
  1854 				else 
       
  1855 				{
       
  1856 					// This is an error case.
       
  1857 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1858 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1859 				}
       
  1860 
       
  1861 				if ((get_is_tunneled_tls() == false
       
  1862 						&& m_tls_peap_state == tls_peap_state_tls_success)
       
  1863 					|| (get_is_tunneled_tls() == true
       
  1864 						&& m_tls_peap_state == tls_peap_state_peap_tunnel_ready))
       
  1865 				{
       
  1866 					// TLS authentication OK.
       
  1867 					// Note PEAP may continue.
       
  1868 					EAP_TRACE_DEBUG(
       
  1869 						m_am_tools,
       
  1870 						TRACE_FLAGS_DEFAULT,
       
  1871 						(EAPL("TLS: %s: process_tls_records() returned, ")
       
  1872 						 EAPL("TLS authentication successfull.\n"),
       
  1873 						 (m_is_client == true ? "client": "server")));
       
  1874 				}
       
  1875 			}
       
  1876 			else
       
  1877 			{
       
  1878 				// Cannot complete yet.
       
  1879 				continue_with_next_action = false;
       
  1880 			}
       
  1881 			break;
       
  1882 		}
       
  1883 		case tls_completion_action_complete_create_handshake_type_server_key_exchange:
       
  1884 		{
       
  1885 			if (m_signed_message_hash.get_is_valid_data() == true
       
  1886 #if defined(USE_FAST_EAP_TYPE)
       
  1887 				|| (m_eap_type == eap_type_fast
       
  1888 					&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  1889 					&& cipher_suite_is_TLS_DH_anon() == true)
       
  1890 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  1891 				)
       
  1892 			{
       
  1893 				status = complete_create_handshake_type_server_key_exchange();
       
  1894 				if (status != eap_status_ok)
       
  1895 				{
       
  1896 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1897 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1898 				}
       
  1899 			}
       
  1900 			else
       
  1901 			{
       
  1902 				// Cannot complete yet.
       
  1903 				continue_with_next_action = false;
       
  1904 			}
       
  1905 			break;
       
  1906 		}
       
  1907 		case tls_completion_action_complete_create_handshake_type_certificate_verify:
       
  1908 		{
       
  1909 			if (m_signed_message_hash.get_is_valid_data() == true
       
  1910 				&& m_own_certificate_chain.get_object_count() > 0ul)
       
  1911 			{
       
  1912 				status = complete_create_handshake_type_certificate_verify();
       
  1913 				if (status != eap_status_ok)
       
  1914 				{
       
  1915 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1916 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1917 				}
       
  1918 			}
       
  1919 			else if (m_own_certificate_chain.get_object_count() == 0ul)
       
  1920 			{
       
  1921 				// No user certificate.
       
  1922 			}
       
  1923 			else
       
  1924 			{
       
  1925 				// Cannot complete yet.
       
  1926 				continue_with_next_action = false;
       
  1927 			}
       
  1928 			break;
       
  1929 		}
       
  1930 		case tls_completion_action_complete_create_handshake_type_client_key_exchange:
       
  1931 		{
       
  1932 			if (cipher_suite_is_TLS_RSA() == true
       
  1933 					&& m_own_encrypted_premaster_secret.get_is_valid_data() == true
       
  1934 				|| ((cipher_suite_is_TLS_DHE_DSS() == true
       
  1935 						|| cipher_suite_is_TLS_DHE_RSA() == true
       
  1936 #if defined(USE_FAST_EAP_TYPE)
       
  1937 						|| (m_eap_type == eap_type_fast
       
  1938 							&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  1939 							&& cipher_suite_is_TLS_DH_anon() == true)
       
  1940 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  1941 						)
       
  1942 					&& m_own_encrypted_premaster_secret.get_is_valid_data() == false))
       
  1943 			{
       
  1944 				status = complete_create_handshake_type_client_key_exchange();
       
  1945 				if (status != eap_status_ok)
       
  1946 				{
       
  1947 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1948 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  1949 				}
       
  1950 			}
       
  1951 			else
       
  1952 			{
       
  1953 				// Cannot complete yet.
       
  1954 				continue_with_next_action = false;
       
  1955 			}
       
  1956 			break;
       
  1957 		}
       
  1958 		case tls_completion_action_verify_certificate_chain:
       
  1959 		{
       
  1960 			if (m_peer_certificate_chain.get_object_count() != 0ul
       
  1961 				&& m_selected_cipher_suite != tls_cipher_suites_none
       
  1962 				&& m_pending_query_certificate_chain == false
       
  1963 				&& m_pending_verify_certificate_chain == false)
       
  1964 			{
       
  1965 				EAP_TRACE_DEBUG(
       
  1966 					m_am_tools,
       
  1967 					TRACE_FLAGS_DEFAULT,
       
  1968 					(EAPL("TLS: %s: pki_function: verify_certificate_chain()\n"),
       
  1969 					 (m_is_client == true ? "client": "server")));
       
  1970 
       
  1971 				status = m_am_tls_services->verify_certificate_chain(
       
  1972 					&m_peer_certificate_chain,
       
  1973 					m_selected_cipher_suite);
       
  1974 				if (status == eap_status_pending_request)
       
  1975 				{
       
  1976 					// This is pending query, that will be completed
       
  1977 					// by complete_verify_certificate_chain() call.
       
  1978 					m_pending_verify_certificate_chain = true;
       
  1979 				}
       
  1980 				else if (status == eap_status_completed_request)
       
  1981 				{
       
  1982 					// This is already completed by complete_verify_certificate_chain() call.
       
  1983 					status = eap_status_ok;
       
  1984 				}
       
  1985 				else if (status == eap_status_ok)
       
  1986 				{
       
  1987 					// This is also an error case, because this call is
       
  1988 					// always completed on success. 
       
  1989 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1990 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  1991 						m_am_tools,
       
  1992 						eap_status_process_general_error);
       
  1993 				}
       
  1994 				else // All other status values means error, because this
       
  1995 					// call is always completed on success.
       
  1996 				{
       
  1997 					// This is an error case.
       
  1998 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1999 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  2000 				}
       
  2001 			}
       
  2002 			else
       
  2003 			{
       
  2004 				// Cannot complete yet.
       
  2005 				continue_with_next_action = false;
       
  2006 			}
       
  2007 			break;
       
  2008 		}
       
  2009 		case tls_completion_action_check_sent_tls_message:
       
  2010 		{
       
  2011 			// Note this call will return eap_status_pending_request if any asyncronous call is pending.
       
  2012 			status = check_sent_tls_message();
       
  2013 			break;
       
  2014 		}
       
  2015 		case tls_completion_action_check_tunnel_authentication_runs:
       
  2016 		{
       
  2017 			// Check we get some tunneled authentication message and tunneled authentication runs or it did finished.
       
  2018 			if (m_tunneled_eap_type_authentication_state == eap_state_none)
       
  2019 			{
       
  2020 				// Here we swap the addresses.
       
  2021 				eap_am_network_id_c receive_network_id(m_am_tools,
       
  2022 					m_send_network_id.get_destination_id(),
       
  2023 					m_send_network_id.get_source_id(),
       
  2024 					m_send_network_id.get_type());
       
  2025 
       
  2026 				status = start_peap_tunneled_authentication(
       
  2027 					&receive_network_id,
       
  2028 					m_received_eap_identifier,
       
  2029 					m_tls_session_type);
       
  2030 				if (status != eap_status_ok)
       
  2031 				{
       
  2032 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2033 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  2034 				}
       
  2035 			}
       
  2036 			break;
       
  2037 		}
       
  2038 		default:
       
  2039 		{
       
  2040 			EAP_TRACE_ERROR(
       
  2041 				m_am_tools,
       
  2042 				TRACE_FLAGS_DEFAULT,
       
  2043 				(EAPL("ERROR TLS: %s: send_function: completion_action_check(): ")
       
  2044 				 EAPL("unhandled action[%u] %s.\n"),
       
  2045 				 (m_is_client == true ? "client": "server"),
       
  2046 				 counter,
       
  2047 				 completion_action->get_completion_action_string()));
       
  2048 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  2049 				m_am_tools,
       
  2050 				eap_status_not_supported);
       
  2051 		}
       
  2052 		} // switch()
       
  2053 
       
  2054 		if (continue_with_next_action == true
       
  2055 			|| status == eap_status_pending_request)
       
  2056 		{
       
  2057 			const tls_completion_c * const removed_completion_action = m_completion_queue.get_object(0ul);
       
  2058 			EAP_UNREFERENCED_PARAMETER(removed_completion_action); // Not referenced without trace.
       
  2059 			EAP_TRACE_DEBUG(
       
  2060 				m_am_tools,
       
  2061 				TRACE_FLAGS_DEFAULT,
       
  2062 				(EAPL("TLS: %s: encrypt_function: starts: tls_record_c::completion_action_check(): removes action[%d] %s\n"),
       
  2063 				(m_is_client == true ? "client": "server"),
       
  2064 				0ul,
       
  2065 				removed_completion_action->get_completion_action_string()));
       
  2066 
       
  2067 			eap_status_e remove_status = m_completion_queue.remove_object(0ul);
       
  2068 			if (remove_status != eap_status_ok)
       
  2069 			{
       
  2070 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2071 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  2072 			}
       
  2073 		}
       
  2074 
       
  2075 		++counter;
       
  2076 
       
  2077 	} // while()
       
  2078 
       
  2079 	if (continue_with_next_action == false)
       
  2080 	{
       
  2081 		status = eap_status_pending_request;
       
  2082 	}
       
  2083 
       
  2084 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2085 	return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  2086 }
       
  2087 
       
  2088 //--------------------------------------------------
       
  2089 
       
  2090 //
       
  2091 EAP_FUNC_EXPORT u8_t tls_record_c::get_extra_padding_length(
       
  2092 	const u8_t padding_length,
       
  2093 	const u32_t block_size)
       
  2094 {
       
  2095 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2096 
       
  2097 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  2098 	EAP_TRACE_DEBUG(
       
  2099 		m_am_tools,
       
  2100 		TRACE_FLAGS_DEFAULT,
       
  2101 		(EAPL("TLS: %s: encrypt_function: starts: tls_record_c::get_extra_padding_length()\n"),
       
  2102 		(m_is_client == true ? "client": "server")));
       
  2103 
       
  2104 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_extra_padding_length()");
       
  2105 
       
  2106 	crypto_random_c rand(m_am_tools);
       
  2107 
       
  2108 	u8_t count = 0ul;
       
  2109 
       
  2110 	if (m_use_extra_padding_length == true)
       
  2111 	{
       
  2112 		eap_status_e status = rand.get_rand_bytes(&count, sizeof(count));
       
  2113 		if (status != eap_status_ok)
       
  2114 		{
       
  2115 			count = 3ul;
       
  2116 		}
       
  2117 	}
       
  2118 
       
  2119 	u32_t final_padding_length = ((count * block_size) % 0xff) + padding_length;
       
  2120 
       
  2121 	count = static_cast<u8_t>((final_padding_length-padding_length) / block_size);
       
  2122 
       
  2123 	while (count > 0ul
       
  2124 		&& (count * block_size)+padding_length > 0xff)
       
  2125 	{
       
  2126 		--count;
       
  2127 	}
       
  2128 
       
  2129 	const u8_t final_length = static_cast<u8_t>((count * block_size)+padding_length);
       
  2130 
       
  2131 	EAP_TRACE_DEBUG(
       
  2132 		m_am_tools,
       
  2133 		TRACE_FLAGS_DEFAULT,
       
  2134 		(EAPL("TLS: %s: encrypt_function: get_extra_padding_length(): length = %d = 0x%02x\n"),
       
  2135 		 (m_is_client == true ? "client": "server"),
       
  2136 		 final_length,
       
  2137 		 final_length));
       
  2138 
       
  2139 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2140 	return final_length;
       
  2141 }
       
  2142 
       
  2143 //--------------------------------------------------
       
  2144 
       
  2145 //
       
  2146 EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_send_block_cipher_suite(
       
  2147 	eap_variable_data_c * const tls_record_message_buffer,
       
  2148 	abs_crypto_cbc_block_algorithm_c * const encrypt,
       
  2149 	abs_crypto_hmac_algorithm_c * const mac)
       
  2150 {
       
  2151 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2152 
       
  2153 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  2154 	EAP_TRACE_DEBUG(
       
  2155 		m_am_tools,
       
  2156 		TRACE_FLAGS_DEFAULT,
       
  2157 		(EAPL("TLS: %s: send_function: starts: tls_record_c::apply_send_block_cipher_suite(): %s\n"),
       
  2158 		(m_is_client == true ? "client": "server"),
       
  2159 		eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite)));
       
  2160 
       
  2161 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_send_block_cipher_suite()");
       
  2162 
       
  2163 	eap_status_e status = eap_status_process_general_error;
       
  2164 
       
  2165 	tls_record_header_c tmp_tls_record_header_on_tls_message_buffer(
       
  2166 		m_am_tools,
       
  2167 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2168 		tls_record_message_buffer->get_data_length());
       
  2169 
       
  2170 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2171 		|| tls_record_message_buffer->get_data_length()
       
  2172 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2173 	{
       
  2174 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2175 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2176 	}
       
  2177 
       
  2178 	EAP_TRACE_DATA_DEBUG(
       
  2179 		m_am_tools,
       
  2180 		TRACE_FLAGS_DEFAULT,
       
  2181 		(EAPL("m_send_mac_key"),
       
  2182 		 m_send_mac_key.get_data(m_send_mac_key.get_data_length()),
       
  2183 		 m_send_mac_key.get_data_length()));
       
  2184 
       
  2185 	status = mac->hmac_set_key(&m_send_mac_key);
       
  2186 	if (status != eap_status_ok)
       
  2187 	{
       
  2188 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2189 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2190 	}
       
  2191 	if (mac->get_is_valid() == false)
       
  2192 	{
       
  2193 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2194 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  2195 	}
       
  2196 
       
  2197 	u64_t send_record_sequence_number_network_order = eap_htonll(m_send_record_sequence_number);
       
  2198 
       
  2199 	EAP_TRACE_DATA_DEBUG(
       
  2200 		m_am_tools,
       
  2201 		TRACE_FLAGS_DEFAULT,
       
  2202 		(EAPL("send_record_sequence_number_network_order"),
       
  2203 		 &send_record_sequence_number_network_order,
       
  2204 		 sizeof(send_record_sequence_number_network_order)));
       
  2205 
       
  2206 	status = mac->hmac_update(
       
  2207 		&send_record_sequence_number_network_order,
       
  2208 		sizeof(send_record_sequence_number_network_order));
       
  2209 	if (status != eap_status_ok)
       
  2210 	{
       
  2211 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2212 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2213 	}
       
  2214 
       
  2215 	EAP_TRACE_DATA_DEBUG(
       
  2216 		m_am_tools,
       
  2217 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2218 		(EAPL("verified record"),
       
  2219 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2220 		 tls_record_message_buffer->get_data_length()));
       
  2221 
       
  2222 	status = mac->hmac_update(
       
  2223 		tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2224 		tls_record_message_buffer->get_data_length());
       
  2225 	if (status != eap_status_ok)
       
  2226 	{
       
  2227 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2228 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2229 	}
       
  2230 
       
  2231 	eap_variable_data_c mac_data(m_am_tools);
       
  2232 
       
  2233 	status = mac_data.set_buffer_length(mac->get_digest_length());
       
  2234 	if (status != eap_status_ok)
       
  2235 	{
       
  2236 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2237 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2238 	}
       
  2239 	mac_data.set_data_length(mac->get_digest_length());
       
  2240 		
       
  2241 	u32_t mac_length = mac->get_digest_length();
       
  2242 
       
  2243 	status = mac->hmac_final(
       
  2244 		mac_data.get_data(mac_data.get_data_length()),
       
  2245 		&mac_length);
       
  2246 	if (status != eap_status_ok)
       
  2247 	{
       
  2248 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2249 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2250 	}
       
  2251 	else if (mac_length != mac->get_digest_length())
       
  2252 	{
       
  2253 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2254 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2255 	}
       
  2256 
       
  2257 	EAP_TRACE_DATA_DEBUG(
       
  2258 		m_am_tools,
       
  2259 		TRACE_FLAGS_DEFAULT,
       
  2260 		(EAPL("send MAC"),
       
  2261 		 mac_data.get_data(mac_data.get_data_length()),
       
  2262 		 mac_data.get_data_length()));
       
  2263 
       
  2264 	status = tls_record_message_buffer->add_data(&mac_data);
       
  2265 	if (status != eap_status_ok)
       
  2266 	{
       
  2267 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2268 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2269 	}
       
  2270 
       
  2271 	// We must get the address of the record header again. A new buffer may be allocated.
       
  2272 	tmp_tls_record_header_on_tls_message_buffer.set_header_buffer(
       
  2273 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2274 		tls_record_message_buffer->get_data_length());
       
  2275 
       
  2276 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2277 		|| tls_record_message_buffer->get_data_length()
       
  2278 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2279 	{
       
  2280 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2281 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2282 	}
       
  2283 
       
  2284 	tmp_tls_record_header_on_tls_message_buffer.set_data_length(
       
  2285 		static_cast<u16_t>(
       
  2286 			tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2287 			+ mac->get_digest_length()));
       
  2288 
       
  2289 
       
  2290 	u32_t padded_data_length = encrypt->aligned_data_length(
       
  2291 		tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  2292 	u8_t padding_length = static_cast<u8_t>(
       
  2293 		padded_data_length-tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  2294 
       
  2295 	padding_length = get_extra_padding_length(padding_length, encrypt->get_block_size());
       
  2296 
       
  2297 	eap_variable_data_c padding(m_am_tools);
       
  2298 	status = padding.set_buffer_length(padding_length);
       
  2299 	if (status != eap_status_ok)
       
  2300 	{
       
  2301 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2302 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2303 	}
       
  2304 	padding.set_data_length(padding_length);
       
  2305 	
       
  2306 	status = encrypt->add_padding_bytes(
       
  2307 		padding.get_data(padding.get_data_length()),
       
  2308 		padding.get_data_length(),
       
  2309 		static_cast<u8_t>(padding_length-1ul));
       
  2310 	if (status != eap_status_ok)
       
  2311 	{
       
  2312 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2313 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2314 	}
       
  2315 
       
  2316 	status = tls_record_message_buffer->add_data(&padding);
       
  2317 	if (status != eap_status_ok)
       
  2318 	{
       
  2319 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2320 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2321 	}
       
  2322 	
       
  2323 	// We must get the address of the record header again. A new buffer may be allocated.
       
  2324 	tmp_tls_record_header_on_tls_message_buffer.set_header_buffer(
       
  2325 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2326 		tls_record_message_buffer->get_data_length());
       
  2327 	
       
  2328 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2329 		|| tls_record_message_buffer->get_data_length()
       
  2330 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2331 	{
       
  2332 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2333 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2334 	}
       
  2335 
       
  2336 	tmp_tls_record_header_on_tls_message_buffer.set_data_length(
       
  2337 		static_cast<u16_t>(
       
  2338 			tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2339 			+ padding_length));
       
  2340 
       
  2341 	EAP_TRACE_DATA_DEBUG(
       
  2342 		m_am_tools,
       
  2343 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2344 		(EAPL("plain text record"),
       
  2345 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2346 		 tls_record_message_buffer->get_data_length()));
       
  2347 
       
  2348 	status = encrypt->encrypt_data(
       
  2349 		tmp_tls_record_header_on_tls_message_buffer.get_data(
       
  2350 			tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2351 		tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  2352 	if (status != eap_status_ok)
       
  2353 	{
       
  2354 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2355 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2356 	}
       
  2357 
       
  2358 	EAP_TRACE_DATA_DEBUG(
       
  2359 		m_am_tools,
       
  2360 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2361 		(EAPL("encrypted record"),
       
  2362 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2363 		 tls_record_message_buffer->get_data_length()));
       
  2364 
       
  2365 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2366 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2367 }
       
  2368 
       
  2369 //--------------------------------------------------
       
  2370 
       
  2371 //
       
  2372 EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_receive_block_cipher_suite(
       
  2373 	eap_variable_data_c * const tls_record_message_buffer,
       
  2374 	abs_crypto_cbc_block_algorithm_c * const encrypt,
       
  2375 	abs_crypto_hmac_algorithm_c * const mac)
       
  2376 {
       
  2377 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2378 
       
  2379 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  2380 	EAP_TRACE_DEBUG(
       
  2381 		m_am_tools,
       
  2382 		TRACE_FLAGS_DEFAULT,
       
  2383 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::apply_receive_block_cipher_suite(): %s\n"),
       
  2384 		(m_is_client == true ? "client": "server"),
       
  2385 		eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite)));
       
  2386 
       
  2387 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_receive_block_cipher_suite()");
       
  2388 
       
  2389 	eap_status_e status = eap_status_process_general_error;
       
  2390 
       
  2391 	tls_record_header_c tmp_tls_record_header_on_tls_message_buffer(
       
  2392 		m_am_tools,
       
  2393 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2394 		tls_record_message_buffer->get_data_length());
       
  2395 
       
  2396 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2397 		|| tls_record_message_buffer->get_data_length()
       
  2398 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2399 	{
       
  2400 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2401 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2402 	}
       
  2403 
       
  2404 	EAP_TRACE_DATA_DEBUG(
       
  2405 		m_am_tools,
       
  2406 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2407 		(EAPL("encrypted record"),
       
  2408 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2409 		 tls_record_message_buffer->get_data_length()));
       
  2410 
       
  2411 	status = encrypt->decrypt_data(
       
  2412 		tmp_tls_record_header_on_tls_message_buffer.get_data(
       
  2413 			tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2414 		tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  2415 	if (status != eap_status_ok)
       
  2416 	{
       
  2417 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2418 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2419 	}
       
  2420 
       
  2421 	EAP_TRACE_DATA_DEBUG(
       
  2422 		m_am_tools,
       
  2423 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2424 		(EAPL("plain text record"),
       
  2425 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2426 		 tls_record_message_buffer->get_data_length()));
       
  2427 
       
  2428 	// We must get the address of the record header again. A new buffer may be allocated.
       
  2429 	tmp_tls_record_header_on_tls_message_buffer.set_header_buffer(
       
  2430 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2431 		tls_record_message_buffer->get_data_length());
       
  2432 
       
  2433 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2434 		|| tls_record_message_buffer->get_data_length()
       
  2435 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2436 	{
       
  2437 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2438 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2439 	}
       
  2440 
       
  2441 	u32_t padding_length_offset
       
  2442 		= tmp_tls_record_header_on_tls_message_buffer.get_data_length() - 1ul;
       
  2443 	const u8_t * const p_padding_length
       
  2444 		= tmp_tls_record_header_on_tls_message_buffer.get_data_offset(padding_length_offset,
       
  2445 			TLS_PADDINF_LENGTH_FIELD_SIZE);
       
  2446 
       
  2447 	if (p_padding_length == 0
       
  2448 		|| (*p_padding_length)+1ul > tmp_tls_record_header_on_tls_message_buffer.get_data_length())
       
  2449 	{
       
  2450 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2451 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding);
       
  2452 	}
       
  2453 
       
  2454 	u32_t padding_length = (*p_padding_length) + 1ul;
       
  2455 
       
  2456 	const u8_t * const p_padding
       
  2457 		= tmp_tls_record_header_on_tls_message_buffer.get_data_offset(
       
  2458 			tmp_tls_record_header_on_tls_message_buffer.get_data_length() - padding_length,
       
  2459 			padding_length);
       
  2460 	if (p_padding == 0)
       
  2461 	{
       
  2462 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2463 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding);
       
  2464 	}
       
  2465 
       
  2466 	eap_status_e padding_status = encrypt->check_padding_bytes(
       
  2467 		p_padding,
       
  2468 		*p_padding_length,
       
  2469 		*p_padding_length);
       
  2470 	if (padding_status != eap_status_ok)
       
  2471 	{
       
  2472 		// NOTE, padding_status is checked in the end of this function.
       
  2473 		// HMAC is checked always.
       
  2474 		// We set the padding length to zero, so the end of the message is used as a MAC.
       
  2475 		// This will fail anyway.
       
  2476 		// This will make some timing attacks more difficult.
       
  2477 		padding_length = 0ul;
       
  2478 	}
       
  2479 
       
  2480 
       
  2481 
       
  2482 	tmp_tls_record_header_on_tls_message_buffer.set_data_length(
       
  2483 		static_cast<u16_t>(
       
  2484 			tmp_tls_record_header_on_tls_message_buffer.get_data_length() - padding_length));
       
  2485 
       
  2486 	tls_record_message_buffer->set_data_length(
       
  2487 		tls_record_message_buffer->get_data_length()
       
  2488 		- padding_length);
       
  2489 	
       
  2490 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2491 	
       
  2492 	// HMAC-XXX authentication.
       
  2493 
       
  2494 	EAP_TRACE_DATA_DEBUG(
       
  2495 		m_am_tools,
       
  2496 		TRACE_FLAGS_DEFAULT,
       
  2497 		(EAPL("m_receive_mac_key"),
       
  2498 		 m_receive_mac_key.get_data(m_receive_mac_key.get_data_length()),
       
  2499 		 m_receive_mac_key.get_data_length()));
       
  2500 	
       
  2501 	status = mac->hmac_set_key(&m_receive_mac_key);
       
  2502 	if (status != eap_status_ok)
       
  2503 	{
       
  2504 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2505 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2506 	}
       
  2507 	if (mac->get_is_valid() == false)
       
  2508 	{
       
  2509 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2510 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  2511 	}
       
  2512 	
       
  2513 	if (tls_record_message_buffer->get_data_length()
       
  2514 		< (tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2515 		   + tmp_tls_record_header_on_tls_message_buffer.get_header_length()))
       
  2516 	{
       
  2517 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2518 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2519 	}
       
  2520 	
       
  2521 	if (tmp_tls_record_header_on_tls_message_buffer.get_data_length() < mac->get_digest_length())
       
  2522 	{
       
  2523 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2524 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2525 	}
       
  2526 
       
  2527 	u32_t start_offset_of_mac
       
  2528 		= tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2529 		- mac->get_digest_length();
       
  2530 	
       
  2531 	const u8_t * const received_mac
       
  2532 		= tmp_tls_record_header_on_tls_message_buffer.get_data_offset(
       
  2533 			start_offset_of_mac,
       
  2534 			mac->get_digest_length());
       
  2535 	if (received_mac == 0)
       
  2536 	{
       
  2537 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2538 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2539 	}
       
  2540 	
       
  2541 	EAP_TRACE_DATA_DEBUG(
       
  2542 		m_am_tools,
       
  2543 		TRACE_FLAGS_DEFAULT,
       
  2544 		(EAPL("received MAC"),
       
  2545 		 received_mac,
       
  2546 		 mac->get_digest_length()));
       
  2547 
       
  2548 	tmp_tls_record_header_on_tls_message_buffer.set_data_length(
       
  2549 		static_cast<u16_t>(tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2550 						   - mac->get_digest_length()));
       
  2551 	
       
  2552 	u64_t receive_record_sequence_number_network_order
       
  2553 		= eap_htonll(m_receive_record_sequence_number);
       
  2554 	
       
  2555 	EAP_TRACE_DATA_DEBUG(
       
  2556 		m_am_tools,
       
  2557 		TRACE_FLAGS_DEFAULT,
       
  2558 		(EAPL("receive_record_sequence_number_network_order"),
       
  2559 		 &receive_record_sequence_number_network_order,
       
  2560 		 sizeof(receive_record_sequence_number_network_order)));
       
  2561 
       
  2562 	status = mac->hmac_update(
       
  2563 		&receive_record_sequence_number_network_order,
       
  2564 		sizeof(receive_record_sequence_number_network_order));
       
  2565 	if (status != eap_status_ok)
       
  2566 	{
       
  2567 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2568 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2569 	}
       
  2570 
       
  2571 	EAP_TRACE_DATA_DEBUG(
       
  2572 		m_am_tools,
       
  2573 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2574 		(EAPL("verified record"),
       
  2575 		 tmp_tls_record_header_on_tls_message_buffer.get_header_buffer(
       
  2576 			 tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2577 			 + tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2578 		 tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2579 		 + tmp_tls_record_header_on_tls_message_buffer.get_data_length()));
       
  2580 
       
  2581 	status = mac->hmac_update(
       
  2582 		tmp_tls_record_header_on_tls_message_buffer.get_header_buffer(
       
  2583 			tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2584 			+ tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2585 		tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2586 		+ tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  2587 	if (status != eap_status_ok)
       
  2588 	{
       
  2589 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2590 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2591 	}
       
  2592 
       
  2593 	eap_variable_data_c mac_data(m_am_tools);
       
  2594 	
       
  2595 	status = mac_data.set_buffer_length(mac->get_digest_length());
       
  2596 	if (status != eap_status_ok)
       
  2597 	{
       
  2598 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2599 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2600 	}
       
  2601 	mac_data.set_data_length(mac->get_digest_length());
       
  2602 	
       
  2603 	u32_t mac_length = mac->get_digest_length();
       
  2604 	
       
  2605 	status = mac->hmac_final(
       
  2606 		mac_data.get_data(mac_data.get_data_length()),
       
  2607 		&mac_length);
       
  2608 	if (status != eap_status_ok)
       
  2609 	{
       
  2610 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2611 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2612 	}
       
  2613 	else if (mac_length != mac->get_digest_length())
       
  2614 	{
       
  2615 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2616 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2617 	}
       
  2618 
       
  2619 	EAP_TRACE_DATA_DEBUG(
       
  2620 		m_am_tools,
       
  2621 		TRACE_FLAGS_DEFAULT,
       
  2622 		(EAPL("verify MAC"),
       
  2623 		 mac_data.get_data(mac_data.get_data_length()),
       
  2624 		 mac_data.get_data_length()));
       
  2625 	
       
  2626 	if (padding_status != eap_status_ok)
       
  2627 	{
       
  2628 		EAP_TRACE_ERROR(
       
  2629 			m_am_tools,
       
  2630 			TRACE_FLAGS_DEFAULT,
       
  2631 			(EAPL("TLS: ERROR: %s: receive_function: apply_receive_cipher_suite(): ")
       
  2632 			 EAPL("padding failed\n"),
       
  2633 			 (m_is_client == true ? "client": "server")));
       
  2634 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2635 		return EAP_STATUS_RETURN(m_am_tools, padding_status);
       
  2636 	}
       
  2637 	else if (m_am_tools->memcmp(
       
  2638 				 mac_data.get_data(mac_data.get_data_length()),
       
  2639 				 received_mac,
       
  2640 				 mac_data.get_data_length()) != 0)
       
  2641 	{
       
  2642 		EAP_TRACE_ERROR(
       
  2643 			m_am_tools,
       
  2644 			TRACE_FLAGS_DEFAULT,
       
  2645 			(EAPL("TLS: ERROR: %s: receive_function: apply_receive_cipher_suite(): MAC failed\n"),
       
  2646 			 (m_is_client == true ? "client": "server")));
       
  2647 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2648 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  2649 	}
       
  2650 	else
       
  2651 	{
       
  2652 		EAP_TRACE_ALWAYS(
       
  2653 			m_am_tools,
       
  2654 			TRACE_FLAGS_DEFAULT,
       
  2655 			(EAPL("TLS: %s: receive_function: apply_receive_cipher_suite(): MAC OK\n"),
       
  2656 			 (m_is_client == true ? "client": "server")));
       
  2657 	}
       
  2658 
       
  2659 	tls_record_message_buffer->set_data_length(
       
  2660 		tls_record_message_buffer->get_data_length()
       
  2661 		- mac->get_digest_length());
       
  2662 	
       
  2663 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2664 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2665 }
       
  2666 
       
  2667 //--------------------------------------------------
       
  2668 
       
  2669 //
       
  2670 EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_send_stream_cipher_suite(
       
  2671 	eap_variable_data_c * const tls_record_message_buffer,
       
  2672 	abs_crypto_stream_algorithm_c * const encrypt,
       
  2673 	abs_crypto_hmac_algorithm_c * const mac)
       
  2674 {
       
  2675 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2676 
       
  2677 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  2678 	EAP_TRACE_DEBUG(
       
  2679 		m_am_tools,
       
  2680 		TRACE_FLAGS_DEFAULT,
       
  2681 		(EAPL("TLS: %s: send_function: starts: tls_record_c::apply_send_stream_cipher_suite(): %s\n"),
       
  2682 		(m_is_client == true ? "client": "server"),
       
  2683 		eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite)));
       
  2684 
       
  2685 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_send_stream_cipher_suite()");
       
  2686 
       
  2687 	eap_status_e status = eap_status_process_general_error;
       
  2688 
       
  2689 	tls_record_header_c tmp_tls_record_header_on_tls_message_buffer(
       
  2690 		m_am_tools,
       
  2691 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2692 		tls_record_message_buffer->get_data_length());
       
  2693 
       
  2694 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2695 		|| tls_record_message_buffer->get_data_length()
       
  2696 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2697 	{
       
  2698 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2699 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2700 	}
       
  2701 
       
  2702 	EAP_TRACE_DATA_DEBUG(
       
  2703 		m_am_tools,
       
  2704 		TRACE_FLAGS_DEFAULT,
       
  2705 		(EAPL("m_send_mac_key"),
       
  2706 		 m_send_mac_key.get_data(m_send_mac_key.get_data_length()),
       
  2707 		 m_send_mac_key.get_data_length()));
       
  2708 
       
  2709 	status = mac->hmac_set_key(&m_send_mac_key);
       
  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 	if (mac->get_is_valid() == false)
       
  2716 	{
       
  2717 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2718 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  2719 	}
       
  2720 
       
  2721 	u64_t send_record_sequence_number_network_order = eap_htonll(m_send_record_sequence_number);
       
  2722 
       
  2723 	EAP_TRACE_DATA_DEBUG(
       
  2724 		m_am_tools,
       
  2725 		TRACE_FLAGS_DEFAULT,
       
  2726 		(EAPL("send_record_sequence_number_network_order"),
       
  2727 		 &send_record_sequence_number_network_order,
       
  2728 		 sizeof(send_record_sequence_number_network_order)));
       
  2729 
       
  2730 	status = mac->hmac_update(
       
  2731 		&send_record_sequence_number_network_order,
       
  2732 		sizeof(send_record_sequence_number_network_order));
       
  2733 	if (status != eap_status_ok)
       
  2734 	{
       
  2735 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2736 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2737 	}
       
  2738 
       
  2739 	EAP_TRACE_DATA_DEBUG(
       
  2740 		m_am_tools,
       
  2741 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2742 		(EAPL("verified record"),
       
  2743 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2744 		 tls_record_message_buffer->get_data_length()));
       
  2745 
       
  2746 	status = mac->hmac_update(
       
  2747 		tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2748 		tls_record_message_buffer->get_data_length());
       
  2749 	if (status != eap_status_ok)
       
  2750 	{
       
  2751 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2752 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2753 	}
       
  2754 
       
  2755 	eap_variable_data_c mac_data(m_am_tools);
       
  2756 
       
  2757 	status = mac_data.set_buffer_length(mac->get_digest_length());
       
  2758 	if (status != eap_status_ok)
       
  2759 	{
       
  2760 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2761 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2762 	}
       
  2763 	mac_data.set_data_length(mac->get_digest_length());
       
  2764 		
       
  2765 	u32_t mac_length = mac->get_digest_length();
       
  2766 
       
  2767 	status = mac->hmac_final(
       
  2768 		mac_data.get_data(mac_data.get_data_length()),
       
  2769 		&mac_length);
       
  2770 	if (status != eap_status_ok)
       
  2771 	{
       
  2772 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2773 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2774 	}
       
  2775 	else if (mac_length != mac->get_digest_length())
       
  2776 	{
       
  2777 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2778 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  2779 	}
       
  2780 
       
  2781 	EAP_TRACE_DATA_DEBUG(
       
  2782 		m_am_tools,
       
  2783 		TRACE_FLAGS_DEFAULT,
       
  2784 		(EAPL("send MAC"),
       
  2785 		 mac_data.get_data(mac_data.get_data_length()),
       
  2786 		 mac_data.get_data_length()));
       
  2787 
       
  2788 	status = tls_record_message_buffer->add_data(&mac_data);
       
  2789 	if (status != eap_status_ok)
       
  2790 	{
       
  2791 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2792 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2793 	}
       
  2794 
       
  2795 	// We must get the address of the record header again. A new buffer may be allocated.
       
  2796 	tmp_tls_record_header_on_tls_message_buffer.set_header_buffer(
       
  2797 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2798 		tls_record_message_buffer->get_data_length());
       
  2799 
       
  2800 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2801 		|| tls_record_message_buffer->get_data_length()
       
  2802 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2803 	{
       
  2804 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2805 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2806 	}
       
  2807 
       
  2808 	tmp_tls_record_header_on_tls_message_buffer.set_data_length(
       
  2809 		static_cast<u16_t>(
       
  2810 			tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2811 			+ mac->get_digest_length()));
       
  2812 
       
  2813 	EAP_TRACE_DATA_DEBUG(
       
  2814 		m_am_tools,
       
  2815 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2816 		(EAPL("plain text record"),
       
  2817 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2818 		 tls_record_message_buffer->get_data_length()));
       
  2819 
       
  2820 	status = encrypt->encrypt_data(
       
  2821 		tmp_tls_record_header_on_tls_message_buffer.get_data(
       
  2822 			tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2823 		tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  2824 	if (status != eap_status_ok)
       
  2825 	{
       
  2826 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2827 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2828 	}
       
  2829 
       
  2830 	EAP_TRACE_DATA_DEBUG(
       
  2831 		m_am_tools,
       
  2832 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2833 		(EAPL("encrypted record"),
       
  2834 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2835 		 tls_record_message_buffer->get_data_length()));
       
  2836 
       
  2837 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2838 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2839 }
       
  2840 
       
  2841 //--------------------------------------------------
       
  2842 
       
  2843 //
       
  2844 EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_receive_stream_cipher_suite(
       
  2845 	eap_variable_data_c * const tls_record_message_buffer,
       
  2846 	abs_crypto_stream_algorithm_c * const encrypt,
       
  2847 	abs_crypto_hmac_algorithm_c * const mac)
       
  2848 {
       
  2849 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2850 
       
  2851 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  2852 	EAP_TRACE_DEBUG(
       
  2853 		m_am_tools,
       
  2854 		TRACE_FLAGS_DEFAULT,
       
  2855 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::apply_receive_block_cipher_suite(): %s\n"),
       
  2856 		(m_is_client == true ? "client": "server"),
       
  2857 		eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite)));
       
  2858 
       
  2859 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_receive_stream_cipher_suite()");
       
  2860 
       
  2861 	eap_status_e status = eap_status_process_general_error;
       
  2862 
       
  2863 	tls_record_header_c tmp_tls_record_header_on_tls_message_buffer(
       
  2864 		m_am_tools,
       
  2865 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  2866 		tls_record_message_buffer->get_data_length());
       
  2867 
       
  2868 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  2869 		|| tls_record_message_buffer->get_data_length()
       
  2870 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  2871 	{
       
  2872 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2873 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2874 	}
       
  2875 
       
  2876 	EAP_TRACE_DATA_DEBUG(
       
  2877 		m_am_tools,
       
  2878 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2879 		(EAPL("encrypted record"),
       
  2880 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2881 		 tls_record_message_buffer->get_data_length()));
       
  2882 
       
  2883 	status = encrypt->decrypt_data(
       
  2884 		tmp_tls_record_header_on_tls_message_buffer.get_data(
       
  2885 			tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2886 		tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  2887 	if (status != eap_status_ok)
       
  2888 	{
       
  2889 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2890 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2891 	}
       
  2892 
       
  2893 	EAP_TRACE_DATA_DEBUG(
       
  2894 		m_am_tools,
       
  2895 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2896 		(EAPL("plain text record"),
       
  2897 		 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  2898 		 tls_record_message_buffer->get_data_length()));
       
  2899 
       
  2900 	tls_record_message_buffer->set_data_length(
       
  2901 		tls_record_message_buffer->get_data_length());
       
  2902 	
       
  2903 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2904 	
       
  2905 	// HMAC-SHA1 authentication.
       
  2906 
       
  2907 	EAP_TRACE_DATA_DEBUG(
       
  2908 		m_am_tools,
       
  2909 		TRACE_FLAGS_DEFAULT,
       
  2910 		(EAPL("m_receive_mac_key"),
       
  2911 		 m_receive_mac_key.get_data(m_receive_mac_key.get_data_length()),
       
  2912 		 m_receive_mac_key.get_data_length()));
       
  2913 	
       
  2914 	status = mac->hmac_set_key(&m_receive_mac_key);
       
  2915 	if (status != eap_status_ok)
       
  2916 	{
       
  2917 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2918 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2919 	}
       
  2920 	if (mac->get_is_valid() == false)
       
  2921 	{
       
  2922 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2923 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  2924 	}
       
  2925 	
       
  2926 	if (tls_record_message_buffer->get_data_length()
       
  2927 		< (tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2928 		   + tmp_tls_record_header_on_tls_message_buffer.get_header_length()))
       
  2929 	{
       
  2930 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2931 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2932 	}
       
  2933 	
       
  2934 	if (tmp_tls_record_header_on_tls_message_buffer.get_data_length() < mac->get_digest_length())
       
  2935 	{
       
  2936 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2937 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2938 	}
       
  2939 
       
  2940 	u32_t start_offset_of_mac
       
  2941 		= tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2942 		- mac->get_digest_length();
       
  2943 	
       
  2944 	const u8_t * const received_mac
       
  2945 		= tmp_tls_record_header_on_tls_message_buffer.get_data_offset(
       
  2946 			start_offset_of_mac,
       
  2947 			mac->get_digest_length());
       
  2948 	if (received_mac == 0)
       
  2949 	{
       
  2950 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2951 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  2952 	}
       
  2953 	
       
  2954 	EAP_TRACE_DATA_DEBUG(
       
  2955 		m_am_tools,
       
  2956 		TRACE_FLAGS_DEFAULT,
       
  2957 		(EAPL("received MAC"),
       
  2958 		 received_mac,
       
  2959 		 mac->get_digest_length()));
       
  2960 
       
  2961 	tmp_tls_record_header_on_tls_message_buffer.set_data_length(
       
  2962 		static_cast<u16_t>(tmp_tls_record_header_on_tls_message_buffer.get_data_length()
       
  2963 						   - mac->get_digest_length()));
       
  2964 	
       
  2965 	u64_t receive_record_sequence_number_network_order
       
  2966 		= eap_htonll(m_receive_record_sequence_number);
       
  2967 	
       
  2968 	EAP_TRACE_DATA_DEBUG(
       
  2969 		m_am_tools,
       
  2970 		TRACE_FLAGS_DEFAULT,
       
  2971 		(EAPL("receive_record_sequence_number_network_order"),
       
  2972 		 &receive_record_sequence_number_network_order,
       
  2973 		 sizeof(receive_record_sequence_number_network_order)));
       
  2974 
       
  2975 	status = mac->hmac_update(
       
  2976 		&receive_record_sequence_number_network_order,
       
  2977 		sizeof(receive_record_sequence_number_network_order));
       
  2978 	if (status != eap_status_ok)
       
  2979 	{
       
  2980 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2981 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2982 	}
       
  2983 
       
  2984 	EAP_TRACE_DATA_DEBUG(
       
  2985 		m_am_tools,
       
  2986 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  2987 		(EAPL("verified record"),
       
  2988 		 tmp_tls_record_header_on_tls_message_buffer.get_header_buffer(
       
  2989 			 tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2990 			 + tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2991 		 tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2992 		 + tmp_tls_record_header_on_tls_message_buffer.get_data_length()));
       
  2993 
       
  2994 	status = mac->hmac_update(
       
  2995 		tmp_tls_record_header_on_tls_message_buffer.get_header_buffer(
       
  2996 			tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2997 			+ tmp_tls_record_header_on_tls_message_buffer.get_data_length()),
       
  2998 		tmp_tls_record_header_on_tls_message_buffer.get_header_length()
       
  2999 		+ tmp_tls_record_header_on_tls_message_buffer.get_data_length());
       
  3000 	if (status != eap_status_ok)
       
  3001 	{
       
  3002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3003 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3004 	}
       
  3005 
       
  3006 	eap_variable_data_c mac_data(m_am_tools);
       
  3007 	
       
  3008 	status = mac_data.set_buffer_length(mac->get_digest_length());
       
  3009 	if (status != eap_status_ok)
       
  3010 	{
       
  3011 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3012 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3013 	}
       
  3014 	mac_data.set_data_length(mac->get_digest_length());
       
  3015 	
       
  3016 	u32_t mac_length = mac->get_digest_length();
       
  3017 	
       
  3018 	status = mac->hmac_final(
       
  3019 		mac_data.get_data(mac_data.get_data_length()),
       
  3020 		&mac_length);
       
  3021 	if (status != eap_status_ok)
       
  3022 	{
       
  3023 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3024 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3025 	}
       
  3026 	else if (mac_length != mac->get_digest_length())
       
  3027 	{
       
  3028 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3029 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3030 	}
       
  3031 
       
  3032 	EAP_TRACE_DATA_DEBUG(
       
  3033 		m_am_tools,
       
  3034 		TRACE_FLAGS_DEFAULT,
       
  3035 		(EAPL("verify MAC"),
       
  3036 		 mac_data.get_data(mac_data.get_data_length()),
       
  3037 		 mac_data.get_data_length()));
       
  3038 	
       
  3039 	if (m_am_tools->memcmp(
       
  3040 			mac_data.get_data(mac_data.get_data_length()),
       
  3041 			received_mac, mac_data.get_data_length()) != 0)
       
  3042 	{
       
  3043 		EAP_TRACE_ERROR(
       
  3044 			m_am_tools,
       
  3045 			TRACE_FLAGS_DEFAULT,
       
  3046 			(EAPL("TLS: %s: receive_function: apply_receive_cipher_suite(): MAC failed\n"),
       
  3047 			 (m_is_client == true ? "client": "server")));
       
  3048 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3049 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  3050 	}
       
  3051 	else
       
  3052 	{
       
  3053 		EAP_TRACE_ALWAYS(
       
  3054 			m_am_tools,
       
  3055 			TRACE_FLAGS_DEFAULT,
       
  3056 			(EAPL("TLS: %s: receive_function: apply_receive_cipher_suite(): MAC OK\n"),
       
  3057 			 (m_is_client == true ? "client": "server")));
       
  3058 	}
       
  3059 
       
  3060 	tls_record_message_buffer->set_data_length(
       
  3061 		tls_record_message_buffer->get_data_length()
       
  3062 		- mac->get_digest_length());
       
  3063 	
       
  3064 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3065 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3066 }
       
  3067 
       
  3068 //--------------------------------------------------
       
  3069 
       
  3070 //
       
  3071 EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_send_cipher_suite(
       
  3072 	eap_variable_data_c * const tls_record_message_buffer)
       
  3073 {
       
  3074 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3075 
       
  3076 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3077 	EAP_TRACE_DEBUG(
       
  3078 		m_am_tools,
       
  3079 		TRACE_FLAGS_DEFAULT,
       
  3080 		(EAPL("TLS: %s: send_function: starts: tls_record_c::apply_send_cipher_suite(): %d=%s\n"),
       
  3081 		(m_is_client == true ? "client": "server"),
       
  3082 		m_send_cipher_suite,
       
  3083 		eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite)));
       
  3084 
       
  3085 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_send_cipher_suite()");
       
  3086 
       
  3087 	eap_status_e status = eap_status_process_general_error;
       
  3088 
       
  3089 	tls_record_header_c tmp_tls_record_header_on_tls_message_buffer(
       
  3090 		m_am_tools,
       
  3091 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  3092 		tls_record_message_buffer->get_data_length());
       
  3093 
       
  3094 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  3095 		|| tls_record_message_buffer->get_data_length()
       
  3096 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  3097 	{
       
  3098 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3099 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  3100 	}
       
  3101 
       
  3102 	if (m_send_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
  3103 	{
       
  3104 		EAP_TRACE_DATA_ALWAYS(
       
  3105 			m_am_tools,
       
  3106 			TRACE_FLAGS_DEFAULT,
       
  3107 			(EAPL("plaintext TLS-record"),
       
  3108 			 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  3109 			 tls_record_message_buffer->get_data_length()));
       
  3110 	}
       
  3111 
       
  3112 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3113 
       
  3114 	/**
       
  3115 	 * @{ Add compression of data. Well this will be optional very long time. }
       
  3116 	 */
       
  3117 	if (m_send_compression_method == tls_compression_method_null)
       
  3118 	{
       
  3119 		// No compression.
       
  3120 		status = eap_status_ok;
       
  3121 	}
       
  3122 	else
       
  3123 	{
       
  3124 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3125 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  3126 	}
       
  3127 
       
  3128 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3129 
       
  3130 	if (m_send_cipher_suite == tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
  3131 	{
       
  3132 		// No authentication.
       
  3133 		// No encryption.
       
  3134 
       
  3135 		u64_t send_record_sequence_number_network_order = eap_htonll(m_send_record_sequence_number);
       
  3136 		EAP_UNREFERENCED_PARAMETER(send_record_sequence_number_network_order); // in release
       
  3137 
       
  3138 		EAP_TRACE_DATA_DEBUG(
       
  3139 			m_am_tools,
       
  3140 			TRACE_FLAGS_DEFAULT,
       
  3141 			(EAPL("send_record_sequence_number_network_order"),
       
  3142 			 &send_record_sequence_number_network_order,
       
  3143 			 sizeof(send_record_sequence_number_network_order)));
       
  3144 
       
  3145 		status = eap_status_ok;
       
  3146 	}
       
  3147 	else if (cipher_suite_is_3DES_EDE_CBC_SHA(m_send_cipher_suite) == true
       
  3148 		|| cipher_suite_is_AES_128_CBC_SHA(m_send_cipher_suite) == true)
       
  3149 	{
       
  3150 		EAP_ASSERT_TOOLS(m_am_tools, m_send_block_cipher != 0);
       
  3151 		EAP_ASSERT_TOOLS(m_am_tools, m_send_hmac_algorithm != 0);
       
  3152 
       
  3153 		status = apply_send_block_cipher_suite(
       
  3154 			tls_record_message_buffer,
       
  3155 			m_send_block_cipher,
       
  3156 			m_send_hmac_algorithm);
       
  3157 	}
       
  3158 	else if (cipher_suite_is_RC4_128_MD5(m_send_cipher_suite) == true
       
  3159 		|| cipher_suite_is_RC4_128_SHA(m_send_cipher_suite) == true)
       
  3160 	{
       
  3161 		EAP_ASSERT_TOOLS(m_am_tools, m_send_stream_cipher != 0);
       
  3162 		EAP_ASSERT_TOOLS(m_am_tools, m_send_hmac_algorithm != 0);
       
  3163 
       
  3164 		status = apply_send_stream_cipher_suite(
       
  3165 			tls_record_message_buffer,
       
  3166 			m_send_stream_cipher,
       
  3167 			m_send_hmac_algorithm);
       
  3168 	}
       
  3169 	else
       
  3170 	{
       
  3171 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3172 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  3173 	}
       
  3174 
       
  3175 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3176 
       
  3177 	if (m_send_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
  3178 	{
       
  3179 		m_send_record_sequence_number = m_send_record_sequence_number + 1ul;
       
  3180 	}
       
  3181 
       
  3182 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3183 
       
  3184 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3185 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3186 }
       
  3187 
       
  3188 //--------------------------------------------------
       
  3189 
       
  3190 //
       
  3191 EAP_FUNC_EXPORT eap_status_e tls_record_c::apply_receive_cipher_suite(
       
  3192 	eap_variable_data_c * const tls_record_message_buffer)
       
  3193 {
       
  3194 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3195 
       
  3196 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3197 	EAP_TRACE_DEBUG(
       
  3198 		m_am_tools,
       
  3199 		TRACE_FLAGS_DEFAULT,
       
  3200 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::apply_receive_cipher_suite(): %d=%s\n"),
       
  3201 		(m_is_client == true ? "client": "server"),
       
  3202 		m_receive_cipher_suite,
       
  3203 		eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite)));
       
  3204 
       
  3205 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::apply_receive_cipher_suite()");
       
  3206 
       
  3207 	eap_status_e status = eap_status_process_general_error;
       
  3208 
       
  3209 	tls_record_header_c tmp_tls_record_header_on_tls_message_buffer(
       
  3210 		m_am_tools,
       
  3211 		tls_record_message_buffer->get_data(tls_record_header_c::get_header_length()),
       
  3212 		tls_record_message_buffer->get_data_length());
       
  3213 
       
  3214 	if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false
       
  3215 		|| tls_record_message_buffer->get_data_length()
       
  3216 		< tmp_tls_record_header_on_tls_message_buffer.get_header_length())
       
  3217 	{
       
  3218 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3219 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  3220 	}
       
  3221 
       
  3222 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3223 
       
  3224 	if (m_receive_cipher_suite == tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
  3225 	{
       
  3226 		// No decryption.
       
  3227 		// No authentication.
       
  3228 
       
  3229 		u64_t receive_record_sequence_number_network_order
       
  3230 			= eap_htonll(m_receive_record_sequence_number);
       
  3231 		EAP_UNREFERENCED_PARAMETER(receive_record_sequence_number_network_order); // in release
       
  3232 
       
  3233 		EAP_TRACE_DATA_DEBUG(
       
  3234 			m_am_tools,
       
  3235 			TRACE_FLAGS_DEFAULT,
       
  3236 			(EAPL("receive_record_sequence_number_network_order"),
       
  3237 			 &receive_record_sequence_number_network_order,
       
  3238 			 sizeof(receive_record_sequence_number_network_order)));
       
  3239 
       
  3240 		status = eap_status_ok;
       
  3241 	}
       
  3242 	else if (cipher_suite_is_3DES_EDE_CBC_SHA(m_receive_cipher_suite) == true
       
  3243 		|| cipher_suite_is_AES_128_CBC_SHA(m_receive_cipher_suite) == true)
       
  3244 	{
       
  3245 		status = apply_receive_block_cipher_suite(
       
  3246 			tls_record_message_buffer,
       
  3247 			m_receive_block_cipher,
       
  3248 			m_receive_hmac_algorithm);
       
  3249 	}
       
  3250 	else if (cipher_suite_is_RC4_128_MD5(m_receive_cipher_suite) == true
       
  3251 		|| cipher_suite_is_RC4_128_SHA(m_receive_cipher_suite) == true)
       
  3252 	{
       
  3253 		status = apply_receive_stream_cipher_suite(
       
  3254 			tls_record_message_buffer,
       
  3255 			m_receive_stream_cipher,
       
  3256 			m_receive_hmac_algorithm);
       
  3257 	}
       
  3258 	else
       
  3259 	{
       
  3260 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3261 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  3262 	}
       
  3263 
       
  3264 	if (m_receive_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
  3265 	{
       
  3266 		EAP_TRACE_DATA_ALWAYS(
       
  3267 			m_am_tools,
       
  3268 			TRACE_FLAGS_DEFAULT,
       
  3269 			(EAPL("decrypted TLS-record"),
       
  3270 			 tls_record_message_buffer->get_data(tls_record_message_buffer->get_data_length()),
       
  3271 			 tls_record_message_buffer->get_data_length()));
       
  3272 	}
       
  3273 
       
  3274 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3275 
       
  3276 	/**
       
  3277 	 * @{ Add de-compression of data. Well this will be optional very long time. }
       
  3278 	 */
       
  3279 	if (m_send_compression_method == tls_compression_method_null)
       
  3280 	{
       
  3281 		// No de-compression.
       
  3282 	}
       
  3283 	else
       
  3284 	{
       
  3285 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3286 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  3287 	}
       
  3288 
       
  3289 
       
  3290 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3291 
       
  3292 	if (m_receive_cipher_suite != tls_cipher_suites_TLS_NULL_WITH_NULL_NULL)
       
  3293 	{
       
  3294 		m_receive_record_sequence_number = m_receive_record_sequence_number + 1ul;
       
  3295 	}
       
  3296 
       
  3297 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3298 
       
  3299 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3300 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3301 }
       
  3302 
       
  3303 //--------------------------------------------------
       
  3304 
       
  3305 // This is commented in abs_tls_base_application_c.
       
  3306 EAP_FUNC_EXPORT eap_status_e tls_record_c::packet_send(
       
  3307 	eap_buf_chain_wr_c * const sent_packet,
       
  3308 	const u32_t header_offset,
       
  3309 	const u32_t /*data_length*/,
       
  3310 	const u32_t /*buffer_length*/)
       
  3311 {
       
  3312 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3313 
       
  3314 	EAP_TRACE_DEBUG(
       
  3315 		m_am_tools,
       
  3316 		TRACE_FLAGS_DEFAULT,
       
  3317 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::packet_send(): %d=%s\n"),
       
  3318 		(m_is_client == true ? "client": "server"),
       
  3319 		m_receive_cipher_suite,
       
  3320 		eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite)));
       
  3321 
       
  3322 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::packet_send()");
       
  3323 
       
  3324 	eap_status_e status = create_tls_application_data(
       
  3325 		sent_packet,
       
  3326 		header_offset);
       
  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 // This is commented in abs_tls_base_application_c.
       
  3335 EAP_FUNC_EXPORT u32_t tls_record_c::get_header_offset(
       
  3336 	u32_t * const MTU_length,
       
  3337 	u32_t * const trailer_length)
       
  3338 {
       
  3339 	EAP_TRACE_DEBUG(
       
  3340 		m_am_tools,
       
  3341 		TRACE_FLAGS_DEFAULT,
       
  3342 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::get_header_offset()\n"),
       
  3343 		(m_is_client == true ? "client": "server")));
       
  3344 
       
  3345 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_header_offset()");
       
  3346 
       
  3347 	if (m_eap_type == eap_type_peap
       
  3348 		&& m_peap_version == peap_version_0_xp)
       
  3349 	{
       
  3350 		// PEAPv0 cannot use long tunneled EAP-packets,
       
  3351 		// bacause of the inner EAP-packets does not
       
  3352 		// have own EAP-header. Long inner EAP-packets will be 
       
  3353 		// fragmented in outer PEAPv0 application data and that will cause
       
  3354 		// wrong EAP-identifier values after reassembly.
       
  3355 		u32_t offset = get_type_partner()->get_header_offset(
       
  3356 			MTU_length,
       
  3357 			trailer_length);
       
  3358 
       
  3359 		// Here we try set MTU such the inner EAP-packets does not need fragmentation.
       
  3360 		*MTU_length -= (offset
       
  3361 						+ 4ul*(tls_record_header_c::get_header_length()
       
  3362 							   + tls_handshake_header_c::get_header_length()));
       
  3363 		*trailer_length = 0ul;
       
  3364 
       
  3365 		return 0ul;
       
  3366 	}
       
  3367 	else
       
  3368 	{
       
  3369 		*MTU_length = EAP_TLS_PEAP_MAX_MESSAGE_LENGTH;
       
  3370 		*trailer_length = 0ul;
       
  3371 
       
  3372 		return 0ul;
       
  3373 	}
       
  3374 }
       
  3375 
       
  3376 //--------------------------------------------------
       
  3377 
       
  3378 // This is commented in abs_tls_base_application_c.
       
  3379 EAP_FUNC_EXPORT eap_status_e tls_record_c::read_configure(
       
  3380 	const eap_configuration_field_c * const field,
       
  3381 	eap_variable_data_c * const data)
       
  3382 {
       
  3383 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3384 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3385 
       
  3386 	return get_type_partner()->read_configure(
       
  3387 			field,
       
  3388 			data);
       
  3389 }
       
  3390 
       
  3391 //--------------------------------------------------
       
  3392 
       
  3393 // This is commented in abs_tls_base_application_c.
       
  3394 EAP_FUNC_EXPORT eap_status_e tls_record_c::write_configure(
       
  3395 	const eap_configuration_field_c * const field,
       
  3396 	eap_variable_data_c * const data)
       
  3397 {
       
  3398 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3399 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3400 
       
  3401 	return get_type_partner()->write_configure(
       
  3402 			field,
       
  3403 			data);
       
  3404 }
       
  3405 
       
  3406 //--------------------------------------------------
       
  3407 
       
  3408 // This is commented in abs_tls_base_application_c.
       
  3409 EAP_FUNC_EXPORT void tls_record_c::state_notification(
       
  3410 	const abs_eap_state_notification_c * const state)
       
  3411 {
       
  3412 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3413 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3414 
       
  3415 	EAP_TRACE_ALWAYS(
       
  3416 		m_am_tools,
       
  3417 		TRACE_FLAGS_DEFAULT,
       
  3418 		(EAPL("this = 0x%08x, %s: starts: tls_record_c::state_notification(): EAP-type 0x%08x: m_tls_session_type=%d=%s, tls_state=%d=%s, notification state=%s\n"),
       
  3419 		 this,
       
  3420 		 (m_is_client == true ? "client": "server"),
       
  3421 		 convert_eap_type_to_u32_t(m_eap_type),
       
  3422 		 m_tls_session_type,
       
  3423 		 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
  3424 		 m_tls_peap_state,
       
  3425 		 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
  3426 		 eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state())));
       
  3427 
       
  3428 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::state_notification()");
       
  3429 
       
  3430 	if (state->get_protocol_layer() == eap_protocol_layer_general)
       
  3431 	{
       
  3432 		if (state->get_current_state() == eap_general_state_authentication_cancelled)
       
  3433 		{
       
  3434 			// Tunneled EAP-type terminated unsuccessfully.
       
  3435 			m_tunneled_eap_type_authentication_state
       
  3436 				= static_cast<eap_state_variable_e>(state->get_current_state());
       
  3437 			set_state(tls_peap_state_failure);
       
  3438 		}
       
  3439 	}
       
  3440 	else if (state->get_protocol_layer() == eap_protocol_layer_eap)
       
  3441 	{
       
  3442 		if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully
       
  3443 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  3444 			|| state->get_current_state() == eap_state_authentication_terminated_unsuccessfully_peapv1_extension
       
  3445 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  3446 			)
       
  3447 		{
       
  3448 			// Tunneled EAP-type terminated unsuccessfully.
       
  3449 			m_tunneled_eap_type_authentication_state
       
  3450 				= static_cast<eap_state_variable_e>(state->get_current_state());
       
  3451 			set_state(tls_peap_state_failure);
       
  3452 
       
  3453 			// Because we process aplication data, we do not send alert messages anymore.
       
  3454 			m_could_send_fatal_alert_message = false;
       
  3455 			m_could_send_warning_alert_message = false;
       
  3456 		}
       
  3457 		else if (state->get_current_state()
       
  3458 				 == eap_state_authentication_finished_successfully
       
  3459 			|| state->get_current_state()
       
  3460 				 == eap_state_tppd_peapv1_authentication_finished_successfully_with_tunneled_eap_success
       
  3461 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  3462 			|| state->get_current_state()
       
  3463 				 == eap_state_authentication_finished_successfully_peapv1_extension
       
  3464 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  3465 			 )
       
  3466 		{
       
  3467 			// Tunneled EAP-type finished successfully.
       
  3468 
       
  3469 			if ((m_eap_type == eap_type_peap
       
  3470 					&& m_peap_version >= peap_version_0_xp
       
  3471 					&& m_peap_version <= peap_version_2)
       
  3472 				|| m_eap_type == eap_type_ttls
       
  3473 #if defined(USE_FAST_EAP_TYPE)
       
  3474 				|| m_eap_type == eap_type_fast
       
  3475 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  3476 				)
       
  3477 			{
       
  3478 				eap_status_e status = get_type_partner()->set_tls_master_secret(
       
  3479 					&m_eap_master_session_key);
       
  3480 				if (status != eap_status_ok)
       
  3481 				{
       
  3482 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3483 					return;
       
  3484 				}
       
  3485 
       
  3486 				if (m_eap_type == eap_type_ttls
       
  3487 					|| m_eap_type == eap_type_peap
       
  3488 #if defined(USE_FAST_EAP_TYPE)
       
  3489 					|| m_eap_type == eap_type_fast
       
  3490 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  3491 					)
       
  3492 				{
       
  3493 
       
  3494 					tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = 
       
  3495 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  3496 						m_tls_identity_privacy_handshake_state;
       
  3497 #else
       
  3498 						tls_identity_privacy_handshake_state_none;
       
  3499 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  3500 					EAP_UNREFERENCED_PARAMETER(tmp_identity_privacy_handshake_state);
       
  3501 
       
  3502 					EAP_TRACE_DEBUG(
       
  3503 						m_am_tools,
       
  3504 						TRACE_FLAGS_DEFAULT,
       
  3505 						(EAPL("%s: state_notification(): TLS/PEAP authentication ")
       
  3506 						 EAPL("SUCCESS: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s, %s\n"),
       
  3507 						 (m_is_client == true ? "client": "server"),
       
  3508 						 (m_tls_peap_server_authenticates_client_action == true
       
  3509 						  ? "mutual": "anonymous client"),
       
  3510 						 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
  3511 						 get_is_tunneled_tls(),
       
  3512 						 eap_header_string_c::get_eap_type_string(m_eap_type),
       
  3513 						 eap_tls_trace_string_c::get_peap_version_string(m_peap_version),
       
  3514 						 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite),
       
  3515 						 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
  3516 
       
  3517 					eap_status_e save_status = m_am_tls_services->save_tls_session(
       
  3518 						&m_session_id,
       
  3519 						&m_master_secret,
       
  3520 						m_selected_cipher_suite
       
  3521 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  3522 						, tls_extension_c::get_tls_extension(
       
  3523 							tls_extension_type_session_ticket,
       
  3524 							&m_received_tls_extensions,
       
  3525 							m_am_tools)
       
  3526 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
  3527 						);
       
  3528 					if (save_status != eap_status_ok)
       
  3529 					{
       
  3530 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3531 						(void) EAP_STATUS_RETURN(m_am_tools, save_status);
       
  3532 					}
       
  3533 				}
       
  3534 
       
  3535 			}
       
  3536 
       
  3537 			m_tunneled_eap_type_authentication_state
       
  3538 				= static_cast<eap_state_variable_e>(state->get_current_state());
       
  3539 			set_state(tls_peap_state_tls_success);
       
  3540 		}
       
  3541 #if defined(USE_FAST_EAP_TYPE)
       
  3542 		else if (m_eap_type == eap_type_fast
       
  3543 			&& state->get_current_state() == eap_state_inner_eap_method_skipped)
       
  3544 		{
       
  3545 			m_tunneled_eap_type_authentication_state
       
  3546 				= static_cast<eap_state_variable_e>(state->get_current_state());
       
  3547 		}
       
  3548 		else if (m_is_client == false
       
  3549 			&& m_eap_type == eap_type_fast
       
  3550 			&& state->get_current_state() == eap_state_authentication_wait_eap_fast_empty_acknowledge)
       
  3551 		{
       
  3552 			set_state(tls_peap_state_wait_tunneled_authentication_start);
       
  3553 		}
       
  3554 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  3555 	}
       
  3556 	else if (state->get_protocol_layer() == eap_protocol_layer_internal_type)
       
  3557 	{
       
  3558 
       
  3559 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  3560 		if (state->get_current_state() == tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack)
       
  3561 		{
       
  3562 			EAP_TRACE_ALWAYS(
       
  3563 				m_am_tools,
       
  3564 				TRACE_FLAGS_DEFAULT,
       
  3565 				(EAPL("%s: tls_record_c::state_notification(): ")
       
  3566 				 EAPL("waits TTLS/plain MsChapv2 empty Ack: EAP-type 0x%08x\n"),
       
  3567 				 (m_is_client == true ? "client": "server"),
       
  3568 				 convert_eap_type_to_u32_t(m_eap_type)));
       
  3569 		}
       
  3570 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  3571 
       
  3572 	}
       
  3573 
       
  3574 	get_type_partner()->state_notification(
       
  3575 			state);
       
  3576 }
       
  3577 
       
  3578 //--------------------------------------------------
       
  3579 
       
  3580 // This is commented in abs_tls_base_application_c.
       
  3581 EAP_FUNC_EXPORT eap_status_e tls_record_c::set_timer(
       
  3582 	abs_eap_base_timer_c * const initializer, 
       
  3583 	const u32_t id, 
       
  3584 	void * const data,
       
  3585 	const u32_t p_time_ms)
       
  3586 {
       
  3587 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3588 
       
  3589 	if (get_type_partner() == 0)
       
  3590 	{
       
  3591 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3592 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3593 	}
       
  3594 
       
  3595 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3596 	return get_type_partner()->set_timer(
       
  3597 		initializer, 
       
  3598 		id, 
       
  3599 		data,
       
  3600 		p_time_ms);
       
  3601 }
       
  3602 
       
  3603 //--------------------------------------------------
       
  3604 
       
  3605 // This is commented in abs_tls_base_application_c.
       
  3606 EAP_FUNC_EXPORT eap_status_e tls_record_c::cancel_timer(
       
  3607 	abs_eap_base_timer_c * const initializer, 
       
  3608 	const u32_t id)
       
  3609 {
       
  3610 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3611 
       
  3612 	if (get_type_partner() == 0)
       
  3613 	{
       
  3614 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3615 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3616 	}
       
  3617 
       
  3618 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3619 	return get_type_partner()->cancel_timer(
       
  3620 		initializer,
       
  3621 		id);
       
  3622 }
       
  3623 
       
  3624 //--------------------------------------------------
       
  3625 
       
  3626 // This is commented in abs_tls_base_application_c.
       
  3627 EAP_FUNC_EXPORT eap_status_e tls_record_c::cancel_all_timers()
       
  3628 {
       
  3629 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3630 
       
  3631 	if (get_type_partner() == 0)
       
  3632 	{
       
  3633 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3634 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3635 	}
       
  3636 
       
  3637 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3638 	return get_type_partner()->cancel_all_timers();
       
  3639 }
       
  3640 
       
  3641 //--------------------------------------------------
       
  3642 
       
  3643 // This is commented in abs_tls_base_application_c.
       
  3644 EAP_FUNC_EXPORT eap_status_e tls_record_c::load_module(
       
  3645 	const eap_type_value_e type,
       
  3646 	const eap_type_value_e tunneling_type,
       
  3647 	abs_eap_base_type_c * const partner,
       
  3648 	eap_base_type_c ** const eap_type,
       
  3649 	const bool is_client_when_true,
       
  3650 	const eap_am_network_id_c * const receive_network_id)
       
  3651 {
       
  3652 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3653 
       
  3654 	eap_status_e status = get_type_partner()->load_module(
       
  3655 		type,
       
  3656 		tunneling_type,
       
  3657 		partner,
       
  3658 		eap_type,
       
  3659 		is_client_when_true,
       
  3660 		receive_network_id);
       
  3661 	
       
  3662 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3663 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3664 }
       
  3665 
       
  3666 // This is commented in abs_tls_base_application_c.
       
  3667 EAP_FUNC_EXPORT eap_status_e tls_record_c::unload_module(const eap_type_value_e type)
       
  3668 {
       
  3669 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3670 
       
  3671 	eap_status_e status = get_type_partner()->unload_module(type);
       
  3672 
       
  3673 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3674 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3675 }
       
  3676 
       
  3677 // This is commented in abs_tls_base_application_c.
       
  3678 EAP_FUNC_EXPORT eap_status_e tls_record_c::restart_authentication(
       
  3679 	const eap_am_network_id_c * const receive_network_id,
       
  3680 	const bool is_client_when_true,
       
  3681 	const bool force_clean_restart,
       
  3682 	const bool from_timer)
       
  3683 {
       
  3684 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3685 
       
  3686 	eap_status_e status = get_type_partner()->restart_authentication(
       
  3687 		receive_network_id,
       
  3688 		is_client_when_true,
       
  3689 		force_clean_restart,
       
  3690 		from_timer);
       
  3691 
       
  3692 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3693 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3694 }
       
  3695 
       
  3696 // This is commented in abs_tls_base_application_c.
       
  3697 EAP_FUNC_EXPORT eap_status_e tls_record_c::packet_data_crypto_keys(
       
  3698 	const eap_am_network_id_c * const /* send_network_id */,
       
  3699 	const eap_master_session_key_c * const master_session_key)
       
  3700 {
       
  3701 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3702 
       
  3703 	EAP_TRACE_DEBUG(
       
  3704 		m_am_tools,
       
  3705 		TRACE_FLAGS_DEFAULT,
       
  3706 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::packet_data_crypto_keys()\n"),
       
  3707 		(m_is_client == true ? "client": "server")));
       
  3708 
       
  3709 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::packet_data_crypto_keys()");
       
  3710 
       
  3711 	if ((m_eap_type == eap_type_peap
       
  3712 			&& (m_peap_version == peap_version_0_xp
       
  3713 				|| m_peap_version == peap_version_1))
       
  3714 		|| m_eap_type == eap_type_ttls)
       
  3715 	{
       
  3716 		// We do not forward keys to lower layer.
       
  3717 	}
       
  3718 #if defined(USE_FAST_EAP_TYPE)
       
  3719 	else if (m_eap_type == eap_type_fast)
       
  3720 	{
       
  3721 		eap_status_e status = m_eap_master_session_key.set_copy_of_buffer(
       
  3722 			master_session_key);
       
  3723 		if (status != eap_status_ok)
       
  3724 		{
       
  3725 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3726 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3727 		}
       
  3728 
       
  3729 		// NOTE: state_notification() will deliver master_session_key to lower layers.
       
  3730 	}
       
  3731 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  3732 	else if (m_eap_type == eap_type_peap
       
  3733 				&& m_peap_version == peap_version_2)
       
  3734 	{
       
  3735 		eap_status_e status = m_eap_master_session_key.set_copy_of_buffer(
       
  3736 			master_session_key);
       
  3737 		if (status != eap_status_ok)
       
  3738 		{
       
  3739 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3740 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3741 		}
       
  3742 
       
  3743 		status = get_type_partner()->set_tls_master_secret(&m_eap_master_session_key);
       
  3744 		if (status != eap_status_ok)
       
  3745 		{
       
  3746 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3747 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3748 		}
       
  3749 	}
       
  3750 
       
  3751 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3752 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3753 }
       
  3754 
       
  3755 // This is commented in abs_tls_base_application_c.
       
  3756 EAP_FUNC_EXPORT eap_status_e tls_record_c::check_is_valid_eap_type(
       
  3757 	const eap_type_value_e eap_type)
       
  3758 {
       
  3759 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3760 
       
  3761 	eap_status_e status = get_type_partner()->check_is_valid_eap_type(eap_type);
       
  3762 
       
  3763 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3764 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3765 }
       
  3766 
       
  3767 // This is commented in abs_tls_base_application_c.
       
  3768 EAP_FUNC_EXPORT eap_status_e tls_record_c::get_eap_type_list(
       
  3769 	eap_array_c<eap_type_value_e> * const eap_type_list)
       
  3770 {
       
  3771 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3772 
       
  3773 	eap_status_e status = get_type_partner()->get_eap_type_list(eap_type_list);
       
  3774 
       
  3775 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3776 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3777 }
       
  3778 
       
  3779 //--------------------------------------------------
       
  3780 
       
  3781 //
       
  3782 EAP_FUNC_EXPORT eap_status_e tls_record_c::start_tls_peap_authentication(
       
  3783 	const eap_variable_data_c * const received_authority_identity_payload
       
  3784 	)
       
  3785 {
       
  3786 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3787 
       
  3788 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3789 	EAP_TRACE_DEBUG(
       
  3790 		m_am_tools,
       
  3791 		TRACE_FLAGS_DEFAULT,
       
  3792 		(EAPL("TLS: %s: message_function: starts: tls_record_c::start_tls_peap_authentication()\n"),
       
  3793 		(m_is_client == true ? "client": "server")));
       
  3794 
       
  3795 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::start_tls_peap_authentication()");
       
  3796 
       
  3797 	eap_status_e status = completion_action_add(tls_completion_action_query_cipher_suites_and_previous_session);
       
  3798 	if (status != eap_status_ok)
       
  3799 	{
       
  3800 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3801 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3802 	}
       
  3803 
       
  3804 	set_state(tls_peap_state_wait_handshake_type_server_hello);
       
  3805 
       
  3806 	status = completion_action_add(tls_completion_action_create_handshake_type_client_hello);
       
  3807 	if (status != eap_status_ok)
       
  3808 	{
       
  3809 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3810 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3811 	}
       
  3812 
       
  3813 #if defined(USE_FAST_EAP_TYPE)
       
  3814 	if (m_eap_type == eap_type_fast)
       
  3815 	{
       
  3816 		if (m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true)
       
  3817 		{
       
  3818 			set_tls_session_type(tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP);
       
  3819 		}
       
  3820 		else if (received_authority_identity_payload != 0
       
  3821 			&& received_authority_identity_payload->get_is_valid_data() == true)
       
  3822 		{
       
  3823 			eap_fast_variable_data_c in_A_ID_TLV(m_am_tools);
       
  3824 
       
  3825 			status = in_A_ID_TLV.set_copy_of_buffer(
       
  3826 				received_authority_identity_payload->get_data(),
       
  3827 				received_authority_identity_payload->get_data_length());
       
  3828 			if (status != eap_status_ok)
       
  3829 			{
       
  3830 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3831 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3832 			}
       
  3833 
       
  3834 			status = m_application->query_tunnel_PAC(
       
  3835 				&in_A_ID_TLV);
       
  3836 			if (status == eap_status_pending_request)
       
  3837 			{
       
  3838 				// This is pending query, that will be completed by
       
  3839 				// complete_query_tunnel_PAC() call.
       
  3840 				m_pending_query_tunnel_PAC = true;
       
  3841 
       
  3842 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3843 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3844 			}
       
  3845 			else if (status == eap_status_completed_request)
       
  3846 			{
       
  3847 				// This is already completed by complete_query_PACs() call.
       
  3848 
       
  3849 				status = check_sent_tls_message();
       
  3850 
       
  3851 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3852 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3853 			}
       
  3854 			else if (status == eap_status_ok)
       
  3855 			{
       
  3856 				// This is also an error case, because this call is always completed on success. 
       
  3857 				status = eap_status_process_general_error;
       
  3858 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3859 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3860 			}
       
  3861 			else // All other status values means error, because this call is always completed on success.
       
  3862 			{
       
  3863 				// This is an error case.
       
  3864 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3865 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  3866 			}
       
  3867 		}
       
  3868 	}
       
  3869 #else
       
  3870 	EAP_UNREFERENCED_PARAMETER(received_authority_identity_payload);
       
  3871 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  3872 
       
  3873 
       
  3874 	status = check_sent_tls_message();
       
  3875 
       
  3876 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3877 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3878 }
       
  3879 
       
  3880 //--------------------------------------------------
       
  3881 
       
  3882 //
       
  3883 EAP_FUNC_EXPORT eap_status_e tls_record_c::start_peap_tunneled_authentication(
       
  3884 	const eap_am_network_id_c * const receive_network_id,
       
  3885 	const u8_t received_eap_identifier,
       
  3886 	const tls_session_type_e tls_session_type)
       
  3887 {
       
  3888 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3889 
       
  3890 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3891 	EAP_TRACE_DEBUG(
       
  3892 		m_am_tools,
       
  3893 		TRACE_FLAGS_DEFAULT,
       
  3894 		(EAPL("TLS: %s: message_function: starts: tls_record_c::start_peap_tunneled_authentication()\n"),
       
  3895 		(m_is_client == true ? "client": "server")));
       
  3896 
       
  3897 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::start_peap_tunneled_authentication()");
       
  3898 
       
  3899 	if (m_is_client == true
       
  3900 		&& verify_state(tls_peap_state_peap_tunnel_ready) == false)
       
  3901 	{
       
  3902 		EAP_TRACE_ERROR(
       
  3903 			m_am_tools,
       
  3904 			TRACE_FLAGS_DEFAULT,
       
  3905 			(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
  3906 			 (m_is_client == true ? "client": "server"),
       
  3907 			 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
  3908 			 eap_tls_trace_string_c::get_state_string(tls_peap_state_peap_tunnel_ready)));
       
  3909 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  3910 	}
       
  3911 	else if (m_is_client == false
       
  3912 		&& verify_state(tls_peap_state_wait_tunneled_authentication_start) == false)
       
  3913 	{
       
  3914 		EAP_TRACE_ERROR(
       
  3915 			m_am_tools,
       
  3916 			TRACE_FLAGS_DEFAULT,
       
  3917 			(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
  3918 			 (m_is_client == true ? "client": "server"),
       
  3919 			 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
  3920 			 eap_tls_trace_string_c::get_state_string(tls_peap_state_wait_tunneled_authentication_start)));
       
  3921 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  3922 	}
       
  3923 	
       
  3924 
       
  3925 	set_state(tls_peap_state_wait_application_data);
       
  3926 
       
  3927 	eap_status_e status = eap_status_process_general_error;
       
  3928 
       
  3929 	{
       
  3930 		// This must be inside a block. Automatic variable must be restored after
       
  3931 		// the start_peap_tunneled_authentication() function call.
       
  3932 		eap_automatic_simple_value_c<bool> restore_allow_message_send(
       
  3933 			m_am_tools,
       
  3934 			&m_allow_message_send,
       
  3935 			m_allow_message_send);
       
  3936 
       
  3937 		// Packet send is delayed until after the
       
  3938 		// m_application->start_peap_tunneled_authentication() function returns.
       
  3939 		m_allow_message_send = false;
       
  3940 
       
  3941 		status = m_application->start_peap_tunneled_authentication(
       
  3942 			receive_network_id,
       
  3943 			m_is_client,
       
  3944 			received_eap_identifier,
       
  3945 			tls_session_type,
       
  3946 			m_tls_peap_server_authenticates_client_action);
       
  3947 	}
       
  3948 
       
  3949 
       
  3950 	{
       
  3951 		// Note this call will return eap_status_pending_request
       
  3952 		// if any asyncronous call is pending.
       
  3953 		eap_status_e send_status = check_sent_tls_message();
       
  3954 		if (send_status != eap_status_ok)
       
  3955 		{
       
  3956 			status = send_status;
       
  3957 		}
       
  3958 	}
       
  3959 
       
  3960 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3961 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3962 }
       
  3963 
       
  3964 //--------------------------------------------------
       
  3965 
       
  3966 EAP_FUNC_EXPORT eap_status_e tls_record_c::allocate_handshake_message_copy(
       
  3967 	tls_handshake_message_c ** const tls_handshake_message,
       
  3968 	eap_automatic_variable_c<tls_handshake_message_c> * const automatic_tls_handshake_message,
       
  3969 	tls_handshake_header_c * const tls_handshake_header)
       
  3970 {
       
  3971 	*tls_handshake_message
       
  3972 		= new tls_handshake_message_c(m_am_tools, this, m_is_client);
       
  3973 	
       
  3974 	automatic_tls_handshake_message->set_variable(*tls_handshake_message);
       
  3975 
       
  3976 	if (*tls_handshake_message == 0
       
  3977 		|| (*tls_handshake_message)->get_is_valid() == false)
       
  3978 	{
       
  3979 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3980 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3981 	}
       
  3982 
       
  3983 	eap_status_e status = (*tls_handshake_message)->set_handshake_header_copy(
       
  3984 		tls_handshake_header);
       
  3985 
       
  3986 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3987 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3988 }
       
  3989 
       
  3990 //--------------------------------------------------
       
  3991 
       
  3992 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  3993 
       
  3994 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_extension_list(
       
  3995 	const u32_t handshake_data_length,
       
  3996 	u32_t * const data_offset,
       
  3997 	const tls_handshake_header_c * const tls_handshake_header,
       
  3998 	tls_handshake_message_c * const tls_handshake_message
       
  3999 )
       
  4000 {
       
  4001 	EAP_TRACE_DEBUG(
       
  4002 		m_am_tools,
       
  4003 		TRACE_FLAGS_DEFAULT,
       
  4004 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::parse_tls_extension_list()\n"),
       
  4005 		(m_is_client == true ? "client": "server")));
       
  4006 
       
  4007 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_extension_list()");
       
  4008 
       
  4009 	eap_status_e status(eap_status_ok);
       
  4010 
       
  4011 	// This is optional field.
       
  4012 	if ((*data_offset)+TLS_EXTENSIONS_LENGTH_FIELD_SIZE <= handshake_data_length)
       
  4013 	{
       
  4014 		// Extension list is formatted as:
       
  4015 		// 0                   1                   2                   3   
       
  4016 		//  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 
       
  4017 		//                                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4018 		//                                 | extension list length         |
       
  4019 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4020 		// | extension 1 type              | extension 1 data length       |
       
  4021 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4022 		// | extension 1 data ...
       
  4023 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4024 		// | extension 2 type              | extension 2 data length       |
       
  4025 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4026 		// | extension 2 data ...
       
  4027 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4028 
       
  4029 		u8_t *p_extension_list = tls_handshake_header->get_data_offset(
       
  4030 			(*data_offset),
       
  4031 			TLS_EXTENSIONS_LENGTH_FIELD_SIZE);
       
  4032 		if (p_extension_list == 0)
       
  4033 		{
       
  4034 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4035 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4036 		}
       
  4037 
       
  4038 		(*data_offset) += TLS_EXTENSIONS_LENGTH_FIELD_SIZE;
       
  4039 
       
  4040 		u32_t extension_list_length(
       
  4041 			eap_read_u16_t_network_order(
       
  4042 				p_extension_list,
       
  4043 				TLS_EXTENSIONS_LENGTH_FIELD_SIZE));
       
  4044 
       
  4045 		if ((*data_offset)+extension_list_length > handshake_data_length)
       
  4046 		{
       
  4047 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4048 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4049 		}
       
  4050 
       
  4051 		const u32_t offset_end((*data_offset)+extension_list_length);
       
  4052 
       
  4053 		EAP_TRACE_DATA_DEBUG(
       
  4054 			m_am_tools,
       
  4055 			TRACE_FLAGS_DEFAULT,
       
  4056 			(EAPL("TLS-handshake extension payload"),
       
  4057 			p_extension_list,
       
  4058 			TLS_EXTENSIONS_LENGTH_FIELD_SIZE+extension_list_length));
       
  4059 
       
  4060 		if (extension_list_length > 0ul)
       
  4061 		{
       
  4062 			eap_array_c<tls_extension_c> extensions_array(m_am_tools);
       
  4063 
       
  4064 			while((*data_offset) < offset_end)
       
  4065 			{
       
  4066 				// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4067 
       
  4068 				if ((*data_offset)+TLS_EXTENSION_TYPE_FIELD_SIZE > handshake_data_length)
       
  4069 				{
       
  4070 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4071 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4072 				}
       
  4073 
       
  4074 				u8_t *p_extension_type = tls_handshake_header->get_data_offset(
       
  4075 					(*data_offset),
       
  4076 					TLS_EXTENSION_TYPE_FIELD_SIZE);
       
  4077 				if (p_extension_type == 0)
       
  4078 				{
       
  4079 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4080 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4081 				}
       
  4082 
       
  4083 				(*data_offset) += TLS_EXTENSION_TYPE_FIELD_SIZE;
       
  4084 
       
  4085 				u16_t extension_type_host(
       
  4086 					eap_read_u16_t_network_order(
       
  4087 						p_extension_type,
       
  4088 						TLS_EXTENSIONS_LENGTH_FIELD_SIZE));
       
  4089 
       
  4090 				tls_extension_type_e extension_type(static_cast<tls_extension_type_e>(extension_type_host));
       
  4091 
       
  4092 				// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4093 
       
  4094 				if ((*data_offset)+TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE > handshake_data_length)
       
  4095 				{
       
  4096 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4097 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4098 				}
       
  4099 
       
  4100 				u8_t *p_extension_data_length = tls_handshake_header->get_data_offset(
       
  4101 					(*data_offset),
       
  4102 					TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE);
       
  4103 				if (p_extension_data_length == 0)
       
  4104 				{
       
  4105 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4106 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4107 				}
       
  4108 
       
  4109 				(*data_offset) += TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE;
       
  4110 
       
  4111 				u16_t extension_data_length_host(
       
  4112 					eap_read_u16_t_network_order(
       
  4113 						p_extension_data_length,
       
  4114 						TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE));
       
  4115 
       
  4116 				// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4117 
       
  4118 				tls_extension_c * const tls_extension = new tls_extension_c(m_am_tools);
       
  4119 
       
  4120 				eap_automatic_variable_c<tls_extension_c>
       
  4121 					automatic_tls_extension(m_am_tools, tls_extension);
       
  4122 
       
  4123 				if (tls_extension == 0
       
  4124 					|| tls_extension->get_is_valid() == false)
       
  4125 				{
       
  4126 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4127 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4128 				}
       
  4129 
       
  4130 				tls_extension->set_type(extension_type);
       
  4131 
       
  4132 				// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4133 
       
  4134 				if (extension_data_length_host > 0ul)
       
  4135 				{
       
  4136 					if ((*data_offset)+extension_data_length_host > handshake_data_length)
       
  4137 					{
       
  4138 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4139 						return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4140 					}
       
  4141 
       
  4142 					const u8_t * const p_extension_data = tls_handshake_header->get_data_offset(
       
  4143 						(*data_offset),
       
  4144 						extension_data_length_host);
       
  4145 					if (p_extension_data == 0)
       
  4146 					{
       
  4147 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4148 						return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4149 					}
       
  4150 
       
  4151 					status = tls_extension->set_copy_of_buffer(p_extension_data, extension_data_length_host);
       
  4152 					if (status != eap_status_ok)
       
  4153 					{
       
  4154 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4155 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  4156 					}
       
  4157 
       
  4158 					(*data_offset) += extension_data_length_host;
       
  4159 				}
       
  4160 
       
  4161 				// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4162 
       
  4163 				automatic_tls_extension.do_not_free_variable();
       
  4164 
       
  4165 				// add_object() will delete extension if operation fails.
       
  4166 				status = extensions_array.add_object(tls_extension, true);
       
  4167 				if (status != eap_status_ok)
       
  4168 				{
       
  4169 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4170 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4171 				}
       
  4172 
       
  4173 			} // while()
       
  4174 
       
  4175 			status = tls_handshake_message->set_tls_extensions(&extensions_array);
       
  4176 			if (status != eap_status_ok)
       
  4177 			{
       
  4178 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4179 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4180 			}
       
  4181 		}
       
  4182 	}
       
  4183 
       
  4184 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4185 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4186 }
       
  4187 
       
  4188 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  4189 
       
  4190 //--------------------------------------------------
       
  4191 
       
  4192 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_hello_request(
       
  4193 	tls_record_message_c * const received_tls_record_message,
       
  4194 	tls_handshake_header_c * const tls_handshake_header,
       
  4195 	const u32_t handshake_data_length)
       
  4196 {
       
  4197 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4198 
       
  4199 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4200 	EAP_TRACE_DEBUG(
       
  4201 		m_am_tools,
       
  4202 		TRACE_FLAGS_DEFAULT,
       
  4203 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_hello_request()\n"),
       
  4204 		(m_is_client == true ? "client": "server")));
       
  4205 
       
  4206 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_hello_request()");
       
  4207 
       
  4208 	tls_handshake_message_c *tls_handshake_message = 0;
       
  4209 
       
  4210 	eap_automatic_variable_c<tls_handshake_message_c>
       
  4211 		automatic_tls_handshake_message(m_am_tools);
       
  4212 
       
  4213 	eap_status_e status = allocate_handshake_message_copy(
       
  4214 		&tls_handshake_message,
       
  4215 		&automatic_tls_handshake_message,
       
  4216 		tls_handshake_header);
       
  4217 	if (status != eap_status_ok)
       
  4218 	{
       
  4219 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4220 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4221 	}
       
  4222 
       
  4223 	if (handshake_data_length != 0ul)
       
  4224 	{
       
  4225 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4226 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message);
       
  4227 	}
       
  4228 
       
  4229 	if (status == eap_status_ok)
       
  4230 	{
       
  4231 		// Note the add_handshake_message() frees message in any case.
       
  4232 		automatic_tls_handshake_message.do_not_free_variable();
       
  4233 
       
  4234 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  4235 		if (status != eap_status_ok)
       
  4236 		{
       
  4237 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4238 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4239 		}
       
  4240 	}
       
  4241 
       
  4242 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4243 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4244 }
       
  4245 
       
  4246 //--------------------------------------------------
       
  4247 
       
  4248 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_client_hello(
       
  4249 	tls_record_message_c * const received_tls_record_message,
       
  4250 	tls_handshake_header_c * const tls_handshake_header,
       
  4251 	const u32_t handshake_data_length)
       
  4252 {
       
  4253 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4254 
       
  4255 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4256 	EAP_TRACE_DEBUG(
       
  4257 		m_am_tools,
       
  4258 		TRACE_FLAGS_DEFAULT,
       
  4259 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_client_hello()\n"),
       
  4260 		(m_is_client == true ? "client": "server")));
       
  4261 
       
  4262 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_client_hello()");
       
  4263 
       
  4264 	tls_handshake_message_c *tls_handshake_message = 0;
       
  4265 
       
  4266 	eap_automatic_variable_c<tls_handshake_message_c>
       
  4267 		automatic_tls_handshake_message(m_am_tools);
       
  4268 
       
  4269 	eap_status_e status = allocate_handshake_message_copy(
       
  4270 		&tls_handshake_message,
       
  4271 		&automatic_tls_handshake_message,
       
  4272 		tls_handshake_header);
       
  4273 	if (status != eap_status_ok)
       
  4274 	{
       
  4275 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4276 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4277 	}
       
  4278 
       
  4279 	u32_t data_offset = 0ul;
       
  4280 	u8_t * const handshake_data = tls_handshake_header->get_data_offset(
       
  4281 		data_offset,
       
  4282 		tls_handshake_header->get_data_length());
       
  4283 	if (handshake_data == 0)
       
  4284 	{
       
  4285 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4286 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4287 	}
       
  4288 
       
  4289 	//----------------------------------------------------------
       
  4290 
       
  4291 	{
       
  4292 		if (data_offset+TLS_VERSION_FIELD_SIZE > handshake_data_length)
       
  4293 		{
       
  4294 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4295 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4296 		}
       
  4297 		
       
  4298 		u8_t *p_version = handshake_data;
       
  4299 		u16_t version = eap_read_u16_t_network_order(p_version, TLS_VERSION_FIELD_SIZE);
       
  4300 		
       
  4301 		if (version != tls_version_3_1)
       
  4302 		{
       
  4303 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4304 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  4305 		}
       
  4306 		
       
  4307 		data_offset += TLS_VERSION_FIELD_SIZE;
       
  4308 	}
       
  4309 
       
  4310 	//----------------------------------------------------------
       
  4311 
       
  4312 	{
       
  4313 		if (data_offset+TLS_HANDSHAKE_RANDOM_VALUE_SIZE > handshake_data_length)
       
  4314 		{
       
  4315 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4316 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4317 		}
       
  4318 		
       
  4319 		u8_t *p_random_value = tls_handshake_header->get_data_offset(
       
  4320 			data_offset,
       
  4321 			TLS_HANDSHAKE_RANDOM_VALUE_SIZE);
       
  4322 		if (p_random_value == 0)
       
  4323 		{
       
  4324 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4325 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4326 		}
       
  4327 		eap_variable_data_c client_random_value(m_am_tools);
       
  4328 		status = client_random_value.set_buffer(
       
  4329 			p_random_value,
       
  4330 			TLS_HANDSHAKE_RANDOM_VALUE_SIZE,
       
  4331 			false,
       
  4332 			false);
       
  4333 		if (status != eap_status_ok)
       
  4334 		{
       
  4335 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4336 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4337 		}
       
  4338 		
       
  4339 		status = tls_handshake_message->set_random_value(&client_random_value);
       
  4340 		if (status != eap_status_ok)
       
  4341 		{
       
  4342 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4343 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4344 		}
       
  4345 
       
  4346 		data_offset += TLS_HANDSHAKE_RANDOM_VALUE_SIZE;
       
  4347 
       
  4348 		EAP_TRACE_DATA_DEBUG(
       
  4349 			m_am_tools,
       
  4350 			TRACE_FLAGS_DEFAULT,
       
  4351 			(EAPL("TLS: parse_handshake_type_client_hello(): m_client_random_value"),
       
  4352 			 client_random_value.get_data(client_random_value.get_data_length()),
       
  4353 			 client_random_value.get_data_length()));
       
  4354 	}
       
  4355 
       
  4356 	//----------------------------------------------------------
       
  4357 
       
  4358 	{
       
  4359 		if (data_offset+TLS_SESSION_ID_LENGTH_FIELD_SIZE > handshake_data_length)
       
  4360 		{
       
  4361 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4362 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4363 		}
       
  4364 		
       
  4365 		u8_t *p_session_id_length = tls_handshake_header->get_data_offset(
       
  4366 			data_offset,
       
  4367 			TLS_SESSION_ID_LENGTH_FIELD_SIZE);
       
  4368 		if (p_session_id_length == 0)
       
  4369 		{
       
  4370 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4371 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4372 		}
       
  4373 		data_offset += TLS_SESSION_ID_LENGTH_FIELD_SIZE;
       
  4374 
       
  4375 		if (data_offset+*p_session_id_length > handshake_data_length)
       
  4376 		{
       
  4377 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4378 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4379 		}
       
  4380 		
       
  4381 		if (*p_session_id_length > 0ul)
       
  4382 		{
       
  4383 			u8_t *p_session_id = tls_handshake_header->get_data_offset(
       
  4384 				data_offset,
       
  4385 				*p_session_id_length);
       
  4386 			if (p_session_id == 0)
       
  4387 			{
       
  4388 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4389 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4390 			}
       
  4391 
       
  4392 			eap_variable_data_c session_id(m_am_tools);
       
  4393 			status = session_id.set_buffer(p_session_id, *p_session_id_length, false, false);
       
  4394 			if (status != eap_status_ok)
       
  4395 			{
       
  4396 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4397 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4398 			}
       
  4399 
       
  4400 			status = tls_handshake_message->set_session_id(&session_id);
       
  4401 			if (status != eap_status_ok)
       
  4402 			{
       
  4403 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4404 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4405 			}
       
  4406 		}
       
  4407 
       
  4408 		data_offset += *p_session_id_length;
       
  4409 	}
       
  4410 
       
  4411 	//----------------------------------------------------------
       
  4412 
       
  4413 	{
       
  4414 		if (data_offset+TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE > handshake_data_length)
       
  4415 		{
       
  4416 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4417 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4418 		}
       
  4419 		
       
  4420 		u8_t *p_cipher_suite_length_network_order = tls_handshake_header->get_data_offset(
       
  4421 			data_offset,
       
  4422 			TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE);
       
  4423 		if (p_cipher_suite_length_network_order == 0)
       
  4424 		{
       
  4425 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4426 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4427 		}
       
  4428 		u16_t cipher_suite_length = eap_read_u16_t_network_order(
       
  4429 			p_cipher_suite_length_network_order,
       
  4430 			TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE);
       
  4431 		data_offset += TLS_CIPHER_SUITE_LENGTH_FIELD_SIZE;
       
  4432 
       
  4433 		if (data_offset+cipher_suite_length > handshake_data_length)
       
  4434 		{
       
  4435 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4436 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4437 		}
       
  4438 
       
  4439 		if ((cipher_suite_length % 2) != 0)
       
  4440 		{
       
  4441 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4442 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  4443 		}
       
  4444 
       
  4445 		if (cipher_suite_length > 0ul)
       
  4446 		{
       
  4447 			u8_t *p_cipher_suite = tls_handshake_header->get_data_offset(
       
  4448 				data_offset,
       
  4449 				cipher_suite_length);
       
  4450 			if (p_cipher_suite == 0)
       
  4451 			{
       
  4452 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4453 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4454 			}
       
  4455 
       
  4456 			eap_array_c<u16_t> cipher_suites_array(m_am_tools);
       
  4457 
       
  4458 			for (u32_t ind = 0ul; ind < cipher_suite_length; ind += 2ul)
       
  4459 			{
       
  4460 				u16_t * const cipher_suite = new u16_t;
       
  4461 				if (cipher_suite == 0)
       
  4462 				{
       
  4463 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4464 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4465 				}
       
  4466 
       
  4467 				u16_t cipher_suite_host_order = eap_read_u16_t_network_order(
       
  4468 					p_cipher_suite,
       
  4469 					TLS_CIPHER_SUITE_FIELD_SIZE);
       
  4470 				*cipher_suite = cipher_suite_host_order;
       
  4471 
       
  4472 				// add_object() will delete cipher_suite if operation fails.
       
  4473 				status = cipher_suites_array.add_object(cipher_suite, true);
       
  4474 				if (status != eap_status_ok)
       
  4475 				{
       
  4476 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4477 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4478 				}
       
  4479 
       
  4480 				p_cipher_suite += TLS_CIPHER_SUITE_FIELD_SIZE;
       
  4481 			} // for()
       
  4482 
       
  4483 			status = tls_handshake_message->set_cipher_suites(&cipher_suites_array);
       
  4484 			if (status != eap_status_ok)
       
  4485 			{
       
  4486 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4487 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4488 			}
       
  4489 		}
       
  4490 
       
  4491 		data_offset += cipher_suite_length;
       
  4492 	}
       
  4493 
       
  4494 	//----------------------------------------------------------
       
  4495 
       
  4496 	{
       
  4497 		if (data_offset+TLS_COMPRESSION_LENGTH_FIELD_SIZE > handshake_data_length)
       
  4498 		{
       
  4499 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4500 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4501 		}
       
  4502 		
       
  4503 		u8_t *p_compression_length = tls_handshake_header->get_data_offset(
       
  4504 			data_offset,
       
  4505 			TLS_COMPRESSION_LENGTH_FIELD_SIZE);
       
  4506 		if (p_compression_length == 0)
       
  4507 		{
       
  4508 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4509 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4510 		}
       
  4511 		data_offset += TLS_COMPRESSION_LENGTH_FIELD_SIZE;
       
  4512 
       
  4513 		if (data_offset+*p_compression_length > handshake_data_length)
       
  4514 		{
       
  4515 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4516 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4517 		}
       
  4518 
       
  4519 		if (*p_compression_length > 0ul)
       
  4520 		{
       
  4521 			u8_t *p_compression = tls_handshake_header->get_data_offset(
       
  4522 				data_offset,
       
  4523 				*p_compression_length);
       
  4524 			if (p_compression == 0)
       
  4525 			{
       
  4526 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4527 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4528 			}
       
  4529 
       
  4530 			eap_array_c<u8_t> compression_array(m_am_tools);
       
  4531 
       
  4532 			for (u32_t ind = 0ul; ind < *p_compression_length; ind++)
       
  4533 			{
       
  4534 				u8_t * const compression_value = new u8_t;
       
  4535 				if (compression_value == 0)
       
  4536 				{
       
  4537 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4538 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4539 				}
       
  4540 				*compression_value = *p_compression;
       
  4541 
       
  4542 				// add_object() will delete compression_value if operation fails.
       
  4543 				status = compression_array.add_object(compression_value, true);
       
  4544 				if (status != eap_status_ok)
       
  4545 				{
       
  4546 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4547 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4548 				}
       
  4549 
       
  4550 				p_compression += TLS_COMPRESSION_FIELD_SIZE;
       
  4551 			} // for()
       
  4552 
       
  4553 			status = tls_handshake_message->set_compression_methods(&compression_array);
       
  4554 			if (status != eap_status_ok)
       
  4555 			{
       
  4556 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4557 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4558 			}
       
  4559 		}
       
  4560 
       
  4561 		data_offset += *p_compression_length;
       
  4562 	}
       
  4563 
       
  4564 	//----------------------------------------------------------
       
  4565 
       
  4566 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  4567 
       
  4568 	status = parse_tls_extension_list(
       
  4569 		handshake_data_length,
       
  4570 		&data_offset,
       
  4571 		tls_handshake_header,
       
  4572 		tls_handshake_message);
       
  4573 	if (status != eap_status_ok)
       
  4574 	{
       
  4575 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4576 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4577 	}
       
  4578 
       
  4579 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  4580 
       
  4581 	//----------------------------------------------------------
       
  4582 
       
  4583 	if (status == eap_status_ok)
       
  4584 	{
       
  4585 		// Note the add_handshake_message() frees message in any case.
       
  4586 		automatic_tls_handshake_message.do_not_free_variable();
       
  4587 
       
  4588 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  4589 		if (status != eap_status_ok)
       
  4590 		{
       
  4591 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4592 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4593 		}
       
  4594 
       
  4595 		status = message_hash_init();
       
  4596 		if (status != eap_status_ok)
       
  4597 		{
       
  4598 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4599 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4600 		}
       
  4601 	}
       
  4602 
       
  4603 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4604 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4605 }
       
  4606 
       
  4607 //--------------------------------------------------
       
  4608 
       
  4609 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_certificate(
       
  4610 	tls_record_message_c * const received_tls_record_message,
       
  4611 	tls_handshake_header_c * const tls_handshake_header,
       
  4612 	const u32_t handshake_data_length)
       
  4613 {
       
  4614 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4615 
       
  4616 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4617 	EAP_TRACE_DEBUG(
       
  4618 		m_am_tools,
       
  4619 		TRACE_FLAGS_DEFAULT,
       
  4620 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_certificate()\n"),
       
  4621 		(m_is_client == true ? "client": "server")));
       
  4622 
       
  4623 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_certificate()");
       
  4624 
       
  4625 	tls_handshake_message_c *tls_handshake_message = 0;
       
  4626 
       
  4627 	eap_automatic_variable_c<tls_handshake_message_c>
       
  4628 		automatic_tls_handshake_message(m_am_tools);
       
  4629 
       
  4630 	eap_status_e status = allocate_handshake_message_copy(
       
  4631 		&tls_handshake_message,
       
  4632 		&automatic_tls_handshake_message,
       
  4633 		tls_handshake_header);
       
  4634 	if (status != eap_status_ok)
       
  4635 	{
       
  4636 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4637 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4638 	}
       
  4639 
       
  4640 	u32_t data_offset = 0ul;
       
  4641 
       
  4642 	//----------------------------------------------------------
       
  4643 
       
  4644 	{
       
  4645 		if (data_offset+(TLS_CERTIFICATE_LENGTH_FIELD_SIZE) > handshake_data_length)
       
  4646 		{
       
  4647 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4648 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4649 		}
       
  4650 
       
  4651 		u8_t *p_certificate_chain_length = tls_handshake_header->get_data_offset(
       
  4652 			data_offset,
       
  4653 			(TLS_CERTIFICATE_LENGTH_FIELD_SIZE));
       
  4654 		if (p_certificate_chain_length == 0)
       
  4655 		{
       
  4656 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4657 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4658 		}
       
  4659 
       
  4660 		u32_t certificate_chain_length = 
       
  4661 			eap_read_u24_t_network_order(
       
  4662 				p_certificate_chain_length,
       
  4663 				TLS_CERTIFICATE_LENGTH_FIELD_SIZE);
       
  4664 
       
  4665 		data_offset += (TLS_CERTIFICATE_LENGTH_FIELD_SIZE);
       
  4666 
       
  4667 		if (certificate_chain_length > 0ul)
       
  4668 		{
       
  4669 			eap_array_c<eap_variable_data_c> certificate_chain(m_am_tools);
       
  4670 			u32_t max_data_offset = data_offset + certificate_chain_length;
       
  4671 
       
  4672 			for (;data_offset < max_data_offset;)
       
  4673 			{
       
  4674 				u8_t *p_certificate_length = tls_handshake_header->get_data_offset(
       
  4675 					data_offset,
       
  4676 					(TLS_CERTIFICATE_LENGTH_FIELD_SIZE));
       
  4677 				if (p_certificate_length == 0)
       
  4678 				{
       
  4679 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4680 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4681 				}
       
  4682 				
       
  4683 				u32_t certificate_length = 
       
  4684 					eap_read_u24_t_network_order(
       
  4685 						p_certificate_length,
       
  4686 						TLS_CERTIFICATE_LENGTH_FIELD_SIZE);
       
  4687 
       
  4688 				data_offset += (TLS_CERTIFICATE_LENGTH_FIELD_SIZE);
       
  4689 
       
  4690 
       
  4691 				eap_variable_data_c * const certificate = new eap_variable_data_c(m_am_tools);
       
  4692 
       
  4693 				eap_automatic_variable_c<eap_variable_data_c>
       
  4694 					automatic_certificate(m_am_tools, certificate);
       
  4695 
       
  4696 				if (certificate == 0)
       
  4697 				{
       
  4698 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4699 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4700 				}
       
  4701 
       
  4702 
       
  4703 				u8_t *p_certificate = tls_handshake_header->get_data_offset(
       
  4704 					data_offset,
       
  4705 					certificate_length);
       
  4706 				if (p_certificate == 0)
       
  4707 				{
       
  4708 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4709 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4710 				}
       
  4711 
       
  4712 				status = certificate->set_copy_of_buffer(p_certificate, certificate_length);
       
  4713 				if (status != eap_status_ok)
       
  4714 				{
       
  4715 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4716 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4717 				}
       
  4718 
       
  4719 				automatic_certificate.do_not_free_variable();
       
  4720 
       
  4721 				// add_object() will delete certificate if operation fails.
       
  4722 				status = certificate_chain.add_object(certificate, true);
       
  4723 				if (status != eap_status_ok)
       
  4724 				{
       
  4725 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4726 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4727 				}
       
  4728 
       
  4729 				data_offset += certificate_length;
       
  4730 			} // for()
       
  4731 
       
  4732 			status = tls_handshake_message->set_certificate_chain(&certificate_chain);
       
  4733 			if (status != eap_status_ok)
       
  4734 			{
       
  4735 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4736 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4737 			}
       
  4738 		}
       
  4739 
       
  4740 		data_offset += certificate_chain_length;
       
  4741 	}
       
  4742 
       
  4743 	//----------------------------------------------------------
       
  4744 
       
  4745 	if (status == eap_status_ok)
       
  4746 	{
       
  4747 		// Note the add_handshake_message() frees message in any case.
       
  4748 		automatic_tls_handshake_message.do_not_free_variable();
       
  4749 
       
  4750 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  4751 		if (status != eap_status_ok)
       
  4752 		{
       
  4753 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4754 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4755 		}
       
  4756 	}
       
  4757 
       
  4758 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4759 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4760 }
       
  4761 
       
  4762 //--------------------------------------------------
       
  4763 
       
  4764 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_certificate_request(
       
  4765 	tls_record_message_c * const received_tls_record_message,
       
  4766 	tls_handshake_header_c * const tls_handshake_header,
       
  4767 	const u32_t handshake_data_length)
       
  4768 {
       
  4769 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4770 
       
  4771 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4772 	EAP_TRACE_DEBUG(
       
  4773 		m_am_tools,
       
  4774 		TRACE_FLAGS_DEFAULT,
       
  4775 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_certificate_request()\n"),
       
  4776 		(m_is_client == true ? "client": "server")));
       
  4777 
       
  4778 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_certificate_request()");
       
  4779 
       
  4780 	tls_handshake_message_c *tls_handshake_message = 0;
       
  4781 
       
  4782 	eap_automatic_variable_c<tls_handshake_message_c>
       
  4783 		automatic_tls_handshake_message(m_am_tools);
       
  4784 
       
  4785 	eap_status_e status = allocate_handshake_message_copy(
       
  4786 		&tls_handshake_message,
       
  4787 		&automatic_tls_handshake_message,
       
  4788 		tls_handshake_header);
       
  4789 	if (status != eap_status_ok)
       
  4790 	{
       
  4791 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4792 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4793 	}
       
  4794 
       
  4795 	u32_t data_offset = 0ul;
       
  4796 
       
  4797 	//----------------------------------------------------------
       
  4798 
       
  4799 	{
       
  4800 		if (data_offset+TLS_CERTIFICATE_TYPE_LENGTH_FIELD_SIZE > handshake_data_length)
       
  4801 		{
       
  4802 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4803 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4804 		}
       
  4805 		
       
  4806 		u8_t *p_certificate_type_length = tls_handshake_header->get_data_offset(
       
  4807 			data_offset,
       
  4808 			TLS_CERTIFICATE_TYPE_LENGTH_FIELD_SIZE);
       
  4809 		if (p_certificate_type_length == 0)
       
  4810 		{
       
  4811 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4812 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4813 		}
       
  4814 		data_offset += TLS_CERTIFICATE_TYPE_LENGTH_FIELD_SIZE;
       
  4815 
       
  4816 		if (data_offset+*p_certificate_type_length > handshake_data_length)
       
  4817 		{
       
  4818 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4819 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4820 		}
       
  4821 
       
  4822 		if (*p_certificate_type_length > 0ul)
       
  4823 		{
       
  4824 			u8_t *p_certificate_type = tls_handshake_header->get_data_offset(
       
  4825 				data_offset,
       
  4826 				*p_certificate_type_length);
       
  4827 			if (p_certificate_type == 0)
       
  4828 			{
       
  4829 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4830 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4831 			}
       
  4832 
       
  4833 			eap_array_c<u8_t> certificate_type_array(m_am_tools);
       
  4834 
       
  4835 			for (u32_t ind = 0ul; ind < *p_certificate_type_length; ind++)
       
  4836 			{
       
  4837 				u8_t * const certificate_type_value = new u8_t;
       
  4838 				if (certificate_type_value == 0)
       
  4839 				{
       
  4840 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4841 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4842 				}
       
  4843 				*certificate_type_value = *p_certificate_type;
       
  4844 
       
  4845 				// add_object() will delete certificate_type_value if operation fails.
       
  4846 				status = certificate_type_array.add_object(certificate_type_value, true);
       
  4847 				if (status != eap_status_ok)
       
  4848 				{
       
  4849 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4850 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4851 				}
       
  4852 
       
  4853 				p_certificate_type += TLS_CERTIFICATE_TYPE_FIELD_SIZE;
       
  4854 			} // for()
       
  4855 
       
  4856 			status = tls_handshake_message->set_certificate_types(&certificate_type_array);
       
  4857 			if (status != eap_status_ok)
       
  4858 			{
       
  4859 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4860 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4861 			}
       
  4862 		}
       
  4863 
       
  4864 		data_offset += *p_certificate_type_length;
       
  4865 	}
       
  4866 
       
  4867 	//----------------------------------------------------------
       
  4868 
       
  4869 	{
       
  4870 		if (data_offset+TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE > handshake_data_length)
       
  4871 		{
       
  4872 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4873 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4874 		}
       
  4875 
       
  4876 		u8_t *p_certificate_authorities_length = tls_handshake_header->get_data_offset(
       
  4877 			data_offset,
       
  4878 			TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE);
       
  4879 		if (p_certificate_authorities_length == 0)
       
  4880 		{
       
  4881 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4882 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4883 		}
       
  4884 
       
  4885 		u32_t certificate_authorities_length = 
       
  4886 			eap_read_u16_t_network_order(
       
  4887 				p_certificate_authorities_length,
       
  4888 				TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE);
       
  4889 
       
  4890 		data_offset += TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE;
       
  4891 
       
  4892 		if (certificate_authorities_length > 0ul)
       
  4893 		{
       
  4894 			eap_array_c<eap_variable_data_c> certificate_authorities(m_am_tools);
       
  4895 			u32_t max_data_offset = data_offset + certificate_authorities_length;
       
  4896 
       
  4897 			for (;data_offset < max_data_offset;)
       
  4898 			{
       
  4899 				u8_t *p_certificate_authority_length = tls_handshake_header->get_data_offset(
       
  4900 					data_offset,
       
  4901 					TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE);
       
  4902 				if (p_certificate_authority_length == 0)
       
  4903 				{
       
  4904 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4905 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4906 				}
       
  4907 				
       
  4908 				u32_t certificate_authority_length = 
       
  4909 					eap_read_u16_t_network_order(
       
  4910 						p_certificate_authority_length,
       
  4911 						TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE);
       
  4912 
       
  4913 				data_offset += TLS_CERTIFICATE_AUTHORITIES_LENGTH_FIELD_SIZE;
       
  4914 
       
  4915 				{
       
  4916 					eap_variable_data_c * const certificate_authority
       
  4917 						= new eap_variable_data_c(m_am_tools);
       
  4918 
       
  4919 					eap_automatic_variable_c<eap_variable_data_c>
       
  4920 						automatic_certificate_authority(m_am_tools, certificate_authority);
       
  4921 
       
  4922 					if (certificate_authority == 0)
       
  4923 					{
       
  4924 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4925 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4926 					}
       
  4927 
       
  4928 
       
  4929 					u8_t *p_certificate_authority = tls_handshake_header->get_data_offset(
       
  4930 						data_offset,
       
  4931 						certificate_authority_length);
       
  4932 					if (p_certificate_authority == 0)
       
  4933 					{
       
  4934 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4935 						return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  4936 					}
       
  4937 
       
  4938 					status = certificate_authority->set_copy_of_buffer(
       
  4939 						p_certificate_authority,
       
  4940 						certificate_authority_length);
       
  4941 					if (status != eap_status_ok)
       
  4942 					{
       
  4943 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4944 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4945 					}
       
  4946 
       
  4947 					automatic_certificate_authority.do_not_free_variable();
       
  4948 
       
  4949 					// add_object() will delete certificate_authority if operation fails.
       
  4950 					status = certificate_authorities.add_object(certificate_authority, true);
       
  4951 					if (status != eap_status_ok)
       
  4952 					{
       
  4953 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4954 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  4955 					}
       
  4956 				}
       
  4957 
       
  4958 				data_offset += certificate_authority_length;
       
  4959 			} // for()
       
  4960 
       
  4961 			status = tls_handshake_message->set_certificate_authorities(&certificate_authorities);
       
  4962 			if (status != eap_status_ok)
       
  4963 			{
       
  4964 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4965 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4966 			}
       
  4967 		}
       
  4968 
       
  4969 		data_offset += certificate_authorities_length;
       
  4970 	}
       
  4971 
       
  4972 	//----------------------------------------------------------
       
  4973 
       
  4974 	if (status == eap_status_ok)
       
  4975 	{
       
  4976 		// Note the add_handshake_message() frees message in any case.
       
  4977 		automatic_tls_handshake_message.do_not_free_variable();
       
  4978 
       
  4979 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  4980 		if (status != eap_status_ok)
       
  4981 		{
       
  4982 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4983 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4984 		}
       
  4985 	}
       
  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 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_server_hello_done(
       
  4994 	tls_record_message_c * const received_tls_record_message,
       
  4995 	tls_handshake_header_c * const tls_handshake_header,
       
  4996 	const u32_t /* handshake_data_length */)
       
  4997 {
       
  4998 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4999 
       
  5000 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5001 	EAP_TRACE_DEBUG(
       
  5002 		m_am_tools,
       
  5003 		TRACE_FLAGS_DEFAULT,
       
  5004 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_hello_done()\n"),
       
  5005 		(m_is_client == true ? "client": "server")));
       
  5006 
       
  5007 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_server_hello_done()");
       
  5008 
       
  5009 	tls_handshake_message_c *tls_handshake_message = 0;
       
  5010 
       
  5011 	eap_automatic_variable_c<tls_handshake_message_c>
       
  5012 		automatic_tls_handshake_message(m_am_tools);
       
  5013 
       
  5014 	eap_status_e status = allocate_handshake_message_copy(
       
  5015 		&tls_handshake_message,
       
  5016 		&automatic_tls_handshake_message,
       
  5017 		tls_handshake_header);
       
  5018 	if (status != eap_status_ok)
       
  5019 	{
       
  5020 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5021 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5022 	}
       
  5023 
       
  5024 	if (tls_handshake_header->get_data_length() > 0ul)
       
  5025 	{
       
  5026 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5027 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message);
       
  5028 	}
       
  5029 
       
  5030 	//----------------------------------------------------------
       
  5031 
       
  5032 	if (status == eap_status_ok)
       
  5033 	{
       
  5034 		// Note the add_handshake_message() frees message in any case.
       
  5035 		automatic_tls_handshake_message.do_not_free_variable();
       
  5036 
       
  5037 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  5038 		if (status != eap_status_ok)
       
  5039 		{
       
  5040 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5041 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5042 		}
       
  5043 	}
       
  5044 
       
  5045 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5046 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5047 }
       
  5048 
       
  5049 //--------------------------------------------------
       
  5050 
       
  5051 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_server_hello(
       
  5052 	tls_record_message_c * const received_tls_record_message,
       
  5053 	tls_handshake_header_c * const tls_handshake_header,
       
  5054 	const u32_t handshake_data_length)
       
  5055 {
       
  5056 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5057 
       
  5058 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5059 	EAP_TRACE_DEBUG(
       
  5060 		m_am_tools,
       
  5061 		TRACE_FLAGS_DEFAULT,
       
  5062 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_hello()\n"),
       
  5063 		(m_is_client == true ? "client": "server")));
       
  5064 
       
  5065 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_server_hello()");
       
  5066 
       
  5067 	tls_handshake_message_c *tls_handshake_message = 0;
       
  5068 
       
  5069 	eap_automatic_variable_c<tls_handshake_message_c>
       
  5070 		automatic_tls_handshake_message(m_am_tools);
       
  5071 
       
  5072 	eap_status_e status = allocate_handshake_message_copy(
       
  5073 		&tls_handshake_message,
       
  5074 		&automatic_tls_handshake_message,
       
  5075 		tls_handshake_header);
       
  5076 	if (status != eap_status_ok)
       
  5077 	{
       
  5078 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5079 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5080 	}
       
  5081 
       
  5082 	u32_t data_offset = 0ul;
       
  5083 
       
  5084 	u8_t * handshake_data = tls_handshake_header->get_data_offset(
       
  5085 		data_offset,
       
  5086 		tls_handshake_header->get_data_length());
       
  5087 	if (handshake_data == 0)
       
  5088 	{
       
  5089 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5090 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5091 	}
       
  5092 
       
  5093 	//----------------------------------------------------------
       
  5094 
       
  5095 	{
       
  5096 		if (data_offset+TLS_VERSION_FIELD_SIZE > handshake_data_length)
       
  5097 		{
       
  5098 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5099 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5100 		}
       
  5101 		
       
  5102 		u8_t *p_version = handshake_data;
       
  5103 		u16_t version = eap_read_u16_t_network_order(p_version, TLS_VERSION_FIELD_SIZE);
       
  5104 		
       
  5105 		if (version != tls_version_3_1)
       
  5106 		{
       
  5107 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5108 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  5109 		}
       
  5110 		
       
  5111 		data_offset += TLS_VERSION_FIELD_SIZE;
       
  5112 	}
       
  5113 
       
  5114 	//----------------------------------------------------------
       
  5115 
       
  5116 	{
       
  5117 		if (data_offset+TLS_HANDSHAKE_RANDOM_VALUE_SIZE > handshake_data_length)
       
  5118 		{
       
  5119 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5120 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5121 		}
       
  5122 		
       
  5123 		u8_t *p_random_value = tls_handshake_header->get_data_offset(
       
  5124 			data_offset,
       
  5125 			TLS_HANDSHAKE_RANDOM_VALUE_SIZE);
       
  5126 		if (p_random_value == 0)
       
  5127 		{
       
  5128 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5129 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5130 		}
       
  5131 		eap_variable_data_c server_random_value(m_am_tools);
       
  5132 		status = server_random_value.set_buffer(
       
  5133 			p_random_value,
       
  5134 			TLS_HANDSHAKE_RANDOM_VALUE_SIZE,
       
  5135 			false,
       
  5136 			false);
       
  5137 		if (status != eap_status_ok)
       
  5138 		{
       
  5139 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5140 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5141 		}
       
  5142 		
       
  5143 		status = tls_handshake_message->set_random_value(&server_random_value);
       
  5144 		if (status != eap_status_ok)
       
  5145 		{
       
  5146 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5147 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5148 		}
       
  5149 
       
  5150 		data_offset += TLS_HANDSHAKE_RANDOM_VALUE_SIZE;
       
  5151 
       
  5152 		EAP_TRACE_DATA_DEBUG(
       
  5153 			m_am_tools,
       
  5154 			TRACE_FLAGS_DEFAULT,
       
  5155 			(EAPL("TLS: parse_handshake_type_server_hello(): m_server_random_value"),
       
  5156 			 server_random_value.get_data(server_random_value.get_data_length()),
       
  5157 			 server_random_value.get_data_length()));
       
  5158 	}
       
  5159 
       
  5160 	//----------------------------------------------------------
       
  5161 
       
  5162 	{
       
  5163 		if (data_offset+TLS_SESSION_ID_LENGTH_FIELD_SIZE > handshake_data_length)
       
  5164 		{
       
  5165 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5166 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5167 		}
       
  5168 		
       
  5169 		u8_t *p_session_id_length = tls_handshake_header->get_data_offset(
       
  5170 			data_offset,
       
  5171 			TLS_SESSION_ID_LENGTH_FIELD_SIZE);
       
  5172 		if (p_session_id_length == 0)
       
  5173 		{
       
  5174 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5175 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5176 		}
       
  5177 		data_offset += TLS_SESSION_ID_LENGTH_FIELD_SIZE;
       
  5178 
       
  5179 		if (data_offset+*p_session_id_length > handshake_data_length)
       
  5180 		{
       
  5181 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5182 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5183 		}
       
  5184 		
       
  5185 		if (*p_session_id_length > 0ul)
       
  5186 		{
       
  5187 			u8_t *p_session_id = tls_handshake_header->get_data_offset(
       
  5188 				data_offset,
       
  5189 				*p_session_id_length);
       
  5190 			if (p_session_id == 0)
       
  5191 			{
       
  5192 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5193 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5194 			}
       
  5195 
       
  5196 			eap_variable_data_c session_id(m_am_tools);
       
  5197 			status = session_id.set_buffer(p_session_id, *p_session_id_length, false, false);
       
  5198 			if (status != eap_status_ok)
       
  5199 			{
       
  5200 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5201 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5202 			}
       
  5203 
       
  5204 			status = tls_handshake_message->set_session_id(&session_id);
       
  5205 			if (status != eap_status_ok)
       
  5206 			{
       
  5207 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5208 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5209 			}
       
  5210 
       
  5211 			EAP_TRACE_DATA_DEBUG(
       
  5212 				m_am_tools,
       
  5213 				TRACE_FLAGS_DEFAULT,
       
  5214 				(EAPL("TLS: parse_handshake_type_server_hello(): session_id"),
       
  5215 				 session_id.get_data(session_id.get_data_length()),
       
  5216 				 session_id.get_data_length()));
       
  5217 		}
       
  5218 		
       
  5219 		data_offset += *p_session_id_length;
       
  5220 	}
       
  5221 
       
  5222 	//----------------------------------------------------------
       
  5223 
       
  5224 	{
       
  5225 		if (data_offset+TLS_CIPHER_SUITE_FIELD_SIZE > handshake_data_length)
       
  5226 		{
       
  5227 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5228 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5229 		}
       
  5230 		
       
  5231 		u8_t *p_cipher_suite_network_order = tls_handshake_header->get_data_offset(
       
  5232 			data_offset,
       
  5233 			TLS_CIPHER_SUITE_FIELD_SIZE);
       
  5234 		if (p_cipher_suite_network_order == 0)
       
  5235 		{
       
  5236 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5237 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5238 		}
       
  5239 		u16_t cipher_suite
       
  5240 			= eap_read_u16_t_network_order(
       
  5241 				p_cipher_suite_network_order,
       
  5242 				TLS_CIPHER_SUITE_FIELD_SIZE);
       
  5243 
       
  5244 		status = tls_handshake_message->set_selected_cipher_suite(
       
  5245 			static_cast<tls_cipher_suites_e>(cipher_suite));
       
  5246 		if (status != eap_status_ok)
       
  5247 		{
       
  5248 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5249 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5250 		}
       
  5251 
       
  5252 		EAP_TRACE_DATA_DEBUG(
       
  5253 			m_am_tools,
       
  5254 			TRACE_FLAGS_DEFAULT,
       
  5255 			(EAPL("TLS: parse_handshake_type_server_hello(): cipher_suite"),
       
  5256 			 &cipher_suite,
       
  5257 			 sizeof(cipher_suite)));
       
  5258 
       
  5259 		data_offset += TLS_CIPHER_SUITE_FIELD_SIZE;
       
  5260 	}
       
  5261 
       
  5262 	//----------------------------------------------------------
       
  5263 
       
  5264 	{
       
  5265 		if (data_offset+TLS_COMPRESSION_METHOD_FIELD_SIZE > handshake_data_length)
       
  5266 		{
       
  5267 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5268 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5269 		}
       
  5270 		
       
  5271 		u8_t *p_compression = tls_handshake_header->get_data_offset(
       
  5272 			data_offset,
       
  5273 			TLS_COMPRESSION_METHOD_FIELD_SIZE);
       
  5274 		if (p_compression == 0)
       
  5275 		{
       
  5276 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5277 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5278 		}
       
  5279 
       
  5280 		status = tls_handshake_message->set_selected_compression_method(
       
  5281 			static_cast<tls_compression_method_e>(*p_compression));
       
  5282 		if (status != eap_status_ok)
       
  5283 		{
       
  5284 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5285 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5286 		}
       
  5287 
       
  5288 		EAP_TRACE_DATA_DEBUG(
       
  5289 			m_am_tools,
       
  5290 			TRACE_FLAGS_DEFAULT,
       
  5291 			(EAPL("TLS: parse_handshake_type_server_hello(): p_compression"),
       
  5292 			 p_compression,
       
  5293 			 sizeof(*p_compression)));
       
  5294 
       
  5295 		data_offset += TLS_COMPRESSION_METHOD_FIELD_SIZE;
       
  5296 	}
       
  5297 
       
  5298 	//----------------------------------------------------------
       
  5299 
       
  5300 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  5301 
       
  5302 	status = parse_tls_extension_list(
       
  5303 		handshake_data_length,
       
  5304 		&data_offset,
       
  5305 		tls_handshake_header,
       
  5306 		tls_handshake_message);
       
  5307 	if (status != eap_status_ok)
       
  5308 	{
       
  5309 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5310 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5311 	}
       
  5312 
       
  5313 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  5314 
       
  5315 	//----------------------------------------------------------
       
  5316 
       
  5317 	if (status == eap_status_ok)
       
  5318 	{
       
  5319 		// Note the add_handshake_message() frees message in any case.
       
  5320 		automatic_tls_handshake_message.do_not_free_variable();
       
  5321 
       
  5322 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  5323 		if (status != eap_status_ok)
       
  5324 		{
       
  5325 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5326 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5327 		}
       
  5328 	}
       
  5329 
       
  5330 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5331 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5332 }
       
  5333 
       
  5334 //--------------------------------------------------
       
  5335 
       
  5336 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_server_key_exchange(
       
  5337 	tls_record_message_c * const received_tls_record_message,
       
  5338 	tls_handshake_header_c * const tls_handshake_header,
       
  5339 	const u32_t handshake_data_length)
       
  5340 {
       
  5341 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5342 
       
  5343 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5344 	EAP_TRACE_DEBUG(
       
  5345 		m_am_tools,
       
  5346 		TRACE_FLAGS_DEFAULT,
       
  5347 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_key_exchange()\n"),
       
  5348 		(m_is_client == true ? "client": "server")));
       
  5349 
       
  5350 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_server_key_exchange()");
       
  5351 
       
  5352 	tls_handshake_message_c *tls_handshake_message = 0;
       
  5353 
       
  5354 	eap_automatic_variable_c<tls_handshake_message_c>
       
  5355 		automatic_tls_handshake_message(m_am_tools);
       
  5356 
       
  5357 	eap_status_e status = allocate_handshake_message_copy(
       
  5358 		&tls_handshake_message,
       
  5359 		&automatic_tls_handshake_message,
       
  5360 		tls_handshake_header);
       
  5361 	if (status != eap_status_ok)
       
  5362 	{
       
  5363 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5364 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5365 	}
       
  5366 
       
  5367 	u32_t handshake_length = tls_handshake_header->get_data_length();
       
  5368 	u32_t data_offset = 0ul;
       
  5369 
       
  5370 	//----------------------------------------------------------
       
  5371 
       
  5372 	{
       
  5373 		if (data_offset+TLS_DHE_PRIME_LENGTH_FIELD_SIZE > handshake_data_length)
       
  5374 		{
       
  5375 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5376 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5377 		}
       
  5378 		
       
  5379 		u8_t *p_dhe_prime_length = tls_handshake_header->get_data_offset(
       
  5380 			data_offset,
       
  5381 			TLS_DHE_PRIME_LENGTH_FIELD_SIZE);
       
  5382 		if (p_dhe_prime_length == 0)
       
  5383 		{
       
  5384 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5385 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5386 		}
       
  5387 		data_offset += TLS_DHE_PRIME_LENGTH_FIELD_SIZE;
       
  5388 
       
  5389 		u16_t dhe_prime_length
       
  5390 			= eap_read_u16_t_network_order(p_dhe_prime_length, TLS_DHE_PRIME_LENGTH_FIELD_SIZE);
       
  5391 
       
  5392 		u8_t *p_dhe_prime_value = tls_handshake_header->get_data_offset(
       
  5393 			data_offset,
       
  5394 			dhe_prime_length);
       
  5395 		if (p_dhe_prime_value == 0)
       
  5396 		{
       
  5397 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5398 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5399 		}
       
  5400 
       
  5401 		eap_variable_data_c dhe_prime(m_am_tools);
       
  5402 		status = dhe_prime.set_buffer(p_dhe_prime_value, dhe_prime_length, false, false);
       
  5403 		if (status != eap_status_ok)
       
  5404 		{
       
  5405 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5406 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5407 		}
       
  5408 		
       
  5409 		status = tls_handshake_message->set_dhe_prime(&dhe_prime);
       
  5410 		if (status != eap_status_ok)
       
  5411 		{
       
  5412 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5413 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5414 		}
       
  5415 
       
  5416 		data_offset += dhe_prime_length;
       
  5417 	}
       
  5418 
       
  5419 	//----------------------------------------------------------
       
  5420 
       
  5421 	{
       
  5422 		if (data_offset+TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE > handshake_data_length)
       
  5423 		{
       
  5424 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5425 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5426 		}
       
  5427 		
       
  5428 		u8_t *p_dhe_group_generator_length = tls_handshake_header->get_data_offset(
       
  5429 			data_offset,
       
  5430 			TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE);
       
  5431 		if (p_dhe_group_generator_length == 0)
       
  5432 		{
       
  5433 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5434 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5435 		}
       
  5436 		data_offset += TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE;
       
  5437 
       
  5438 		u16_t dhe_group_generator_length = 
       
  5439 			eap_read_u16_t_network_order(
       
  5440 				p_dhe_group_generator_length,
       
  5441 				TLS_DHE_GROUP_GENERATOR_LENGTH_FIELD_SIZE);
       
  5442 
       
  5443 		u8_t *p_dhe_group_generator_value = tls_handshake_header->get_data_offset(
       
  5444 			data_offset,
       
  5445 			dhe_group_generator_length);
       
  5446 		if (p_dhe_group_generator_value == 0)
       
  5447 		{
       
  5448 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5449 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5450 		}
       
  5451 
       
  5452 		eap_variable_data_c dhe_group_generator(m_am_tools);
       
  5453 		status = dhe_group_generator.set_buffer(
       
  5454 			p_dhe_group_generator_value,
       
  5455 			dhe_group_generator_length,
       
  5456 			false,
       
  5457 			false);
       
  5458 		if (status != eap_status_ok)
       
  5459 		{
       
  5460 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5461 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5462 		}
       
  5463 		
       
  5464 		status = tls_handshake_message->set_dhe_group_generator(&dhe_group_generator);
       
  5465 		if (status != eap_status_ok)
       
  5466 		{
       
  5467 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5468 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5469 		}
       
  5470 
       
  5471 		data_offset += dhe_group_generator_length;
       
  5472 	}
       
  5473 
       
  5474 	//----------------------------------------------------------
       
  5475 
       
  5476 	{
       
  5477 		if (data_offset+TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE > handshake_data_length)
       
  5478 		{
       
  5479 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5480 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5481 		}
       
  5482 		
       
  5483 		u8_t *p_public_dhe_key_length = tls_handshake_header->get_data_offset(
       
  5484 			data_offset,
       
  5485 			TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE);
       
  5486 		if (p_public_dhe_key_length == 0)
       
  5487 		{
       
  5488 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5489 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5490 		}
       
  5491 		data_offset += TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE;
       
  5492 
       
  5493 		u16_t public_dhe_key_length = 
       
  5494 			eap_read_u16_t_network_order(
       
  5495 				p_public_dhe_key_length,
       
  5496 				TLS_PUBLIC_DHE_KEY_LENGTH_FIELD_SIZE);
       
  5497 
       
  5498 		u8_t *p_public_dhe_key_value = tls_handshake_header->get_data_offset(
       
  5499 			data_offset,
       
  5500 			public_dhe_key_length);
       
  5501 		if (p_public_dhe_key_value == 0)
       
  5502 		{
       
  5503 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5504 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5505 		}
       
  5506 
       
  5507 		eap_variable_data_c public_dhe_key(m_am_tools);
       
  5508 		status = public_dhe_key.set_buffer(
       
  5509 			p_public_dhe_key_value,
       
  5510 			public_dhe_key_length,
       
  5511 			false,
       
  5512 			false);
       
  5513 		if (status != eap_status_ok)
       
  5514 		{
       
  5515 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5516 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5517 		}
       
  5518 		
       
  5519 		status = tls_handshake_message->set_public_dhe_key(&public_dhe_key);
       
  5520 		if (status != eap_status_ok)
       
  5521 		{
       
  5522 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5523 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5524 		}
       
  5525 
       
  5526 		data_offset += public_dhe_key_length;
       
  5527 	}
       
  5528 
       
  5529 	//----------------------------------------------------------
       
  5530 
       
  5531 #if defined(USE_FAST_EAP_TYPE)
       
  5532 	if (m_eap_type == eap_type_fast
       
  5533 		&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  5534 		&& data_offset == handshake_data_length)
       
  5535 	{
       
  5536 		// Here are no signed hash.
       
  5537 		EAP_TRACE_DEBUG(
       
  5538 			m_am_tools,
       
  5539 			TRACE_FLAGS_DEFAULT,
       
  5540 			(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_server_key_exchange(): EAP-FAST server unauthenticated provisioning mode, no signed hash\n"),
       
  5541 			(m_is_client == true ? "client": "server")));
       
  5542 	}
       
  5543 	else
       
  5544 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  5545 	{
       
  5546 		if (data_offset >= handshake_data_length)
       
  5547 		{
       
  5548 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5549 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5550 		}
       
  5551 
       
  5552 		u16_t expected_dss_sha1_signature_length
       
  5553 			= static_cast<u16_t>(handshake_length - data_offset);
       
  5554 		
       
  5555 		u8_t *p_dss_sha1_signature_length = tls_handshake_header->get_data_offset(
       
  5556 			data_offset,
       
  5557 			TLS_DSS_SHA1_SIGNATURE_LENGTH_FIELD_SIZE);
       
  5558 		if (p_dss_sha1_signature_length == 0)
       
  5559 		{
       
  5560 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5561 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5562 		}
       
  5563 
       
  5564 		u16_t dss_sha1_signature_length = 
       
  5565 			eap_read_u16_t_network_order(
       
  5566 				p_dss_sha1_signature_length,
       
  5567 				TLS_DSS_SHA1_SIGNATURE_LENGTH_FIELD_SIZE);
       
  5568 
       
  5569 		if (expected_dss_sha1_signature_length == dss_sha1_signature_length+2ul)
       
  5570 		{
       
  5571 			// WARNING: Here we have additional length field. OpenSSL does this.
       
  5572 			/*
       
  5573 				// TLS 1.0 RFC 2246 says the length of sha_hash is explicitly 20 bytes
       
  5574 				// (Chapter 7.4.3. Server key exchange message).
       
  5575 				// The length of the vector is not included in the encoded stream
       
  5576 				// (Chapter 4.3. Vectors).
       
  5577 				select (SignatureAlgorithm)
       
  5578 				{   case anonymous: struct { };
       
  5579 				   case rsa:
       
  5580 					   digitally-signed struct {
       
  5581 						   opaque md5_hash[16];
       
  5582 						   opaque sha_hash[20];
       
  5583 					   };
       
  5584 				   case dsa:
       
  5585 					   digitally-signed struct {
       
  5586 						   opaque sha_hash[20];
       
  5587 					   };
       
  5588 				} Signature;
       
  5589 			*/
       
  5590 			data_offset += TLS_DSS_SHA1_SIGNATURE_LENGTH_FIELD_SIZE;
       
  5591 		}
       
  5592 		else
       
  5593 		{
       
  5594 			dss_sha1_signature_length = expected_dss_sha1_signature_length;
       
  5595 		}
       
  5596 
       
  5597 		u8_t *p_dss_sha1_signature = tls_handshake_header->get_data_offset(
       
  5598 			data_offset,
       
  5599 			dss_sha1_signature_length);
       
  5600 		if (p_dss_sha1_signature == 0)
       
  5601 		{
       
  5602 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5603 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5604 		}
       
  5605 
       
  5606 		eap_variable_data_c dss_sha1_signature(m_am_tools);
       
  5607 		status = dss_sha1_signature.set_buffer(
       
  5608 			p_dss_sha1_signature,
       
  5609 			dss_sha1_signature_length,
       
  5610 			false,
       
  5611 			false);
       
  5612 		if (status != eap_status_ok)
       
  5613 		{
       
  5614 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5615 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5616 		}
       
  5617 		
       
  5618 		status = tls_handshake_message->set_signed_message_hash(&dss_sha1_signature);
       
  5619 		if (status != eap_status_ok)
       
  5620 		{
       
  5621 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5622 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5623 		}
       
  5624 
       
  5625 		data_offset += dss_sha1_signature_length;
       
  5626 	}
       
  5627 
       
  5628 	//----------------------------------------------------------
       
  5629 
       
  5630 	if (status == eap_status_ok)
       
  5631 	{
       
  5632 		// Note the add_handshake_message() frees message in any case.
       
  5633 		automatic_tls_handshake_message.do_not_free_variable();
       
  5634 
       
  5635 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  5636 		if (status != eap_status_ok)
       
  5637 		{
       
  5638 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5639 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5640 		}
       
  5641 	}
       
  5642 
       
  5643 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5644 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5645 }
       
  5646 
       
  5647 //--------------------------------------------------
       
  5648 
       
  5649 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_client_key_exchange(
       
  5650 	tls_record_message_c * const received_tls_record_message,
       
  5651 	tls_handshake_header_c * const tls_handshake_header,
       
  5652 	const u32_t handshake_data_length)
       
  5653 {
       
  5654 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5655 
       
  5656 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5657 	EAP_TRACE_DEBUG(
       
  5658 		m_am_tools,
       
  5659 		TRACE_FLAGS_DEFAULT,
       
  5660 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_client_key_exchange()\n"),
       
  5661 		(m_is_client == true ? "client": "server")));
       
  5662 
       
  5663 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_client_key_exchange()");
       
  5664 
       
  5665 	tls_handshake_message_c *tls_handshake_message = 0;
       
  5666 
       
  5667 	eap_automatic_variable_c<tls_handshake_message_c>
       
  5668 		automatic_tls_handshake_message(m_am_tools);
       
  5669 
       
  5670 	eap_status_e status = allocate_handshake_message_copy(
       
  5671 		&tls_handshake_message,
       
  5672 		&automatic_tls_handshake_message,
       
  5673 		tls_handshake_header);
       
  5674 	if (status != eap_status_ok)
       
  5675 	{
       
  5676 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5677 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5678 	}
       
  5679 
       
  5680 	u32_t data_offset = 0ul;
       
  5681 
       
  5682 	//----------------------------------------------------------
       
  5683 
       
  5684 	if (cipher_suite_is_TLS_RSA() == true)
       
  5685 	{
       
  5686 		u32_t encrypted_premaster_secret_length = tls_handshake_header->get_data_length();
       
  5687 
       
  5688 		if (data_offset+encrypted_premaster_secret_length > handshake_data_length)
       
  5689 		{
       
  5690 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5691 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5692 		}
       
  5693 		
       
  5694 		u8_t *p_encrypted_premaster_secret_length = tls_handshake_header->get_data_offset(
       
  5695 			data_offset,
       
  5696 			TLS_ENCRYPTED_PREMASTER_SECRET_LENGTH_FIELD_SIZE);
       
  5697 		if (p_encrypted_premaster_secret_length == 0)
       
  5698 		{
       
  5699 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5700 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5701 		}
       
  5702 		data_offset += TLS_ENCRYPTED_PREMASTER_SECRET_LENGTH_FIELD_SIZE;
       
  5703 
       
  5704 		u16_t data_encrypted_premaster_secret_length
       
  5705 			= eap_read_u16_t_network_order(
       
  5706 				p_encrypted_premaster_secret_length,
       
  5707 				TLS_ENCRYPTED_PREMASTER_SECRET_LENGTH_FIELD_SIZE);
       
  5708 
       
  5709 		if ((data_encrypted_premaster_secret_length + 2ul) != encrypted_premaster_secret_length)
       
  5710 		{
       
  5711 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5712 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  5713 		}
       
  5714 
       
  5715 		u8_t *p_encrypted_premaster_secret_value = tls_handshake_header->get_data_offset(
       
  5716 			data_offset,
       
  5717 			encrypted_premaster_secret_length-2ul);
       
  5718 		if (p_encrypted_premaster_secret_value == 0)
       
  5719 		{
       
  5720 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5721 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5722 		}
       
  5723 
       
  5724 		eap_variable_data_c encrypted_premaster_secret(m_am_tools);
       
  5725 		status = encrypted_premaster_secret.set_buffer(
       
  5726 			p_encrypted_premaster_secret_value,
       
  5727 			encrypted_premaster_secret_length-2ul,
       
  5728 			false,
       
  5729 			false);
       
  5730 		if (status != eap_status_ok)
       
  5731 		{
       
  5732 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5733 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5734 		}
       
  5735 		
       
  5736 		EAP_TRACE_DATA_DEBUG(
       
  5737 			m_am_tools,
       
  5738 			TRACE_FLAGS_DEFAULT,
       
  5739 			(EAPL("TLS: parse_handshake_type_client_key_exchange(): encrypted premaster_secret"),
       
  5740 			 encrypted_premaster_secret.get_data(),
       
  5741 			 encrypted_premaster_secret.get_data_length()));
       
  5742 
       
  5743 		status = tls_handshake_message->set_encrypted_premaster_secret(&encrypted_premaster_secret);
       
  5744 		if (status != eap_status_ok)
       
  5745 		{
       
  5746 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5747 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5748 		}
       
  5749 
       
  5750 		data_offset += encrypted_premaster_secret_length;
       
  5751 	}
       
  5752 	else if (cipher_suite_is_TLS_DHE_DSS() == true
       
  5753 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
  5754 #if defined(USE_FAST_EAP_TYPE)
       
  5755 		|| (m_eap_type == eap_type_fast
       
  5756 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  5757 			&& cipher_suite_is_TLS_DH_anon() == true)
       
  5758 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  5759 		)
       
  5760 	{
       
  5761 		if (data_offset+TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE > handshake_data_length)
       
  5762 		{
       
  5763 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5764 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5765 		}
       
  5766 		
       
  5767 		u8_t *p_public_dhe_key_length = tls_handshake_header->get_data_offset(
       
  5768 			data_offset,
       
  5769 			TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE);
       
  5770 		if (p_public_dhe_key_length == 0)
       
  5771 		{
       
  5772 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5773 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5774 		}
       
  5775 		data_offset += TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE;
       
  5776 
       
  5777 		u16_t public_dhe_key_length
       
  5778 			= eap_read_u16_t_network_order(
       
  5779 				p_public_dhe_key_length,
       
  5780 				TLS_PUBLIC_DHE_KEY_LENGTH_LENGTH_FIELD_SIZE);
       
  5781 
       
  5782 		u8_t *p_public_dhe_key_value = tls_handshake_header->get_data_offset(
       
  5783 			data_offset,
       
  5784 			public_dhe_key_length);
       
  5785 		if (p_public_dhe_key_value == 0)
       
  5786 		{
       
  5787 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5788 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5789 		}
       
  5790 
       
  5791 		eap_variable_data_c public_dhe_key(m_am_tools);
       
  5792 		status = public_dhe_key.set_buffer(
       
  5793 			p_public_dhe_key_value,
       
  5794 			public_dhe_key_length,
       
  5795 			false,
       
  5796 			false);
       
  5797 		if (status != eap_status_ok)
       
  5798 		{
       
  5799 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5800 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5801 		}
       
  5802 		
       
  5803 		status = tls_handshake_message->set_public_dhe_key(&public_dhe_key);
       
  5804 		if (status != eap_status_ok)
       
  5805 		{
       
  5806 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5807 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5808 		}
       
  5809 
       
  5810 		data_offset += public_dhe_key_length;
       
  5811 	}
       
  5812 	else
       
  5813 	{
       
  5814 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5815 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
  5816 	}
       
  5817 
       
  5818 	//----------------------------------------------------------
       
  5819 
       
  5820 	if (status == eap_status_ok)
       
  5821 	{
       
  5822 		// Note the add_handshake_message() frees message in any case.
       
  5823 		automatic_tls_handshake_message.do_not_free_variable();
       
  5824 
       
  5825 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  5826 		if (status != eap_status_ok)
       
  5827 		{
       
  5828 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5829 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5830 		}
       
  5831 	}
       
  5832 
       
  5833 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5834 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5835 }
       
  5836 
       
  5837 //--------------------------------------------------
       
  5838 
       
  5839 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_certificate_verify(
       
  5840 	tls_record_message_c * const received_tls_record_message,
       
  5841 	tls_handshake_header_c * const tls_handshake_header,
       
  5842 	const u32_t handshake_data_length)
       
  5843 {
       
  5844 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5845 
       
  5846 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5847 	EAP_TRACE_DEBUG(
       
  5848 		m_am_tools,
       
  5849 		TRACE_FLAGS_DEFAULT,
       
  5850 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_certificate_verify()\n"),
       
  5851 		(m_is_client == true ? "client": "server")));
       
  5852 
       
  5853 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_certificate_verify()");
       
  5854 
       
  5855 	tls_handshake_message_c *tls_handshake_message = 0;
       
  5856 
       
  5857 	eap_automatic_variable_c<tls_handshake_message_c>
       
  5858 		automatic_tls_handshake_message(m_am_tools);
       
  5859 
       
  5860 	eap_status_e status = allocate_handshake_message_copy(
       
  5861 		&tls_handshake_message,
       
  5862 		&automatic_tls_handshake_message,
       
  5863 		tls_handshake_header);
       
  5864 	if (status != eap_status_ok)
       
  5865 	{
       
  5866 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5867 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5868 	}
       
  5869 
       
  5870 	u32_t data_offset = 0ul;
       
  5871 
       
  5872 	//----------------------------------------------------------
       
  5873 
       
  5874 
       
  5875 	// Save the message hash.
       
  5876 	message_hash_save_certificate_verify();
       
  5877 
       
  5878 	if (cipher_suite_is_TLS_RSA() == true
       
  5879 		|| cipher_suite_is_TLS_DHE_RSA() == true)
       
  5880 	{
       
  5881 		eap_variable_data_c signed_hash(m_am_tools);
       
  5882 
       
  5883 		if (data_offset >= handshake_data_length)
       
  5884 		{
       
  5885 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5886 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5887 		}
       
  5888 
       
  5889 		u32_t handshake_length = tls_handshake_header->get_data_length();
       
  5890 		u32_t rsa_md5_sha1_signature_length = handshake_length - data_offset;
       
  5891 		
       
  5892 		u8_t *p_signature_length = tls_handshake_header->get_data_offset(
       
  5893 			data_offset,
       
  5894 			TLS_SIGNATURE_LENGTH_FIELD_SIZE);
       
  5895 		if (p_signature_length == 0)
       
  5896 		{
       
  5897 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5898 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5899 		}
       
  5900 		data_offset += TLS_SIGNATURE_LENGTH_FIELD_SIZE;
       
  5901 
       
  5902 		u16_t data_signature_length
       
  5903 			= eap_read_u16_t_network_order(p_signature_length, TLS_SIGNATURE_LENGTH_FIELD_SIZE);
       
  5904 
       
  5905 		if ((data_signature_length + 2ul) != rsa_md5_sha1_signature_length)
       
  5906 		{
       
  5907 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5908 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  5909 		}
       
  5910 
       
  5911 		u8_t *p_rsa_md5_sha1_signature = tls_handshake_header->get_data_offset(
       
  5912 			data_offset,
       
  5913 			rsa_md5_sha1_signature_length-2ul);
       
  5914 		if (p_rsa_md5_sha1_signature == 0)
       
  5915 		{
       
  5916 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5917 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5918 		}
       
  5919 
       
  5920 		status = signed_hash.set_copy_of_buffer(
       
  5921 			p_rsa_md5_sha1_signature,
       
  5922 			rsa_md5_sha1_signature_length-2ul);
       
  5923 		if (status != eap_status_ok)
       
  5924 		{
       
  5925 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5926 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5927 		}
       
  5928 
       
  5929 		status = tls_handshake_message->set_signed_message_hash(
       
  5930 			&signed_hash);
       
  5931 		if (status != eap_status_ok)
       
  5932 		{
       
  5933 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5934 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5935 		}
       
  5936 
       
  5937 		data_offset += rsa_md5_sha1_signature_length;
       
  5938 	}
       
  5939 	else if (cipher_suite_is_TLS_DHE_DSS() == true)
       
  5940 	{
       
  5941 		eap_variable_data_c signed_hash(m_am_tools);
       
  5942 
       
  5943 		if (data_offset >= handshake_data_length)
       
  5944 		{
       
  5945 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5946 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5947 		}
       
  5948 
       
  5949 		u32_t handshake_length = tls_handshake_header->get_data_length();
       
  5950 		u32_t dss_sha1_signature_length = handshake_length - data_offset;
       
  5951 		
       
  5952 		u8_t *p_signature_length = tls_handshake_header->get_data_offset(
       
  5953 			data_offset,
       
  5954 			TLS_SIGNATURE_LENGTH_FIELD_SIZE);
       
  5955 		if (p_signature_length == 0)
       
  5956 		{
       
  5957 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5958 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5959 		}
       
  5960 		data_offset += TLS_SIGNATURE_LENGTH_FIELD_SIZE;
       
  5961 
       
  5962 		u16_t data_signature_length
       
  5963 			= eap_read_u16_t_network_order(p_signature_length, TLS_SIGNATURE_LENGTH_FIELD_SIZE);
       
  5964 
       
  5965 		if ((data_signature_length + 2ul) != dss_sha1_signature_length)
       
  5966 		{
       
  5967 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5968 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  5969 		}
       
  5970 
       
  5971 		u8_t *p_dss_sha1_signature = tls_handshake_header->get_data_offset(
       
  5972 			data_offset,
       
  5973 			dss_sha1_signature_length-2ul);
       
  5974 		if (p_dss_sha1_signature == 0)
       
  5975 		{
       
  5976 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5977 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5978 		}
       
  5979 
       
  5980 		status = signed_hash.set_copy_of_buffer(
       
  5981 			p_dss_sha1_signature,
       
  5982 			dss_sha1_signature_length-2ul);
       
  5983 		if (status != eap_status_ok)
       
  5984 		{
       
  5985 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5986 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5987 		}
       
  5988 
       
  5989 		status = tls_handshake_message->set_signed_message_hash(
       
  5990 			&signed_hash);
       
  5991 		if (status != eap_status_ok)
       
  5992 		{
       
  5993 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5994 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5995 		}
       
  5996 
       
  5997 		data_offset += dss_sha1_signature_length;
       
  5998 	}
       
  5999 
       
  6000 	//----------------------------------------------------------
       
  6001 
       
  6002 	if (status == eap_status_ok)
       
  6003 	{
       
  6004 		// Note the add_handshake_message() frees message in any case.
       
  6005 		automatic_tls_handshake_message.do_not_free_variable();
       
  6006 
       
  6007 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  6008 		if (status != eap_status_ok)
       
  6009 		{
       
  6010 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6011 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6012 		}
       
  6013 	}
       
  6014 
       
  6015 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6016 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6017 }
       
  6018 
       
  6019 //--------------------------------------------------
       
  6020 
       
  6021 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_finished(
       
  6022 	tls_record_message_c * const received_tls_record_message,
       
  6023 	tls_handshake_header_c * const tls_handshake_header,
       
  6024 	const u32_t /* handshake_data_length */)
       
  6025 {
       
  6026 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6027 
       
  6028 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6029 	EAP_TRACE_DEBUG(
       
  6030 		m_am_tools,
       
  6031 		TRACE_FLAGS_DEFAULT,
       
  6032 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_finished()\n"),
       
  6033 		(m_is_client == true ? "client": "server")));
       
  6034 
       
  6035 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_finished()");
       
  6036 
       
  6037 	tls_handshake_message_c *tls_handshake_message = 0;
       
  6038 
       
  6039 	eap_automatic_variable_c<tls_handshake_message_c>
       
  6040 		automatic_tls_handshake_message(m_am_tools);
       
  6041 
       
  6042 	eap_status_e status = allocate_handshake_message_copy(
       
  6043 		&tls_handshake_message,
       
  6044 		&automatic_tls_handshake_message,
       
  6045 		tls_handshake_header);
       
  6046 	if (status != eap_status_ok)
       
  6047 	{
       
  6048 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6049 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6050 	}
       
  6051 
       
  6052 	u32_t data_offset = 0ul;
       
  6053 
       
  6054 	//----------------------------------------------------------
       
  6055 
       
  6056 	bool client_originated = true;
       
  6057 	if (m_is_client == true)
       
  6058 	{
       
  6059 		client_originated = false;
       
  6060 	}
       
  6061 	// Save the message hash.
       
  6062 	message_hash_save_finished(client_originated);
       
  6063 
       
  6064 	{
       
  6065 		eap_variable_data_c finished_data(m_am_tools);
       
  6066 
       
  6067 		u8_t *p_finished_data = tls_handshake_header->get_data_offset(
       
  6068 			data_offset,
       
  6069 			TLS_FINISHED_DATA_SIZE);
       
  6070 		if (p_finished_data == 0)
       
  6071 		{
       
  6072 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6073 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6074 		}
       
  6075 
       
  6076 		status = finished_data.set_copy_of_buffer(p_finished_data, TLS_FINISHED_DATA_SIZE);
       
  6077 		if (status != eap_status_ok)
       
  6078 		{
       
  6079 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6080 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6081 		}
       
  6082 
       
  6083 		status = tls_handshake_message->set_finished_data(
       
  6084 			&finished_data);
       
  6085 		if (status != eap_status_ok)
       
  6086 		{
       
  6087 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6088 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6089 		}
       
  6090 
       
  6091 		data_offset += TLS_FINISHED_DATA_SIZE;
       
  6092 	}
       
  6093 
       
  6094 	//----------------------------------------------------------
       
  6095 
       
  6096 	if (status == eap_status_ok)
       
  6097 	{
       
  6098 		// Note the add_handshake_message() frees message in any case.
       
  6099 		automatic_tls_handshake_message.do_not_free_variable();
       
  6100 
       
  6101 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  6102 		if (status != eap_status_ok)
       
  6103 		{
       
  6104 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6105 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6106 		}
       
  6107 	}
       
  6108 
       
  6109 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6110 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6111 }
       
  6112 
       
  6113 //--------------------------------------------------
       
  6114 
       
  6115 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  6116 
       
  6117 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_handshake_type_new_session_ticket(
       
  6118 	tls_record_message_c * const received_tls_record_message,
       
  6119 	tls_handshake_header_c * const tls_handshake_header,
       
  6120 	const u32_t handshake_data_length)
       
  6121 {
       
  6122 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6123 
       
  6124 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6125 	EAP_TRACE_DEBUG(
       
  6126 		m_am_tools,
       
  6127 		TRACE_FLAGS_DEFAULT,
       
  6128 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_handshake_type_new_session_ticket()\n"),
       
  6129 		(m_is_client == true ? "client": "server")));
       
  6130 
       
  6131 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_handshake_type_new_session_ticket()");
       
  6132 
       
  6133 	tls_handshake_message_c *tls_handshake_message = 0;
       
  6134 
       
  6135 	eap_automatic_variable_c<tls_handshake_message_c>
       
  6136 		automatic_tls_handshake_message(m_am_tools);
       
  6137 
       
  6138 	eap_status_e status = allocate_handshake_message_copy(
       
  6139 		&tls_handshake_message,
       
  6140 		&automatic_tls_handshake_message,
       
  6141 		tls_handshake_header);
       
  6142 	if (status != eap_status_ok)
       
  6143 	{
       
  6144 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6145 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6146 	}
       
  6147 
       
  6148 	u32_t data_offset = 0ul;
       
  6149 
       
  6150 	u8_t * handshake_data = tls_handshake_header->get_data_offset(
       
  6151 		data_offset,
       
  6152 		tls_handshake_header->get_data_length());
       
  6153 	if (handshake_data == 0)
       
  6154 	{
       
  6155 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6156 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6157 	}
       
  6158 
       
  6159 	//----------------------------------------------------------
       
  6160 
       
  6161 	u32_t session_ticket_lifetime_hint(0ul);
       
  6162 
       
  6163 	{
       
  6164 		if (data_offset+TLS_SESSION_TICKET_LIFETIME_HINT_FIELD_SIZE > handshake_data_length)
       
  6165 		{
       
  6166 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6167 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6168 		}
       
  6169 		
       
  6170 		u8_t *p_session_ticket_lifetime_hint = handshake_data;
       
  6171 
       
  6172 		session_ticket_lifetime_hint = eap_read_u32_t_network_order(
       
  6173 			p_session_ticket_lifetime_hint,
       
  6174 			TLS_SESSION_TICKET_LIFETIME_HINT_FIELD_SIZE);
       
  6175 		
       
  6176 		data_offset += TLS_SESSION_TICKET_LIFETIME_HINT_FIELD_SIZE;
       
  6177 	}
       
  6178 
       
  6179 	//----------------------------------------------------------
       
  6180 
       
  6181 	{
       
  6182 		if (data_offset+TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE > handshake_data_length)
       
  6183 		{
       
  6184 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6185 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6186 		}
       
  6187 		
       
  6188 		u8_t *p_opaque_session_ticket_length = tls_handshake_header->get_data_offset(
       
  6189 			data_offset,
       
  6190 			TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE);
       
  6191 		if (p_opaque_session_ticket_length == 0)
       
  6192 		{
       
  6193 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6194 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6195 		}
       
  6196 
       
  6197 		u16_t opaque_session_ticket_length = eap_read_u16_t_network_order(
       
  6198 			p_opaque_session_ticket_length,
       
  6199 			TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE);
       
  6200 		
       
  6201 		data_offset += TLS_EXTENSION_DATA_LENGTH_FIELD_SIZE;
       
  6202 
       
  6203 		if (data_offset+opaque_session_ticket_length > handshake_data_length)
       
  6204 		{
       
  6205 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6206 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6207 		}
       
  6208 
       
  6209 		tls_extension_c opaque_session_ticket(m_am_tools);
       
  6210 
       
  6211 		if (opaque_session_ticket.get_is_valid() == false)
       
  6212 		{
       
  6213 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6214 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6215 		}
       
  6216 
       
  6217 		u8_t *p_opaque_session_ticket = tls_handshake_header->get_data_offset(
       
  6218 			data_offset,
       
  6219 			opaque_session_ticket_length);
       
  6220 		if (p_opaque_session_ticket_length == 0)
       
  6221 		{
       
  6222 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6223 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6224 		}
       
  6225 
       
  6226 		status = opaque_session_ticket.set_buffer(
       
  6227 			p_opaque_session_ticket,
       
  6228 			opaque_session_ticket_length,
       
  6229 			false,
       
  6230 			false);
       
  6231 		if (status != eap_status_ok)
       
  6232 		{
       
  6233 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6234 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6235 		}
       
  6236 
       
  6237 		opaque_session_ticket.set_type(tls_extension_type_session_ticket);
       
  6238 
       
  6239 		opaque_session_ticket.set_lifetime_hint(session_ticket_lifetime_hint);
       
  6240 
       
  6241 		eap_array_c<tls_extension_c> tls_extensions(m_am_tools);
       
  6242 
       
  6243 		status = tls_extensions.add_object(&opaque_session_ticket, false);
       
  6244 		if (status != eap_status_ok)
       
  6245 		{
       
  6246 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6247 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6248 		}
       
  6249 
       
  6250 		// Save the new session ticket to be included in next NewSessionTicket message.
       
  6251 		status = tls_handshake_message->set_tls_extensions(
       
  6252 			&tls_extensions);
       
  6253 		if (status != eap_status_ok)
       
  6254 		{
       
  6255 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6256 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6257 		}
       
  6258 
       
  6259 		EAP_TRACE_DATA_DEBUG(
       
  6260 			m_am_tools,
       
  6261 			TRACE_FLAGS_DEFAULT,
       
  6262 			(EAPL("TLS: parse_handshake_type_new_session_ticket(): opaque_session_ticket"),
       
  6263 			 opaque_session_ticket.get_data(opaque_session_ticket.get_data_length()),
       
  6264 			 opaque_session_ticket.get_data_length()));
       
  6265 
       
  6266 		data_offset += opaque_session_ticket_length;
       
  6267 	}
       
  6268 
       
  6269 	//----------------------------------------------------------
       
  6270 
       
  6271 	if (status == eap_status_ok)
       
  6272 	{
       
  6273 		// Note the add_handshake_message() frees message in any case.
       
  6274 		automatic_tls_handshake_message.do_not_free_variable();
       
  6275 
       
  6276 		status = received_tls_record_message->add_handshake_message(tls_handshake_message, true);
       
  6277 		if (status != eap_status_ok)
       
  6278 		{
       
  6279 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6280 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6281 		}
       
  6282 	}
       
  6283 
       
  6284 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6285 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6286 }
       
  6287 
       
  6288 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  6289 
       
  6290 //--------------------------------------------------
       
  6291 
       
  6292 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_change_cipher_spec(
       
  6293 	tls_record_message_c * const tls_record_message,
       
  6294 	eap_variable_data_c * const tls_protocol_messages_buffer)
       
  6295 {
       
  6296 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6297 
       
  6298 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6299 	EAP_TRACE_DEBUG(
       
  6300 		m_am_tools,
       
  6301 		TRACE_FLAGS_DEFAULT,
       
  6302 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_change_cipher_spec()\n"),
       
  6303 		(m_is_client == true ? "client": "server")));
       
  6304 
       
  6305 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_change_cipher_spec()");
       
  6306 
       
  6307 	tls_record_message->set_parsed_record();
       
  6308 
       
  6309 	if (verify_state(tls_peap_state_wait_change_cipher_spec) == false
       
  6310 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  6311 		&& (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none
       
  6312 			&& verify_state(tls_peap_state_wait_handshake_type_certificate_verify) == false)
       
  6313 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  6314 		)
       
  6315 	{
       
  6316 		EAP_TRACE_ERROR(
       
  6317 			m_am_tools,
       
  6318 			TRACE_FLAGS_DEFAULT,
       
  6319 			(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
  6320 			 (m_is_client == true ? "client": "server"),
       
  6321 			 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
  6322 			 eap_tls_trace_string_c::get_state_string(tls_peap_state_wait_change_cipher_spec)));
       
  6323 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  6324 	}
       
  6325 
       
  6326 	eap_status_e status = eap_status_not_supported;
       
  6327 
       
  6328 	const u32_t tls_protocols_length = tls_protocol_messages_buffer->get_data_length();
       
  6329 
       
  6330 	tls_change_cipher_spec_message_c * const tls_change_cipher_spec_message
       
  6331 		= new tls_change_cipher_spec_message_c(m_am_tools, this, m_is_client);
       
  6332 
       
  6333 	eap_automatic_variable_c<tls_change_cipher_spec_message_c>
       
  6334 		automatic_tls_change_cipher_spec_message(m_am_tools, tls_change_cipher_spec_message);
       
  6335 
       
  6336 	if (tls_change_cipher_spec_message == 0
       
  6337 		|| tls_change_cipher_spec_message->get_is_valid() == false)
       
  6338 	{
       
  6339 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6340 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6341 	}
       
  6342 
       
  6343 	u32_t data_offset = 0ul;
       
  6344 
       
  6345 	//----------------------------------------------------------
       
  6346 
       
  6347 	{
       
  6348 		if (data_offset+TLS_CHANGE_CIPHER_SPEC_FIELD_SIZE > tls_protocols_length)
       
  6349 		{
       
  6350 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6351 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6352 		}
       
  6353 
       
  6354 		u8_t *p_change_cipher_spec_type = tls_protocol_messages_buffer->get_data_offset(
       
  6355 			data_offset,
       
  6356 			TLS_CHANGE_CIPHER_SPEC_FIELD_SIZE);
       
  6357 		if (p_change_cipher_spec_type == 0)
       
  6358 		{
       
  6359 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6360 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6361 		}
       
  6362 
       
  6363 		status = tls_change_cipher_spec_message->set_change_cipher_spec_type(
       
  6364 			static_cast<tls_change_cipher_spec_type_e>(*p_change_cipher_spec_type));
       
  6365 		if (status != eap_status_ok)
       
  6366 		{
       
  6367 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6368 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6369 		}
       
  6370 
       
  6371 		data_offset += TLS_CHANGE_CIPHER_SPEC_FIELD_SIZE;
       
  6372 	}
       
  6373 
       
  6374 	//----------------------------------------------------------
       
  6375 
       
  6376 	if (tls_protocols_length != data_offset)
       
  6377 	{
       
  6378 		// Parsed record length does not match with received record length.
       
  6379 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6380 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6381 	}
       
  6382 
       
  6383 	if (status == eap_status_ok)
       
  6384 	{
       
  6385 		// Note add_change_cipher_spec_message() frees message on any case.
       
  6386 		automatic_tls_change_cipher_spec_message.do_not_free_variable();
       
  6387 
       
  6388 		status = tls_record_message->add_change_cipher_spec_message(
       
  6389 			tls_change_cipher_spec_message,
       
  6390 			true);
       
  6391 		if (status != eap_status_ok)
       
  6392 		{
       
  6393 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6394 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6395 		}
       
  6396 	}
       
  6397 
       
  6398 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6399 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6400 }
       
  6401 
       
  6402 //--------------------------------------------------
       
  6403 
       
  6404 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_alert(
       
  6405 	tls_record_message_c * const tls_record_message,
       
  6406 	eap_variable_data_c * const tls_protocol_messages_buffer)
       
  6407 {
       
  6408 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6409 
       
  6410 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6411 	EAP_TRACE_DEBUG(
       
  6412 		m_am_tools,
       
  6413 		TRACE_FLAGS_DEFAULT,
       
  6414 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_alert()\n"),
       
  6415 		(m_is_client == true ? "client": "server")));
       
  6416 
       
  6417 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_alert()");
       
  6418 
       
  6419 	tls_record_message->set_parsed_record();
       
  6420 
       
  6421 	eap_status_e status = eap_status_not_supported;
       
  6422 
       
  6423 	// Because we received alert message, we do not send alert messages anymore.
       
  6424 	m_could_send_fatal_alert_message = false;
       
  6425 	m_could_send_warning_alert_message = false;
       
  6426 
       
  6427 	const u32_t tls_protocol_messages_length = tls_protocol_messages_buffer->get_data_length();
       
  6428 	u32_t data_start_offset = 0ul;
       
  6429 
       
  6430 	while (data_start_offset < tls_protocol_messages_length)
       
  6431 	{
       
  6432 		tls_alert_message_c * const tls_alert_message
       
  6433 			= new tls_alert_message_c(m_am_tools, m_is_client);
       
  6434 
       
  6435 		eap_automatic_variable_c<tls_alert_message_c>
       
  6436 			automatic_tls_alert_message(m_am_tools, tls_alert_message);
       
  6437 
       
  6438 		if (tls_alert_message == 0
       
  6439 			|| tls_alert_message->get_is_valid() == false)
       
  6440 		{
       
  6441 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6442 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6443 		}
       
  6444 		
       
  6445 		u32_t data_offset = 0ul;
       
  6446 
       
  6447 		//----------------------------------------------------------
       
  6448 
       
  6449 		{
       
  6450 			if (data_start_offset+data_offset+TLS_ALERT_LEVEL_FIELD_SIZE
       
  6451 				> tls_protocol_messages_length)
       
  6452 			{
       
  6453 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6454 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6455 			}
       
  6456 
       
  6457 			u8_t *p_alert_level = tls_protocol_messages_buffer->get_data_offset(
       
  6458 				data_start_offset+data_offset,
       
  6459 				TLS_ALERT_LEVEL_FIELD_SIZE);
       
  6460 			if (p_alert_level == 0)
       
  6461 			{
       
  6462 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6463 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6464 			}
       
  6465 
       
  6466 			status = tls_alert_message->set_alert_level(
       
  6467 				static_cast<tls_alert_level_e>(*p_alert_level));
       
  6468 			if (status != eap_status_ok)
       
  6469 			{
       
  6470 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6471 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6472 			}
       
  6473 
       
  6474 			data_offset += TLS_ALERT_LEVEL_FIELD_SIZE;
       
  6475 		}
       
  6476 
       
  6477 		//----------------------------------------------------------
       
  6478 
       
  6479 		{
       
  6480 			if (data_start_offset+data_offset+TLS_ALERT_DESCRIPTION_FIELD_SIZE
       
  6481 				> tls_protocol_messages_length)
       
  6482 			{
       
  6483 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6484 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6485 			}
       
  6486 
       
  6487 			u8_t *p_alert_description = tls_protocol_messages_buffer->get_data_offset(
       
  6488 				data_start_offset+data_offset,
       
  6489 				TLS_ALERT_DESCRIPTION_FIELD_SIZE);
       
  6490 			if (p_alert_description == 0)
       
  6491 			{
       
  6492 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6493 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6494 			}
       
  6495 
       
  6496 			status = tls_alert_message->set_alert_description(
       
  6497 				static_cast<tls_alert_description_e>(*p_alert_description));
       
  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 			data_offset += TLS_ALERT_DESCRIPTION_FIELD_SIZE;
       
  6505 		}
       
  6506 
       
  6507 		if (status == eap_status_ok)
       
  6508 		{
       
  6509 			// Note add_alert_message() frees message on any case.
       
  6510 			automatic_tls_alert_message.do_not_free_variable();
       
  6511 
       
  6512 			status = tls_record_message->add_alert_message(tls_alert_message, true);
       
  6513 			if (status != eap_status_ok)
       
  6514 			{
       
  6515 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6516 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6517 			}
       
  6518 		}
       
  6519 
       
  6520 		data_start_offset += data_offset;
       
  6521 	} // while()
       
  6522 
       
  6523 	//----------------------------------------------------------
       
  6524 
       
  6525 	if (tls_protocol_messages_length != data_start_offset)
       
  6526 	{
       
  6527 		// Parsed record length does not match with received record length.
       
  6528 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6529 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6530 	}
       
  6531 
       
  6532 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6533 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6534 }
       
  6535 
       
  6536 //--------------------------------------------------
       
  6537 
       
  6538 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_handshake(
       
  6539 	tls_record_message_c * const tls_record_message,
       
  6540 	eap_variable_data_c * const tls_protocol_messages_buffer)
       
  6541 {
       
  6542 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6543 
       
  6544 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6545 	EAP_TRACE_DEBUG(
       
  6546 		m_am_tools,
       
  6547 		TRACE_FLAGS_DEFAULT,
       
  6548 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_handshake()\n"),
       
  6549 		(m_is_client == true ? "client": "server")));
       
  6550 
       
  6551 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_handshake()");
       
  6552 
       
  6553 	tls_record_message->set_parsed_record();
       
  6554 
       
  6555 	const u32_t tls_protocol_messages_length = tls_protocol_messages_buffer->get_data_length();
       
  6556 
       
  6557 	u32_t data_start_offset = 0ul;
       
  6558 
       
  6559 	tls_handshake_header_c tls_handshake_header(
       
  6560 		m_am_tools,
       
  6561 		tls_protocol_messages_buffer->get_data_offset(
       
  6562 			data_start_offset,
       
  6563 			tls_protocol_messages_buffer->get_data_length()-data_start_offset),
       
  6564 		tls_protocol_messages_buffer->get_data_length()-data_start_offset);
       
  6565 	if (tls_handshake_header.get_is_valid() == false)
       
  6566 	{
       
  6567 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6568 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6569 	}
       
  6570 
       
  6571 	if (tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length() > tls_handshake_header.get_header_buffer_length()
       
  6572 		|| tls_handshake_header.get_header_buffer(
       
  6573 			 tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()) == 0)
       
  6574 	{
       
  6575 		// Not enough data.
       
  6576 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6577 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6578 	}
       
  6579 
       
  6580 	EAP_TRACE_DATA_DEBUG(
       
  6581 		m_am_tools, 
       
  6582 		EAP_TRACE_FLAGS_MESSAGE_DATA, 
       
  6583 		(EAPL("TLS-handshake tls_handshake_header"),
       
  6584 		 tls_handshake_header.get_header_buffer(
       
  6585 			 tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()),
       
  6586 		 (tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length())));
       
  6587 
       
  6588 	eap_status_e status = eap_status_ok;
       
  6589 
       
  6590 	u32_t counter = 0ul;
       
  6591 
       
  6592 
       
  6593 	while (tls_handshake_header.get_is_valid() == true
       
  6594 		&& data_start_offset < tls_protocol_messages_length)
       
  6595 	{
       
  6596 		const u32_t handshake_data_length = tls_handshake_header.get_data_length();
       
  6597 		if (handshake_data_length+data_start_offset > tls_protocol_messages_length)
       
  6598 		{
       
  6599 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6600 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6601 		}
       
  6602 
       
  6603 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6604 		EAP_TRACE_DEBUG(
       
  6605 			m_am_tools,
       
  6606 			TRACE_FLAGS_DEFAULT,
       
  6607 			(EAPL("TLS: %s: parse_function: parse_tls_protocol_handshake(): ")
       
  6608 			 EAPL("counter[%u] type = 0x%08x=%s.\n"),
       
  6609 			 (m_is_client == true ? "client": "server"),
       
  6610 			 counter,
       
  6611 			 tls_handshake_header.get_handshake_type(),
       
  6612 			 tls_handshake_header.get_tls_handshake_string()));
       
  6613 
       
  6614 		status = tls_handshake_header.check_header(
       
  6615 			tls_handshake_header.get_handshake_type(),
       
  6616 			m_is_client);
       
  6617 		if (status != eap_status_ok)
       
  6618 		{
       
  6619 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6620 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6621 		}
       
  6622 
       
  6623 		if (tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()
       
  6624 				> tls_handshake_header.get_header_buffer_length()
       
  6625 			|| tls_handshake_header.get_header_buffer(
       
  6626 				 tls_handshake_header.get_header_length()+tls_handshake_header.get_data_length()) == 0)
       
  6627 		{
       
  6628 			// Not enough data.
       
  6629 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6630 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6631 		}
       
  6632 
       
  6633 		bool add_to_message_hash = false;
       
  6634 
       
  6635 		switch (tls_handshake_header.get_handshake_type())
       
  6636 		{
       
  6637 		case tls_handshake_type_hello_request:
       
  6638 			status = parse_handshake_type_hello_request(
       
  6639 				tls_record_message,
       
  6640 				&tls_handshake_header,
       
  6641 				handshake_data_length);
       
  6642 			add_to_message_hash = false;
       
  6643 			break;
       
  6644 		case tls_handshake_type_client_hello:
       
  6645 			status = parse_handshake_type_client_hello(
       
  6646 				tls_record_message,
       
  6647 				&tls_handshake_header,
       
  6648 				handshake_data_length);
       
  6649 			add_to_message_hash = true;
       
  6650 			break;
       
  6651 		case tls_handshake_type_server_hello:
       
  6652 			status = parse_handshake_type_server_hello(
       
  6653 				tls_record_message,
       
  6654 				&tls_handshake_header,
       
  6655 				handshake_data_length);
       
  6656 			add_to_message_hash = true;
       
  6657 			break;
       
  6658 		case tls_handshake_type_certificate:
       
  6659 			status = parse_handshake_type_certificate(
       
  6660 				tls_record_message,
       
  6661 				&tls_handshake_header,
       
  6662 				handshake_data_length);
       
  6663 			add_to_message_hash = true;
       
  6664 			break;
       
  6665 		case tls_handshake_type_server_key_exchange:
       
  6666 			status = parse_handshake_type_server_key_exchange(
       
  6667 				tls_record_message,
       
  6668 				&tls_handshake_header,
       
  6669 				handshake_data_length);
       
  6670 			add_to_message_hash = true;
       
  6671 			break;
       
  6672 		case tls_handshake_type_certificate_request:
       
  6673 			status = parse_handshake_type_certificate_request(
       
  6674 				tls_record_message,
       
  6675 				&tls_handshake_header,
       
  6676 				handshake_data_length);
       
  6677 			add_to_message_hash = true;
       
  6678 			break;
       
  6679 		case tls_handshake_type_server_hello_done:
       
  6680 			status = parse_handshake_type_server_hello_done(
       
  6681 				tls_record_message,
       
  6682 				&tls_handshake_header,
       
  6683 				handshake_data_length);
       
  6684 			add_to_message_hash = true;
       
  6685 			break;
       
  6686 		case tls_handshake_type_certificate_verify:
       
  6687 			status = parse_handshake_type_certificate_verify(
       
  6688 				tls_record_message,
       
  6689 				&tls_handshake_header,
       
  6690 				handshake_data_length);
       
  6691 			add_to_message_hash = true;
       
  6692 			break;
       
  6693 		case tls_handshake_type_client_key_exchange:
       
  6694 			status = parse_handshake_type_client_key_exchange(
       
  6695 				tls_record_message,
       
  6696 				&tls_handshake_header,
       
  6697 				handshake_data_length);
       
  6698 			add_to_message_hash = true;
       
  6699 			break;
       
  6700 		case tls_handshake_type_finished:
       
  6701 			status = parse_handshake_type_finished(
       
  6702 				tls_record_message,
       
  6703 				&tls_handshake_header,
       
  6704 				handshake_data_length);
       
  6705 			add_to_message_hash = true;
       
  6706 			break;
       
  6707 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  6708 		case tls_handshake_type_new_session_ticket:
       
  6709 			status = parse_handshake_type_new_session_ticket(
       
  6710 				tls_record_message,
       
  6711 				&tls_handshake_header,
       
  6712 				handshake_data_length);
       
  6713 			add_to_message_hash = true;
       
  6714 			break;
       
  6715 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  6716 		default:
       
  6717 			return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  6718 		} // switch()
       
  6719 
       
  6720 
       
  6721 		if (status != eap_status_ok)
       
  6722 		{
       
  6723 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6724 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6725 		}
       
  6726 
       
  6727 
       
  6728 		if (add_to_message_hash == true)
       
  6729 		{
       
  6730 			status = message_hash_update(
       
  6731 				true,
       
  6732 				tls_handshake_header.get_handshake_type(),
       
  6733 				tls_handshake_header.get_header_buffer(
       
  6734 					tls_handshake_header.get_header_length()
       
  6735 					+tls_handshake_header.get_data_length()),
       
  6736 				tls_handshake_header.get_header_length()
       
  6737 				+tls_handshake_header.get_data_length());
       
  6738 			if (status != eap_status_ok)
       
  6739 			{
       
  6740 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6741 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6742 			}
       
  6743 		}
       
  6744 
       
  6745 		data_start_offset += (tls_handshake_header.get_header_length()
       
  6746 							  +tls_handshake_header.get_data_length());
       
  6747 
       
  6748 		if (data_start_offset > tls_protocol_messages_buffer->get_data_length())
       
  6749 		{
       
  6750 			// Parsed record length does not match with received record length.
       
  6751 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6752 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6753 		}
       
  6754 
       
  6755 		tls_handshake_header.set_header_buffer(
       
  6756 			tls_protocol_messages_buffer->get_data_offset(
       
  6757 				data_start_offset,
       
  6758 				tls_protocol_messages_buffer->get_data_length()-data_start_offset),
       
  6759 			tls_protocol_messages_buffer->get_data_length()-data_start_offset);
       
  6760 		// NOTE tls_handshake_header is checked in the begin of the loop.
       
  6761 
       
  6762 		++counter;
       
  6763 
       
  6764 	} // while()
       
  6765 
       
  6766 	if (tls_protocol_messages_length != data_start_offset)
       
  6767 	{
       
  6768 		// Parsed record length does not match with received record length.
       
  6769 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6770 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6771 	}
       
  6772 
       
  6773 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6774 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6775 }
       
  6776 
       
  6777 //--------------------------------------------------
       
  6778 
       
  6779 EAP_FUNC_EXPORT eap_status_e tls_record_c::parse_tls_protocol_application_data(
       
  6780 	tls_record_message_c * const tls_record_message,
       
  6781 	eap_variable_data_c * const tls_protocol_messages_buffer)
       
  6782 {
       
  6783 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6784 
       
  6785 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6786 	EAP_TRACE_DEBUG(
       
  6787 		m_am_tools,
       
  6788 		TRACE_FLAGS_DEFAULT,
       
  6789 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::parse_tls_protocol_application_data()\n"),
       
  6790 		(m_is_client == true ? "client": "server")));
       
  6791 
       
  6792 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::parse_tls_protocol_application_data()");
       
  6793 
       
  6794 	tls_record_message->set_parsed_record();
       
  6795 
       
  6796 	eap_status_e status = eap_status_not_supported;
       
  6797 
       
  6798 	const u32_t tls_protocol_messages_length = tls_protocol_messages_buffer->get_data_length();
       
  6799 
       
  6800 	EAP_TRACE_DATA_DEBUG(
       
  6801 		m_am_tools, 
       
  6802 		EAP_TRACE_FLAGS_MESSAGE_DATA, 
       
  6803 		(EAPL("TLS-application data"),
       
  6804 		tls_protocol_messages_buffer->get_data(tls_protocol_messages_length),
       
  6805 		tls_protocol_messages_length));
       
  6806 
       
  6807 	tls_application_data_message_c * const tls_application_data_message
       
  6808 		= new tls_application_data_message_c(m_am_tools, m_is_client);
       
  6809 
       
  6810 		eap_automatic_variable_c<tls_application_data_message_c>
       
  6811 			automatic_tls_application_data_message(m_am_tools, tls_application_data_message);
       
  6812 
       
  6813 	if (tls_application_data_message == 0
       
  6814 		|| tls_application_data_message->get_is_valid() == false)
       
  6815 	{
       
  6816 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6817 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6818 	}
       
  6819 
       
  6820 	u32_t data_offset = 0ul;
       
  6821 
       
  6822 	//----------------------------------------------------------
       
  6823 
       
  6824 	{
       
  6825 		u8_t *p_application_data = tls_protocol_messages_buffer->get_data(
       
  6826 			tls_protocol_messages_length);
       
  6827 		if (p_application_data == 0)
       
  6828 		{
       
  6829 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6830 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6831 		}
       
  6832 
       
  6833 		status = tls_application_data_message->set_application_data(
       
  6834 			p_application_data,
       
  6835 			tls_protocol_messages_length);
       
  6836 		if (status != eap_status_ok)
       
  6837 		{
       
  6838 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6839 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6840 		}
       
  6841 
       
  6842 		data_offset += tls_protocol_messages_length;
       
  6843 	}
       
  6844 
       
  6845 	//----------------------------------------------------------
       
  6846 
       
  6847 	if (tls_protocol_messages_length != data_offset)
       
  6848 	{
       
  6849 		// Parsed record length does not match with received record length.
       
  6850 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6851 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6852 	}
       
  6853 
       
  6854 	if (status == eap_status_ok)
       
  6855 	{
       
  6856 		// Note add_application_data_message() frees message on any case.
       
  6857 		automatic_tls_application_data_message.do_not_free_variable();
       
  6858 
       
  6859 		status = tls_record_message->add_application_data_message(
       
  6860 			tls_application_data_message, true);
       
  6861 		if (status != eap_status_ok)
       
  6862 		{
       
  6863 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6864 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6865 		}
       
  6866 	}
       
  6867 
       
  6868 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6869 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6870 }
       
  6871 
       
  6872 //--------------------------------------------------
       
  6873 
       
  6874 EAP_FUNC_EXPORT eap_status_e tls_record_c::reassemble_tls_records(
       
  6875 	tls_record_message_c * const tls_record_message,
       
  6876 	tls_record_header_c * const next_tls_record_header)
       
  6877 {
       
  6878 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6879 
       
  6880 	EAP_TRACE_DEBUG(
       
  6881 		m_am_tools, 
       
  6882 		TRACE_FLAGS_DEFAULT, 
       
  6883 		(EAPL("TLS: this = 0x%08x, %s: starts: tls_record_c::reassemble_tls_records()\n"),
       
  6884 		 this,
       
  6885 		 (m_is_client == true ? "client": "server")));
       
  6886 
       
  6887 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::reassemble_tls_records()");
       
  6888 
       
  6889 	eap_status_e status = tls_record_message->get_record_message_data()->add_data(
       
  6890 		next_tls_record_header->get_data(next_tls_record_header->get_data_length()),
       
  6891 		next_tls_record_header->get_data_length());
       
  6892 	if (status != eap_status_ok)
       
  6893 	{
       
  6894 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6895 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6896 	}
       
  6897 
       
  6898 	status = tls_record_message->add_data_length(next_tls_record_header->get_data_length());
       
  6899 
       
  6900 	EAP_TRACE_DEBUG(
       
  6901 		m_am_tools, 
       
  6902 		TRACE_FLAGS_DEFAULT, 
       
  6903 		(EAPL("TLS: this = 0x%08x, %s: tls_record_c::reassemble_tls_records(): fragment %d bytes, ")
       
  6904 		 EAPL("message %d bytes.\n"),
       
  6905 		 this,
       
  6906 		 (m_is_client == true ? "client": "server"),
       
  6907 		 next_tls_record_header->get_data_length(),
       
  6908 		 tls_record_message->get_data_length()));
       
  6909 
       
  6910 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6911 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6912 }
       
  6913 
       
  6914 //--------------------------------------------------
       
  6915 
       
  6916 EAP_FUNC_EXPORT eap_status_e tls_record_c::process_tls_records()
       
  6917 {
       
  6918 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6919 
       
  6920 	EAP_TRACE_DEBUG(
       
  6921 		m_am_tools,
       
  6922 		TRACE_FLAGS_DEFAULT,
       
  6923 		(EAPL("\n")));
       
  6924 	EAP_TRACE_DEBUG(
       
  6925 		m_am_tools,
       
  6926 		TRACE_FLAGS_DEFAULT,
       
  6927 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::process_tls_records(): index = %d, record count = %d\n"),
       
  6928 		 (m_is_client == true ? "client": "server"),
       
  6929 		 m_received_tls_message.get_analyse_index(),
       
  6930 		 m_received_tls_message.get_record_message_count()));
       
  6931 
       
  6932 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::process_tls_records()");
       
  6933 
       
  6934 	if (m_already_in_process_tls_records == true)
       
  6935 	{
       
  6936 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6937 		// This is recursive call of process_tls_records().
       
  6938 		// This MUST return eap_status_ok. Other return values will skip
       
  6939 		// further prosessing of TLS message.
       
  6940 		EAP_TRACE_DEBUG(
       
  6941 			m_am_tools, TRACE_FLAGS_DEFAULT,
       
  6942 			(EAPL("TLS: %s: send_function: process_tls_records(): skip recursion\n"),
       
  6943 			(m_is_client == true ? "client": "server")));
       
  6944 		return EAP_STATUS_RETURN(m_am_tools, eap_status_end_recursion);
       
  6945 	}
       
  6946 	m_already_in_process_tls_records = true;
       
  6947 
       
  6948 	eap_automatic_simple_value_c<bool> restore_already_in_process_tls_records(
       
  6949 		m_am_tools,
       
  6950 		&m_already_in_process_tls_records,
       
  6951 		false);
       
  6952 
       
  6953 	// One TLS-message could include many records. Each of records could
       
  6954 	// include many protocol messages.
       
  6955 	// +=================================================+
       
  6956 	// +=================================================+
       
  6957 	// | 1. tls_record_header_c                          |
       
  6958 	// | protocol tls_record_protocol_handshake          |
       
  6959 	// +-------------------------------------------------+
       
  6960 	// | 1a. tls_handshake_header_c                      |
       
  6961 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  6962 	// | 1a. data of handshake                           |
       
  6963 	// +-------------------------------------------------+
       
  6964 	// | 1b. tls_handshake_header_c                      |
       
  6965 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  6966 	// | 1b. data of handshake                           |
       
  6967 	// +=================================================+
       
  6968 	// +=================================================+
       
  6969 	// | 2. tls_record_header_c                          |
       
  6970 	// | protocol tls_record_protocol_change_cipher_spec |
       
  6971 	// +-------------------------------------------------+
       
  6972 	// | 2a. data of change_cipher_spec                  |
       
  6973 	// +=================================================+
       
  6974 	// +=================================================+
       
  6975 	// | 3. tls_record_header_c                          |
       
  6976 	// | protocol tls_record_protocol_handshake          |
       
  6977 	// +-------------------------------------------------+
       
  6978 	// | 3a. tls_handshake_header_c                      |
       
  6979 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  6980 	// | 3a. data of handshake                           |
       
  6981 	// +=================================================+
       
  6982 	// +=================================================+
       
  6983 
       
  6984 	// One protocol message could be fragmented to many records.
       
  6985 	// +=================================================+
       
  6986 	// +=================================================+
       
  6987 	// | 1. tls_record_header_c                          |
       
  6988 	// | protocol tls_record_protocol_handshake          |
       
  6989 	// +-------------------------------------------------+
       
  6990 	// | 1a. tls_handshake_header_c                      |
       
  6991 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  6992 	// | 1a. data of handshake (1/2)                     |
       
  6993 	// +=================================================+
       
  6994 	// +=================================================+
       
  6995 	// | 2. tls_record_header_c                          |
       
  6996 	// | protocol tls_record_protocol_change_cipher_spec |
       
  6997 	// +-------------------------------------------------+
       
  6998 	// | 2a. data of handshake (2/2)                     |
       
  6999 	// +=================================================+
       
  7000 	// +=================================================+
       
  7001 
       
  7002 	eap_status_e status = eap_status_ok;
       
  7003 	u32_t index = 0ul;
       
  7004 	bool analyse_messages = true;
       
  7005 
       
  7006 	for (index = m_received_tls_message.get_analyse_index()
       
  7007 			 ; analyse_messages == true
       
  7008 			 && index < m_received_tls_message.get_record_message_count()
       
  7009 			 ; index++)
       
  7010 	{
       
  7011 		// This is used in EAP-FAST to see the next TLS message type.
       
  7012 		m_received_tls_message.save_analyse_index(index);
       
  7013 
       
  7014 		tls_record_message_c * const tls_record_message
       
  7015 			= m_received_tls_message.get_record_message(index);
       
  7016 		if (tls_record_message == 0)
       
  7017 		{
       
  7018 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7019 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7020 				m_am_tools,
       
  7021 				eap_status_too_short_message);
       
  7022 		}
       
  7023 
       
  7024 		u32_t tls_record_length = tls_record_message->get_record_message_data()->get_data_length();
       
  7025 
       
  7026 		tls_record_header_c tls_record_header(
       
  7027 			m_am_tools,
       
  7028 			tls_record_message->get_record_message_data()->get_data(
       
  7029 				tls_record_header_c::get_header_length()),
       
  7030 			tls_record_length);
       
  7031 
       
  7032 		if (tls_record_header.get_is_valid() == false
       
  7033 			|| tls_record_length < tls_record_header.get_data_length())
       
  7034 		{
       
  7035 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7036 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7037 				m_am_tools,
       
  7038 				eap_status_too_short_message);
       
  7039 		}
       
  7040 
       
  7041 		EAP_TRACE_DATA_DEBUG(
       
  7042 			m_am_tools,
       
  7043 			EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  7044 			(EAPL("process TLS-record message"),
       
  7045 			 tls_record_header.get_header_buffer(tls_record_header.get_header_length()
       
  7046 												 + tls_record_header.get_data_length()),
       
  7047 			 tls_record_header.get_header_length()
       
  7048 			 + tls_record_header.get_data_length()));
       
  7049 
       
  7050 		if ((tls_record_length)
       
  7051 			< (tls_record_header.get_header_length() + tls_record_header.get_data_length()))
       
  7052 		{
       
  7053 			// Record header indicates more data than the received buffer includes.
       
  7054 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7055 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7056 				m_am_tools,
       
  7057 				eap_status_process_illegal_packet_error);
       
  7058 		}
       
  7059 
       
  7060 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7061 		EAP_TRACE_DEBUG(
       
  7062 			m_am_tools,
       
  7063 			TRACE_FLAGS_DEFAULT,
       
  7064 			(EAPL("TLS: %s: parse_function: process_tls_records(): ")
       
  7065 			 EAPL("index[%u] protocol = 0x%08x=%s.\n"),
       
  7066 			(m_is_client == true ? "client": "server"),
       
  7067 			index,
       
  7068 			tls_record_header.get_protocol(),
       
  7069 			tls_record_header.get_tls_protocol_string()));
       
  7070 
       
  7071 
       
  7072 		if (tls_record_message->get_cipher_suite_applied() == false)
       
  7073 		{
       
  7074 			status = apply_receive_cipher_suite(tls_record_message->get_record_message_data());
       
  7075 			if (status != eap_status_ok)
       
  7076 			{
       
  7077 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7078 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7079 			}
       
  7080 
       
  7081 			tls_record_message->set_cipher_suite_applied();
       
  7082 
       
  7083 			tls_record_length = tls_record_message->get_record_message_data()->get_data_length();
       
  7084 
       
  7085 			// We must query tls_record_header again,
       
  7086 			// memory buffer may be changed during apply_receive_cipher_suite() call.
       
  7087 			tls_record_header.set_header_buffer(
       
  7088 				tls_record_message->get_record_message_data()->get_data(
       
  7089 					tls_record_header_c::get_header_length()),
       
  7090 				tls_record_length);
       
  7091 
       
  7092 			if (tls_record_header.get_is_valid() == false
       
  7093 				|| tls_record_length < tls_record_header.get_data_length()
       
  7094 				|| tls_record_length
       
  7095 				< tls_record_header.get_header_length()
       
  7096 				+ tls_record_header.get_data_length())
       
  7097 			{
       
  7098 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7099 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7100 					m_am_tools,
       
  7101 					eap_status_too_short_message);
       
  7102 			}
       
  7103 		}
       
  7104 
       
  7105 
       
  7106 		while (index+1ul < m_received_tls_message.get_record_message_count())
       
  7107 		{
       
  7108 			tls_record_message_c * const next_tls_record_message
       
  7109 				= m_received_tls_message.get_record_message(index+1ul);
       
  7110 			if (next_tls_record_message != 0)
       
  7111 			{
       
  7112 				u32_t next_tls_record_length
       
  7113 					= next_tls_record_message->get_record_message_data()->get_data_length();
       
  7114 
       
  7115 				tls_record_header_c next_tls_record_header(
       
  7116 					m_am_tools,
       
  7117 					next_tls_record_message->get_record_message_data()->get_data(
       
  7118 						tls_record_header_c::get_header_length()),
       
  7119 					next_tls_record_length);
       
  7120 
       
  7121 				if (next_tls_record_header.get_is_valid() == false
       
  7122 					|| next_tls_record_length < next_tls_record_header.get_data_length())
       
  7123 				{
       
  7124 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7125 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7126 						m_am_tools,
       
  7127 						eap_status_too_short_message);
       
  7128 				}
       
  7129 
       
  7130 				if (tls_record_header.get_protocol() == next_tls_record_header.get_protocol())
       
  7131 				{
       
  7132 					// Reassembly checks this and the next TLS-records whether they are fragments
       
  7133 					// and it reassembles fragments to one TLS-record.
       
  7134 					// The easiest check does need only the TLS-protocol fields.
       
  7135 					// If TLS-protocol fields are the same those records could be reassembled.
       
  7136 
       
  7137 					if (next_tls_record_message->get_cipher_suite_applied() == false)
       
  7138 					{
       
  7139 						status = apply_receive_cipher_suite(
       
  7140 							next_tls_record_message->get_record_message_data());
       
  7141 						if (status != eap_status_ok)
       
  7142 						{
       
  7143 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7144 							return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7145 								m_am_tools,
       
  7146 								status);
       
  7147 						}
       
  7148 						
       
  7149 						next_tls_record_message->set_cipher_suite_applied();
       
  7150 					}
       
  7151 
       
  7152 					next_tls_record_length
       
  7153 						= next_tls_record_message->get_record_message_data()->get_data_length();
       
  7154 
       
  7155 					next_tls_record_header.set_header_buffer(
       
  7156 						next_tls_record_message->get_record_message_data()->get_data(
       
  7157 							tls_record_header_c::get_header_length()),
       
  7158 						next_tls_record_length);
       
  7159 					
       
  7160 					if (next_tls_record_header.get_is_valid() == false
       
  7161 						|| next_tls_record_length < next_tls_record_header.get_data_length())
       
  7162 					{
       
  7163 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7164 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7165 							m_am_tools,
       
  7166 							eap_status_too_short_message);
       
  7167 					}
       
  7168 
       
  7169 					status = reassemble_tls_records(tls_record_message, &next_tls_record_header);
       
  7170 					if (status != eap_status_ok)
       
  7171 					{
       
  7172 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7173 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7174 					}
       
  7175 
       
  7176 					// If TLS-record is complete then it could be parsed and analysed.
       
  7177 					// TLS-record is complete when the next TLS-record is other type of protocol.
       
  7178 					// If TLS-record is NOT complete the next TLS-record must processed.
       
  7179 					// In a case the TLS-record cannot be reassemled the whole
       
  7180 					// TLS-message must be dropped.
       
  7181 
       
  7182 					// Remove the next_tls_record_message.
       
  7183 					status = m_received_tls_message.remove_record_message(index+1ul);
       
  7184 					if (status != eap_status_ok)
       
  7185 					{
       
  7186 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7187 						return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7188 					}
       
  7189 				}
       
  7190 				else
       
  7191 				{
       
  7192 					break;
       
  7193 				}
       
  7194 			}
       
  7195 			else
       
  7196 			{
       
  7197 				break;
       
  7198 			}
       
  7199 		} // while()
       
  7200 
       
  7201 		// NOTE at this point the length may be longer than 2^14 bytes.
       
  7202 		tls_record_length = tls_record_message->get_record_message_data()->get_data_length();
       
  7203 
       
  7204 		// We must query tls_record_header again,
       
  7205 		// memory buffer may be changed during reassembly.
       
  7206 		tls_record_header.set_header_buffer(
       
  7207 			tls_record_message->get_record_message_data()->get_data(
       
  7208 				tls_record_length),
       
  7209 			tls_record_length);
       
  7210 		
       
  7211 		if (tls_record_header.get_is_valid() == false
       
  7212 			|| tls_record_length < tls_record_header.get_data_length()
       
  7213 			|| tls_record_length
       
  7214 			< tls_record_header.get_header_length()
       
  7215 			+ tls_record_header.get_data_length())
       
  7216 		{
       
  7217 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7218 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7219 				m_am_tools,
       
  7220 				eap_status_too_short_message);
       
  7221 		}
       
  7222 
       
  7223 
       
  7224 
       
  7225 		// Here we extract the protocol messages from the buffer.
       
  7226 		// Note the tls_record_header includes only the first protocol message,
       
  7227 		// that causes the use of tls_record_message->get_record_message_data().
       
  7228 		u32_t protocol_messages_length = tls_record_length - tls_record_header.get_header_length();
       
  7229 		eap_variable_data_c protocol_messages(m_am_tools);
       
  7230 
       
  7231 		status = protocol_messages.set_buffer(
       
  7232 			tls_record_message->get_record_message_data()->get_data_offset(
       
  7233 				tls_record_header.get_header_length(),
       
  7234 				protocol_messages_length),
       
  7235 			protocol_messages_length,
       
  7236 			false,
       
  7237 			true);
       
  7238 		if (status != eap_status_ok)
       
  7239 		{
       
  7240 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7241 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7242 		}
       
  7243 
       
  7244 		EAP_TRACE_DATA_DEBUG(
       
  7245 			m_am_tools,
       
  7246 			EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  7247 			(EAPL("reassembled TLS-protocol messages"),
       
  7248 			 protocol_messages.get_data(
       
  7249 				 protocol_messages.get_data_length()),
       
  7250 			 protocol_messages.get_data_length()));
       
  7251 
       
  7252 		switch(tls_record_header.get_protocol())
       
  7253 		{
       
  7254 		case tls_record_protocol_change_cipher_spec:
       
  7255 		{
       
  7256 			if (tls_record_message->get_parsed_record() == false)
       
  7257 			{
       
  7258 				status = parse_tls_protocol_change_cipher_spec(
       
  7259 					tls_record_message,
       
  7260 					&protocol_messages);
       
  7261 				if (status != eap_status_ok)
       
  7262 				{
       
  7263 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7264 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7265 				}
       
  7266 			}
       
  7267 
       
  7268 			status = analyse_tls_protocol_change_cipher_spec(
       
  7269 				tls_record_message);
       
  7270 			break;
       
  7271 		}
       
  7272 		case tls_record_protocol_alert:
       
  7273 		{
       
  7274 			if (tls_record_message->get_parsed_record() == false)
       
  7275 			{
       
  7276 				status = parse_tls_protocol_alert(
       
  7277 					tls_record_message,
       
  7278 					&protocol_messages);
       
  7279 				if (status != eap_status_ok)
       
  7280 				{
       
  7281 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7282 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7283 				}
       
  7284 			}
       
  7285 
       
  7286 			status = analyse_tls_protocol_alert(
       
  7287 				tls_record_message);
       
  7288 			break;
       
  7289 		}
       
  7290 		case tls_record_protocol_handshake:
       
  7291 		{
       
  7292 			if (tls_record_message->get_parsed_record() == false)
       
  7293 			{
       
  7294 				status = parse_tls_protocol_handshake(
       
  7295 					tls_record_message,
       
  7296 					&protocol_messages);
       
  7297 				if (status != eap_status_ok)
       
  7298 				{
       
  7299 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7300 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7301 				}
       
  7302 			}
       
  7303 
       
  7304 			status = analyse_tls_protocol_handshake(
       
  7305 				tls_record_message,
       
  7306 				m_received_tls_message.get_received_eap_identifier());
       
  7307 			break;
       
  7308 		}
       
  7309 		case tls_record_protocol_application_data:
       
  7310 		{
       
  7311 			if (tls_record_message->get_parsed_record() == false)
       
  7312 			{
       
  7313 				status = parse_tls_protocol_application_data(
       
  7314 					tls_record_message,
       
  7315 					&protocol_messages);
       
  7316 				if (status != eap_status_ok)
       
  7317 				{
       
  7318 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7319 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7320 				}
       
  7321 			}
       
  7322 
       
  7323 			status = analyse_tls_protocol_application_data(
       
  7324 				tls_record_message,
       
  7325 				m_received_tls_message.get_received_eap_identifier());
       
  7326 			break;
       
  7327 		}
       
  7328 		default:
       
  7329 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7330 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7331 				m_am_tools,
       
  7332 				eap_status_wrong_protocol);
       
  7333 		} // switch()
       
  7334 
       
  7335 
       
  7336 		// Save the analysed state. We will continue from the following record
       
  7337 		// after the pending request is completed.
       
  7338 		m_received_tls_message.save_analyse_index(index+1ul);
       
  7339 
       
  7340 		EAP_TRACE_DEBUG(
       
  7341 			m_am_tools,
       
  7342 			TRACE_FLAGS_DEFAULT,
       
  7343 			(EAPL("TLS: %s: parse_function: process_tls_records(): saves index+1 = %u.\n"),
       
  7344 			(m_is_client == true ? "client": "server"),
       
  7345 			index+1ul));
       
  7346 
       
  7347 
       
  7348 		if (status == eap_status_pending_request)
       
  7349 		{
       
  7350 			// Save analyse state. We will continue from the current record
       
  7351 			// after the pending request is completed.
       
  7352 			m_received_tls_message.save_analyse_index(index);
       
  7353 
       
  7354 			EAP_TRACE_DEBUG(
       
  7355 				m_am_tools,
       
  7356 				TRACE_FLAGS_DEFAULT,
       
  7357 				(EAPL("TLS: %s: parse_function: process_tls_records(): pending request, saves index = %u.\n"),
       
  7358 				(m_is_client == true ? "client": "server"),
       
  7359 				index));
       
  7360 
       
  7361 			analyse_messages = false;
       
  7362 			
       
  7363 			eap_status_e compl_status = completion_action_add(
       
  7364 				tls_completion_action_process_tls_records);
       
  7365 			if (compl_status != eap_status_ok)
       
  7366 			{
       
  7367 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7368 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7369 			}
       
  7370 		}
       
  7371 		else if (status != eap_status_ok)
       
  7372 		{
       
  7373 			analyse_messages = false;
       
  7374 		}
       
  7375 
       
  7376 		if ((get_is_tunneled_tls() == false
       
  7377 				&& m_tls_peap_state == tls_peap_state_tls_success)
       
  7378 			|| (get_is_tunneled_tls() == true
       
  7379 				&& m_tls_peap_state == tls_peap_state_peap_tunnel_ready))
       
  7380 		{
       
  7381 			// Authentication OK.
       
  7382 
       
  7383 			if (m_eap_type == eap_type_peap
       
  7384 				&& m_peap_version == peap_version_2
       
  7385 				&& m_tls_peap_state == tls_peap_state_peap_tunnel_ready)
       
  7386 			{
       
  7387 				// PEAPv2 sends EAP-Request/Identity message
       
  7388 				// within the application data within the same message
       
  7389 				// with TLS hello finished.
       
  7390 				EAP_TRACE_DEBUG(
       
  7391 					m_am_tools,
       
  7392 					TRACE_FLAGS_DEFAULT,
       
  7393 					(EAPL("TLS: PEAPv2 tunnel ready, application data may follow.\n")));
       
  7394 			}
       
  7395 			else
       
  7396 			{
       
  7397 				analyse_messages = false;
       
  7398 				if ((index+1ul) != m_received_tls_message.get_record_message_count())
       
  7399 				{
       
  7400 					EAP_TRACE_DEBUG(
       
  7401 						m_am_tools,
       
  7402 						TRACE_FLAGS_DEFAULT,
       
  7403 						(EAPL("ERROR: TLS: %s: parse_function: starts: tls_record_c::process_tls_records(): (index+1 = %d) != (record count = %d)\n"),
       
  7404 						 (m_is_client == true ? "client": "server"),
       
  7405 						 index+1,
       
  7406 						 m_received_tls_message.get_record_message_count()));
       
  7407 					// Authentication was successfull, but there are unused TLS-records to process.
       
  7408 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7409 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  7410 				}
       
  7411 				EAP_TRACE_DEBUG(
       
  7412 					m_am_tools,
       
  7413 					TRACE_FLAGS_DEFAULT,
       
  7414 					(EAPL("TLS: tls_record_c::process_tls_records(): m_received_tls_message.reset().\n")));
       
  7415 				m_received_tls_message.reset();
       
  7416 			}
       
  7417 		}
       
  7418 	} // for()
       
  7419 
       
  7420 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7421 	return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7422 }
       
  7423 
       
  7424 //--------------------------------------------------
       
  7425 
       
  7426 EAP_FUNC_EXPORT eap_status_e tls_record_c::process_tls_message()
       
  7427 {
       
  7428 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7429 
       
  7430 	EAP_TRACE_DEBUG(
       
  7431 		m_am_tools, 
       
  7432 		TRACE_FLAGS_DEFAULT, 
       
  7433 		(EAPL("\n")));
       
  7434 	EAP_TRACE_DEBUG(
       
  7435 		m_am_tools, 
       
  7436 		TRACE_FLAGS_DEFAULT, 
       
  7437 		(EAPL("TLS: %s: parse_function: starts: tls_record_c::process_tls_message()\n"),
       
  7438 		 (m_is_client == true ? "client": "server")));
       
  7439 
       
  7440 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::process_tls_message()");
       
  7441 
       
  7442 	EAP_TRACE_DATA_DEBUG(
       
  7443 		m_am_tools, 
       
  7444 		EAP_TRACE_FLAGS_MESSAGE_DATA, 
       
  7445 		(EAPL("TLS-message"),
       
  7446 		m_received_tls_message.get_tls_message_data()->get_data(
       
  7447 			m_received_tls_message.get_tls_message_data()->get_data_length()),
       
  7448 		m_received_tls_message.get_tls_message_data()->get_data_length()));
       
  7449 
       
  7450 	u32_t next_start_offset = 0ul;
       
  7451 	u32_t tls_packet_length = m_received_tls_message.get_tls_message_data()->get_data_length();
       
  7452 
       
  7453 	if (tls_packet_length < tls_record_header_c::get_header_length())
       
  7454 	{
       
  7455 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7456 		return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7457 			m_am_tools,
       
  7458 			eap_status_too_short_message);
       
  7459 	}
       
  7460 
       
  7461 	tls_record_header_c tls_record_header(
       
  7462 		m_am_tools,
       
  7463 		m_received_tls_message.get_tls_message_data()->get_data_offset(
       
  7464 			next_start_offset,
       
  7465 			tls_record_header_c::get_header_length()),
       
  7466 		tls_packet_length);
       
  7467 
       
  7468 	if (tls_record_header.get_is_valid() == false
       
  7469 		|| tls_packet_length < tls_record_header.get_data_length())
       
  7470 	{
       
  7471 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7472 		return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7473 			m_am_tools,
       
  7474 			eap_status_too_short_message);
       
  7475 	}
       
  7476 
       
  7477 	eap_status_e status = eap_status_ok;
       
  7478 	u32_t counter = 0ul;
       
  7479 
       
  7480 	// One TLS-message could include many records. Each of records
       
  7481 	// could include many protocol messages.
       
  7482 	// +=================================================+
       
  7483 	// +=================================================+
       
  7484 	// | 1. tls_record_header_c                          |
       
  7485 	// | protocol tls_record_protocol_handshake          |
       
  7486 	// +-------------------------------------------------+
       
  7487 	// | 1a. tls_handshake_header_c                      |
       
  7488 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  7489 	// | 1a. data of handshake                           |
       
  7490 	// +-------------------------------------------------+
       
  7491 	// | 1b. tls_handshake_header_c                      |
       
  7492 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  7493 	// | 1b. data of handshake                           |
       
  7494 	// +=================================================+
       
  7495 	// +=================================================+
       
  7496 	// | 2. tls_record_header_c                          |
       
  7497 	// | protocol tls_record_protocol_change_cipher_spec |
       
  7498 	// +-------------------------------------------------+
       
  7499 	// | 2a. data of change_cipher_spec                  |
       
  7500 	// +=================================================+
       
  7501 	// +=================================================+
       
  7502 	// | 3. tls_record_header_c                          |
       
  7503 	// | protocol tls_record_protocol_handshake          |
       
  7504 	// +-------------------------------------------------+
       
  7505 	// | 3a. tls_handshake_header_c                      |
       
  7506 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  7507 	// | 3a. data of handshake                           |
       
  7508 	// +=================================================+
       
  7509 	// +=================================================+
       
  7510 
       
  7511 	// One protocol message could be fragmented to many records.
       
  7512 	// +=================================================+
       
  7513 	// +=================================================+
       
  7514 	// | 1. tls_record_header_c                          |
       
  7515 	// | protocol tls_record_protocol_handshake          |
       
  7516 	// +-------------------------------------------------+
       
  7517 	// | 1a. tls_handshake_header_c                      |
       
  7518 	// +- - - - - - - - - - - - - - - - - - - - - - - - -+
       
  7519 	// | 1a. data of handshake (1/2)                     |
       
  7520 	// +=================================================+
       
  7521 	// +=================================================+
       
  7522 	// | 2. tls_record_header_c                          |
       
  7523 	// | protocol tls_record_protocol_change_cipher_spec |
       
  7524 	// +-------------------------------------------------+
       
  7525 	// | 2a. data of handshake (2/2)                     |
       
  7526 	// +=================================================+
       
  7527 	// +=================================================+
       
  7528 
       
  7529 	while(status == eap_status_ok
       
  7530 		  && next_start_offset < tls_packet_length
       
  7531 		  && tls_record_header.get_is_valid() == true)
       
  7532 	{
       
  7533 		if ((tls_packet_length-next_start_offset)
       
  7534 			< (tls_record_header.get_header_length() + tls_record_header.get_data_length()))
       
  7535 		{
       
  7536 			// Record header indicates more data than the received buffer includes.
       
  7537 			EAP_TRACE_ERROR(
       
  7538 				m_am_tools,
       
  7539 				TRACE_FLAGS_DEFAULT,
       
  7540 				(EAPL("ERROR: Record header indicates more data %u ")
       
  7541 				 EAPL("than the received buffer includes %u.\n"),
       
  7542 				 (tls_record_header.get_header_length() + tls_record_header.get_data_length()),
       
  7543 				 (tls_packet_length-next_start_offset)));
       
  7544 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7545 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7546 				m_am_tools,
       
  7547 				eap_status_process_illegal_packet_error);
       
  7548 		}
       
  7549 
       
  7550 		EAP_TRACE_DATA_DEBUG(
       
  7551 			m_am_tools,
       
  7552 			EAP_TRACE_FLAGS_MESSAGE_DATA,
       
  7553 			(EAPL("process TLS-record"),
       
  7554 			 tls_record_header.get_header_buffer(
       
  7555 				 tls_record_header.get_header_length()
       
  7556 				 + tls_record_header.get_data_length()),
       
  7557 			 tls_record_header.get_header_length()
       
  7558 			 + tls_record_header.get_data_length()));
       
  7559 
       
  7560 		u32_t tls_record_length = tls_record_header.get_header_length()
       
  7561 			+ tls_record_header.get_data_length();
       
  7562 
       
  7563 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7564 		EAP_TRACE_DEBUG(
       
  7565 			m_am_tools,
       
  7566 			TRACE_FLAGS_DEFAULT,
       
  7567 			(EAPL("TLS: %s: parse_function: process_tls_message(): ")
       
  7568 			 EAPL("counter[%u] protocol = 0x%08x=%s.\n"),
       
  7569 			(m_is_client == true ? "client": "server"),
       
  7570 			counter,
       
  7571 			tls_record_header.get_protocol(),
       
  7572 			tls_record_header.get_tls_protocol_string()));
       
  7573 
       
  7574 		tls_record_message_c * const tls_record_message
       
  7575 			= new tls_record_message_c(m_am_tools, this, m_is_client);
       
  7576 
       
  7577 		eap_automatic_variable_c<tls_record_message_c>
       
  7578 			automatic_tls_record_message(m_am_tools, tls_record_message);
       
  7579 
       
  7580 		if (tls_record_message == 0
       
  7581 			|| tls_record_message->get_is_valid() == false)
       
  7582 		{
       
  7583 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7584 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7585 				m_am_tools,
       
  7586 				eap_status_allocation_error);
       
  7587 		}
       
  7588 
       
  7589 		tls_record_message->set_tls_record_header_is_included(true);
       
  7590 
       
  7591 		status = tls_record_message->set_record_header_copy(&tls_record_header);
       
  7592 		if (status != eap_status_ok)
       
  7593 		{
       
  7594 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7595 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7596 		}
       
  7597 
       
  7598 		tls_record_message->set_record_message_data(
       
  7599 			tls_record_header.get_header_buffer(tls_record_header.get_header_length()
       
  7600 												+ tls_record_header.get_data_length()),
       
  7601 			tls_record_header.get_header_length()
       
  7602 			+ tls_record_header.get_data_length());
       
  7603 
       
  7604 		// Note m_received_tls_message frees message on any case.
       
  7605 		automatic_tls_record_message.do_not_free_variable();
       
  7606 
       
  7607 		status = m_received_tls_message.add_record_message(
       
  7608 			tls_record_message,
       
  7609 			true,
       
  7610 			false // Here the TLS-Hello messages are not marked.
       
  7611 			);
       
  7612 		if (status != eap_status_ok)
       
  7613 		{
       
  7614 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7615 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7616 		}
       
  7617 
       
  7618 
       
  7619 		next_start_offset += tls_record_length;
       
  7620 
       
  7621 		if (next_start_offset < tls_packet_length)
       
  7622 		{
       
  7623 			u32_t remain_data_length = tls_packet_length - next_start_offset;
       
  7624 			if (remain_data_length < tls_record_header_c::get_header_length())
       
  7625 			{
       
  7626 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7627 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7628 					m_am_tools,
       
  7629 					eap_status_too_short_message);
       
  7630 			}
       
  7631 
       
  7632 			tls_record_header.set_header_buffer(
       
  7633 				m_received_tls_message.get_tls_message_data()->get_data_offset(
       
  7634 					next_start_offset,
       
  7635 					tls_record_header_c::get_header_length()),
       
  7636 				remain_data_length);
       
  7637 
       
  7638 			if (tls_record_header.get_is_valid() == false
       
  7639 				|| remain_data_length < tls_record_header.get_data_length())
       
  7640 			{
       
  7641 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7642 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7643 					m_am_tools,
       
  7644 					eap_status_too_short_message);
       
  7645 			}
       
  7646 		}
       
  7647 
       
  7648 		++counter;
       
  7649 
       
  7650 	} // while()
       
  7651 
       
  7652 	if (next_start_offset != tls_packet_length)
       
  7653 	{
       
  7654 		// Parsed packet length does not match with received packet length.
       
  7655 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7656 		return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(
       
  7657 			m_am_tools,
       
  7658 			eap_status_process_illegal_packet_error);
       
  7659 	}
       
  7660 
       
  7661 	status = process_tls_records();
       
  7662 
       
  7663 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7664 	return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  7665 }
       
  7666 
       
  7667 //--------------------------------------------------
       
  7668 
       
  7669 EAP_FUNC_EXPORT eap_status_e tls_record_c::check_selected_cipher_suite(
       
  7670 	const tls_cipher_suites_e selected_cipher_suite)
       
  7671 {
       
  7672 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7673 
       
  7674 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7675 	EAP_TRACE_DEBUG(
       
  7676 		m_am_tools,
       
  7677 		TRACE_FLAGS_DEFAULT,
       
  7678 		(EAPL("TLS: %s: suite_function: starts: tls_record_c::check_selected_cipher_suite(): selected_cipher_suite=%d=%s\n"),
       
  7679 		 (m_is_client == true ? "client": "server"),
       
  7680 		 selected_cipher_suite,
       
  7681 		 eap_tls_trace_string_c::get_cipher_suite_string(selected_cipher_suite)));
       
  7682 
       
  7683 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::check_selected_cipher_suite()");
       
  7684 
       
  7685 	u16_t tmp_selected_cipher_suite = static_cast<u16_t>(selected_cipher_suite);
       
  7686 
       
  7687 	i32_t index = find_simple<u16_t>(
       
  7688 		&m_proposed_cipher_suites,
       
  7689 		&tmp_selected_cipher_suite,
       
  7690 		m_am_tools);
       
  7691 	if (index == -1)
       
  7692 	{
       
  7693 		for (u32_t ind = 0ul; ind < m_proposed_cipher_suites.get_object_count(); ++ind)
       
  7694 		{
       
  7695 			u16_t * proposed_cipher_suite = m_proposed_cipher_suites.get_object(ind);
       
  7696 			if (proposed_cipher_suite != 0)
       
  7697 			{
       
  7698 				EAP_TRACE_DEBUG(
       
  7699 					m_am_tools,
       
  7700 					TRACE_FLAGS_DEFAULT,
       
  7701 					(EAPL("TLS: %s: suite_function: check_selected_cipher_suite(): proposed cipher suite=%d=%s\n"),
       
  7702 					 (m_is_client == true ? "client": "server"),
       
  7703 					 *proposed_cipher_suite,
       
  7704 					 eap_tls_trace_string_c::get_cipher_suite_string(static_cast<tls_cipher_suites_e>(*proposed_cipher_suite))));
       
  7705 			}
       
  7706 		}
       
  7707 
       
  7708 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7709 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
  7710 	}
       
  7711 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7712 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7713 }
       
  7714 
       
  7715 //--------------------------------------------------
       
  7716 
       
  7717 EAP_FUNC_EXPORT eap_status_e tls_record_c::check_selected_compression_method(
       
  7718 	const tls_compression_method_e selected_compression_method)
       
  7719 {
       
  7720 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7721 
       
  7722 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7723 	EAP_TRACE_DEBUG(
       
  7724 		m_am_tools,
       
  7725 		TRACE_FLAGS_DEFAULT,
       
  7726 		(EAPL("TLS: %s: suite_function: starts: tls_record_c::check_selected_compression_method(): %s\n"),
       
  7727 		 (m_is_client == true ? "client": "server"),
       
  7728 		 eap_tls_trace_string_c::get_compression_method_string(selected_compression_method)));
       
  7729 
       
  7730 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::check_selected_compression_method()");
       
  7731 
       
  7732 	if (selected_compression_method == tls_compression_method_null)
       
  7733 	{
       
  7734 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7735 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7736 	}
       
  7737 
       
  7738 	u8_t tmp_selected_compression_method = static_cast<u8_t>(selected_compression_method);
       
  7739 
       
  7740 	i32_t index = find_simple<u8_t>(
       
  7741 		&m_proposed_compression_methods,
       
  7742 		&tmp_selected_compression_method, m_am_tools);
       
  7743 	if (index == -1)
       
  7744 	{
       
  7745 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7746 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
  7747 	}
       
  7748 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7749 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7750 }
       
  7751 
       
  7752 //--------------------------------------------------
       
  7753 
       
  7754 EAP_FUNC_EXPORT eap_status_e tls_record_c::u16_t_to_host_order(
       
  7755 	u16_t * const value,
       
  7756 	abs_eap_am_tools_c * const m_am_tools)
       
  7757 {
       
  7758 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7759 	EAP_UNREFERENCED_PARAMETER(m_am_tools);
       
  7760 
       
  7761 	*value = eap_ntohs(*value);
       
  7762 
       
  7763 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7764 }
       
  7765 
       
  7766 //--------------------------------------------------
       
  7767 
       
  7768 EAP_FUNC_EXPORT eap_status_e tls_record_c::u16_t_to_network_order(
       
  7769 	u16_t * const value,
       
  7770 	abs_eap_am_tools_c * const m_am_tools)
       
  7771 {
       
  7772 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7773 	EAP_UNREFERENCED_PARAMETER(m_am_tools);
       
  7774 
       
  7775 	*value = eap_htons(*value);
       
  7776 
       
  7777 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7778 }
       
  7779 
       
  7780 
       
  7781 //--------------------------------------------------
       
  7782 
       
  7783 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_hello_request(
       
  7784 	EAP_TEMPLATE_CONST tls_handshake_message_c * const /* handshake_message */)
       
  7785 {
       
  7786 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7787 
       
  7788 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7789 	EAP_TRACE_DEBUG(
       
  7790 		m_am_tools,
       
  7791 		TRACE_FLAGS_DEFAULT,
       
  7792 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_hello_request()\n"),
       
  7793 		(m_is_client == true ? "client": "server")));
       
  7794 
       
  7795 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_hello_request()");
       
  7796 
       
  7797 	EAP_ASSERT(m_is_client == true);
       
  7798 
       
  7799 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  7800 	set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_runs);
       
  7801 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  7802 
       
  7803 	set_state(tls_peap_state_wait_handshake_type_server_hello);
       
  7804 
       
  7805 	eap_status_e status = completion_action_add(tls_completion_action_create_handshake_type_client_hello);
       
  7806 	if (status != eap_status_ok)
       
  7807 	{
       
  7808 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7809 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7810 	}
       
  7811 
       
  7812 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7813 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7814 }
       
  7815 
       
  7816 //--------------------------------------------------
       
  7817 
       
  7818 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_client_hello(
       
  7819 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message)
       
  7820 {
       
  7821 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7822 
       
  7823 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7824 
       
  7825 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  7826 	EAP_TRACE_DEBUG(
       
  7827 		m_am_tools,
       
  7828 		TRACE_FLAGS_DEFAULT,
       
  7829 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_client_hello(): privacy_handshake_state=%d=%s, session_type=%s\n"),
       
  7830 		 (m_is_client == true ? "client": "server"),
       
  7831 		 m_tls_identity_privacy_handshake_state,
       
  7832 		 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(m_tls_identity_privacy_handshake_state),
       
  7833 		 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)
       
  7834 		));
       
  7835 #else
       
  7836 	EAP_TRACE_DEBUG(
       
  7837 		m_am_tools,
       
  7838 		TRACE_FLAGS_DEFAULT,
       
  7839 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_client_hello(): privacy_handshake_state=%d=%s\n"),
       
  7840 		(m_is_client == true ? "client": "server"),
       
  7841 		0,
       
  7842 		""
       
  7843 		));
       
  7844 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  7845 
       
  7846 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_client_hello()");
       
  7847 
       
  7848 	EAP_ASSERT(m_is_client == false);
       
  7849 
       
  7850 	// 0                   1                   2                   3   
       
  7851 	//  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 
       
  7852 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  7853 	//                 | Version: 3    | Version: 1    |               |
       
  7854 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  7855 	// |                                                               |
       
  7856 	// +                                                               +
       
  7857 	// |                                                               |
       
  7858 	// +                                                               +
       
  7859 	// |          ClientRandomValue                                    |
       
  7860 	// +              (32 bytes)                       +-+-+-+-+-+-+-+-+
       
  7861 	// |                                               | ID length     |
       
  7862 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  7863 	// |                                                               |
       
  7864 	// +                                                               +
       
  7865 	// |                Session ID                                     |
       
  7866 	// +             (maximum 32 bytes)                                +
       
  7867 	// |                                                               |
       
  7868 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  7869 	// | CipherSuite length            | CipherSuite 1                 |
       
  7870 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  7871 	// | CipherSuite 2                 | CipherSuite 3                 |
       
  7872 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  7873 	// | CipherSuite 4                 | Cmp length    | Cmp 1         |
       
  7874 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  7875 	// | Cmp 2         | Cmp 3         |  extensions ...               |
       
  7876 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  7877 
       
  7878 	eap_status_e status = eap_status_not_supported;
       
  7879 
       
  7880 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7881 
       
  7882 	if (handshake_message->get_random_value() == 0
       
  7883 		|| handshake_message->get_random_value()->get_data_length()
       
  7884 		!= TLS_HANDSHAKE_RANDOM_VALUE_SIZE)
       
  7885 	{
       
  7886 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7887 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7888 	}
       
  7889 
       
  7890 
       
  7891 	status = m_client_handshake_random_value.set_copy_of_buffer(
       
  7892 		handshake_message->get_random_value());
       
  7893 	if (status != eap_status_ok
       
  7894 		|| m_client_handshake_random_value.get_data_length() != TLS_HANDSHAKE_RANDOM_VALUE_SIZE)
       
  7895 	{
       
  7896 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7897 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7898 	}
       
  7899 
       
  7900 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7901 
       
  7902 	if (handshake_message->get_session_id() == 0
       
  7903 		|| (handshake_message->get_session_id()->get_is_valid_data() == true
       
  7904 			&& handshake_message->get_session_id()->get_data_length() > TLS_SESSION_ID_SIZE))
       
  7905 	{
       
  7906 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7907 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7908 	}
       
  7909 
       
  7910 	if (handshake_message->get_session_id()->get_is_valid_data() == true
       
  7911 		&& handshake_message->get_session_id()->get_data_length() > 0ul)
       
  7912 	{
       
  7913 		status = m_session_id.set_copy_of_buffer(handshake_message->get_session_id());
       
  7914 		if (status != eap_status_ok
       
  7915 			|| m_session_id.get_data_length() > TLS_SESSION_ID_SIZE)
       
  7916 		{
       
  7917 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7918 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7919 		}
       
  7920 	}
       
  7921 
       
  7922 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7923 
       
  7924 	{
       
  7925 		EAP_TEMPLATE_CONST eap_array_c<u16_t> * const cipher_suites
       
  7926 			= handshake_message->get_cipher_suites();
       
  7927 
       
  7928 		if (cipher_suites->get_object_count() == 0ul)
       
  7929 		{
       
  7930 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7931 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7932 		}
       
  7933 
       
  7934 		m_proposed_cipher_suites.reset();
       
  7935 
       
  7936 		status = copy_simple<u16_t>(
       
  7937 			cipher_suites,
       
  7938 			&m_proposed_cipher_suites,
       
  7939 			m_am_tools,
       
  7940 			false);
       
  7941 		if (status != eap_status_ok
       
  7942 			|| m_proposed_cipher_suites.get_object_count() == 0ul)
       
  7943 		{
       
  7944 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7945 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7946 		}
       
  7947 	}
       
  7948 
       
  7949 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7950 
       
  7951 	{
       
  7952 		EAP_TEMPLATE_CONST eap_array_c<u8_t> * const compression_methods
       
  7953 			= handshake_message->get_compression_methods();
       
  7954 
       
  7955 		status = copy_simple<u8_t>(
       
  7956 			compression_methods,
       
  7957 			&m_proposed_compression_methods,
       
  7958 			m_am_tools,
       
  7959 			false);
       
  7960 		if (status != eap_status_ok)
       
  7961 		{
       
  7962 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7963 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7964 		}
       
  7965 	}
       
  7966 
       
  7967 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7968 
       
  7969 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  7970 
       
  7971 	{
       
  7972 		EAP_TEMPLATE_CONST eap_array_c<tls_extension_c> * const tls_extensions
       
  7973 			= handshake_message->get_tls_extensions();
       
  7974 
       
  7975 		status = copy<tls_extension_c>(
       
  7976 			tls_extensions,
       
  7977 			&m_received_tls_extensions,
       
  7978 			m_am_tools,
       
  7979 			false);
       
  7980 		if (status != eap_status_ok)
       
  7981 		{
       
  7982 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7983 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  7984 		}
       
  7985 	}
       
  7986 
       
  7987 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  7988 
       
  7989 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7990 
       
  7991 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  7992 	if (m_tls_session_type == tls_session_type_full_authentication
       
  7993 		&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates)
       
  7994 	{
       
  7995 		set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_runs);
       
  7996 	}
       
  7997 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  7998 
       
  7999 	status = completion_action_add(tls_completion_action_create_handshake_type_server_hello);
       
  8000 	if (status != eap_status_ok)
       
  8001 	{
       
  8002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8003 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  8004 	}
       
  8005 
       
  8006 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8007 	if (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none)
       
  8008 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8009 	{
       
  8010 		status = m_am_tls_services->select_cipher_suite_and_check_session_id(
       
  8011 			&m_proposed_cipher_suites,
       
  8012 			&m_session_id
       
  8013 	#if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8014 			, tls_extension_c::get_tls_extension(
       
  8015 				tls_extension_type_session_ticket,
       
  8016 				&m_received_tls_extensions,
       
  8017 				m_am_tools)
       
  8018 	#endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8019 			);
       
  8020 		if (status == eap_status_pending_request)
       
  8021 		{
       
  8022 			// This is pending query, that will be completed by
       
  8023 			// complete_select_cipher_suite_and_check_session_id() call.
       
  8024 			m_pending_select_cipher_suite_and_check_session_id = true;
       
  8025 		}
       
  8026 		else if (status == eap_status_completed_request)
       
  8027 		{
       
  8028 			// This is already completed by complete_select_cipher_suite_and_check_session_id() call.
       
  8029 		}
       
  8030 		else if (status == eap_status_ok)
       
  8031 		{
       
  8032 			// This is also an error case, because this call is always completed on success. 
       
  8033 			status = eap_status_process_general_error;
       
  8034 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8035 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8036 		}
       
  8037 		else // All other status values means error, because this call is always completed on success.
       
  8038 		{
       
  8039 			// This is an error case.
       
  8040 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8041 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  8042 		}
       
  8043 	}
       
  8044 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8045 	else if (m_tls_session_type == tls_session_type_full_authentication
       
  8046 		&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs)
       
  8047 	{
       
  8048 		if (m_tls_peap_server_authenticates_client_config_server == true)
       
  8049 		{
       
  8050 			set_state(tls_peap_state_wait_handshake_type_certificate);
       
  8051 		}
       
  8052 		else
       
  8053 		{
       
  8054 			set_state(tls_peap_state_wait_handshake_type_client_key_exchange);
       
  8055 		}
       
  8056 
       
  8057 		status = completion_action_add(tls_completion_action_create_handshake_type_certificate);
       
  8058 		if (status != eap_status_ok)
       
  8059 		{
       
  8060 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8061 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8062 		}
       
  8063 
       
  8064 		if (cipher_suite_is_TLS_DHE_DSS() == true
       
  8065 			|| cipher_suite_is_TLS_DHE_RSA() == true)
       
  8066 		{
       
  8067 			// Ephemeral DH key exchange causes creation of server_key_exchange message.
       
  8068 			// Server sends DH public key and related parameters to client.
       
  8069 
       
  8070 			status = completion_action_add(tls_completion_action_query_dh_parameters);
       
  8071 			if (status != eap_status_ok)
       
  8072 			{
       
  8073 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8074 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8075 			}
       
  8076 
       
  8077 			status = completion_action_add(
       
  8078 				tls_completion_action_create_handshake_type_server_key_exchange);
       
  8079 			if (status != eap_status_ok)
       
  8080 			{
       
  8081 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8082 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8083 			}
       
  8084 
       
  8085 			// This will complete creation of handshake_type_server_key_exchange message.
       
  8086 			status = completion_action_add(
       
  8087 				tls_completion_action_complete_create_handshake_type_server_key_exchange);
       
  8088 			if (status != eap_status_ok)
       
  8089 			{
       
  8090 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8091 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8092 			}
       
  8093 
       
  8094 			// Also the other pending messages will be processed after this action is completed.
       
  8095 			eap_status_e compl_status = completion_action_add(
       
  8096 				tls_completion_action_process_tls_records);
       
  8097 			if (compl_status != eap_status_ok)
       
  8098 			{
       
  8099 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8100 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8101 			}
       
  8102 		}
       
  8103 
       
  8104 		if (m_tls_peap_server_authenticates_client_config_server == true)
       
  8105 		{
       
  8106 			// Server initiates client authentication.
       
  8107 			status = completion_action_add(
       
  8108 				tls_completion_action_create_handshake_type_certificate_request);
       
  8109 			if (status != eap_status_ok)
       
  8110 			{
       
  8111 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8112 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8113 			}
       
  8114 		}
       
  8115 		
       
  8116 		status = completion_action_add(
       
  8117 			tls_completion_action_create_handshake_type_server_hello_done);
       
  8118 		if (status != eap_status_ok)
       
  8119 		{
       
  8120 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8121 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8122 		}
       
  8123 	}
       
  8124 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8125 
       
  8126 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8127 
       
  8128 	if (/* status == eap_status_pending_request
       
  8129 		   || */ status == eap_status_completed_request)
       
  8130 	{
       
  8131 		status = eap_status_ok;
       
  8132 	}
       
  8133 
       
  8134 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8135 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  8136 }
       
  8137 
       
  8138 //--------------------------------------------------
       
  8139 
       
  8140 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_server_hello(
       
  8141 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message)
       
  8142 {
       
  8143 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8144 
       
  8145 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  8146 	EAP_TRACE_DEBUG(
       
  8147 		m_am_tools,
       
  8148 		TRACE_FLAGS_DEFAULT,
       
  8149 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_server_hello()\n"),
       
  8150 		(m_is_client == true ? "client": "server")));
       
  8151 
       
  8152 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_server_hello()");
       
  8153 
       
  8154 	// 0                   1                   2                   3   
       
  8155 	//  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 
       
  8156 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8157 	//                 | Version: 3    | Version: 1    |               |
       
  8158 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  8159 	// |                                                               |
       
  8160 	// +                                                               +
       
  8161 	// |                                                               |
       
  8162 	// +                                                               +
       
  8163 	// |          ServerRandomValue                                    |
       
  8164 	// +              (32 bytes)                       +-+-+-+-+-+-+-+-+
       
  8165 	// |                                               | ID length     |
       
  8166 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8167 	// |                                                               |
       
  8168 	// +                                                               +
       
  8169 	// |                Session ID                                     |
       
  8170 	// +             (maximum 32 bytes)                                +
       
  8171 	// |                                                               |
       
  8172 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8173 	// | CipherSuite                   | Cmp           | extensions ...|
       
  8174 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8175 
       
  8176 	eap_status_e status = eap_status_not_supported;
       
  8177 
       
  8178 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8179 
       
  8180 	if (handshake_message->get_random_value() == 0
       
  8181 		|| handshake_message->get_random_value()->get_data_length()
       
  8182 		!= TLS_HANDSHAKE_RANDOM_VALUE_SIZE)
       
  8183 	{
       
  8184 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8185 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8186 	}
       
  8187 
       
  8188 	status = m_server_handshake_random_value.set_copy_of_buffer(
       
  8189 		handshake_message->get_random_value());
       
  8190 	if (status != eap_status_ok
       
  8191 		|| m_server_handshake_random_value.get_data_length() != TLS_HANDSHAKE_RANDOM_VALUE_SIZE)
       
  8192 	{
       
  8193 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8194 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8195 	}
       
  8196 
       
  8197 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8198 
       
  8199 	set_selected_cipher_suite(handshake_message->get_selected_cipher_suite());
       
  8200 
       
  8201 	status = check_selected_cipher_suite(m_selected_cipher_suite);
       
  8202 	if (status != eap_status_ok)
       
  8203 	{
       
  8204 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8205 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  8206 	}
       
  8207 
       
  8208 	{
       
  8209 		EAP_TRACE_DEBUG(
       
  8210 			m_am_tools,
       
  8211 			TRACE_FLAGS_DEFAULT,
       
  8212 			(EAPL("%s: TLS/PEAP selected cipher_suite %s\n"),
       
  8213 			 (m_is_client == true ? "client": "server"),
       
  8214 			 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite)));
       
  8215 	}
       
  8216 
       
  8217 
       
  8218 	m_selected_compression_method = handshake_message->get_selected_compression_method();
       
  8219 
       
  8220 	status = check_selected_compression_method(m_selected_compression_method);
       
  8221 	if (status != eap_status_ok)
       
  8222 	{
       
  8223 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8224 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  8225 	}
       
  8226 
       
  8227 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8228 
       
  8229 	if (handshake_message->get_session_id() == 0
       
  8230 		|| (handshake_message->get_session_id()->get_is_valid_data() == true
       
  8231 		&& handshake_message->get_session_id()->get_data_length() > TLS_SESSION_ID_SIZE))
       
  8232 	{
       
  8233 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8234 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8235 	}
       
  8236 
       
  8237 
       
  8238 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8239 	m_will_receive_new_session_ticket = false;
       
  8240 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8241 
       
  8242 
       
  8243 #if defined(USE_FAST_EAP_TYPE)
       
  8244 	if (m_eap_type == eap_type_fast
       
  8245 		&& m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP
       
  8246 		&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true)
       
  8247 	{
       
  8248 		EAP_TRACE_DEBUG(
       
  8249 			m_am_tools,
       
  8250 			TRACE_FLAGS_DEFAULT,
       
  8251 			(EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ")
       
  8252 			 EAPL("EAP-FAST server unauthenticated provisioning mode\n"),
       
  8253 			 (m_is_client == true ? "client": "server")));
       
  8254 	}
       
  8255 	else
       
  8256 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8257 	if (handshake_message->get_session_id()->get_is_valid_data() == true
       
  8258 		&& handshake_message->get_session_id()->get_data_length() > 0ul
       
  8259 #if defined(USE_FAST_EAP_TYPE)
       
  8260 		// EAP-FAST specification says to watch the next message to see whether the session is resumed or not.
       
  8261 		// Original TLS is specified to correctly so the client know what happens when it receives ServerHello message.
       
  8262 		&& (m_eap_type != eap_type_fast
       
  8263 			|| (m_tls_session_type == tls_session_type_original_session_resumption
       
  8264 				|| m_tls_session_type == tls_session_type_full_authentication))
       
  8265 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8266 		)
       
  8267 	{
       
  8268 
       
  8269 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8270 
       
  8271 		if (m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  8272 		{
       
  8273 			m_received_tls_extensions.reset();
       
  8274 			
       
  8275 			const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension(
       
  8276 				tls_extension_type_session_ticket,
       
  8277 				&m_supported_tls_extensions,
       
  8278 				m_am_tools);
       
  8279 
       
  8280 			if (supported_session_ticket_extension != 0)
       
  8281 			{
       
  8282 				EAP_TEMPLATE_CONST eap_array_c<tls_extension_c> * const tls_extensions
       
  8283 					= handshake_message->get_tls_extensions();
       
  8284 
       
  8285 				const tls_extension_c * const received_session_ticket_extension = tls_extension_c::get_tls_extension(
       
  8286 					tls_extension_type_session_ticket,
       
  8287 					tls_extensions,
       
  8288 					m_am_tools);
       
  8289 
       
  8290 				if (received_session_ticket_extension != 0)
       
  8291 				{
       
  8292 					EAP_TRACE_DEBUG(
       
  8293 						m_am_tools,
       
  8294 						TRACE_FLAGS_DEFAULT,
       
  8295 						(EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ")
       
  8296 						 EAPL("SST: receives stateless session ticket: length = %d\n"),
       
  8297 						 (m_is_client == true ? "client": "server"),
       
  8298 						 received_session_ticket_extension->get_data_length()));
       
  8299 
       
  8300 					eap_array_c<tls_extension_c> tmp_extensions(m_am_tools);
       
  8301 
       
  8302 					tls_extension_c * const received_session_ticket_extension_copy = received_session_ticket_extension->copy();
       
  8303 
       
  8304 					if (received_session_ticket_extension_copy != 0)
       
  8305 					{
       
  8306 						status = tmp_extensions.add_object(received_session_ticket_extension_copy, true);
       
  8307 
       
  8308 						status = copy<tls_extension_c>(
       
  8309 							&tmp_extensions,
       
  8310 							&m_received_tls_extensions,
       
  8311 							m_am_tools,
       
  8312 							false);
       
  8313 						if (status != eap_status_ok)
       
  8314 						{
       
  8315 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8316 							return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8317 						}
       
  8318 
       
  8319 						m_will_receive_new_session_ticket = true;
       
  8320 					}
       
  8321 				}
       
  8322 			}
       
  8323 		}
       
  8324 
       
  8325 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8326 
       
  8327 
       
  8328 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8329 		if (m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  8330 		{
       
  8331 			EAP_TRACE_DEBUG(
       
  8332 				m_am_tools,
       
  8333 				TRACE_FLAGS_DEFAULT,
       
  8334 				(EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ")
       
  8335 				 EAPL("restores stateless session\n"),
       
  8336 				 (m_is_client == true ? "client": "server")));
       
  8337 
       
  8338 			status = m_session_id.set_copy_of_buffer(handshake_message->get_session_id());
       
  8339 			if (status != eap_status_ok
       
  8340 				|| m_session_id.get_data_length() > TLS_SESSION_ID_SIZE)
       
  8341 			{
       
  8342 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8343 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8344 			}
       
  8345 
       
  8346 			status = indicate_state_to_lower_layer(
       
  8347 				tls_peap_state_stateless_session_resumption);
       
  8348 			if (status != eap_status_ok)
       
  8349 			{
       
  8350 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8351 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8352 			}
       
  8353 		}
       
  8354 		else
       
  8355 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8356 		/** @{ PEAPv2 does not support session resumption yet. } */
       
  8357 		if (((m_eap_type == eap_type_peap
       
  8358 				&& m_peap_version != peap_version_2)
       
  8359 			|| m_eap_type == eap_type_tls
       
  8360 			|| m_eap_type == eap_type_ttls
       
  8361 #if defined(USE_FAST_EAP_TYPE)
       
  8362 			|| m_eap_type == eap_type_fast
       
  8363 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8364 			)
       
  8365 			&& m_tls_session_type == tls_session_type_original_session_resumption
       
  8366 			&& m_resumed_cipher_suite == m_selected_cipher_suite
       
  8367 			&& handshake_message->get_session_id()->compare(&m_session_id) == 0)
       
  8368 		{
       
  8369 			// OK, previous session will be restored.
       
  8370 
       
  8371 			EAP_TRACE_DEBUG(
       
  8372 				m_am_tools,
       
  8373 				TRACE_FLAGS_DEFAULT,
       
  8374 				(EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ")
       
  8375 				 EAPL("restores session\n"),
       
  8376 				 (m_is_client == true ? "client": "server")));
       
  8377 
       
  8378 
       
  8379 			eap_status_e notification_status = indicate_state_to_lower_layer(
       
  8380 				tls_peap_state_original_session_resumption);
       
  8381 			if (notification_status != eap_status_ok)
       
  8382 			{
       
  8383 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8384 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
  8385 			}
       
  8386 		}
       
  8387 		else
       
  8388 		{
       
  8389 
       
  8390 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8391 			if (m_is_client == true
       
  8392 				&& m_tls_use_identity_privacy == true
       
  8393 				&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none)
       
  8394 			{
       
  8395 				set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_negotiates);
       
  8396 			}
       
  8397 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8398 
       
  8399 			set_tls_session_type(tls_session_type_full_authentication);
       
  8400 
       
  8401 			EAP_TRACE_DEBUG(
       
  8402 				m_am_tools,
       
  8403 				TRACE_FLAGS_DEFAULT,
       
  8404 				(EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ")
       
  8405 				 EAPL("creates new session\n"),
       
  8406 				 (m_is_client == true ? "client": "server")));
       
  8407 
       
  8408 			status = m_session_id.set_copy_of_buffer(handshake_message->get_session_id());
       
  8409 			if (status != eap_status_ok
       
  8410 				|| m_session_id.get_data_length() > TLS_SESSION_ID_SIZE)
       
  8411 			{
       
  8412 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8413 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8414 			}
       
  8415 
       
  8416 			status = indicate_state_to_lower_layer(
       
  8417 				tls_peap_state_full_authentication);
       
  8418 			if (status != eap_status_ok)
       
  8419 			{
       
  8420 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8421 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8422 			}
       
  8423 		}
       
  8424 	}
       
  8425 	else
       
  8426 	{
       
  8427 		// No session identifier.
       
  8428 #if defined(USE_FAST_EAP_TYPE)
       
  8429 		if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption
       
  8430 			&& get_next_tls_handshake_message_type() == tls_handshake_type_none
       
  8431 			&& get_next_tls_record_message_protocol() == tls_record_protocol_change_cipher_spec)
       
  8432 		{
       
  8433 			EAP_TRACE_DEBUG(
       
  8434 				m_am_tools,
       
  8435 				TRACE_FLAGS_DEFAULT,
       
  8436 				(EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ")
       
  8437 				 EAPL("EAP-FAST PAC session resumtion.\n"),
       
  8438 				 (m_is_client == true ? "client": "server")));
       
  8439 
       
  8440 			// Generates master secret from PAC-Key.
       
  8441 			status = generate_eap_fast_master_secret_from_pac_key(
       
  8442 				&m_eap_fast_pac_key);
       
  8443 
       
  8444 			m_eap_fast_pac_key.reset();
       
  8445 
       
  8446 			if (status != eap_status_ok)
       
  8447 			{
       
  8448 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8449 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8450 			}
       
  8451 		}
       
  8452 		else
       
  8453 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8454 		{
       
  8455 			EAP_TRACE_DEBUG(
       
  8456 				m_am_tools,
       
  8457 				TRACE_FLAGS_DEFAULT,
       
  8458 				(EAPL("TLS: %s: message_function: analyse_handshake_type_server_hello(): ")
       
  8459 				 EAPL("creates new session, no session identifier\n"),
       
  8460 				 (m_is_client == true ? "client": "server")));
       
  8461 
       
  8462 #if defined(USE_FAST_EAP_TYPE)
       
  8463 			if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
  8464 			{
       
  8465 				// Server does not accept the Tunnel PAC.
       
  8466 				// We will remove the Tunnel PAC if server authenticates OK.
       
  8467 				m_remove_tunnel_pac = true;
       
  8468 			}
       
  8469 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8470 
       
  8471 			set_tls_session_type(tls_session_type_full_authentication);
       
  8472 		}
       
  8473 
       
  8474 	}
       
  8475 
       
  8476 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8477 
       
  8478 	if (m_tls_session_type == tls_session_type_original_session_resumption
       
  8479 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8480 		|| m_tls_session_type == tls_session_type_stateless_session_resumption
       
  8481 #if defined(USE_FAST_EAP_TYPE)
       
  8482 		|| m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption
       
  8483 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8484 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  8485 		)
       
  8486 	{
       
  8487 		if (m_tls_session_type == tls_session_type_original_session_resumption
       
  8488 #if defined(USE_FAST_EAP_TYPE)
       
  8489 			|| m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption
       
  8490 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8491 			)
       
  8492 		{
       
  8493 			// We must generate the key material.
       
  8494 			status = generate_key_material();
       
  8495 			if (status != eap_status_ok)
       
  8496 			{
       
  8497 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8498 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8499 			}
       
  8500 		}
       
  8501 
       
  8502 		set_state(tls_peap_state_wait_change_cipher_spec);
       
  8503 	}
       
  8504 #if defined(USE_FAST_EAP_TYPE)
       
  8505 	else if (m_eap_type == eap_type_fast
       
  8506 			&& m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP
       
  8507 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true)
       
  8508 	{
       
  8509 		set_state(tls_peap_state_wait_handshake_type_server_key_exchange);
       
  8510 	}
       
  8511 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8512 	else
       
  8513 	{
       
  8514 		set_state(tls_peap_state_wait_handshake_type_certificate);
       
  8515 	}
       
  8516 
       
  8517 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8518 
       
  8519 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8520 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  8521 }
       
  8522 
       
  8523 //--------------------------------------------------
       
  8524 
       
  8525 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_certificate(
       
  8526 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message)
       
  8527 {
       
  8528 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8529 
       
  8530 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  8531 	EAP_TRACE_DEBUG(
       
  8532 		m_am_tools,
       
  8533 		TRACE_FLAGS_DEFAULT,
       
  8534 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_certificate()\n"),
       
  8535 		(m_is_client == true ? "client": "server")));
       
  8536 
       
  8537 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_certificate()");
       
  8538 
       
  8539 	// 0                   1                   2                   3   
       
  8540 	//  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 
       
  8541 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8542 	//                 | Certificate Chain Length                      |
       
  8543 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8544 	// | Certificate 1 Length                          |               |
       
  8545 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  8546 	// |                                                               |
       
  8547 	// +                                                               +
       
  8548 	// |          Certificate 1                                        |
       
  8549 	// +                                                               +
       
  8550 	// |                                                               |
       
  8551 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8552 	// .                    ...                                        .
       
  8553 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8554 	// | Certificate n Length                          |               |
       
  8555 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  8556 	// |                                                               |
       
  8557 	// +                                                               +
       
  8558 	// |          Certificate n                                        |
       
  8559 	// +                                                               +
       
  8560 	// |                                                               |
       
  8561 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8562 
       
  8563 	eap_status_e status = eap_status_not_supported;
       
  8564 
       
  8565 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8566 
       
  8567 	EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_chain
       
  8568 		= handshake_message->get_certificate_chain();
       
  8569 
       
  8570 	if (m_is_client == false
       
  8571 		&& certificate_chain->get_object_count() == 0ul
       
  8572 		&& m_tls_peap_server_authenticates_client_policy_flag == false)
       
  8573 	{
       
  8574 		// Server allows server only authentication, client is anonymous.
       
  8575 
       
  8576 		EAP_TRACE_DEBUG(
       
  8577 			m_am_tools,
       
  8578 			TRACE_FLAGS_DEFAULT,
       
  8579 			(EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ")
       
  8580 			 EAPL("Server allows anonymous client.\n"),
       
  8581 			(m_is_client == true ? "client": "server")));
       
  8582 
       
  8583 		m_tls_peap_server_authenticates_client_action = false;
       
  8584 	}
       
  8585 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8586 	else if (m_is_client == false
       
  8587 		&& m_tls_use_identity_privacy == true
       
  8588 		&& m_tls_session_type == tls_session_type_full_authentication
       
  8589 		&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none
       
  8590 		&& certificate_chain->get_object_count() == 0ul)
       
  8591 	{
       
  8592 		// Server allows TLS identity privacy, at this point client is anonymous.
       
  8593 
       
  8594 		EAP_TRACE_DEBUG(
       
  8595 			m_am_tools,
       
  8596 			TRACE_FLAGS_DEFAULT,
       
  8597 			(EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ")
       
  8598 			 EAPL("Server allows TLS identity privacy.\n"),
       
  8599 			(m_is_client == true ? "client": "server")));
       
  8600 
       
  8601 		set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_negotiates);
       
  8602 	}
       
  8603 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8604 	else if (certificate_chain->get_object_count() == 0ul)
       
  8605 	{
       
  8606 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8607 #if defined(USE_FAST_EAP_TYPE)
       
  8608 		if (m_is_client == false
       
  8609 			&& m_tls_use_identity_privacy == false
       
  8610 			&& m_eap_type == eap_type_fast
       
  8611 			&& m_tls_session_type == tls_session_type_full_authentication)
       
  8612 		{
       
  8613 			EAP_TRACE_DEBUG(
       
  8614 				m_am_tools,
       
  8615 				TRACE_FLAGS_DEFAULT,
       
  8616 				(EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ")
       
  8617 				 EAPL("EAP-FAST %s allows anonymous client.\n"),
       
  8618 				(m_is_client == true ? "client": "server"),
       
  8619 				(m_is_client == true ? "client": "server")));
       
  8620 
       
  8621 			m_tls_peap_server_authenticates_client_action = false;
       
  8622 			m_tls_identity_privacy_handshake_state = tls_identity_privacy_handshake_state_none;
       
  8623 		}
       
  8624 		else
       
  8625 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8626 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8627 		{
       
  8628 			EAP_TRACE_ERROR(
       
  8629 				m_am_tools,
       
  8630 				TRACE_FLAGS_DEFAULT,
       
  8631 				(EAPL("TLS: %s: pki_function: analyse_handshake_type_certificate(): ")
       
  8632 				 EAPL("TLS %s does NOT allow anonymous %s.\n"),
       
  8633 				(m_is_client == true ? "client": "server"),
       
  8634 				(m_is_client == true ? "client": "server"),
       
  8635 				(m_is_client == false ? "client": "server")));
       
  8636 
       
  8637 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8638 			return EAP_STATUS_RETURN(m_am_tools, eap_status_insufficient_security);
       
  8639 		}
       
  8640 	}
       
  8641 	else
       
  8642 	{
       
  8643 		status = copy<eap_variable_data_c>(
       
  8644 			certificate_chain,
       
  8645 			&m_peer_certificate_chain,
       
  8646 			m_am_tools,
       
  8647 			false);
       
  8648 		if (status != eap_status_ok
       
  8649 			|| m_peer_certificate_chain.get_object_count() == 0ul)
       
  8650 		{
       
  8651 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8652 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8653 		}
       
  8654 	}
       
  8655 
       
  8656 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8657 
       
  8658 	if (m_is_client == true)
       
  8659 	{
       
  8660 		status = completion_action_add(tls_completion_action_verify_certificate_chain);
       
  8661 		if (status != eap_status_ok)
       
  8662 		{
       
  8663 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8664 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8665 		}
       
  8666 
       
  8667 		EAP_TRACE_DEBUG(
       
  8668 			m_am_tools,
       
  8669 			TRACE_FLAGS_DEFAULT,
       
  8670 			(EAPL("TLS: %s: pki_function: query_certificate_chain()\n"),
       
  8671 			(m_is_client == true ? "client": "server")));
       
  8672 
       
  8673 		status = m_am_tls_services->query_certificate_chain(
       
  8674 			&m_peer_certificate_authorities,
       
  8675 			&m_peer_certificate_types,
       
  8676 			m_selected_cipher_suite);
       
  8677 		if (status == eap_status_pending_request)
       
  8678 		{
       
  8679 			// This is pending query, that will be completed by
       
  8680 			// complete_query_certificate_chain() call.
       
  8681 			m_pending_query_certificate_chain = true;
       
  8682 		}
       
  8683 		else if (status == eap_status_completed_request)
       
  8684 		{
       
  8685 			// This is already completed by complete_query_certificate_chain() call.
       
  8686 		}
       
  8687 		else if (status == eap_status_ok)
       
  8688 		{
       
  8689 			// This is also an error case, because this call is always completed on success. 
       
  8690 			status = eap_status_process_general_error;
       
  8691 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8692 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8693 		}
       
  8694 		else // All other status values means error, because this
       
  8695 			// call is always completed on success.
       
  8696 		{
       
  8697 			// This is an error case.
       
  8698 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8699 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  8700 		}
       
  8701 	}
       
  8702 	else if (m_is_client == false
       
  8703 			 && m_tls_peap_server_authenticates_client_action == true)
       
  8704 	{
       
  8705 		// This is server.
       
  8706 
       
  8707 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8708 		if (m_tls_session_type == tls_session_type_full_authentication
       
  8709 			&& m_tls_use_identity_privacy == true
       
  8710 			&& certificate_chain->get_object_count() == 0ul)
       
  8711 		{
       
  8712 			EAP_TRACE_DEBUG(
       
  8713 				m_am_tools,
       
  8714 				TRACE_FLAGS_DEFAULT,
       
  8715 				(EAPL("TLS: %s: pki_function: TLS identity privacy does not verify client certificate yet.\n"),
       
  8716 				 (m_is_client == true ? "client": "server")));
       
  8717 			status = eap_status_ok;
       
  8718 		}
       
  8719 		else
       
  8720 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8721 		{
       
  8722 			EAP_TRACE_DEBUG(
       
  8723 				m_am_tools,
       
  8724 				TRACE_FLAGS_DEFAULT,
       
  8725 				(EAPL("TLS: %s: pki_function: verify_certificate_chain()\n"),
       
  8726 				 (m_is_client == true ? "client": "server")));
       
  8727 
       
  8728 			status = m_am_tls_services->verify_certificate_chain(
       
  8729 				&m_peer_certificate_chain,
       
  8730 				m_selected_cipher_suite);
       
  8731 			if (status == eap_status_pending_request)
       
  8732 			{
       
  8733 				// This is pending query, that will be completed by
       
  8734 				// complete_verify_certificate_chain() call.
       
  8735 				m_pending_verify_certificate_chain = true;
       
  8736 			}
       
  8737 			else if (status == eap_status_completed_request)
       
  8738 			{
       
  8739 				// This is already completed by complete_verify_certificate_chain() call.
       
  8740 			}
       
  8741 			else if (status == eap_status_ok)
       
  8742 			{
       
  8743 				// This is also an error case, because this call is always completed on success. 
       
  8744 				status = eap_status_process_general_error;
       
  8745 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8746 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8747 			}
       
  8748 			else // All other status values means error, because this
       
  8749 				// call is always completed on success.
       
  8750 			{
       
  8751 				// This is an error case.
       
  8752 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8753 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  8754 			}
       
  8755 		}
       
  8756 	}
       
  8757 	else if (m_is_client == false
       
  8758 			 && m_tls_peap_server_authenticates_client_action == false)
       
  8759 	{
       
  8760 		// This is server. Server allows anonymous client.
       
  8761 		status = eap_status_ok;
       
  8762 	}
       
  8763 
       
  8764 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8765 
       
  8766 	if (status == eap_status_completed_request)
       
  8767 	{
       
  8768 		status = eap_status_ok;
       
  8769 	}
       
  8770 
       
  8771 	if (m_is_client == true)
       
  8772 	{
       
  8773 		if (cipher_suite_is_TLS_DHE_DSS() == true
       
  8774 			|| cipher_suite_is_TLS_DHE_RSA() == true)
       
  8775 		{
       
  8776 			set_state(tls_peap_state_wait_handshake_type_server_key_exchange);
       
  8777 		}
       
  8778 		else if (cipher_suite_is_TLS_RSA() == true)
       
  8779 		{
       
  8780 			set_state(tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done);
       
  8781 		}
       
  8782 		else
       
  8783 		{
       
  8784 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8785 			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  8786 		}
       
  8787 	}
       
  8788 	else
       
  8789 	{
       
  8790 		// Server.
       
  8791 		set_state(tls_peap_state_wait_handshake_type_client_key_exchange);
       
  8792 	}
       
  8793 
       
  8794 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8795 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  8796 }
       
  8797 
       
  8798 //--------------------------------------------------
       
  8799 
       
  8800 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_certificate_request(
       
  8801 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message)
       
  8802 {
       
  8803 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8804 
       
  8805 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  8806 	EAP_TRACE_DEBUG(
       
  8807 		m_am_tools,
       
  8808 		TRACE_FLAGS_DEFAULT,
       
  8809 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_certificate_request()\n"),
       
  8810 		(m_is_client == true ? "client": "server")));
       
  8811 
       
  8812 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_certificate_request()");
       
  8813 
       
  8814 	EAP_ASSERT_ALWAYS(m_is_client == true);
       
  8815 
       
  8816 	// 0                   1                   2                   3   
       
  8817 	//  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 
       
  8818 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8819 	//                 | CT length     | CT 1          | CT 2          |
       
  8820 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8821 	// | CT 3          | CT 4          | CAs length                    |
       
  8822 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8823 	// | CA 1 length                   |                               |
       
  8824 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  8825 	// |                                                               |
       
  8826 	// +                                                               +
       
  8827 	// |      Distinguished name of Certificate Authority 1            |
       
  8828 	// +                                                               +
       
  8829 	// |                                                               |
       
  8830 	// +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8831 	// |                               | CA 2 length                   |
       
  8832 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8833 	// |                                                               |
       
  8834 	// +                                                               +
       
  8835 	// |      Distinguished name of Certificate Authority 2            |
       
  8836 	// +                                                               +
       
  8837 	// |                                                               |
       
  8838 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  8839 
       
  8840 	eap_status_e status = eap_status_not_supported;
       
  8841 
       
  8842 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8843 
       
  8844 	{
       
  8845 		EAP_TEMPLATE_CONST eap_array_c<u8_t> * const certificate_types
       
  8846 			= handshake_message->get_certificate_types();
       
  8847 
       
  8848 		if (certificate_types->get_object_count() == 0ul)
       
  8849 		{
       
  8850 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8851 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8852 		}
       
  8853 
       
  8854 		status = copy_simple<u8_t>(
       
  8855 			certificate_types,
       
  8856 			&m_peer_certificate_types,
       
  8857 			m_am_tools,
       
  8858 			false);
       
  8859 		if (status != eap_status_ok)
       
  8860 		{
       
  8861 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8862 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8863 		}
       
  8864 	}
       
  8865 
       
  8866 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8867 
       
  8868 	{
       
  8869 		EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_authorities
       
  8870 			= handshake_message->get_certificate_authorities();
       
  8871 
       
  8872 		if (certificate_authorities->get_object_count() == 0ul
       
  8873 			&& m_client_allows_empty_certificate_authorities_list == false)
       
  8874 		{
       
  8875 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8876 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8877 		}
       
  8878 
       
  8879 		status = copy<eap_variable_data_c>(
       
  8880 			certificate_authorities,
       
  8881 			&m_peer_certificate_authorities,
       
  8882 			m_am_tools,
       
  8883 			false);
       
  8884 		if (status != eap_status_ok)
       
  8885 		{
       
  8886 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8887 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  8888 		}
       
  8889 	}
       
  8890 
       
  8891 	m_tls_peap_server_requested_client_certificate = true;
       
  8892 
       
  8893 
       
  8894 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  8895 
       
  8896 	set_state(tls_peap_state_wait_handshake_type_server_hello_done);
       
  8897 
       
  8898 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8899 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  8900 }
       
  8901 
       
  8902 //--------------------------------------------------
       
  8903 
       
  8904 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_server_hello_done(
       
  8905 	EAP_TEMPLATE_CONST tls_handshake_message_c * const /*handshake_message*/)
       
  8906 {
       
  8907 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8908 
       
  8909 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  8910 	EAP_TRACE_DEBUG(
       
  8911 		m_am_tools,
       
  8912 		TRACE_FLAGS_DEFAULT,
       
  8913 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_server_hello_done()\n"),
       
  8914 		(m_is_client == true ? "client": "server")));
       
  8915 
       
  8916 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_server_hello_done()");
       
  8917 
       
  8918 	EAP_ASSERT(m_is_client == true);
       
  8919 
       
  8920 	eap_status_e status = eap_status_process_general_error;
       
  8921 
       
  8922 	// 0                   1                   2                   3   
       
  8923 	//  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 
       
  8924 	//
       
  8925 	// ServerHelloDone message does not include payload.
       
  8926 
       
  8927 	if (cipher_suite_is_TLS_DHE_DSS() == true
       
  8928 		|| cipher_suite_is_TLS_RSA() == true
       
  8929 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
  8930 #if defined(USE_FAST_EAP_TYPE)
       
  8931 		|| (m_eap_type == eap_type_fast
       
  8932 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  8933 			&& cipher_suite_is_TLS_DH_anon() == true)
       
  8934 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  8935 		)
       
  8936 	{
       
  8937 		if (m_tls_peap_server_requested_client_certificate == true)
       
  8938 		{
       
  8939 			status = completion_action_add(tls_completion_action_create_handshake_type_certificate);
       
  8940 			if (status != eap_status_ok)
       
  8941 			{
       
  8942 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8943 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8944 			}
       
  8945 		}
       
  8946 
       
  8947 		status = completion_action_add(
       
  8948 			tls_completion_action_create_handshake_type_client_key_exchange);
       
  8949 		if (status != eap_status_ok)
       
  8950 		{
       
  8951 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8952 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8953 		}
       
  8954 
       
  8955 		status = completion_action_add(
       
  8956 			tls_completion_action_complete_create_handshake_type_client_key_exchange);
       
  8957 		if (status != eap_status_ok)
       
  8958 		{
       
  8959 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8960 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8961 		}
       
  8962 
       
  8963 		if (m_tls_peap_server_authenticates_client_action == true
       
  8964 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8965 			&& (
       
  8966 				m_tls_use_identity_privacy == false
       
  8967 				|| (m_tls_session_type == tls_session_type_full_authentication
       
  8968 					&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs))
       
  8969 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  8970 			)
       
  8971 		{
       
  8972 			status = completion_action_add(
       
  8973 				tls_completion_action_create_handshake_type_certificate_verify);
       
  8974 			if (status != eap_status_ok)
       
  8975 			{
       
  8976 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8977 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8978 			}
       
  8979 
       
  8980 			// This will complete creation of handshake_type_certificate_verify message.
       
  8981 			status = completion_action_add(
       
  8982 				tls_completion_action_complete_create_handshake_type_certificate_verify);
       
  8983 			if (status != eap_status_ok)
       
  8984 			{
       
  8985 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8986 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8987 			}
       
  8988 
       
  8989 			// Also the other pending messages will be processed after this action is completed.
       
  8990 			eap_status_e compl_status = completion_action_add(
       
  8991 				tls_completion_action_process_tls_records);
       
  8992 			if (compl_status != eap_status_ok)
       
  8993 			{
       
  8994 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8995 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8996 			}
       
  8997 		}
       
  8998 
       
  8999 		status = completion_action_add(
       
  9000 			tls_completion_action_create_change_cipher_spec_type_change_cipher_spec);
       
  9001 		if (status != eap_status_ok)
       
  9002 		{
       
  9003 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9004 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9005 		}
       
  9006 
       
  9007 		status = completion_action_add(tls_completion_action_create_handshake_type_finished);
       
  9008 		if (status != eap_status_ok)
       
  9009 		{
       
  9010 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9011 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9012 		}
       
  9013 	}
       
  9014 	else
       
  9015 	{
       
  9016 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9017 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
  9018 	}
       
  9019 
       
  9020 
       
  9021 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9022 
       
  9023 	set_state(tls_peap_state_wait_change_cipher_spec);
       
  9024 
       
  9025 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9026 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  9027 }
       
  9028 
       
  9029 //--------------------------------------------------
       
  9030 
       
  9031 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_server_key_exchange(
       
  9032 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message)
       
  9033 {
       
  9034 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9035 
       
  9036 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  9037 	EAP_TRACE_DEBUG(
       
  9038 		m_am_tools,
       
  9039 		TRACE_FLAGS_DEFAULT,
       
  9040 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_server_key_exchange()\n"),
       
  9041 		(m_is_client == true ? "client": "server")));
       
  9042 
       
  9043 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_server_key_exchange()");
       
  9044 
       
  9045 	eap_status_e status = eap_status_not_supported;
       
  9046 
       
  9047 #if EAP_TLS_UNSUPPORTED_CIPHER_SUITE
       
  9048 	#error This one needs more code. RSA key exchange with different parameters is NOT supported.
       
  9049 	if (cipher_suite_is_TLS_RSA() == true)
       
  9050 	{
       
  9051 		// RSA modulus and exponent are included when selected cipher suite
       
  9052 		// is using RSA key exchange
       
  9053 		// and parameters are different than included in the certificate.
       
  9054 		// 0                   1                   2                   3   
       
  9055 		//  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 
       
  9056 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9057 		//                 | rsa_modulus length            |               |
       
  9058 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  9059 		// |                                                               |
       
  9060 		// +                                                               +
       
  9061 		// |          rsa_modulus                                          |
       
  9062 		// +                                                               +
       
  9063 		// |                                                               |
       
  9064 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9065 		// |  rsa_exponent length          |                               |
       
  9066 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  9067 		// |                                                               |
       
  9068 		// +                  rsa_exponent                                 +
       
  9069 		// |                                                               |
       
  9070 		// +                                                               +
       
  9071 		// |                                                               |
       
  9072 		// +                                                               +
       
  9073 		// |                                                               |
       
  9074 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9075 		// |                                                               |
       
  9076 		// +                                                               +
       
  9077 		// |       digitally-signed MD5 hash 16 bytes                      |
       
  9078 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
  9079 		// |                                                               |
       
  9080 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9081 		// |                                                               |
       
  9082 		// +                                                               +
       
  9083 		// |       digitally-signed SHA-1 hash 20 bytes                    |
       
  9084 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
  9085 		// |                                                               |
       
  9086 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9087 
       
  9088 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9089 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  9090 	}
       
  9091 	else
       
  9092 #endif
       
  9093 	if (cipher_suite_is_TLS_DHE_DSS() == true
       
  9094 		|| cipher_suite_is_TLS_DHE_RSA() == true)
       
  9095 	{
       
  9096 		// Diffie-Hellman prime modulus, generator and server's
       
  9097 		// Diffie-Hellman public value (g^X mod p)
       
  9098 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
  9099 		// 0                   1                   2                   3   
       
  9100 		//  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 
       
  9101 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9102 		//                 | DH p length                   |               |
       
  9103 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  9104 		// |                                                               |
       
  9105 		// +                                                               +
       
  9106 		// |                DH p value (prime modulus)                     |
       
  9107 		// +                                                               +
       
  9108 		// |                                                               |
       
  9109 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9110 		// |  DH g length                  |                               |
       
  9111 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  9112 		// |                                                               |
       
  9113 		// +                                                               +
       
  9114 		// |                DH g value (generator)                         |
       
  9115 		// +                                                               +
       
  9116 		// |                                                               |
       
  9117 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9118 		// |  DH Ys length                 |                               |
       
  9119 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  9120 		// |                                                               |
       
  9121 		// +                                                               +
       
  9122 		// |                DH Ys value                                    |
       
  9123 		// +         (server's Diffie-Hellman public value)                +
       
  9124 		// |                                                               |
       
  9125 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9126 		// |                                                               |
       
  9127 		// +                                                               +
       
  9128 		// |       digitally-signed SHA-1 hash 47 bytes                    |
       
  9129 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
  9130 		// |                                                               |
       
  9131 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9132 
       
  9133 		if (handshake_message->get_dhe_prime() == 0
       
  9134 			|| handshake_message->get_dhe_prime()->get_is_valid_data() == false
       
  9135 			|| handshake_message->get_dhe_prime()->get_data_length() == 0)
       
  9136 		{
       
  9137 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9138 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9139 		}
       
  9140 
       
  9141 		if (handshake_message->get_dhe_group_generator() == 0
       
  9142 			|| handshake_message->get_dhe_group_generator()->get_is_valid_data() == false
       
  9143 			|| handshake_message->get_dhe_group_generator()->get_data_length() == 0)
       
  9144 		{
       
  9145 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9146 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9147 		}
       
  9148 
       
  9149 		if (handshake_message->get_public_dhe_key() == 0
       
  9150 			|| handshake_message->get_public_dhe_key()->get_is_valid_data() == false
       
  9151 			|| handshake_message->get_public_dhe_key()->get_data_length() == 0)
       
  9152 		{
       
  9153 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9154 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9155 		}
       
  9156 
       
  9157 		if (handshake_message->get_signed_message_hash() == 0
       
  9158 			|| handshake_message->get_signed_message_hash()->get_is_valid_data() == false
       
  9159 			|| handshake_message->get_signed_message_hash()->get_data_length() == 0)
       
  9160 		{
       
  9161 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9162 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9163 		}
       
  9164 
       
  9165 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9166 
       
  9167 		status = m_dhe_prime.set_copy_of_buffer(handshake_message->get_dhe_prime());
       
  9168 		if (status != eap_status_ok
       
  9169 			|| m_dhe_prime.get_is_valid_data() == false
       
  9170 			|| m_dhe_prime.get_data_length() == 0)
       
  9171 		{
       
  9172 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9173 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9174 		}
       
  9175 
       
  9176 		status = m_dhe_group_generator.set_copy_of_buffer(
       
  9177 			handshake_message->get_dhe_group_generator());
       
  9178 		if (status != eap_status_ok
       
  9179 			|| m_dhe_group_generator.get_is_valid_data() == false
       
  9180 			|| m_dhe_group_generator.get_data_length() == 0)
       
  9181 		{
       
  9182 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9183 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9184 		}
       
  9185 
       
  9186 		status = m_peer_public_dhe_key.set_copy_of_buffer(handshake_message->get_public_dhe_key());
       
  9187 		if (status != eap_status_ok
       
  9188 			|| m_peer_public_dhe_key.get_is_valid_data() == false
       
  9189 			|| m_peer_public_dhe_key.get_data_length() == 0)
       
  9190 		{
       
  9191 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9192 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9193 		}
       
  9194 
       
  9195 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9196 
       
  9197 		if (cipher_suite_is_TLS_DHE_DSS() == true
       
  9198 			|| cipher_suite_is_TLS_DHE_RSA() == true)
       
  9199 		{
       
  9200 			// We must verify the signature of ServerKeyExchange.
       
  9201 			status = verify_signature_of_server_key_exchange(
       
  9202 				handshake_message->get_signed_message_hash());
       
  9203 			if (status == eap_status_pending_request)
       
  9204 			{
       
  9205 				// This is pending query, that will be completed by
       
  9206 				// complete_query_certificate_chain() call.
       
  9207 				m_pending_verify_with_public_key = true;
       
  9208 			}
       
  9209 			else if (status == eap_status_completed_request)
       
  9210 			{
       
  9211 				// This is already completed by complete_query_certificate_chain() call.
       
  9212 			}
       
  9213 			else if (status == eap_status_ok)
       
  9214 			{
       
  9215 				// This is also an error case, because this call is always completed on success. 
       
  9216 				status = eap_status_process_general_error;
       
  9217 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9218 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  9219 			}
       
  9220 			else // All other status values means error, because this call
       
  9221 				// is always completed on success.
       
  9222 			{
       
  9223 				// This is an error case.
       
  9224 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9225 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  9226 			}
       
  9227 		}
       
  9228 		else
       
  9229 		{
       
  9230 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9231 			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  9232 		}
       
  9233 	}
       
  9234 #if defined(USE_FAST_EAP_TYPE)
       
  9235 	else if (m_eap_type == eap_type_fast
       
  9236 		&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  9237 		&& cipher_suite_is_TLS_DH_anon() == true)
       
  9238 	{
       
  9239 		// Diffie-Hellman prime modulus, generator and server's
       
  9240 		// Diffie-Hellman public value (g^X mod p)
       
  9241 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
  9242 		// NOTE: Here are no signed hash. This is not authenticated at all and vulnerable to
       
  9243 		// man-in-the-middle attacks.
       
  9244 		// 0                   1                   2                   3   
       
  9245 		//  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 
       
  9246 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9247 		//                 | DH p length                   |               |
       
  9248 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  9249 		// |                                                               |
       
  9250 		// +                                                               +
       
  9251 		// |                DH p value (prime modulus)                     |
       
  9252 		// +                                                               +
       
  9253 		// |                                                               |
       
  9254 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9255 		// |  DH g length                  |                               |
       
  9256 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  9257 		// |                                                               |
       
  9258 		// +                                                               +
       
  9259 		// |                DH g value (generator)                         |
       
  9260 		// +                                                               +
       
  9261 		// |                                                               |
       
  9262 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9263 		// |  DH Ys length                 |                               |
       
  9264 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  9265 		// |                                                               |
       
  9266 		// +                                                               +
       
  9267 		// |                DH Ys value                                    |
       
  9268 		// +         (server's Diffie-Hellman public value)                +
       
  9269 		// |                                                               |
       
  9270 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9271 
       
  9272 		EAP_TRACE_DEBUG(
       
  9273 			m_am_tools,
       
  9274 			TRACE_FLAGS_DEFAULT,
       
  9275 			(EAPL("TLS: analyse_handshake_type_server_key_exchange() no m_signed_message_hash\n")));
       
  9276 
       
  9277 		if (handshake_message->get_dhe_prime() == 0
       
  9278 			|| handshake_message->get_dhe_prime()->get_is_valid_data() == false
       
  9279 			|| handshake_message->get_dhe_prime()->get_data_length() == 0)
       
  9280 		{
       
  9281 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9282 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9283 		}
       
  9284 
       
  9285 		if (handshake_message->get_dhe_group_generator() == 0
       
  9286 			|| handshake_message->get_dhe_group_generator()->get_is_valid_data() == false
       
  9287 			|| handshake_message->get_dhe_group_generator()->get_data_length() == 0)
       
  9288 		{
       
  9289 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9290 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9291 		}
       
  9292 
       
  9293 		if (handshake_message->get_public_dhe_key() == 0
       
  9294 			|| handshake_message->get_public_dhe_key()->get_is_valid_data() == false
       
  9295 			|| handshake_message->get_public_dhe_key()->get_data_length() == 0)
       
  9296 		{
       
  9297 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9298 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9299 		}
       
  9300 
       
  9301 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9302 
       
  9303 		status = m_dhe_prime.set_copy_of_buffer(handshake_message->get_dhe_prime());
       
  9304 		if (status != eap_status_ok
       
  9305 			|| m_dhe_prime.get_is_valid_data() == false
       
  9306 			|| m_dhe_prime.get_data_length() == 0)
       
  9307 		{
       
  9308 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9309 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9310 		}
       
  9311 
       
  9312 		status = m_dhe_group_generator.set_copy_of_buffer(
       
  9313 			handshake_message->get_dhe_group_generator());
       
  9314 		if (status != eap_status_ok
       
  9315 			|| m_dhe_group_generator.get_is_valid_data() == false
       
  9316 			|| m_dhe_group_generator.get_data_length() == 0)
       
  9317 		{
       
  9318 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9319 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9320 		}
       
  9321 
       
  9322 		status = m_peer_public_dhe_key.set_copy_of_buffer(handshake_message->get_public_dhe_key());
       
  9323 		if (status != eap_status_ok
       
  9324 			|| m_peer_public_dhe_key.get_is_valid_data() == false
       
  9325 			|| m_peer_public_dhe_key.get_data_length() == 0)
       
  9326 		{
       
  9327 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9328 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9329 		}
       
  9330 	}
       
  9331 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  9332 
       
  9333 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9334 
       
  9335 	if (/* status == eap_status_pending_request
       
  9336 		   ||*/ status == eap_status_completed_request)
       
  9337 	{
       
  9338 		status = eap_status_ok;
       
  9339 	}
       
  9340 
       
  9341 	// Next we wait certificate_request or server_hello_done
       
  9342 	// If next message is certificate_request, server requires client authentication.
       
  9343 	// If next message is server_hello_done, server does NOT require client authentication.
       
  9344 	set_state(tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done);
       
  9345 
       
  9346 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9347 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  9348 }
       
  9349 
       
  9350 //--------------------------------------------------
       
  9351 
       
  9352 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_client_key_exchange(
       
  9353 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message)
       
  9354 {
       
  9355 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9356 
       
  9357 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  9358 	EAP_TRACE_DEBUG(
       
  9359 		m_am_tools,
       
  9360 		TRACE_FLAGS_DEFAULT,
       
  9361 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_client_key_exchange()\n"),
       
  9362 		(m_is_client == true ? "client": "server")));
       
  9363 
       
  9364 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_client_key_exchange()");
       
  9365 
       
  9366 	eap_status_e status = eap_status_not_supported;
       
  9367 
       
  9368 
       
  9369 	if (cipher_suite_is_TLS_RSA() == true)
       
  9370 	{
       
  9371 		// Encrypted premaster secret is included when selected cipher suite
       
  9372 		// is using RSA key exchange.
       
  9373 		// First two bytes are version of TLS.
       
  9374 		// 0                   1                   2                   3   
       
  9375 		//  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 
       
  9376 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9377 		//                 |                                               |
       
  9378 		// +-+-+-+-+-+-+-+-+                                               +
       
  9379 		// |                                                               |
       
  9380 		// +                                                               +
       
  9381 		// |                Encrypted Premaster Secret (48 bytes)          |
       
  9382 		// +                                                               +
       
  9383 		// |                                                               |
       
  9384 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9385 
       
  9386 		if (handshake_message->get_encrypted_premaster_secret() == 0
       
  9387 			|| handshake_message->get_encrypted_premaster_secret()->get_is_valid_data() == false
       
  9388 			|| handshake_message->get_encrypted_premaster_secret()->get_data_length() == 0)
       
  9389 		{
       
  9390 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9391 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9392 		}
       
  9393 
       
  9394 		EAP_TRACE_DEBUG(
       
  9395 			m_am_tools,
       
  9396 			TRACE_FLAGS_DEFAULT,
       
  9397 			(EAPL("TLS: %s:     pki_function: rsa_decrypt_with_private_key()\n"),
       
  9398 			(m_is_client == true ? "client": "server")));
       
  9399 
       
  9400 		EAP_TRACE_DATA_DEBUG(
       
  9401 			m_am_tools,
       
  9402 			TRACE_FLAGS_DEFAULT,
       
  9403 			(EAPL("TLS: analyse_handshake_type_client_key_exchange(): encrypted premaster_secret"),
       
  9404 			 handshake_message->get_encrypted_premaster_secret()->get_data(),
       
  9405 			 handshake_message->get_encrypted_premaster_secret()->get_data_length()));
       
  9406 
       
  9407 		status = m_am_tls_services->rsa_decrypt_with_private_key(
       
  9408 			handshake_message->get_encrypted_premaster_secret());
       
  9409 		if (status == eap_status_pending_request)
       
  9410 		{
       
  9411 			// This is pending query, that will be completed by
       
  9412 			// complete_rsa_decrypt_with_private_key() call.
       
  9413 			m_pending_rsa_decrypt_with_private_key = true;
       
  9414 		}
       
  9415 		else if (status == eap_status_completed_request)
       
  9416 		{
       
  9417 			// This is already completed by complete_rsa_decrypt_with_private_key() call.
       
  9418 		}
       
  9419 		else if (status == eap_status_ok)
       
  9420 		{
       
  9421 			// This is also an error case, because this call is always completed on success. 
       
  9422 			status = eap_status_process_general_error;
       
  9423 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9424 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9425 		}
       
  9426 		else // All other status values means error, because this call
       
  9427 			// is always completed on success.
       
  9428 		{
       
  9429 			// This is an error case.
       
  9430 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9431 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  9432 		}
       
  9433 	}
       
  9434 	else if (cipher_suite_is_TLS_DHE_DSS() == true
       
  9435 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
  9436 #if defined(USE_FAST_EAP_TYPE)
       
  9437 		|| (m_eap_type == eap_type_fast
       
  9438 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  9439 			&& cipher_suite_is_TLS_DH_anon() == true)
       
  9440 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  9441 		)
       
  9442 	{
       
  9443 		// Diffie-Hellman prime modulus, generator and server's
       
  9444 		// Diffie-Hellman public value (g^X mod p)
       
  9445 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
  9446 		// 0                   1                   2                   3   
       
  9447 		//  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 
       
  9448 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9449 		//                 | DH p length                   |               |
       
  9450 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
  9451 		// |                                                               |
       
  9452 		// +                                                               +
       
  9453 		// |                DH p value (prime modulus)                     |
       
  9454 		// +                                                               +
       
  9455 		// |                                                               |
       
  9456 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9457 		// |  DH g length                  |                               |
       
  9458 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  9459 		// |                                                               |
       
  9460 		// +                                                               +
       
  9461 		// |                DH g value (generator)                         |
       
  9462 		// +                                                               +
       
  9463 		// |                                                               |
       
  9464 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9465 		// |  DH Ys length                 |                               |
       
  9466 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
  9467 		// |                                                               |
       
  9468 		// +                                                               +
       
  9469 		// |                DH Ys value                                    |
       
  9470 		// +         (server's Diffie-Hellman public value)                +
       
  9471 		// |                                                               |
       
  9472 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9473 
       
  9474 		if (handshake_message->get_public_dhe_key() == 0
       
  9475 			|| handshake_message->get_public_dhe_key()->get_is_valid_data() == false
       
  9476 			|| handshake_message->get_public_dhe_key()->get_data_length() == 0)
       
  9477 		{
       
  9478 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9479 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9480 		}
       
  9481 
       
  9482 		status = m_peer_public_dhe_key.set_copy_of_buffer(handshake_message->get_public_dhe_key());
       
  9483 		if (status != eap_status_ok
       
  9484 			|| m_peer_public_dhe_key.get_is_valid_data() == false
       
  9485 			|| m_peer_public_dhe_key.get_data_length() == 0)
       
  9486 		{
       
  9487 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9488 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9489 		}
       
  9490 
       
  9491 
       
  9492 		// We must generate premaster secret.
       
  9493 		status = generate_premaster_secret();
       
  9494 		if (status != eap_status_ok)
       
  9495 		{
       
  9496 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9497 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9498 		}
       
  9499 		
       
  9500 		// We must generate master secret.
       
  9501 		status = generate_master_secret();
       
  9502 		if (status != eap_status_ok)
       
  9503 		{
       
  9504 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9505 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9506 		}
       
  9507 
       
  9508 		// We must generate the key material.
       
  9509 		status = generate_key_material();
       
  9510 		if (status != eap_status_ok)
       
  9511 		{
       
  9512 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9513 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9514 		}
       
  9515 	}
       
  9516 
       
  9517 
       
  9518 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9519 
       
  9520 	if (/*status == eap_status_pending_request
       
  9521 		  ||*/ status == eap_status_completed_request)
       
  9522 	{
       
  9523 		status = eap_status_ok;
       
  9524 	}
       
  9525 
       
  9526 	if (m_tls_peap_server_authenticates_client_action == true)
       
  9527 	{
       
  9528 		set_state(tls_peap_state_wait_handshake_type_certificate_verify);
       
  9529 	}
       
  9530 	else
       
  9531 	{
       
  9532 		set_state(tls_peap_state_wait_change_cipher_spec);
       
  9533 	}
       
  9534 
       
  9535 
       
  9536 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9537 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  9538 }
       
  9539 
       
  9540 //--------------------------------------------------
       
  9541 
       
  9542 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_certificate_verify(
       
  9543 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message)
       
  9544 {
       
  9545 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9546 
       
  9547 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  9548 	EAP_TRACE_DEBUG(
       
  9549 		m_am_tools,
       
  9550 		TRACE_FLAGS_DEFAULT,
       
  9551 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_certificate_verify()\n"),
       
  9552 		(m_is_client == true ? "client": "server")));
       
  9553 
       
  9554 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_certificate_verify()");
       
  9555 
       
  9556 	eap_status_e status = eap_status_not_supported;
       
  9557 
       
  9558 	if (cipher_suite_is_TLS_RSA() == true
       
  9559 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
  9560 		|| cipher_suite_is_TLS_DHE_DSS() == true)
       
  9561 	{
       
  9562 		// Signatures when RSA is used:
       
  9563 		// 0                   1                   2                   3   
       
  9564 		//  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 
       
  9565 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9566 		//                 |                                               |
       
  9567 		// +-+-+-+-+-+-+-+-+                                               +
       
  9568 		// |                                                               |
       
  9569 		// +                   Signed MD5 hash                             +
       
  9570 		// |                    (16 bytes)                                 |
       
  9571 		// +                                                               +
       
  9572 		// |                                                               |
       
  9573 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9574 		// |                                                               |
       
  9575 		// +                   Signed SHA hash                             +
       
  9576 		// |                    (20 bytes)                                 |
       
  9577 		// +                                                               +
       
  9578 		// |                                                               |
       
  9579 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9580 
       
  9581 		// Signature when DSA is used:
       
  9582 		// 0                   1                   2                   3   
       
  9583 		//  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 
       
  9584 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9585 		//                 |                                               |
       
  9586 		// +-+-+-+-+-+-+-+-+                                               +
       
  9587 		// |                                                               |
       
  9588 		// +                   Signed SHA hash                             +
       
  9589 		// |                    (48 bytes)                                 |
       
  9590 		// +                                                               +
       
  9591 		// |                                                               |
       
  9592 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  9593 
       
  9594 		eap_variable_data_c signed_certificate_verify_hash(m_am_tools);
       
  9595 
       
  9596 		status = signed_certificate_verify_hash.set_copy_of_buffer(
       
  9597 			handshake_message->get_signed_message_hash());
       
  9598 		if (status != eap_status_ok)
       
  9599 		{
       
  9600 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9601 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9602 		}
       
  9603 
       
  9604 		if (signed_certificate_verify_hash.get_is_valid_data() == false)
       
  9605 		{
       
  9606 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9607 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  9608 		}
       
  9609 
       
  9610 		eap_variable_data_c message_hash(m_am_tools);
       
  9611 
       
  9612 		status = message_hash_create(
       
  9613 			true,
       
  9614 			tls_handshake_type_certificate_verify,
       
  9615 			&message_hash,
       
  9616 			true);
       
  9617 		if (status != eap_status_ok)
       
  9618 		{
       
  9619 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9620 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9621 		}
       
  9622 
       
  9623 		EAP_TRACE_DEBUG(
       
  9624 			m_am_tools,
       
  9625 			TRACE_FLAGS_DEFAULT,
       
  9626 			(EAPL("TLS: %s:     pki_function: analyse_handshake_type_certificate_verify()\n"),
       
  9627 			(m_is_client == true ? "client": "server")));
       
  9628 
       
  9629 		EAP_TRACE_DATA_DEBUG(
       
  9630 			m_am_tools,
       
  9631 			TRACE_FLAGS_DEFAULT,
       
  9632 			(EAPL("TLS: analyse_handshake_type_certificate_verify(): message_hash"),
       
  9633 			message_hash.get_data(message_hash.get_data_length()),
       
  9634 			message_hash.get_data_length()));
       
  9635 
       
  9636 		EAP_TRACE_DATA_DEBUG(
       
  9637 			m_am_tools,
       
  9638 			TRACE_FLAGS_DEFAULT,
       
  9639 			(EAPL("TLS: analyse_handshake_type_certificate_verify(): signed_certificate_verify_hash"),
       
  9640 			signed_certificate_verify_hash.get_data(
       
  9641 				signed_certificate_verify_hash.get_data_length()),
       
  9642 			signed_certificate_verify_hash.get_data_length()));
       
  9643 
       
  9644 		status = m_am_tls_services->verify_with_public_key(
       
  9645 			&message_hash,
       
  9646 			&signed_certificate_verify_hash);
       
  9647 		if (status == eap_status_pending_request)
       
  9648 		{
       
  9649 			// This is pending query, that will be completed by
       
  9650 			// complete_query_certificate_chain() call.
       
  9651 			m_pending_verify_with_public_key = true;
       
  9652 		}
       
  9653 		else if (status == eap_status_completed_request)
       
  9654 		{
       
  9655 			// This is already completed by complete_query_certificate_chain() call.
       
  9656 			status = eap_status_ok;
       
  9657 		}
       
  9658 		else if (status == eap_status_ok)
       
  9659 		{
       
  9660 			// This is also an error case, because this call is always completed on success. 
       
  9661 			status = eap_status_process_general_error;
       
  9662 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9663 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9664 		}
       
  9665 		else // All other status values means error, because this call
       
  9666 			// is always completed on success.
       
  9667 		{
       
  9668 			// This is an error case.
       
  9669 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9670 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
  9671 		}
       
  9672 	}
       
  9673 	else
       
  9674 	{
       
  9675 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9676 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  9677 	}
       
  9678 
       
  9679 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9680 
       
  9681 	set_state(tls_peap_state_wait_change_cipher_spec);
       
  9682 
       
  9683 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9684 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  9685 }
       
  9686 
       
  9687 //--------------------------------------------------
       
  9688 
       
  9689 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_finished(
       
  9690 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message,
       
  9691 	const u8_t received_eap_identifier)
       
  9692 {
       
  9693 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9694 
       
  9695 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  9696 	EAP_TRACE_DEBUG(
       
  9697 		m_am_tools,
       
  9698 		TRACE_FLAGS_DEFAULT,
       
  9699 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_finished()\n"),
       
  9700 		(m_is_client == true ? "client": "server")));
       
  9701 
       
  9702 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_finished()");
       
  9703 
       
  9704 	eap_status_e status = eap_status_not_supported;
       
  9705 
       
  9706 
       
  9707 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9708 
       
  9709 	if (handshake_message->get_finished_data() == 0
       
  9710 		|| handshake_message->get_finished_data()->get_is_valid_data() == false)
       
  9711 	{
       
  9712 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9713 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9714 	}
       
  9715 
       
  9716 	eap_variable_data_c message_hash(m_am_tools);
       
  9717 
       
  9718 	bool client_originated_message = true;
       
  9719 	if (m_is_client == true)
       
  9720 	{
       
  9721 		client_originated_message = false;
       
  9722 	}
       
  9723 
       
  9724 	status = message_hash_create_finished(client_originated_message, &message_hash);
       
  9725 	if (status != eap_status_ok)
       
  9726 	{
       
  9727 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9728 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  9729 	}
       
  9730 
       
  9731 	if (message_hash.compare(handshake_message->get_finished_data()) != 0)
       
  9732 	{
       
  9733 		EAP_TRACE_ERROR(
       
  9734 			m_am_tools,
       
  9735 			TRACE_FLAGS_DEFAULT,
       
  9736 			(EAPL("ERROR: TLS: %s: analyse_handshake_type_finished(): ")
       
  9737 			 EAPL("verify check finished data failed, m_tls_session_type=%d=%s.\n"),
       
  9738 			 (m_is_client == true ? "client": "server"),
       
  9739 			 m_tls_session_type,
       
  9740 			 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)
       
  9741 			 ));
       
  9742 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9743 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  9744 	}
       
  9745 	else
       
  9746 	{
       
  9747 		EAP_TRACE_ALWAYS(
       
  9748 			m_am_tools,
       
  9749 			TRACE_FLAGS_DEFAULT,
       
  9750 			(EAPL("TLS: %s: message_function: analyse_handshake_type_finished(): ")
       
  9751 			 EAPL("verify check finished data OK, m_tls_session_type=%d=%s.\n"),
       
  9752 			 (m_is_client == true ? "client": "server"),
       
  9753 			 m_tls_session_type,
       
  9754 			 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)));
       
  9755 	}
       
  9756 
       
  9757 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9758 
       
  9759 	if ((m_is_client == false
       
  9760 		 && m_tls_session_type == tls_session_type_full_authentication)
       
  9761 		|| (m_is_client == true
       
  9762 			&& (m_tls_session_type == tls_session_type_original_session_resumption
       
  9763 				|| m_tls_session_type == tls_session_type_stateless_session_resumption
       
  9764 #if defined(USE_FAST_EAP_TYPE)
       
  9765 				|| m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption
       
  9766 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  9767 				)
       
  9768 			)
       
  9769 		)
       
  9770 	{
       
  9771 		// We need to send ChangeCipherSpec and Handshake/Finished.
       
  9772 
       
  9773 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  9774 		if (
       
  9775 			m_is_client == false
       
  9776 #if defined(USE_FAST_EAP_TYPE)
       
  9777 			&& m_eap_type != eap_type_fast
       
  9778 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  9779 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  9780 			&& (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none
       
  9781 					|| m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs)
       
  9782 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  9783 			&& m_tls_session_type == tls_session_type_full_authentication
       
  9784 			&& tls_extension_c::get_tls_extension(
       
  9785 						tls_extension_type_session_ticket,
       
  9786 						&m_supported_tls_extensions,
       
  9787 						m_am_tools) != 0)
       
  9788 		{
       
  9789 			{
       
  9790 				const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension(
       
  9791 						tls_extension_type_session_ticket,
       
  9792 						&m_supported_tls_extensions,
       
  9793 						m_am_tools);
       
  9794 				EAP_UNREFERENCED_PARAMETER(supported_session_ticket_extension);
       
  9795 
       
  9796 				EAP_TRACE_DEBUG(
       
  9797 					m_am_tools,
       
  9798 					TRACE_FLAGS_DEFAULT,
       
  9799 					(EAPL("TLS: %s: message_function: analyse_handshake_type_finished(): ")
       
  9800 					 EAPL("SST: Server will send a new session ticket to client, length = %d.\n"),
       
  9801 					 (m_is_client == true ? "client": "server"),
       
  9802 					 supported_session_ticket_extension->get_data_length()));
       
  9803 			}
       
  9804 
       
  9805 			// Server will send a new session ticket to client.
       
  9806 			status = completion_action_add(
       
  9807 				tls_completion_action_create_handshake_type_new_session_ticket);
       
  9808 			if (status != eap_status_ok)
       
  9809 			{
       
  9810 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9811 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  9812 			}
       
  9813 		}
       
  9814 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  9815 
       
  9816 		status = completion_action_add(
       
  9817 			tls_completion_action_create_change_cipher_spec_type_change_cipher_spec);
       
  9818 		if (status != eap_status_ok)
       
  9819 		{
       
  9820 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9821 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9822 		}
       
  9823 
       
  9824 		status = completion_action_add(tls_completion_action_create_handshake_type_finished);
       
  9825 		if (status != eap_status_ok)
       
  9826 		{
       
  9827 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9828 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9829 		}
       
  9830 
       
  9831 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  9832 		if (m_is_client == false
       
  9833 			&& m_tls_session_type == tls_session_type_full_authentication
       
  9834 			&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates)
       
  9835 		{
       
  9836 			status = completion_action_add(tls_completion_action_create_handshake_type_hello_request);
       
  9837 			if (status != eap_status_ok)
       
  9838 			{
       
  9839 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9840 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  9841 			}
       
  9842 		}
       
  9843 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  9844 
       
  9845 		status = completion_action_add(tls_completion_action_check_sent_tls_message);
       
  9846 		if (status != eap_status_ok)
       
  9847 		{
       
  9848 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9849 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9850 		}
       
  9851 	}
       
  9852 #if defined(USE_FAST_EAP_TYPE)
       
  9853 	else if (m_is_client == false
       
  9854 				&& m_eap_type == eap_type_fast
       
  9855 				&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
  9856 				&& cipher_suite_is_TLS_DH_anon() == true)
       
  9857 	{
       
  9858 		status = completion_action_add(
       
  9859 			tls_completion_action_create_change_cipher_spec_type_change_cipher_spec);
       
  9860 		if (status != eap_status_ok)
       
  9861 		{
       
  9862 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9863 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9864 		}
       
  9865 
       
  9866 		status = completion_action_add(tls_completion_action_create_handshake_type_finished);
       
  9867 		if (status != eap_status_ok)
       
  9868 		{
       
  9869 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9870 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9871 		}
       
  9872 
       
  9873 		status = completion_action_add(tls_completion_action_check_sent_tls_message);
       
  9874 		if (status != eap_status_ok)
       
  9875 		{
       
  9876 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9877 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9878 		}
       
  9879 	}
       
  9880 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  9881 
       
  9882 
       
  9883 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  9884 	if (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none
       
  9885 			|| m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs
       
  9886 			|| m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates
       
  9887 		)
       
  9888 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
  9889 	{
       
  9890 		// Authentication OK.
       
  9891 		status = completion_action_add(tls_completion_action_finish_handshake);
       
  9892 		if (status != eap_status_ok)
       
  9893 		{
       
  9894 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9895 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9896 		}
       
  9897 
       
  9898 		status = completion_action_add(tls_completion_action_process_tls_records);
       
  9899 		if (status != eap_status_ok)
       
  9900 		{
       
  9901 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9902 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9903 		}
       
  9904 
       
  9905 #if defined(USE_FAST_EAP_TYPE)
       
  9906 		if (m_is_client == false
       
  9907 			&& m_eap_type == eap_type_fast
       
  9908 			&& m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
  9909 		{
       
  9910 			status = completion_action_add(tls_completion_action_check_tunnel_authentication_runs);
       
  9911 			if (status != eap_status_ok)
       
  9912 			{
       
  9913 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9914 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  9915 			}
       
  9916 		}
       
  9917 #endif //#if defined(USE_FAST_EAP_TYPE)
       
  9918 	}
       
  9919 
       
  9920 	m_received_eap_identifier = received_eap_identifier;
       
  9921 
       
  9922 
       
  9923 	set_state(tls_peap_state_process_pending_tls_completions);
       
  9924 
       
  9925 	if (status == eap_status_ok)
       
  9926 	{
       
  9927 		status = check_sent_tls_message();
       
  9928 		if (status != eap_status_ok)
       
  9929 		{
       
  9930 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9931 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  9932 		}
       
  9933 	}
       
  9934 
       
  9935 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9936 
       
  9937 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9938 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  9939 }
       
  9940 
       
  9941 //--------------------------------------------------
       
  9942 
       
  9943 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
  9944 
       
  9945 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_handshake_type_new_session_ticket(
       
  9946 	EAP_TEMPLATE_CONST tls_handshake_message_c * const handshake_message,
       
  9947 	const u8_t /* received_eap_identifier */)
       
  9948 {
       
  9949 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9950 
       
  9951 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  9952 	EAP_TRACE_DEBUG(
       
  9953 		m_am_tools,
       
  9954 		TRACE_FLAGS_DEFAULT,
       
  9955 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_handshake_type_new_session_ticket()\n"),
       
  9956 		(m_is_client == true ? "client": "server")));
       
  9957 
       
  9958 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_handshake_type_new_session_ticket()");
       
  9959 
       
  9960 	eap_status_e status = eap_status_not_supported;
       
  9961 
       
  9962 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  9963 
       
  9964 	EAP_TEMPLATE_CONST eap_array_c<tls_extension_c> * const tls_extensions
       
  9965 		= handshake_message->get_tls_extensions();
       
  9966 
       
  9967 	if (tls_extensions == 0)
       
  9968 	{
       
  9969 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9970 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9971 	}
       
  9972 
       
  9973 	const tls_extension_c * const session_ticket = tls_extension_c::get_tls_extension(
       
  9974 			tls_extension_type_session_ticket,
       
  9975 			tls_extensions,
       
  9976 			m_am_tools);
       
  9977 
       
  9978 	if (session_ticket == 0)
       
  9979 	{
       
  9980 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9981 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  9982 	}
       
  9983 
       
  9984 	m_received_tls_extensions.reset();
       
  9985 
       
  9986 	EAP_TRACE_DEBUG(
       
  9987 		m_am_tools,
       
  9988 		TRACE_FLAGS_DEFAULT,
       
  9989 		(EAPL("TLS: %s: message_function: analyse_handshake_type_new_session_ticket(): ")
       
  9990 		 EAPL("SST: session ticket received, length = %d.\n"),
       
  9991 		 (m_is_client == true ? "client": "server"),
       
  9992 		 session_ticket->get_data_length()));
       
  9993 
       
  9994 	tls_extension_c * const copy_of_session_ticket = session_ticket->copy();
       
  9995 
       
  9996 	if (copy_of_session_ticket == 0)
       
  9997 	{
       
  9998 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  9999 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 10000 	}
       
 10001 
       
 10002 	status = m_received_tls_extensions.add_object(copy_of_session_ticket, true);
       
 10003 
       
 10004 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10005 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 10006 }
       
 10007 
       
 10008 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 10009 
       
 10010 //--------------------------------------------------
       
 10011 
       
 10012 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_change_cipher_spec(
       
 10013 	const tls_record_message_c * const record)
       
 10014 {
       
 10015 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10016 
       
 10017 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 10018 	EAP_TRACE_DEBUG(
       
 10019 		m_am_tools,
       
 10020 		TRACE_FLAGS_DEFAULT,
       
 10021 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_change_cipher_spec()\n"),
       
 10022 		(m_is_client == true ? "client": "server")));
       
 10023 
       
 10024 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_change_cipher_spec()");
       
 10025 
       
 10026 	eap_status_e status = eap_status_not_supported;
       
 10027 
       
 10028 	u32_t ind_change_cipher_spec = 0ul;
       
 10029 
       
 10030 	for (ind_change_cipher_spec = 0ul
       
 10031 			 ; ind_change_cipher_spec < record->get_change_cipher_spec_count()
       
 10032 			 ; ind_change_cipher_spec++)
       
 10033 	{
       
 10034 		const tls_change_cipher_spec_message_c * const change_cipher_spec_message
       
 10035 			= record->get_change_cipher_spec(ind_change_cipher_spec);
       
 10036 
       
 10037 		switch (change_cipher_spec_message->get_change_cipher_spec_type())
       
 10038 		{
       
 10039 		case tls_change_cipher_spec_type_change_cipher_spec:
       
 10040 
       
 10041 			if (m_tls_session_type == tls_session_type_stateless_session_resumption
       
 10042 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 10043 				|| (m_tls_session_type == tls_session_type_full_authentication
       
 10044 					&& m_tls_use_identity_privacy == true
       
 10045 					&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs)
       
 10046 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 10047 					)
       
 10048 			{
       
 10049 				// We must generate the key material.
       
 10050 				status = generate_key_material();
       
 10051 				if (status != eap_status_ok)
       
 10052 				{
       
 10053 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10054 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 10055 				}
       
 10056 			}
       
 10057 
       
 10058 			// We change the receive cipher suite.
       
 10059 			status = change_cipher_spec(false);
       
 10060 			if (status != eap_status_ok)
       
 10061 			{
       
 10062 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10063 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 10064 			}
       
 10065 			else
       
 10066 			{
       
 10067 				set_state(tls_peap_state_wait_handshake_type_finished);
       
 10068 			}
       
 10069 
       
 10070 			break;
       
 10071 
       
 10072 		default:
       
 10073 
       
 10074 			set_state(tls_peap_state_failure);
       
 10075 			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
 10076 		} // switch()
       
 10077 
       
 10078 	} // for()
       
 10079 
       
 10080 
       
 10081 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10082 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 10083 }
       
 10084 
       
 10085 //--------------------------------------------------
       
 10086 
       
 10087 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_alert(
       
 10088 	const tls_record_message_c * const record)
       
 10089 {
       
 10090 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10091 
       
 10092 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 10093 	EAP_TRACE_DEBUG(
       
 10094 		m_am_tools,
       
 10095 		TRACE_FLAGS_DEFAULT,
       
 10096 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_alert()\n"),
       
 10097 		(m_is_client == true ? "client": "server")));
       
 10098 
       
 10099 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_alert()");
       
 10100 
       
 10101 	eap_status_e status = eap_status_authentication_failure;
       
 10102 
       
 10103 	u32_t ind_alert = 0ul;
       
 10104 
       
 10105 	m_new_tls_message.reset();
       
 10106 
       
 10107 
       
 10108 	for (ind_alert = 0ul
       
 10109 			 ; ind_alert < record->get_alert_count()
       
 10110 			 ; ind_alert++)
       
 10111 	{
       
 10112 		const tls_alert_message_c * const alert_message
       
 10113 			= record->get_alert(ind_alert);
       
 10114 
       
 10115 		EAP_TRACE_ERROR(
       
 10116 			m_am_tools,
       
 10117 			TRACE_FLAGS_DEFAULT,
       
 10118 			(EAPL("ERROR: %s: EAP_type_TLS_PEAP: Alert message %s:%s\n"),
       
 10119 			(m_is_client == true) ? "client": "server",
       
 10120 			eap_tls_trace_string_c::get_alert_level_string(alert_message->get_alert_level()),
       
 10121 			eap_tls_trace_string_c::get_alert_description_string(alert_message->get_alert_description())));
       
 10122 
       
 10123 		if (m_application != 0)
       
 10124 		{
       
 10125 			// Indication to TLS-application.
       
 10126 			(void) m_application->alert_received(
       
 10127 				alert_message->get_alert_level(),
       
 10128 				alert_message->get_alert_description());
       
 10129 		}
       
 10130 
       
 10131 		// indication to TLS AM.
       
 10132 		m_am_tls_services->alert_received(
       
 10133 			alert_message->get_alert_level(),
       
 10134 			alert_message->get_alert_description());
       
 10135 
       
 10136 		switch (alert_message->get_alert_description())
       
 10137 		{
       
 10138 		case tls_alert_description_close_notify:
       
 10139 			break;
       
 10140 		case tls_alert_description_unexpected_message:
       
 10141 			// This message is always fatal.
       
 10142 			break;
       
 10143 		case tls_alert_description_bad_record_mac:
       
 10144 			// This message is always fatal.
       
 10145 			break;
       
 10146 		case tls_alert_description_decryption_failed:
       
 10147 			// This message is always fatal.
       
 10148 			break;
       
 10149 		case tls_alert_description_record_overflow:
       
 10150 			// This message is always fatal.
       
 10151 			break;
       
 10152 		case tls_alert_description_decompression_failure:
       
 10153 			// This message is always fatal.
       
 10154 			break;
       
 10155 		case tls_alert_description_handshake_failure:
       
 10156 			// This message is always fatal.
       
 10157 			break;
       
 10158 		case tls_alert_description_bad_certificate:
       
 10159 			break;
       
 10160 		case tls_alert_description_unsupported_certificate:
       
 10161 			break;
       
 10162 		case tls_alert_description_certificate_revoked:
       
 10163 			break;
       
 10164 		case tls_alert_description_certificate_expired:
       
 10165 			break;
       
 10166 		case tls_alert_description_certificate_unknown:
       
 10167 			break;
       
 10168 		case tls_alert_description_illegal_parameter:
       
 10169 			// This message is always fatal.
       
 10170 			break;
       
 10171 		case tls_alert_description_unknown_ca:
       
 10172 			// This message is always fatal.
       
 10173 			break;
       
 10174 		case tls_alert_description_access_denied:
       
 10175 			// This message is always fatal.
       
 10176 			break;
       
 10177 		case tls_alert_description_decode_error:
       
 10178 			// This message is always fatal.
       
 10179 			break;
       
 10180 		case tls_alert_description_decrypt_error:
       
 10181 			break;
       
 10182 		case tls_alert_description_export_restriction:
       
 10183 			// This message is always fatal.
       
 10184 			break;
       
 10185 		case tls_alert_description_protocol_version:
       
 10186 			// This message is always fatal.
       
 10187 			break;
       
 10188 		case tls_alert_description_insufficient_security:
       
 10189 			// This message is always fatal.
       
 10190 			break;
       
 10191 		case tls_alert_description_internal_error:
       
 10192 			// This message is always fatal.
       
 10193 			break;
       
 10194 		case tls_alert_description_user_canceled:
       
 10195 			break;
       
 10196 		case tls_alert_description_no_renegotiation:
       
 10197 			// This message is always a warning.
       
 10198 			break;
       
 10199 		case tls_alert_description_none:
       
 10200 			break;
       
 10201 		default:
       
 10202 			break;
       
 10203 		} // switch()
       
 10204 
       
 10205 	} // for()
       
 10206 
       
 10207 
       
 10208 	set_state(tls_peap_state_failure);
       
 10209 
       
 10210 	// This will cause the session terminate immediately.
       
 10211 	status = get_type_partner()->set_session_timeout(0ul);
       
 10212 	if (status != eap_status_ok)
       
 10213 	{
       
 10214 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10215 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 10216 	}
       
 10217 
       
 10218 
       
 10219 	{
       
 10220 		eap_state_notification_c notification(
       
 10221 			m_am_tools,
       
 10222 			&m_send_network_id,
       
 10223 			m_is_client,
       
 10224 			eap_state_notification_generic,
       
 10225 			eap_protocol_layer_internal_type,
       
 10226 			0,
       
 10227 			tls_peap_state_none,
       
 10228 			eap_state_authentication_terminated_unsuccessfully,
       
 10229 			0,
       
 10230 			false);
       
 10231 
       
 10232 		notification.set_authentication_error(eap_status_authentication_failure);
       
 10233 
       
 10234 		get_type_partner()->state_notification(&notification);
       
 10235 	}
       
 10236 
       
 10237 
       
 10238 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10239 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 10240 }
       
 10241 
       
 10242 //--------------------------------------------------
       
 10243 
       
 10244 EAP_FUNC_EXPORT tls_record_protocol_e tls_record_c::get_next_tls_record_message_protocol()
       
 10245 {
       
 10246 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10247 
       
 10248 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 10249 	EAP_TRACE_DEBUG(
       
 10250 		m_am_tools,
       
 10251 		TRACE_FLAGS_DEFAULT,
       
 10252 		(EAPL("TLS: %s: message_function: starts: tls_record_c::get_next_tls_record_message_protocol()\n"),
       
 10253 		(m_is_client == true ? "client": "server")));
       
 10254 
       
 10255 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_next_tls_record_message_protocol()");
       
 10256 
       
 10257 	tls_record_protocol_e record_protocol(tls_record_protocol_none);
       
 10258 
       
 10259 	if (m_received_tls_message.get_record_message_count() <= m_received_tls_message.get_analyse_index()+1ul)
       
 10260 	{
       
 10261 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10262 		return record_protocol;
       
 10263 	}
       
 10264 
       
 10265 	tls_record_message_c * const tls_record_message
       
 10266 		= m_received_tls_message.get_record_message(m_received_tls_message.get_analyse_index()+1ul);
       
 10267 	if (tls_record_message == 0
       
 10268 		|| tls_record_message->get_is_valid() == false)
       
 10269 	{
       
 10270 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10271 		return record_protocol;
       
 10272 	}
       
 10273 
       
 10274 	const u32_t tls_record_length = tls_record_message->get_record_message_data()->get_data_length();
       
 10275 
       
 10276 	if (tls_record_message->get_record_message_data()->get_data_length() < tls_record_header_c::get_header_length())
       
 10277 	{
       
 10278 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10279 		return record_protocol;
       
 10280 	}
       
 10281 
       
 10282 	tls_record_header_c tls_record_header(
       
 10283 		m_am_tools,
       
 10284 		tls_record_message->get_record_message_data()->get_data(
       
 10285 			tls_record_header_c::get_header_length()),
       
 10286 		tls_record_length);
       
 10287 
       
 10288 	if (tls_record_header.get_is_valid() == false
       
 10289 		|| tls_record_length < tls_record_header.get_data_length()
       
 10290 		|| tls_record_length
       
 10291 		< tls_record_header.get_header_length()
       
 10292 		+ tls_record_header.get_data_length())
       
 10293 	{
       
 10294 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10295 		return record_protocol;
       
 10296 	}
       
 10297 
       
 10298 	record_protocol = tls_record_header.get_protocol();
       
 10299 
       
 10300 	EAP_TRACE_DEBUG(
       
 10301 		m_am_tools,
       
 10302 		TRACE_FLAGS_DEFAULT,
       
 10303 		(EAPL("TLS: %s: message_function: ends: tls_record_c::get_next_tls_record_message_protocol(): %d=%s\n"),
       
 10304 		(m_is_client == true ? "client": "server"),
       
 10305 		record_protocol,
       
 10306 		tls_record_header_c::get_tls_protocol_string(record_protocol)));
       
 10307 	
       
 10308 
       
 10309 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10310 	return record_protocol;
       
 10311 }
       
 10312 
       
 10313 //--------------------------------------------------
       
 10314 
       
 10315 EAP_FUNC_EXPORT tls_handshake_type_e tls_record_c::get_next_tls_handshake_message_type()
       
 10316 {
       
 10317 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10318 
       
 10319 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 10320 	EAP_TRACE_DEBUG(
       
 10321 		m_am_tools,
       
 10322 		TRACE_FLAGS_DEFAULT,
       
 10323 		(EAPL("TLS: %s: message_function: starts: tls_record_c::get_next_tls_handshake_message_type()\n"),
       
 10324 		(m_is_client == true ? "client": "server")));
       
 10325 
       
 10326 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_next_tls_handshake_message_type()");
       
 10327 
       
 10328 	tls_handshake_type_e handshake_type(tls_handshake_type_none);
       
 10329 
       
 10330 	if (m_received_tls_message.get_record_message_count() <= m_received_tls_message.get_analyse_index())
       
 10331 	{
       
 10332 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10333 		return handshake_type;
       
 10334 	}
       
 10335 
       
 10336 	tls_record_message_c * const tls_record_message
       
 10337 		= m_received_tls_message.get_record_message(m_received_tls_message.get_analyse_index());
       
 10338 	if (tls_record_message == 0
       
 10339 		|| tls_record_message->get_is_valid() == false)
       
 10340 	{
       
 10341 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10342 		return handshake_type;
       
 10343 	}
       
 10344 
       
 10345 	const u32_t tls_record_length = tls_record_message->get_record_message_data()->get_data_length();
       
 10346 
       
 10347 	if (tls_record_message->get_record_message_data()->get_data_length() < tls_record_header_c::get_header_length())
       
 10348 	{
       
 10349 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10350 		return handshake_type;
       
 10351 	}
       
 10352 
       
 10353 	tls_record_header_c tls_record_header(
       
 10354 		m_am_tools,
       
 10355 		tls_record_message->get_record_message_data()->get_data(
       
 10356 			tls_record_header_c::get_header_length()),
       
 10357 		tls_record_length);
       
 10358 
       
 10359 	if (tls_record_header.get_is_valid() == false
       
 10360 		|| tls_record_length < tls_record_header.get_data_length()
       
 10361 		|| tls_record_length
       
 10362 		< tls_record_header.get_header_length()
       
 10363 		+ tls_record_header.get_data_length())
       
 10364 	{
       
 10365 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10366 		return handshake_type;
       
 10367 	}
       
 10368 
       
 10369 	tls_record_protocol_e tls_protocol(tls_record_header.get_protocol());
       
 10370 
       
 10371 	if (tls_protocol == tls_record_protocol_handshake)
       
 10372 	{
       
 10373 		if (tls_record_message->get_handshake_count() <= tls_record_message->get_analyse_index()+1ul)
       
 10374 		{
       
 10375 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10376 			return handshake_type;
       
 10377 		}
       
 10378 
       
 10379 		tls_handshake_message_c * const handshake_message = tls_record_message->get_handshake(tls_record_message->get_analyse_index()+1ul);
       
 10380 
       
 10381 		if (handshake_message == 0
       
 10382 			|| handshake_message->get_is_valid() == false)
       
 10383 		{
       
 10384 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10385 			return handshake_type;
       
 10386 		}
       
 10387 
       
 10388 		handshake_type = handshake_message->get_handshake_type();
       
 10389 
       
 10390 		EAP_TRACE_DEBUG(
       
 10391 			m_am_tools,
       
 10392 			TRACE_FLAGS_DEFAULT,
       
 10393 			(EAPL("TLS: %s: message_function: ends: tls_record_c::get_next_tls_handshake_message_type(): %d=%s\n"),
       
 10394 			(m_is_client == true ? "client": "server"),
       
 10395 			handshake_type,
       
 10396 			tls_handshake_header_c::get_tls_handshake_string(handshake_type)));
       
 10397 	}
       
 10398 
       
 10399 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10400 	return handshake_type;
       
 10401 }
       
 10402 
       
 10403 //--------------------------------------------------
       
 10404 
       
 10405 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_handshake(
       
 10406 	tls_record_message_c * const record,
       
 10407 	const u8_t received_eap_identifier)
       
 10408 {
       
 10409 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10410 
       
 10411 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 10412 	EAP_TRACE_DEBUG(
       
 10413 		m_am_tools,
       
 10414 		TRACE_FLAGS_DEFAULT,
       
 10415 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_handshake()\n"),
       
 10416 		(m_is_client == true ? "client": "server")));
       
 10417 
       
 10418 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_handshake()");
       
 10419 
       
 10420 	eap_status_e status = eap_status_ok;
       
 10421 
       
 10422 	u32_t ind_handshake = 0ul;
       
 10423 
       
 10424 	for (ind_handshake = record->get_analyse_index()
       
 10425 			 ; ind_handshake < record->get_handshake_count()
       
 10426 			 ; ind_handshake++)
       
 10427 	{
       
 10428 		// This is used in EAP-FAST to see the next TLS-handshake message type.
       
 10429 		record->save_analyse_index(ind_handshake);
       
 10430 
       
 10431 		tls_handshake_message_c * const handshake_message = record->get_handshake(ind_handshake);
       
 10432 
       
 10433 		if (handshake_message->get_is_valid() == false)
       
 10434 		{
       
 10435 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10436 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
 10437 		}
       
 10438 
       
 10439 		EAP_TRACE_DEBUG(
       
 10440 			m_am_tools,
       
 10441 			TRACE_FLAGS_DEFAULT,
       
 10442 			(EAPL("TLS: %s: message_function: analyse_tls_protocol_handshake(): ")
       
 10443 			 EAPL("handshake type %d, analysed %d\n"),
       
 10444 			 (m_is_client == true ? "client": "server"),
       
 10445 				handshake_message->get_handshake_type(),
       
 10446 				handshake_message->get_is_analysed()));
       
 10447 
       
 10448 		if (handshake_message->get_is_analysed() == false)
       
 10449 		{
       
 10450 			handshake_message->set_is_analysed();
       
 10451 
       
 10452 			switch (handshake_message->get_handshake_type())
       
 10453 			{
       
 10454 			case tls_handshake_type_hello_request:
       
 10455 				status = analyse_handshake_type_hello_request(
       
 10456 					handshake_message);
       
 10457 				break;
       
 10458 			case tls_handshake_type_client_hello:
       
 10459 				if (m_tls_peap_test_version == true
       
 10460 					&& verify_state(tls_peap_state_tls_success) == true)
       
 10461 				{
       
 10462 					// OK, this is test version.
       
 10463 				}
       
 10464 				else if (verify_state(tls_peap_state_wait_handshake_type_client_hello) == false)
       
 10465 				{
       
 10466 					EAP_TRACE_ERROR(
       
 10467 						m_am_tools,
       
 10468 						TRACE_FLAGS_DEFAULT,
       
 10469 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10470 						 (m_is_client == true ? "client": "server"),
       
 10471 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10472 						 eap_tls_trace_string_c::get_state_string(
       
 10473 							 tls_peap_state_wait_handshake_type_client_hello)));
       
 10474 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10475 				}
       
 10476 
       
 10477 				status = analyse_handshake_type_client_hello(
       
 10478 					handshake_message);
       
 10479 				break;
       
 10480 			case tls_handshake_type_server_hello:
       
 10481 				if (verify_state(tls_peap_state_wait_handshake_type_server_hello) == false)
       
 10482 				{
       
 10483 					EAP_TRACE_ERROR(
       
 10484 						m_am_tools,
       
 10485 						TRACE_FLAGS_DEFAULT,
       
 10486 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10487 						 (m_is_client == true ? "client": "server"),
       
 10488 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10489 						 eap_tls_trace_string_c::get_state_string(
       
 10490 							 tls_peap_state_wait_handshake_type_server_hello)));
       
 10491 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10492 				}
       
 10493 
       
 10494 				status = analyse_handshake_type_server_hello(
       
 10495 					handshake_message);
       
 10496 				break;
       
 10497 			case tls_handshake_type_certificate:
       
 10498 				if (m_tls_session_type == tls_session_type_stateless_session_resumption
       
 10499 					&& verify_state(tls_peap_state_wait_change_cipher_spec) == true)
       
 10500 				{
       
 10501 					// Server wish to initiate a full handshake.
       
 10502 					m_tls_session_type = tls_session_type_full_authentication;
       
 10503 					set_state(tls_peap_state_wait_handshake_type_certificate);
       
 10504 				}
       
 10505 				else if (verify_state(tls_peap_state_wait_handshake_type_certificate) == false)
       
 10506 				{
       
 10507 					EAP_TRACE_ERROR(
       
 10508 						m_am_tools,
       
 10509 						TRACE_FLAGS_DEFAULT,
       
 10510 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10511 						 (m_is_client == true ? "client": "server"),
       
 10512 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10513 						 eap_tls_trace_string_c::get_state_string(
       
 10514 							 tls_peap_state_wait_handshake_type_certificate)));
       
 10515 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10516 				}
       
 10517 
       
 10518 				status = analyse_handshake_type_certificate(
       
 10519 					handshake_message);
       
 10520 				break;
       
 10521 			case tls_handshake_type_server_key_exchange:
       
 10522 				if (verify_state(tls_peap_state_wait_handshake_type_server_key_exchange) == false)
       
 10523 				{
       
 10524 					EAP_TRACE_ERROR(
       
 10525 						m_am_tools,
       
 10526 						TRACE_FLAGS_DEFAULT,
       
 10527 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10528 						 (m_is_client == true ? "client": "server"),
       
 10529 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10530 						 eap_tls_trace_string_c::get_state_string(
       
 10531 							 tls_peap_state_wait_handshake_type_server_key_exchange)));
       
 10532 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10533 				}
       
 10534 
       
 10535 				status = analyse_handshake_type_server_key_exchange(
       
 10536 					handshake_message);
       
 10537 				break;
       
 10538 			case tls_handshake_type_certificate_request:
       
 10539 				if (verify_state(
       
 10540 						tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done)
       
 10541 					== false)
       
 10542 				{
       
 10543 					EAP_TRACE_ERROR(
       
 10544 						m_am_tools,
       
 10545 						TRACE_FLAGS_DEFAULT,
       
 10546 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10547 						 (m_is_client == true ? "client": "server"),
       
 10548 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10549 						 eap_tls_trace_string_c::get_state_string(
       
 10550 							 tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done)));
       
 10551 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10552 				}
       
 10553 
       
 10554 				status = analyse_handshake_type_certificate_request(
       
 10555 					handshake_message);
       
 10556 				break;
       
 10557 			case tls_handshake_type_server_hello_done:
       
 10558 
       
 10559 				EAP_TRACE_DEBUG(
       
 10560 					m_am_tools,
       
 10561 					TRACE_FLAGS_DEFAULT,
       
 10562 					(EAPL("TLS: %s: message_function: analyse_tls_protocol_handshake(): m_tls_peap_server_authenticates_client_policy_flag=%d\n"),
       
 10563 					 (m_is_client == true ? "client": "server"),
       
 10564 					 m_tls_peap_server_authenticates_client_policy_flag));
       
 10565 
       
 10566 				if (verify_state(
       
 10567 						tls_peap_state_wait_handshake_type_certificate_request_or_server_hello_done)
       
 10568 					== true)
       
 10569 				{
       
 10570 					if (m_tls_peap_server_authenticates_client_policy_flag == false)
       
 10571 					{
       
 10572 						// Client accepts server only authentication.
       
 10573 						m_tls_peap_server_authenticates_client_action = false;
       
 10574 					}
       
 10575 					else
       
 10576 					{
       
 10577 						// ERROR: Client does NOT accept server only authentication.
       
 10578 						EAP_TRACE_ERROR(
       
 10579 							m_am_tools,
       
 10580 							TRACE_FLAGS_DEFAULT,
       
 10581 							(EAPL("ERROR: TLS: %s: function: current state %s: ")
       
 10582 							 EAPL("Client does NOT accept server only authentication.\n"),
       
 10583 							 (m_is_client == true ? "client": "server"),
       
 10584 							 eap_tls_trace_string_c::get_state_string(m_tls_peap_state)));
       
 10585 						return EAP_STATUS_RETURN(m_am_tools, eap_status_insufficient_security);
       
 10586 					}
       
 10587 				}
       
 10588 				else if (verify_state(tls_peap_state_wait_handshake_type_server_hello_done)
       
 10589 						 == false)
       
 10590 				{
       
 10591 					EAP_TRACE_ERROR(
       
 10592 						m_am_tools,
       
 10593 						TRACE_FLAGS_DEFAULT,
       
 10594 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10595 						 (m_is_client == true ? "client": "server"),
       
 10596 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10597 						 eap_tls_trace_string_c::get_state_string(
       
 10598 							 tls_peap_state_wait_handshake_type_server_hello_done)));
       
 10599 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10600 				}
       
 10601 
       
 10602 				status = analyse_handshake_type_server_hello_done(
       
 10603 					handshake_message);
       
 10604 				break;
       
 10605 			case tls_handshake_type_certificate_verify:
       
 10606 				if (verify_state(tls_peap_state_wait_handshake_type_certificate_verify) == false)
       
 10607 				{
       
 10608 					EAP_TRACE_ERROR(
       
 10609 						m_am_tools,
       
 10610 						TRACE_FLAGS_DEFAULT,
       
 10611 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10612 						 (m_is_client == true ? "client": "server"),
       
 10613 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10614 						 eap_tls_trace_string_c::get_state_string(
       
 10615 							 tls_peap_state_wait_handshake_type_certificate_verify)));
       
 10616 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10617 				}
       
 10618 
       
 10619 				status = analyse_handshake_type_certificate_verify(
       
 10620 					handshake_message);
       
 10621 				break;
       
 10622 			case tls_handshake_type_client_key_exchange:
       
 10623 				if (verify_state(tls_peap_state_wait_handshake_type_client_key_exchange) == false)
       
 10624 				{
       
 10625 					EAP_TRACE_ERROR(
       
 10626 						m_am_tools,
       
 10627 						TRACE_FLAGS_DEFAULT,
       
 10628 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10629 						 (m_is_client == true ? "client": "server"),
       
 10630 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10631 						 eap_tls_trace_string_c::get_state_string(
       
 10632 							 tls_peap_state_wait_handshake_type_client_key_exchange)));
       
 10633 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10634 				}
       
 10635 
       
 10636 				status = analyse_handshake_type_client_key_exchange(
       
 10637 					handshake_message);
       
 10638 				break;
       
 10639 			case tls_handshake_type_finished:
       
 10640 				if (verify_state(tls_peap_state_wait_handshake_type_finished) == false)
       
 10641 				{
       
 10642 					EAP_TRACE_ERROR(
       
 10643 						m_am_tools,
       
 10644 						TRACE_FLAGS_DEFAULT,
       
 10645 						(EAPL("ERROR: TLS: %s: function: verify_state(): current state %s != %s\n"),
       
 10646 						 (m_is_client == true ? "client": "server"),
       
 10647 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10648 						 eap_tls_trace_string_c::get_state_string(
       
 10649 							 tls_peap_state_wait_handshake_type_finished)));
       
 10650 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10651 				}
       
 10652 
       
 10653 				status = analyse_handshake_type_finished(
       
 10654 					handshake_message,
       
 10655 					received_eap_identifier);
       
 10656 				break;
       
 10657 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 10658 			case tls_handshake_type_new_session_ticket:
       
 10659 			{
       
 10660 				// Note This is optional Handshake message.
       
 10661 
       
 10662 				const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension(
       
 10663 					tls_extension_type_session_ticket,
       
 10664 					&m_supported_tls_extensions,
       
 10665 					m_am_tools);
       
 10666 
       
 10667 				if (supported_session_ticket_extension != 0
       
 10668 				&& (verify_state(tls_peap_state_wait_change_cipher_spec) == true
       
 10669 					|| verify_state(tls_peap_state_wait_handshake_type_new_session_ticket) == true))
       
 10670 				{
       
 10671 					// OK new Session ticket handshake allowed.
       
 10672 					EAP_TRACE_DEBUG(
       
 10673 						m_am_tools,
       
 10674 						TRACE_FLAGS_DEFAULT,
       
 10675 						(EAPL("TLS: %s: function: verify_state(): SST: current state %s == %s: Session Ticket Handshake allowed, length = %d.\n"),
       
 10676 						 (m_is_client == true ? "client": "server"),
       
 10677 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10678 						 eap_tls_trace_string_c::get_state_string(
       
 10679 							 tls_peap_state_wait_handshake_type_new_session_ticket),
       
 10680 						 supported_session_ticket_extension->get_data_length()));
       
 10681 				}
       
 10682 				else if (verify_state(tls_peap_state_wait_handshake_type_new_session_ticket) == false)
       
 10683 				{
       
 10684 					EAP_TRACE_ERROR(
       
 10685 						m_am_tools,
       
 10686 						TRACE_FLAGS_DEFAULT,
       
 10687 						(EAPL("ERROR: TLS: %s: function: verify_state(): SST: current state %s != %s\n"),
       
 10688 						 (m_is_client == true ? "client": "server"),
       
 10689 						 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 10690 						 eap_tls_trace_string_c::get_state_string(
       
 10691 							 tls_peap_state_wait_handshake_type_new_session_ticket)));
       
 10692 					return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
 10693 				}
       
 10694 
       
 10695 				status = analyse_handshake_type_new_session_ticket(
       
 10696 					handshake_message,
       
 10697 					received_eap_identifier);
       
 10698 				break;
       
 10699 			}
       
 10700 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 10701 			default:
       
 10702 				return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
 10703 			} // switch()
       
 10704 		}
       
 10705 
       
 10706 		if (status == eap_status_pending_request)
       
 10707 		{
       
 10708 			// Save pending state.
       
 10709 			record->save_analyse_index(ind_handshake);
       
 10710 
       
 10711 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10712 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 10713 		}
       
 10714 		else if (status != eap_status_ok)
       
 10715 		{
       
 10716 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10717 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 10718 		}
       
 10719 
       
 10720 		if ((get_is_tunneled_tls() == false
       
 10721 				&& m_tls_peap_state == tls_peap_state_tls_success)
       
 10722 			|| (get_is_tunneled_tls() == true
       
 10723 				&& m_tls_peap_state == tls_peap_state_peap_tunnel_ready))
       
 10724 		{
       
 10725 			// Stop processing TLS-records.
       
 10726 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10727 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 10728 		}
       
 10729 	} // for()
       
 10730 
       
 10731 
       
 10732 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10733 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 10734 }
       
 10735 
       
 10736 //--------------------------------------------------
       
 10737 
       
 10738 EAP_FUNC_EXPORT eap_status_e tls_record_c::analyse_tls_protocol_application_data(
       
 10739 	const tls_record_message_c * const record,
       
 10740 	const u8_t received_eap_identifier)
       
 10741 {
       
 10742 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10743 
       
 10744 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 10745 	EAP_TRACE_DEBUG(
       
 10746 		m_am_tools,
       
 10747 		TRACE_FLAGS_DEFAULT,
       
 10748 		(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_application_data()\n"),
       
 10749 		 (m_is_client == true ? "client": "server")));
       
 10750 
       
 10751 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::analyse_tls_protocol_application_data()");
       
 10752 
       
 10753 	eap_status_e status = eap_status_ok;
       
 10754 
       
 10755 	u32_t ind;
       
 10756 	for (ind = 0ul
       
 10757 			; ind < record->get_application_data_count()
       
 10758 			; ind++)
       
 10759 	{
       
 10760 		tls_application_data_message_c * const application_data_message
       
 10761 			= record->get_application_data(ind);
       
 10762 		if (application_data_message == 0
       
 10763 			|| application_data_message->get_is_valid() == false)
       
 10764 		{
       
 10765 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10766 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 10767 		}
       
 10768 
       
 10769 		if (application_data_message->get_is_analysed() == false)
       
 10770 		{
       
 10771 			application_data_message->set_is_analysed();
       
 10772 
       
 10773 			if (m_application == 0)
       
 10774 			{
       
 10775 				// ERROR: No application.
       
 10776 				EAP_TRACE_DEBUG(
       
 10777 					m_am_tools,
       
 10778 					TRACE_FLAGS_DEFAULT,
       
 10779 					(EAPL("ERROR: TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_application_data(): no application.\n"),
       
 10780 					 (m_is_client == true ? "client": "server")));
       
 10781 				status = eap_status_illegal_data_payload;
       
 10782 			}
       
 10783 			else
       
 10784 			{
       
 10785 				status = m_application->packet_process(
       
 10786 					application_data_message->get_application_data(),
       
 10787 					received_eap_identifier);
       
 10788 			}
       
 10789 
       
 10790 			if (status != eap_status_ok)
       
 10791 			{
       
 10792 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10793 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 10794 			}
       
 10795 		}
       
 10796 		else
       
 10797 		{
       
 10798 			EAP_TRACE_DEBUG(
       
 10799 				m_am_tools,
       
 10800 				TRACE_FLAGS_DEFAULT,
       
 10801 				(EAPL("TLS: %s: message_function: starts: tls_record_c::analyse_tls_protocol_application_data(): already analysed.\n"),
       
 10802 				 (m_is_client == true ? "client": "server")));
       
 10803 		}
       
 10804 	}
       
 10805 
       
 10806 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10807 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 10808 }
       
 10809 
       
 10810 //--------------------------------------------------
       
 10811 
       
 10812 EAP_FUNC_EXPORT eap_status_e tls_record_c::are_pending_queries_completed()
       
 10813 {
       
 10814 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10815 
       
 10816 	eap_status_e status = eap_status_pending_request;
       
 10817 
       
 10818 	eap_status_string_c status_string;
       
 10819 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 10820 	EAP_TRACE_DEBUG(
       
 10821 		m_am_tools,
       
 10822 		TRACE_FLAGS_DEFAULT,
       
 10823 		(EAPL("TLS: %s: pending_function: starts: tls_record_c::are_pending_queries_completed(): %s\n"),
       
 10824 		(m_is_client == true ? "client": "server"),
       
 10825 		status_string.get_status_string(status)));
       
 10826 
       
 10827 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::are_pending_queries_completed()");
       
 10828 
       
 10829 	if (m_pending_query_certificate_authorities_and_types == false
       
 10830 		&& m_pending_query_certificate_chain == false
       
 10831 		&& m_pending_query_cipher_suites_and_previous_session == false
       
 10832 		&& m_pending_query_dh_parameters == false
       
 10833 		&& m_pending_query_realm == false
       
 10834 		&& m_pending_select_cipher_suite_and_check_session_id == false
       
 10835 		&& m_pending_verify_certificate_chain == false
       
 10836 		&& m_pending_rsa_decrypt_with_private_key == false
       
 10837 		&& m_pending_rsa_encrypt_with_public_key == false
       
 10838 		&& m_pending_sign_with_private_key == false
       
 10839 		&& m_pending_verify_with_public_key == false
       
 10840 		&& m_pending_query_tunnel_PAC == false)
       
 10841 	{
       
 10842 		status = eap_status_ok;
       
 10843 	}
       
 10844 
       
 10845 	EAP_TRACE_DEBUG(
       
 10846 		m_am_tools,
       
 10847 		TRACE_FLAGS_DEFAULT,
       
 10848 		(EAPL("TLS: %s: pending_function: are_pending_queries_completed(): %s\n"),
       
 10849 		(m_is_client == true ? "client": "server"),
       
 10850 		status_string.get_status_string(status)));
       
 10851 
       
 10852 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10853 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 10854 }
       
 10855 
       
 10856 //--------------------------------------------------
       
 10857 
       
 10858 EAP_FUNC_EXPORT eap_status_e tls_record_c::indicate_state_to_lower_layer(
       
 10859 	const tls_peap_state_e indicated_state)
       
 10860 {
       
 10861 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10862 
       
 10863 	// Notify lower layer the state of TLS.
       
 10864 
       
 10865 	EAP_TRACE_DEBUG(
       
 10866 		m_am_tools,
       
 10867 		TRACE_FLAGS_DEFAULT,
       
 10868 		(EAPL("TLS: %s: state_function: starts: tls_record_c::indicate_state_to_lower_layer(): m_tls_session_type=%d=%s, state=%d=%s\n"),
       
 10869 		(m_is_client == true ? "client": "server"),
       
 10870 		m_tls_session_type,
       
 10871 		eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 10872 		indicated_state,
       
 10873 		eap_tls_trace_string_c::get_state_string(indicated_state)));
       
 10874 
       
 10875 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::indicate_state_to_lower_layer()");
       
 10876 
       
 10877 
       
 10878 #if defined(USE_EAP_TRACE_ALWAYS)
       
 10879 
       
 10880 	if (m_tls_peap_state == tls_peap_state_tls_success)
       
 10881 	{
       
 10882 
       
 10883 		tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = 
       
 10884 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 10885 			m_tls_identity_privacy_handshake_state;
       
 10886 #else
       
 10887 			tls_identity_privacy_handshake_state_none;
       
 10888 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 10889 
       
 10890 		EAP_TRACE_ALWAYS(
       
 10891 			m_am_tools,
       
 10892 			TRACE_FLAGS_DEFAULT,
       
 10893 			(EAPL("%s: indicate_state_to_lower_layer(): TLS/PEAP authentication ")
       
 10894 			 EAPL("SUCCESS: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s, %s\n"),
       
 10895 			 (m_is_client == true ? "client": "server"),
       
 10896 			 (m_tls_peap_server_authenticates_client_action == true
       
 10897 			  ? "mutual": "anonymous client"),
       
 10898 			 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 10899 			 get_is_tunneled_tls(),
       
 10900 			 eap_header_string_c::get_eap_type_string(m_eap_type),
       
 10901 			 eap_tls_trace_string_c::get_peap_version_string(m_peap_version),
       
 10902 			 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite),
       
 10903 			 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 10904 	}
       
 10905 	else if (m_tls_peap_state == tls_peap_state_peap_tunnel_ready
       
 10906 		|| m_tls_peap_state == tls_peap_state_wait_application_data)
       
 10907 	{
       
 10908 		EAP_TRACE_ALWAYS(
       
 10909 			m_am_tools,
       
 10910 			TRACE_FLAGS_DEFAULT,
       
 10911 			(EAPL("%s: indicate_state_to_lower_layer(): TLS/PEAP authentication ")
       
 10912 			 EAPL("tunnel ready: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s\n"),
       
 10913 			 (m_is_client == true ? "client": "server"),
       
 10914 			 (m_tls_peap_server_authenticates_client_action == true
       
 10915 			  ? "mutual": "anonymous client"),
       
 10916 			 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 10917 			 get_is_tunneled_tls(),
       
 10918 			 eap_header_string_c::get_eap_type_string(m_eap_type),
       
 10919 			 eap_tls_trace_string_c::get_peap_version_string(m_peap_version),
       
 10920 			 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite)));
       
 10921 
       
 10922 	}
       
 10923 	else if (m_tls_peap_state == tls_peap_state_failure)
       
 10924 	{
       
 10925 		EAP_TRACE_ERROR(
       
 10926 			m_am_tools,
       
 10927 			TRACE_FLAGS_DEFAULT,
       
 10928 			(EAPL("%s: indicate_state_to_lower_layer(): TLS/PEAP authentication ")
       
 10929 			 EAPL("FAILED: %s, %s, tunnel %d, tunneling type %s, tunneling version %s, cipher_suite %s\n"),
       
 10930 			 (m_is_client == true ? "client": "server"),
       
 10931 			 (m_tls_peap_server_authenticates_client_action == true ? "mutual": "anonymous client"),
       
 10932 			 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 10933 			 get_is_tunneled_tls(),
       
 10934 			 eap_header_string_c::get_eap_type_string(m_eap_type),
       
 10935 			 eap_tls_trace_string_c::get_peap_version_string(m_peap_version),
       
 10936 			 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite)));
       
 10937 	}
       
 10938 
       
 10939 #endif //#if !defined(USE_EAP_TRACE_ALWAYS)
       
 10940 
       
 10941 	
       
 10942 	eap_state_notification_c notification(
       
 10943 		m_am_tools,
       
 10944 		&m_send_network_id,
       
 10945 		m_is_client,
       
 10946 		eap_state_notification_generic,
       
 10947 		eap_protocol_layer_internal_type,
       
 10948 		0,
       
 10949 		tls_peap_state_none,
       
 10950 		indicated_state,
       
 10951 		0,
       
 10952 		false);
       
 10953 	get_type_partner()->state_notification(&notification);
       
 10954 
       
 10955 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10956 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
 10957 }
       
 10958 
       
 10959 //--------------------------------------------------
       
 10960 
       
 10961 EAP_FUNC_EXPORT eap_status_e tls_record_c::indicate_messages_processed()
       
 10962 {
       
 10963 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10964 
       
 10965 	// Notify lower layer that TLS-messages are processed.
       
 10966 
       
 10967 	EAP_TRACE_DEBUG(
       
 10968 		m_am_tools,
       
 10969 		TRACE_FLAGS_DEFAULT,
       
 10970 		(EAPL("TLS: %s: state_function: starts: tls_record_c::indicate_messages_processed(): %s\n"),
       
 10971 		(m_is_client == true ? "client": "server"),
       
 10972 		eap_tls_trace_string_c::get_state_string(m_tls_peap_state)));
       
 10973 
       
 10974 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::indicate_messages_processed()");
       
 10975 
       
 10976 	eap_state_notification_c notification(
       
 10977 		m_am_tools,
       
 10978 		&m_send_network_id,
       
 10979 		m_is_client,
       
 10980 		eap_state_notification_generic,
       
 10981 		eap_protocol_layer_internal_type,
       
 10982 		0,
       
 10983 		tls_peap_state_none,
       
 10984 		tls_peap_state_pending_tls_messages_processed,
       
 10985 		0,
       
 10986 		false);
       
 10987 	get_type_partner()->state_notification(&notification);
       
 10988 
       
 10989 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10990 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
 10991 }
       
 10992 
       
 10993 //--------------------------------------------------
       
 10994 
       
 10995 EAP_FUNC_EXPORT eap_status_e tls_record_c::send_tls_message()
       
 10996 {
       
 10997 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 10998 	
       
 10999 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11000 	EAP_TRACE_DEBUG(
       
 11001 		m_am_tools,
       
 11002 		TRACE_FLAGS_DEFAULT,
       
 11003 		(EAPL("TLS: %s: send_function: starts: tls_record_c::send_tls_message()\n"),
       
 11004 		 (m_is_client == true ? "client": "server")));
       
 11005 
       
 11006 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::send_tls_message()");
       
 11007 
       
 11008 	eap_variable_data_c tls_message_buffer(m_am_tools);
       
 11009 
       
 11010 	bool includes_tls_handshake_message = false;
       
 11011 
       
 11012 	eap_status_e status = m_new_tls_message.add_message_data(
       
 11013 		&tls_message_buffer,
       
 11014 		&includes_tls_handshake_message);
       
 11015 	if (status != eap_status_ok)
       
 11016 	{
       
 11017 		m_new_tls_message.reset();
       
 11018 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11019 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11020 	}
       
 11021 
       
 11022 	// --------------------------------------------------------------------
       
 11023 
       
 11024 	eap_buf_chain_wr_c sent_packet(
       
 11025 		eap_write_buffer,
       
 11026 		m_am_tools,
       
 11027 		tls_message_buffer.get_data(tls_message_buffer.get_data_length()),
       
 11028 		tls_message_buffer.get_data_length(),
       
 11029 		false,
       
 11030 		false,
       
 11031 		0ul);
       
 11032 	if (sent_packet.get_is_valid() == false)
       
 11033 	{
       
 11034 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 11035 	}
       
 11036 	
       
 11037 	EAP_TRACE_DATA_DEBUG(
       
 11038 		m_am_tools,
       
 11039 		EAP_TRACE_FLAGS_MESSAGE_DATA,
       
 11040 		(EAPL("send TLS-message"),
       
 11041 		 sent_packet.get_data(sent_packet.get_data_length()),
       
 11042 		 sent_packet.get_data_length()));
       
 11043 	
       
 11044 	status = get_type_partner()->tls_peap_packet_send(
       
 11045 		&sent_packet,
       
 11046 		0ul,
       
 11047 		sent_packet.get_data_length(),
       
 11048 		sent_packet.get_data_length(),
       
 11049 		includes_tls_handshake_message
       
 11050 		);
       
 11051 
       
 11052 	m_new_tls_message.reset();
       
 11053 	
       
 11054 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11055 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11056 }
       
 11057 
       
 11058 //--------------------------------------------------
       
 11059 
       
 11060 EAP_FUNC_EXPORT eap_status_e tls_record_c::check_sent_tls_message()
       
 11061 {
       
 11062 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11063 
       
 11064 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11065 	EAP_TRACE_DEBUG(
       
 11066 		m_am_tools,
       
 11067 		TRACE_FLAGS_DEFAULT,
       
 11068 		(EAPL("TLS: %s: send_function: starts: tls_record_c::check_sent_tls_message()\n"),
       
 11069 		(m_is_client == true ? "client": "server")));
       
 11070 
       
 11071 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::check_sent_tls_message()");
       
 11072 
       
 11073 	eap_status_e msg_status = eap_status_authentication_failure;
       
 11074 
       
 11075 	if (m_already_in_completion_action_check == true)
       
 11076 	{
       
 11077 		// This is recursive call. Do not process yet.
       
 11078 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11079 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
 11080 	}
       
 11081 
       
 11082 	if (m_force_tls_message_send == true)
       
 11083 	{
       
 11084 		// There may be an alert message pending.
       
 11085 		msg_status = send_tls_message();
       
 11086 	}
       
 11087 	else
       
 11088 	{
       
 11089 		msg_status = are_pending_queries_completed();
       
 11090 		if (msg_status == eap_status_ok)
       
 11091 		{
       
 11092 			eap_status_e compl_status = completion_action_check();
       
 11093 
       
 11094 			if (compl_status == eap_status_pending_request)
       
 11095 			{
       
 11096 				// Some asyncronous query is still pending.
       
 11097 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11098 				return EAP_STATUS_RETURN(m_am_tools, compl_status);
       
 11099 			}
       
 11100 			else if (compl_status != eap_status_ok)
       
 11101 			{
       
 11102 				// There may be Alert message to be sent.
       
 11103 				msg_status = compl_status;
       
 11104 			}
       
 11105 
       
 11106 
       
 11107 			if (m_allow_message_send == true)
       
 11108 			{
       
 11109 				if (msg_status == eap_status_ok
       
 11110 					&& m_new_tls_message.get_record_message_count() > 0ul)
       
 11111 				{
       
 11112 					// We could send the pending TLS-messages.
       
 11113 					msg_status = send_tls_message();
       
 11114 				}
       
 11115 				else if (m_force_tls_message_send == true // There may be Alert message to be sent.
       
 11116 					&& m_new_tls_message.get_record_message_count() > 0ul)
       
 11117 				{
       
 11118 					// We could send the pending TLS-messages.
       
 11119 					send_tls_message();
       
 11120 				}
       
 11121 				else
       
 11122 				{
       
 11123 					// No message to sent.
       
 11124 					EAP_TRACE_DEBUG(
       
 11125 						m_am_tools,
       
 11126 						TRACE_FLAGS_DEFAULT,
       
 11127 						(EAPL("TLS: %s: send_function: check_sent_tls_message(), ")
       
 11128 						 EAPL("No message to sent.\n"),
       
 11129 						(m_is_client == true ? "client": "server")));
       
 11130 				}
       
 11131 			}
       
 11132 
       
 11133 			if (msg_status == eap_status_ok
       
 11134 				&& m_allow_message_send == true)
       
 11135 			{
       
 11136 				eap_status_e indication_status = indicate_messages_processed();
       
 11137 				if (indication_status != eap_status_ok)
       
 11138 				{
       
 11139 					// This is an error case.
       
 11140 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11141 					return EAP_STATUS_RETURN(m_am_tools, indication_status);
       
 11142 				}
       
 11143 			}
       
 11144 		}
       
 11145 	}
       
 11146 
       
 11147 
       
 11148 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11149 	return EAP_STATUS_RETURN(m_am_tools, msg_status);
       
 11150 }
       
 11151 
       
 11152 //--------------------------------------------------
       
 11153 
       
 11154 EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_init()
       
 11155 {
       
 11156 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11157 
       
 11158 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11159 	EAP_TRACE_DEBUG(
       
 11160 		m_am_tools,
       
 11161 		TRACE_FLAGS_DEFAULT,
       
 11162 		(EAPL("TLS: %s:    hash_function: starts: tls_record_c::message_hash_init()\n"),
       
 11163 		(m_is_client == true ? "client": "server")));
       
 11164 
       
 11165 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_init()");
       
 11166 
       
 11167 	eap_status_e status = eap_status_not_supported;
       
 11168 
       
 11169 	status = m_message_hash_md5.hash_init();
       
 11170 	if (status != eap_status_ok)
       
 11171 	{
       
 11172 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11173 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11174 	}
       
 11175 
       
 11176 	status = m_message_hash_sha1.hash_init();
       
 11177 	if (status != eap_status_ok)
       
 11178 	{
       
 11179 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11180 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11181 	}
       
 11182 
       
 11183 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11184 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11185 }
       
 11186 
       
 11187 //--------------------------------------------------
       
 11188 
       
 11189 EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_update(
       
 11190 	const bool true_when_parse_message,
       
 11191 	const tls_handshake_type_e type,
       
 11192 	u8_t * const tls_packet,
       
 11193 	const u32_t tls_packet_length)
       
 11194 {
       
 11195 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11196 	
       
 11197 #if !defined(USE_EAP_DEBUG_TRACE)
       
 11198 EAP_UNREFERENCED_PARAMETER(true_when_parse_message);
       
 11199 EAP_UNREFERENCED_PARAMETER(type);
       
 11200 #endif
       
 11201 
       
 11202 	eap_status_e status = eap_status_not_supported;
       
 11203 
       
 11204 	EAP_TRACE_DEBUG(
       
 11205 		m_am_tools, 
       
 11206 		TRACE_FLAGS_DEFAULT, 
       
 11207 		(EAPL("\n")));
       
 11208 	EAP_TRACE_DEBUG(
       
 11209 		m_am_tools, 
       
 11210 		TRACE_FLAGS_DEFAULT, 
       
 11211 		(EAPL("TLS: %s:    hash_function: starts: tls_record_c::message_hash_update(): handshake type %s, %s\n"),
       
 11212 		 (m_is_client == true ? "client": "server"),
       
 11213 		 tls_handshake_header_c::get_tls_handshake_string(type),
       
 11214 		 (true_when_parse_message == true ? "parse": "create")));
       
 11215 
       
 11216 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_update()");
       
 11217 
       
 11218 	EAP_TRACE_DATA_DEBUG(
       
 11219 		m_am_tools, 
       
 11220 		EAP_TRACE_FLAGS_MESSAGE_DATA, 
       
 11221 		(EAPL("TLS: message_hash_update()"),
       
 11222 		 tls_packet,
       
 11223 		 tls_packet_length));
       
 11224 
       
 11225 	if (tls_packet == 0
       
 11226 		|| tls_packet_length == 0ul)
       
 11227 	{
       
 11228 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11229 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
 11230 	}
       
 11231 
       
 11232 	status = m_message_hash_md5.hash_update(tls_packet, tls_packet_length);
       
 11233 	if (status != eap_status_ok)
       
 11234 	{
       
 11235 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11236 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11237 	}
       
 11238 
       
 11239 	status = m_message_hash_sha1.hash_update(tls_packet, tls_packet_length);
       
 11240 	if (status != eap_status_ok)
       
 11241 	{
       
 11242 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11243 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11244 	}
       
 11245 
       
 11246 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11247 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11248 }
       
 11249 
       
 11250 //--------------------------------------------------
       
 11251 
       
 11252 EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_create(
       
 11253 	const bool true_when_parse_message,
       
 11254 	const tls_handshake_type_e type,
       
 11255 	eap_variable_data_c * const message_hash,
       
 11256 	const bool client_originated)
       
 11257 {
       
 11258 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11259 	
       
 11260 #if !defined(USE_EAP_DEBUG_TRACE)
       
 11261 EAP_UNREFERENCED_PARAMETER(true_when_parse_message);
       
 11262 #endif
       
 11263 
       
 11264 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11265 	EAP_TRACE_DEBUG(
       
 11266 		m_am_tools,
       
 11267 		TRACE_FLAGS_DEFAULT,
       
 11268 		(EAPL("TLS: %s:    hash_function: starts: tls_record_c::message_hash_create(): handshake type %s, %s\n"),
       
 11269 		(m_is_client == true ? "client": "server"),
       
 11270 		tls_handshake_header_c::get_tls_handshake_string(type),
       
 11271 		(true_when_parse_message == true ? "parse": "create")));
       
 11272 
       
 11273 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_create()");
       
 11274 
       
 11275 	eap_status_e status = eap_status_not_supported;
       
 11276 
       
 11277 	eap_variable_data_c * message_hash_md5 = 0;
       
 11278 	eap_variable_data_c * message_hash_sha1 = 0;
       
 11279 
       
 11280 	if (type == tls_handshake_type_certificate_verify)
       
 11281 	{
       
 11282 		message_hash_md5 = &m_message_hash_md5_certificate_verify;
       
 11283 		message_hash_sha1 = &m_message_hash_sha1_certificate_verify;
       
 11284 	}
       
 11285 	else if (type == tls_handshake_type_finished)
       
 11286 	{
       
 11287 		if (client_originated == true)
       
 11288 		{
       
 11289 			message_hash_md5 = &m_client_message_hash_md5_finished;
       
 11290 			message_hash_sha1 = &m_client_message_hash_sha1_finished;
       
 11291 		}
       
 11292 		else
       
 11293 		{
       
 11294 			message_hash_md5 = &m_server_message_hash_md5_finished;
       
 11295 			message_hash_sha1 = &m_server_message_hash_sha1_finished;
       
 11296 		}
       
 11297 	}
       
 11298 	else
       
 11299 	{
       
 11300 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11301 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_type);
       
 11302 	}
       
 11303 
       
 11304 	u32_t md5_digest_length = message_hash_md5->get_data_length();
       
 11305 
       
 11306 	u32_t sha1_digest_length = message_hash_sha1->get_data_length();
       
 11307 
       
 11308 	if (cipher_suite_is_TLS_DHE_DSS() == true)
       
 11309 	{
       
 11310 		md5_digest_length = 0ul;
       
 11311 	}
       
 11312 
       
 11313 	status = message_hash->set_buffer_length(md5_digest_length+sha1_digest_length);
       
 11314 	if (status != eap_status_ok)
       
 11315 	{
       
 11316 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11317 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11318 	}
       
 11319 	message_hash->set_data_length(0ul);
       
 11320 
       
 11321 
       
 11322 
       
 11323 	if (type == tls_handshake_type_certificate_verify)
       
 11324 	{
       
 11325 		if (cipher_suite_is_TLS_RSA() == true
       
 11326 			|| cipher_suite_is_TLS_DHE_RSA() == true)
       
 11327 		{
       
 11328 			status = message_hash->add_data(message_hash_md5);
       
 11329 			if (status != eap_status_ok)
       
 11330 			{
       
 11331 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11332 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 11333 			}
       
 11334 		}
       
 11335 
       
 11336 		if (cipher_suite_is_TLS_RSA() == true
       
 11337 			|| cipher_suite_is_TLS_DHE_DSS() == true
       
 11338 			|| cipher_suite_is_TLS_DHE_RSA() == true)
       
 11339 		{
       
 11340 			status = message_hash->add_data(message_hash_sha1);
       
 11341 			if (status != eap_status_ok)
       
 11342 			{
       
 11343 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11344 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 11345 			}
       
 11346 		}
       
 11347 	}
       
 11348 	else if (type == tls_handshake_type_finished)
       
 11349 	{
       
 11350 		status = message_hash->add_data(message_hash_md5);
       
 11351 		if (status != eap_status_ok)
       
 11352 		{
       
 11353 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11354 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 11355 		}
       
 11356 
       
 11357 		status = message_hash->add_data(message_hash_sha1);
       
 11358 		if (status != eap_status_ok)
       
 11359 		{
       
 11360 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11361 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 11362 		}
       
 11363 	}
       
 11364 
       
 11365 	EAP_TRACE_DATA_DEBUG(
       
 11366 		m_am_tools, 
       
 11367 		TRACE_FLAGS_DEFAULT, 
       
 11368 		(EAPL("TLS: message_hash_create(): message_hash"),
       
 11369 		 message_hash->get_data(message_hash->get_data_length()),
       
 11370 		 message_hash->get_data_length()));
       
 11371 
       
 11372 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11373 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11374 }
       
 11375 
       
 11376 //--------------------------------------------------
       
 11377 
       
 11378 EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_final(
       
 11379 	eap_variable_data_c * const md5_digest,
       
 11380 	eap_variable_data_c * const sha1_digest)
       
 11381 {
       
 11382 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11383 
       
 11384 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11385 	EAP_TRACE_DEBUG(
       
 11386 		m_am_tools,
       
 11387 		TRACE_FLAGS_DEFAULT,
       
 11388 		(EAPL("TLS: %s:    hash_function: starts: tls_record_c::message_hash_final()\n"),
       
 11389 		(m_is_client == true ? "client": "server")));
       
 11390 
       
 11391 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_final()");
       
 11392 
       
 11393 	eap_status_e status = eap_status_process_general_error;
       
 11394 
       
 11395 	if (md5_digest == 0
       
 11396 		|| sha1_digest == 0)
       
 11397 	{
       
 11398 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11399 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 11400 	}
       
 11401 
       
 11402 
       
 11403 	{
       
 11404 		// The copy of hash context saves original hash context for later use. 
       
 11405 		// This way we do need store only one SHA1 and MD5 context for all handshake message hashes.
       
 11406 		abs_crypto_hash_algorithm_c * const copy_message_hash_md5 = m_message_hash_md5.copy();
       
 11407 
       
 11408 		eap_automatic_variable_c<abs_crypto_hash_algorithm_c>
       
 11409 			deletes_copy_message_hash_md5(m_am_tools, copy_message_hash_md5);
       
 11410 
       
 11411 		if (copy_message_hash_md5 == 0
       
 11412 			|| copy_message_hash_md5->get_is_valid() == false)
       
 11413 		{
       
 11414 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11415 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 11416 		}
       
 11417 
       
 11418 		status = md5_digest->set_buffer_length(copy_message_hash_md5->get_digest_length());
       
 11419 		if (status != eap_status_ok)
       
 11420 		{
       
 11421 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11422 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 11423 		}
       
 11424 		md5_digest->set_data_length(copy_message_hash_md5->get_digest_length());
       
 11425 
       
 11426 		u32_t digest_length = md5_digest->get_data_length();
       
 11427 
       
 11428 		status = copy_message_hash_md5->hash_final(
       
 11429 			md5_digest->get_data(md5_digest->get_data_length()),
       
 11430 			&digest_length);
       
 11431 		if (digest_length != copy_message_hash_md5->get_digest_length())
       
 11432 		{
       
 11433 			status = eap_status_process_general_error;
       
 11434 		}
       
 11435 		if (status != eap_status_ok)
       
 11436 		{
       
 11437 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11438 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 11439 		}
       
 11440 	}
       
 11441 
       
 11442 
       
 11443 	{
       
 11444 		// The copy of hash context saves original hash context for later use. 
       
 11445 		// This way we do need store only one SHA1 and MD5 context for all handshake message hashes.
       
 11446 		abs_crypto_hash_algorithm_c * const copy_message_hash_sha1 = m_message_hash_sha1.copy();
       
 11447 
       
 11448 		eap_automatic_variable_c<abs_crypto_hash_algorithm_c>
       
 11449 			deletes_copy_message_hash_sha1(m_am_tools, copy_message_hash_sha1);
       
 11450 
       
 11451 		if (copy_message_hash_sha1 == 0
       
 11452 			|| copy_message_hash_sha1->get_is_valid() == false)
       
 11453 		{
       
 11454 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11455 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 11456 		}
       
 11457 
       
 11458 		status = sha1_digest->set_buffer_length(copy_message_hash_sha1->get_digest_length());
       
 11459 		if (status != eap_status_ok)
       
 11460 		{
       
 11461 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11462 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 11463 		}
       
 11464 		sha1_digest->set_data_length(copy_message_hash_sha1->get_digest_length());
       
 11465 
       
 11466 		u32_t digest_length = sha1_digest->get_data_length();
       
 11467 
       
 11468 		status = copy_message_hash_sha1->hash_final(
       
 11469 			sha1_digest->get_data(sha1_digest->get_data_length()),
       
 11470 			&digest_length);
       
 11471 		if (digest_length != copy_message_hash_sha1->get_digest_length())
       
 11472 		{
       
 11473 			status = eap_status_process_general_error;
       
 11474 		}
       
 11475 		if (status != eap_status_ok)
       
 11476 		{
       
 11477 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11478 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 11479 		}
       
 11480 	}
       
 11481 
       
 11482 
       
 11483 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11484 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11485 }
       
 11486 
       
 11487 //--------------------------------------------------
       
 11488 
       
 11489 EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_save_certificate_verify()
       
 11490 {
       
 11491 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11492 
       
 11493 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11494 	EAP_TRACE_DEBUG(
       
 11495 		m_am_tools,
       
 11496 		TRACE_FLAGS_DEFAULT,
       
 11497 		(EAPL("TLS: %s:    hash_function: starts: tls_record_c::message_hash_save_certificate_verify()\n"),
       
 11498 		(m_is_client == true ? "client": "server")));
       
 11499 
       
 11500 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_save_certificate_verify()");
       
 11501 
       
 11502 	eap_status_e status = eap_status_process_general_error;
       
 11503 
       
 11504 	status = message_hash_final(
       
 11505 		&m_message_hash_md5_certificate_verify,
       
 11506 		&m_message_hash_sha1_certificate_verify);
       
 11507 
       
 11508 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11509 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11510 }
       
 11511 
       
 11512 //--------------------------------------------------
       
 11513 
       
 11514 EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_save_finished(
       
 11515 	const bool client_originated)
       
 11516 {
       
 11517 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11518 
       
 11519 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11520 	EAP_TRACE_DEBUG(
       
 11521 		m_am_tools,
       
 11522 		TRACE_FLAGS_DEFAULT,
       
 11523 		(EAPL("TLS: %s:    hash_function: starts: tls_record_c::message_hash_save_finished()\n"),
       
 11524 		(m_is_client == true ? "client": "server")));
       
 11525 
       
 11526 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_save_finished()");
       
 11527 
       
 11528 	eap_variable_data_c *message_hash_md5_finished = &m_client_message_hash_md5_finished;
       
 11529 	eap_variable_data_c *message_hash_sha1_finished = &m_client_message_hash_sha1_finished;
       
 11530 
       
 11531 	eap_status_e status = eap_status_process_general_error;
       
 11532 
       
 11533 
       
 11534 	if (client_originated == false)
       
 11535 	{
       
 11536 		message_hash_md5_finished = &m_server_message_hash_md5_finished;
       
 11537 		message_hash_sha1_finished = &m_server_message_hash_sha1_finished;
       
 11538 	}
       
 11539 
       
 11540 	status = message_hash_final(
       
 11541 		message_hash_md5_finished,
       
 11542 		message_hash_sha1_finished);
       
 11543 
       
 11544 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11545 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11546 }
       
 11547 
       
 11548 //--------------------------------------------------
       
 11549 
       
 11550 EAP_FUNC_EXPORT eap_status_e tls_record_c::message_hash_create_finished(
       
 11551 	const bool client_originated_message,
       
 11552 	eap_variable_data_c * const message_hash)
       
 11553 {
       
 11554 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11555 
       
 11556 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11557 	EAP_TRACE_DEBUG(
       
 11558 		m_am_tools,
       
 11559 		TRACE_FLAGS_DEFAULT,
       
 11560 		(EAPL("TLS: %s:    hash_function: starts: tls_record_c::message_hash_create_finished()\n"),
       
 11561 		(m_is_client == true ? "client": "server")));
       
 11562 
       
 11563 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::message_hash_create_finished()");
       
 11564 
       
 11565 	eap_status_e status = eap_status_not_supported;
       
 11566 
       
 11567 	eap_variable_data_c label_finished(m_am_tools);
       
 11568 	if (label_finished.get_is_valid() == false)
       
 11569 	{
       
 11570 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 11571 	}
       
 11572 
       
 11573 	if (client_originated_message == true)
       
 11574 	{
       
 11575 		status = label_finished.add_data(
       
 11576 			TLS_CLIENT_FINISHED_LABEL,
       
 11577 			TLS_CLIENT_FINISHED_LABEL_LENGTH);
       
 11578 	}
       
 11579 	else
       
 11580 	{
       
 11581 		status = label_finished.add_data(
       
 11582 			TLS_SERVER_FINISHED_LABEL,
       
 11583 			TLS_SERVER_FINISHED_LABEL_LENGTH);
       
 11584 	}
       
 11585 
       
 11586 	if (status != eap_status_ok)
       
 11587 	{
       
 11588 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11589 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11590 	}
       
 11591 
       
 11592 	eap_variable_data_c hash(m_am_tools);
       
 11593 	if (hash.get_is_valid() == false)
       
 11594 	{
       
 11595 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 11596 	}
       
 11597 
       
 11598 	status = message_hash_create(
       
 11599 		false,
       
 11600 		tls_handshake_type_finished,
       
 11601 		&hash,
       
 11602 		client_originated_message);
       
 11603 	if (status != eap_status_ok)
       
 11604 	{
       
 11605 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11606 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11607 	}
       
 11608 
       
 11609 
       
 11610 	EAP_TRACE_DATA_DEBUG(
       
 11611 		m_am_tools,
       
 11612 		TRACE_FLAGS_DEFAULT,
       
 11613 		(EAPL("TLS: message_hash_create_finished(): m_master_secret"),
       
 11614 		m_master_secret.get_data(),
       
 11615 		m_master_secret.get_data_length()));
       
 11616 
       
 11617 	EAP_TRACE_DATA_DEBUG(
       
 11618 		m_am_tools,
       
 11619 		TRACE_FLAGS_DEFAULT,
       
 11620 		(EAPL("TLS: message_hash_create_finished(): label_finished"),
       
 11621 		label_finished.get_data(),
       
 11622 		label_finished.get_data_length()));
       
 11623 
       
 11624 	EAP_TRACE_DATA_DEBUG(
       
 11625 		m_am_tools,
       
 11626 		TRACE_FLAGS_DEFAULT,
       
 11627 		(EAPL("TLS: message_hash_create_finished(): hash"),
       
 11628 		hash.get_data(),
       
 11629 		hash.get_data_length()));
       
 11630 
       
 11631 
       
 11632 	EAP_TRACE_DEBUG(
       
 11633 		m_am_tools,
       
 11634 		TRACE_FLAGS_DEFAULT,
       
 11635 		(EAPL("TLS: %s:     prf_function: tls_prf.tls_prf_output()\n"),
       
 11636 		(m_is_client == true ? "client": "server")));
       
 11637 
       
 11638 	crypto_tls_prf_c tls_prf(m_am_tools);
       
 11639 
       
 11640 	status = tls_prf.tls_prf_init(
       
 11641 		&m_master_secret,
       
 11642 		&label_finished,
       
 11643 		&hash);
       
 11644 	if (status != eap_status_ok)
       
 11645 	{
       
 11646 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11647 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11648 	}
       
 11649 
       
 11650 	status = message_hash->set_buffer_length(TLS_FINISHED_DATA_SIZE);
       
 11651 	if (status != eap_status_ok)
       
 11652 	{
       
 11653 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11654 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11655 	}
       
 11656 	message_hash->set_data_length(TLS_FINISHED_DATA_SIZE);
       
 11657 
       
 11658 	status = tls_prf.tls_prf_output(
       
 11659 		message_hash->get_data(message_hash->get_data_length()),
       
 11660 		message_hash->get_data_length());
       
 11661 	if (status != eap_status_ok)
       
 11662 	{
       
 11663 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11664 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11665 	}
       
 11666 
       
 11667 	EAP_TRACE_DATA_DEBUG(
       
 11668 		m_am_tools,
       
 11669 		TRACE_FLAGS_DEFAULT,
       
 11670 		(EAPL("TLS: message_hash_create_finished(): message hash"),
       
 11671 		message_hash->get_data(),
       
 11672 		message_hash->get_data_length()));
       
 11673 
       
 11674 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11675 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11676 }
       
 11677 
       
 11678 //--------------------------------------------------
       
 11679 
       
 11680 EAP_FUNC_EXPORT eap_status_e tls_record_c::packet_process(
       
 11681 	eap_variable_data_c * const tls_packet,
       
 11682 	const u8_t received_eap_identifier)
       
 11683 {
       
 11684 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11685 
       
 11686 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11687 
       
 11688 	tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = 
       
 11689 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 11690 		m_tls_identity_privacy_handshake_state;
       
 11691 #else
       
 11692 		tls_identity_privacy_handshake_state_none;
       
 11693 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 11694 	EAP_UNREFERENCED_PARAMETER(tmp_identity_privacy_handshake_state);
       
 11695 
       
 11696 	EAP_TRACE_DEBUG(
       
 11697 		m_am_tools,
       
 11698 		TRACE_FLAGS_DEFAULT,
       
 11699 		(EAPL("TLS: %s: message_function: starts: tls_record_c::packet_process(): state %s, privacy_handshake_state=%d=%s, session_type=%s\n"),
       
 11700 		(m_is_client == true ? "client": "server"),
       
 11701 		eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 11702 		 tmp_identity_privacy_handshake_state,
       
 11703 		 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state),
       
 11704 		 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)));
       
 11705 
       
 11706 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::packet_process()");
       
 11707 
       
 11708 	m_received_tls_message.reset();
       
 11709 
       
 11710 	eap_status_e status = m_received_tls_message.set_tls_message_data(
       
 11711 		tls_packet,
       
 11712 		received_eap_identifier);
       
 11713 	if (status != eap_status_ok)
       
 11714 	{
       
 11715 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11716 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11717 	}
       
 11718 
       
 11719 	eap_automatic_simple_value_c<bool> restore_allow_message_send(
       
 11720 		m_am_tools,
       
 11721 		&m_allow_message_send,
       
 11722 		true);
       
 11723 
       
 11724 	// Packet send is delayed until after the process_tls_message() function returns.
       
 11725 	m_allow_message_send = false;
       
 11726 
       
 11727 	status = process_tls_message();
       
 11728 
       
 11729 	m_allow_message_send = true;
       
 11730 
       
 11731 
       
 11732 	if (status != eap_status_pending_request)
       
 11733 	{
       
 11734 		// Note this call will return eap_status_pending_request if any asyncronous call is pending.
       
 11735 		eap_status_e send_status = check_sent_tls_message();
       
 11736 		if (send_status != eap_status_ok)
       
 11737 		{
       
 11738 			status = send_status;
       
 11739 		}
       
 11740 	}
       
 11741 
       
 11742 	if (status == eap_status_success
       
 11743 		&& m_tls_peap_state != tls_peap_state_tls_success)
       
 11744 	{
       
 11745 		status = eap_status_ok;
       
 11746 	}
       
 11747 
       
 11748 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11749 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11750 }
       
 11751 
       
 11752 //--------------------------------------------------
       
 11753 
       
 11754 EAP_FUNC_EXPORT eap_status_e tls_record_c::plain_eap_success_failure_packet_received(
       
 11755 	const eap_am_network_id_c * const receive_network_id,
       
 11756 	const eap_code_value_e received_eap_code,
       
 11757 	const u8_t received_eap_identifier)
       
 11758 {
       
 11759 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11760 
       
 11761 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11762 	EAP_TRACE_DEBUG(
       
 11763 		m_am_tools,
       
 11764 		TRACE_FLAGS_DEFAULT,
       
 11765 		(EAPL("TLS: %s: message_function: starts: tls_record_c::plain_eap_success_failure_packet_received(): state %s, m_tls_session_type=%s\n"),
       
 11766 		(m_is_client == true ? "client": "server"),
       
 11767 		eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 11768 		eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)));
       
 11769 
       
 11770 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::plain_eap_success_failure_packet_received()");
       
 11771 
       
 11772 	eap_status_e status(eap_status_ok);
       
 11773 
       
 11774 	if (received_eap_code == eap_code_success
       
 11775 		&& m_eap_type == eap_type_peap
       
 11776 		&& m_peap_version == peap_version_1
       
 11777 		&& m_use_tppd_tls_peap == true)
       
 11778 	{
       
 11779 		status = m_am_tls_services->save_tls_session(
       
 11780 			&m_session_id,
       
 11781 			&m_master_secret,
       
 11782 			m_selected_cipher_suite
       
 11783 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 11784 			, tls_extension_c::get_tls_extension(
       
 11785 				tls_extension_type_session_ticket,
       
 11786 				&m_received_tls_extensions,
       
 11787 				m_am_tools)
       
 11788 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
 11789 			);
       
 11790 		if (status != eap_status_ok)
       
 11791 		{
       
 11792 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11793 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 11794 		}
       
 11795 	}
       
 11796 #if defined(USE_FAST_EAP_TYPE)
       
 11797 	else if (m_eap_type == eap_type_fast)
       
 11798 	{
       
 11799 		if (received_eap_code == eap_code_success
       
 11800 			&& m_tls_peap_state == tls_peap_state_tls_success
       
 11801 			&& (m_tls_session_type == tls_session_type_original_session_resumption
       
 11802 				|| m_tls_session_type == tls_session_type_stateless_session_resumption))
       
 11803 		{
       
 11804 			eap_state_variable_e current_state(eap_state_authentication_finished_successfully);
       
 11805 
       
 11806 			// Here we swap the addresses.
       
 11807 			eap_am_network_id_c send_network_id(m_am_tools,
       
 11808 				receive_network_id->get_destination_id(),
       
 11809 				receive_network_id->get_source_id(),
       
 11810 				receive_network_id->get_type());
       
 11811 
       
 11812 			eap_state_notification_c notification(
       
 11813 				m_am_tools,
       
 11814 				&send_network_id,
       
 11815 				m_is_client,
       
 11816 				eap_state_notification_eap,
       
 11817 				eap_protocol_layer_eap,
       
 11818 				m_eap_type,
       
 11819 				eap_state_none,
       
 11820 				current_state,
       
 11821 				m_received_eap_identifier,
       
 11822 				false);
       
 11823 
       
 11824 			state_notification(&notification);
       
 11825 		}
       
 11826 		else
       
 11827 		{
       
 11828 			status = m_application->plain_eap_success_failure_packet_received(
       
 11829 				receive_network_id,
       
 11830 				received_eap_code,
       
 11831 				received_eap_identifier);
       
 11832 		}
       
 11833 	}
       
 11834 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 11835 	else if (m_eap_type == eap_type_peap
       
 11836 		|| m_eap_type == eap_type_ttls
       
 11837 		)
       
 11838 	{
       
 11839 		status = m_application->plain_eap_success_failure_packet_received(
       
 11840 			receive_network_id,
       
 11841 			received_eap_code,
       
 11842 			received_eap_identifier);
       
 11843 	}
       
 11844 
       
 11845 	if (status != eap_status_pending_request)
       
 11846 	{
       
 11847 		// Note this call will return eap_status_pending_request if any asyncronous call is pending.
       
 11848 		eap_status_e send_status = check_sent_tls_message();
       
 11849 		if (send_status != eap_status_ok)
       
 11850 		{
       
 11851 			status = send_status;
       
 11852 		}
       
 11853 	}
       
 11854 
       
 11855 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11856 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11857 }
       
 11858 
       
 11859 //--------------------------------------------------
       
 11860 
       
 11861 EAP_FUNC_EXPORT eap_status_e tls_record_c::empty_ack_packet_received(
       
 11862 	const eap_am_network_id_c * const receive_network_id,
       
 11863 	const u8_t received_eap_identifier)
       
 11864 {
       
 11865 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11866 
       
 11867 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11868 	EAP_TRACE_DEBUG(
       
 11869 		m_am_tools,
       
 11870 		TRACE_FLAGS_DEFAULT,
       
 11871 		(EAPL("TLS: %s: message_function: starts: tls_record_c::empty_ack_packet_received(): state %s\n"),
       
 11872 		(m_is_client == true ? "client": "server"),
       
 11873 		eap_tls_trace_string_c::get_state_string(m_tls_peap_state)));
       
 11874 
       
 11875 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::empty_ack_packet_received()");
       
 11876 
       
 11877 	eap_status_e status(eap_status_not_supported);
       
 11878 
       
 11879 	if (m_eap_type == eap_type_ttls)
       
 11880 	{
       
 11881 		status = m_application->empty_ack_packet_received(
       
 11882 			receive_network_id,
       
 11883 			received_eap_identifier);
       
 11884 
       
 11885 		if (status != eap_status_pending_request)
       
 11886 		{
       
 11887 			// Note this call will return eap_status_pending_request if any asyncronous call is pending.
       
 11888 			eap_status_e send_status = check_sent_tls_message();
       
 11889 			if (send_status != eap_status_ok)
       
 11890 			{
       
 11891 				status = send_status;
       
 11892 			}
       
 11893 		}
       
 11894 	}
       
 11895 
       
 11896 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11897 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 11898 }
       
 11899 
       
 11900 //--------------------------------------------------
       
 11901 
       
 11902 EAP_FUNC_EXPORT bool tls_record_c::get_is_valid()
       
 11903 {
       
 11904 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11905 
       
 11906 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11907 	return m_is_valid;
       
 11908 }
       
 11909 
       
 11910 //--------------------------------------------------
       
 11911 
       
 11912 EAP_FUNC_EXPORT eap_status_e tls_record_c::reset()
       
 11913 {
       
 11914 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11915 
       
 11916 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 11917 	EAP_TRACE_DEBUG(
       
 11918 		m_am_tools,
       
 11919 		TRACE_FLAGS_DEFAULT,
       
 11920 		(EAPL("TLS: this = 0x%08x, %s: function: starts: tls_record_c::reset()\n"),
       
 11921 		 this,
       
 11922 		 (m_is_client == true ? "client": "server")));
       
 11923 
       
 11924 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::reset()");
       
 11925 
       
 11926 	completion_action_clenup();
       
 11927 
       
 11928 	{
       
 11929 		m_received_tls_message.reset();
       
 11930 		m_new_tls_message.reset();
       
 11931 		m_message_hash_md5.hash_cleanup();
       
 11932 		m_message_hash_sha1.hash_cleanup();
       
 11933 		m_message_hash_md5_certificate_verify.reset();
       
 11934 		m_message_hash_sha1_certificate_verify.reset();
       
 11935 		m_client_message_hash_md5_finished.reset();
       
 11936 		m_client_message_hash_sha1_finished.reset();
       
 11937 		m_server_message_hash_md5_finished.reset();
       
 11938 		m_server_message_hash_sha1_finished.reset();
       
 11939 		m_client_handshake_random_value.reset();
       
 11940 		m_server_handshake_random_value.reset();
       
 11941 		m_session_id.reset();
       
 11942 		m_master_secret.reset();
       
 11943 		m_eap_master_session_key.reset();
       
 11944 		m_send_mac_key.reset();
       
 11945 		m_receive_mac_key.reset();
       
 11946 		m_send_encryption_key.reset();
       
 11947 		m_receive_encryption_key.reset();
       
 11948 		m_send_iv.reset();
       
 11949 		m_receive_iv.reset();
       
 11950 		m_own_private_dhe_key.reset();
       
 11951 		m_own_public_dhe_key.reset();
       
 11952 		m_peer_public_dhe_key.reset();
       
 11953 		m_shared_dh_key.reset();
       
 11954 		m_dhe_prime.reset();
       
 11955 		m_dhe_group_generator.reset();
       
 11956 		m_signed_message_hash.reset();
       
 11957 		m_premaster_secret.reset();
       
 11958 #if defined(USE_FAST_EAP_TYPE)
       
 11959 		m_eap_fast_pac_key.reset();
       
 11960 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 11961 		m_own_encrypted_premaster_secret.reset();
       
 11962 		m_proposed_cipher_suites.reset();
       
 11963 		m_proposed_compression_methods.reset();
       
 11964 		m_NAI_realm.reset();
       
 11965 		m_own_certificate_chain.reset();
       
 11966 		m_own_certificate_types.reset();
       
 11967 		m_own_certificate_authorities.reset();
       
 11968 		m_peer_certificate_chain.reset();
       
 11969 		m_peer_certificate_chain_result = eap_status_illegal_certificate;
       
 11970 		m_verify_signature = eap_status_authentication_failure;
       
 11971 		m_peer_certificate_types.reset();
       
 11972 		m_peer_certificate_authorities.reset();
       
 11973 	}
       
 11974 
       
 11975 	eap_status_e status = message_hash_init();
       
 11976 	if (status != eap_status_ok)
       
 11977 	{
       
 11978 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11979 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11980 	}
       
 11981 
       
 11982 	set_selected_cipher_suite(tls_cipher_suites_none);
       
 11983 	m_selected_compression_method = tls_compression_method_none;
       
 11984 
       
 11985 	status = set_receive_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL);
       
 11986 	if (status != eap_status_ok)
       
 11987 	{
       
 11988 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11989 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11990 	}
       
 11991 	m_receive_compression_method = tls_compression_method_null;
       
 11992 
       
 11993 	status = set_send_cipher_suite(tls_cipher_suites_TLS_NULL_WITH_NULL_NULL);
       
 11994 	if (status != eap_status_ok)
       
 11995 	{
       
 11996 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 11997 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 11998 	}
       
 11999 	m_send_compression_method = tls_compression_method_null;
       
 12000 
       
 12001 	m_completion_queue.reset();
       
 12002 
       
 12003 	m_send_record_sequence_number = 0ul;
       
 12004 	m_receive_record_sequence_number = 0ul;
       
 12005 
       
 12006 	m_key_material_generated = false;
       
 12007 
       
 12008 	m_force_tls_message_send = false;
       
 12009 
       
 12010 	if (m_is_client == false)
       
 12011 	{
       
 12012 		// Server
       
 12013 		// NOTE: set_state() function cannot reset state.
       
 12014 		m_tls_peap_state = tls_peap_state_wait_handshake_type_client_hello;
       
 12015 	}
       
 12016 	else
       
 12017 	{
       
 12018 		// Client
       
 12019 		// NOTE: set_state() function cannot reset state.
       
 12020 		m_tls_peap_state = tls_peap_state_wait_tls_start;
       
 12021 	}
       
 12022 
       
 12023 	m_tunneled_eap_type_authentication_state = eap_state_none;
       
 12024 
       
 12025 	m_tls_peap_server_authenticates_client_action = true;
       
 12026 	if (m_is_client == false
       
 12027 		&& m_tls_peap_server_authenticates_client_config_server == false)
       
 12028 	{
       
 12029 		m_tls_peap_server_authenticates_client_action = false;
       
 12030 	}
       
 12031 
       
 12032 	m_tls_peap_server_requested_client_certificate = false;
       
 12033 
       
 12034 	m_could_send_fatal_alert_message = true;
       
 12035 	m_could_send_warning_alert_message = true;
       
 12036 
       
 12037 	if (m_application != 0)
       
 12038 	{
       
 12039 		m_application->reset();
       
 12040 	}
       
 12041 
       
 12042 	reset_block_ciphers(true);
       
 12043 	reset_block_ciphers(false);
       
 12044 
       
 12045 	reset_stream_ciphers(true);
       
 12046 	reset_stream_ciphers(false);
       
 12047 
       
 12048 	reset_hmac_algorithms(true);
       
 12049 	reset_hmac_algorithms(false);
       
 12050 
       
 12051 	m_use_tppd_tls_peap = false;
       
 12052 	m_use_tppd_peapv1_acknowledge_hack = false;
       
 12053 
       
 12054 	m_will_receive_new_session_ticket = false;
       
 12055 
       
 12056 #if defined(USE_FAST_EAP_TYPE)
       
 12057 	m_remove_tunnel_pac = false;
       
 12058 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 12059 
       
 12060 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 12061 	set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_none);
       
 12062 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 12063 
       
 12064 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12065 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
 12066 }
       
 12067 
       
 12068 
       
 12069 //--------------------------------------------------
       
 12070 
       
 12071 EAP_FUNC_EXPORT u32_t tls_record_c::get_key_expansion_size(
       
 12072 	u32_t * const mac_key_length,
       
 12073 	u32_t * const encryption_key_length,
       
 12074 	u32_t * const iv_length,
       
 12075 	u32_t * const session_key_seed_length,
       
 12076 	u32_t * const mschapv2_challenges_length
       
 12077 	)
       
 12078 {
       
 12079 	u32_t length = 0ul;
       
 12080 
       
 12081 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 12082 	EAP_TRACE_DEBUG(
       
 12083 		m_am_tools,
       
 12084 		TRACE_FLAGS_DEFAULT,
       
 12085 		(EAPL("TLS: %s:     key_function: starts: tls_record_c::get_key_expansion_size()\n"),
       
 12086 		(m_is_client == true ? "client": "server")));
       
 12087 
       
 12088 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_key_expansion_size()");
       
 12089 
       
 12090 	*mac_key_length = 0ul;
       
 12091 	*encryption_key_length = 0ul;
       
 12092 	*iv_length = 0ul;
       
 12093 	*session_key_seed_length = 0ul;
       
 12094 	*mschapv2_challenges_length = 0ul;
       
 12095 
       
 12096 	if (cipher_suite_is_3DES_EDE_CBC_SHA(m_selected_cipher_suite) == true)
       
 12097 	{
       
 12098 		crypto_3des_ede_c ede_3des(m_am_tools);
       
 12099 
       
 12100 		crypto_sha1_c sha1(m_am_tools);
       
 12101 		crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false);
       
 12102 
       
 12103 		if (hmac_sha1.get_is_valid() == false)
       
 12104 		{
       
 12105 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12106 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12107 		}
       
 12108 
       
 12109 
       
 12110 		eap_variable_data_c tmp_key(m_am_tools);
       
 12111 		if (tmp_key.get_is_valid() == false)
       
 12112 		{
       
 12113 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12114 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12115 		}
       
 12116 
       
 12117 		eap_status_e status = tmp_key.add_data("", 0ul);
       
 12118 		if (status != eap_status_ok)
       
 12119 		{
       
 12120 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12121 			return 0;
       
 12122 		}
       
 12123 
       
 12124 		status = hmac_sha1.hmac_set_key(&tmp_key);
       
 12125 		if (status != eap_status_ok)
       
 12126 		{
       
 12127 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12128 			return 0;
       
 12129 		}
       
 12130 
       
 12131 		length = 2ul * hmac_sha1.get_digest_length()
       
 12132 			+ 2ul * ede_3des.get_key_length()
       
 12133 			+ 2ul * ede_3des.get_block_size();
       
 12134 		
       
 12135 		*mac_key_length = hmac_sha1.get_digest_length();
       
 12136 		*encryption_key_length = ede_3des.get_key_length();
       
 12137 		*iv_length = ede_3des.get_block_size();
       
 12138 	}
       
 12139 	else if (cipher_suite_is_AES_128_CBC_SHA(m_selected_cipher_suite) == true)
       
 12140 	{
       
 12141 		crypto_aes_c aes(m_am_tools);
       
 12142 
       
 12143 		crypto_sha1_c sha1(m_am_tools);
       
 12144 		crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false);
       
 12145 
       
 12146 		if (hmac_sha1.get_is_valid() == false)
       
 12147 		{
       
 12148 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12149 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12150 		}
       
 12151 
       
 12152 		eap_variable_data_c tmp_key(m_am_tools);
       
 12153 		if (tmp_key.get_is_valid() == false)
       
 12154 		{
       
 12155 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12156 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12157 		}
       
 12158 
       
 12159 		eap_status_e status = tmp_key.add_data("", 0ul);
       
 12160 		if (status != eap_status_ok)
       
 12161 		{
       
 12162 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12163 			return 0;
       
 12164 		}
       
 12165 
       
 12166 		status = hmac_sha1.hmac_set_key(&tmp_key);
       
 12167 		if (status != eap_status_ok)
       
 12168 		{
       
 12169 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12170 			return 0;
       
 12171 		}
       
 12172 
       
 12173 		length = 2ul * hmac_sha1.get_digest_length()
       
 12174 			+ 2ul * aes.get_key_length()
       
 12175 			+ 2ul * aes.get_block_size();
       
 12176 		
       
 12177 		*mac_key_length = hmac_sha1.get_digest_length();
       
 12178 		*encryption_key_length = aes.get_key_length();
       
 12179 		*iv_length = aes.get_block_size();
       
 12180 	}
       
 12181 	else if (cipher_suite_is_RC4_128_MD5(m_selected_cipher_suite) == true)
       
 12182 	{
       
 12183 		crypto_md5_c md5(m_am_tools);
       
 12184 		crypto_hmac_c hmac_md5(m_am_tools, &md5, false);
       
 12185 
       
 12186 		if (hmac_md5.get_is_valid() == false)
       
 12187 		{
       
 12188 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12189 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12190 		}
       
 12191 
       
 12192 		eap_variable_data_c tmp_key(m_am_tools);
       
 12193 		if (tmp_key.get_is_valid() == false)
       
 12194 		{
       
 12195 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12196 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12197 		}
       
 12198 
       
 12199 		eap_status_e status = tmp_key.add_data("", 0ul);
       
 12200 		if (status != eap_status_ok)
       
 12201 		{
       
 12202 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12203 			return 0;
       
 12204 		}
       
 12205 
       
 12206 		status = hmac_md5.hmac_set_key(&tmp_key);
       
 12207 		if (status != eap_status_ok)
       
 12208 		{
       
 12209 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12210 			return 0;
       
 12211 		}
       
 12212 
       
 12213 		length = 2ul * hmac_md5.get_digest_length()
       
 12214 			+ 2ul * TLS_RC4_128_KEY_LENGTH
       
 12215 			+ 2ul * TLS_RC4_128_IV_LENGTH;
       
 12216 		
       
 12217 		*mac_key_length = hmac_md5.get_digest_length();
       
 12218 		*encryption_key_length = TLS_RC4_128_KEY_LENGTH;
       
 12219 		*iv_length = TLS_RC4_128_IV_LENGTH;
       
 12220 	}
       
 12221 	else if (cipher_suite_is_RC4_128_SHA(m_selected_cipher_suite) == true)
       
 12222 	{
       
 12223 		crypto_sha1_c sha1(m_am_tools);
       
 12224 		crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false);
       
 12225 
       
 12226 		if (hmac_sha1.get_is_valid() == false)
       
 12227 		{
       
 12228 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12229 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12230 		}
       
 12231 
       
 12232 		eap_variable_data_c tmp_key(m_am_tools);
       
 12233 		if (tmp_key.get_is_valid() == false)
       
 12234 		{
       
 12235 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12236 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12237 		}
       
 12238 
       
 12239 		eap_status_e status = tmp_key.add_data("", 0ul);
       
 12240 		if (status != eap_status_ok)
       
 12241 		{
       
 12242 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12243 			return 0;
       
 12244 		}
       
 12245 
       
 12246 		status = hmac_sha1.hmac_set_key(&tmp_key);
       
 12247 		if (status != eap_status_ok)
       
 12248 		{
       
 12249 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12250 			return 0;
       
 12251 		}
       
 12252 
       
 12253 		length = 2ul * hmac_sha1.get_digest_length()
       
 12254 			+ 2ul * TLS_RC4_128_KEY_LENGTH
       
 12255 			+ 2ul * TLS_RC4_128_IV_LENGTH;
       
 12256 		
       
 12257 		*mac_key_length = hmac_sha1.get_digest_length();
       
 12258 		*encryption_key_length = TLS_RC4_128_KEY_LENGTH;
       
 12259 		*iv_length = TLS_RC4_128_IV_LENGTH;
       
 12260 	}
       
 12261 
       
 12262 #if defined(USE_FAST_EAP_TYPE)
       
 12263 	if (m_eap_type == eap_type_fast)
       
 12264 	{
       
 12265 		*session_key_seed_length = EAP_FAST_SESSION_KEY_SEED_LENGTH;
       
 12266 		length += EAP_FAST_SESSION_KEY_SEED_LENGTH;
       
 12267 
       
 12268 		if (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP
       
 12269 			&& m_selected_cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA)
       
 12270 		{
       
 12271 			*mschapv2_challenges_length = 2ul * EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH;
       
 12272 			length += 2ul * EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH;
       
 12273 		}
       
 12274 	}
       
 12275 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 12276 
       
 12277 	return length;
       
 12278 }
       
 12279 
       
 12280 //--------------------------------------------------
       
 12281 
       
 12282 EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_cbc(
       
 12283 	abs_crypto_cbc_block_algorithm_c ** const member_cbc_crypto_block_algorithm,
       
 12284 	abs_crypto_block_algorithm_c * const crypto_block_algorithm,
       
 12285 	const eap_variable_data_c * const member_iv,
       
 12286 	const eap_variable_data_c * const member_key,
       
 12287 	const bool true_when_encrypt)
       
 12288 {
       
 12289 	EAP_TRACE_DEBUG(
       
 12290 		m_am_tools,
       
 12291 		TRACE_FLAGS_DEFAULT,
       
 12292 		(EAPL("TLS: %s:     key_function: starts: tls_record_c::cipher_suite_initialization_cbc()\n"),
       
 12293 		(m_is_client == true ? "client": "server")));
       
 12294 
       
 12295 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_cbc()");
       
 12296 
       
 12297 	eap_automatic_variable_c<abs_crypto_block_algorithm_c>
       
 12298 		block_algorithm_remove(m_am_tools, crypto_block_algorithm);
       
 12299 
       
 12300 	if (crypto_block_algorithm == 0)
       
 12301 	{
       
 12302 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12303 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12304 	}
       
 12305 
       
 12306 	if (crypto_block_algorithm->get_is_valid() == false)
       
 12307 	{
       
 12308 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12309 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12310 	}
       
 12311 
       
 12312 	if (member_cbc_crypto_block_algorithm == 0)
       
 12313 	{
       
 12314 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12315 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12316 	}
       
 12317 
       
 12318 	*member_cbc_crypto_block_algorithm = new crypto_cbc_c(
       
 12319 		m_am_tools,
       
 12320 		crypto_block_algorithm,
       
 12321 		true);
       
 12322 
       
 12323 	if (*member_cbc_crypto_block_algorithm == 0
       
 12324 		|| (*member_cbc_crypto_block_algorithm)->get_is_valid() == false)
       
 12325 	{
       
 12326 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12327 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12328 	}
       
 12329 
       
 12330 	// After this point *member_cbc_crypto_block_algorithm will delete crypto_block_algorithm.
       
 12331 	block_algorithm_remove.do_not_free_variable();
       
 12332 
       
 12333 	if ((*member_cbc_crypto_block_algorithm)->get_is_valid() == false)
       
 12334 	{
       
 12335 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12336 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12337 	}
       
 12338 
       
 12339 	eap_status_e status = eap_status_process_general_error;
       
 12340 
       
 12341 
       
 12342 	EAP_TRACE_DATA_DEBUG(
       
 12343 		m_am_tools,
       
 12344 		TRACE_FLAGS_DEFAULT,
       
 12345 		(EAPL("CBC member_iv"),
       
 12346 		 member_iv->get_data(member_iv->get_data_length()),
       
 12347 		 member_iv->get_data_length()));
       
 12348 
       
 12349 	EAP_TRACE_DATA_DEBUG(
       
 12350 		m_am_tools,
       
 12351 		TRACE_FLAGS_DEFAULT,
       
 12352 		(EAPL("CBC member_key"),
       
 12353 		 member_key->get_data(member_key->get_data_length()),
       
 12354 		 member_key->get_data_length()));
       
 12355 
       
 12356 
       
 12357 	if (true_when_encrypt == true)
       
 12358 	{
       
 12359 		status = (*member_cbc_crypto_block_algorithm)->set_encryption_key(
       
 12360 			member_iv->get_data(member_iv->get_data_length()),
       
 12361 			member_iv->get_data_length(),
       
 12362 			member_key->get_data(member_key->get_data_length()),
       
 12363 			member_key->get_data_length());
       
 12364 	}
       
 12365 	else
       
 12366 	{
       
 12367 		status = (*member_cbc_crypto_block_algorithm)->set_decryption_key(
       
 12368 			member_iv->get_data(member_iv->get_data_length()),
       
 12369 			member_iv->get_data_length(),
       
 12370 			member_key->get_data(member_key->get_data_length()),
       
 12371 			member_key->get_data_length());
       
 12372 	}
       
 12373 
       
 12374 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12375 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 12376 }
       
 12377 
       
 12378 //--------------------------------------------------
       
 12379 
       
 12380 EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_hmac(
       
 12381 	abs_crypto_hmac_algorithm_c * const member_hmac_algorithm,
       
 12382 	const eap_variable_data_c * const member_key)
       
 12383 {
       
 12384 	EAP_TRACE_DEBUG(
       
 12385 		m_am_tools,
       
 12386 		TRACE_FLAGS_DEFAULT,
       
 12387 		(EAPL("TLS: %s:     key_function: starts: tls_record_c::cipher_suite_initialization_hmac()\n"),
       
 12388 		(m_is_client == true ? "client": "server")));
       
 12389 
       
 12390 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_hmac()");
       
 12391 
       
 12392 	if (member_hmac_algorithm == 0)
       
 12393 	{
       
 12394 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12395 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12396 	}
       
 12397 
       
 12398 	if (member_hmac_algorithm->get_is_valid() == false)
       
 12399 	{
       
 12400 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12401 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12402 	}
       
 12403 
       
 12404 	eap_status_e status = eap_status_process_general_error;
       
 12405 
       
 12406 	EAP_TRACE_DATA_DEBUG(
       
 12407 		m_am_tools,
       
 12408 		TRACE_FLAGS_DEFAULT,
       
 12409 		(EAPL("HMAC member_key"),
       
 12410 		 member_key->get_data(member_key->get_data_length()),
       
 12411 		 member_key->get_data_length()));
       
 12412 
       
 12413 	status = member_hmac_algorithm->hmac_set_key(
       
 12414 		member_key);
       
 12415 
       
 12416 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12417 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 12418 }
       
 12419 
       
 12420 //--------------------------------------------------
       
 12421 
       
 12422 EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_stream(
       
 12423 	abs_crypto_stream_algorithm_c * const member_crypto_stream_algorithm,
       
 12424 	const eap_variable_data_c * const member_key,
       
 12425 	const bool /* true_when_encrypt */)
       
 12426 {
       
 12427 	EAP_TRACE_DEBUG(
       
 12428 		m_am_tools,
       
 12429 		TRACE_FLAGS_DEFAULT,
       
 12430 		(EAPL("TLS: %s:     key_function: starts: tls_record_c::cipher_suite_initialization_stream()\n"),
       
 12431 		(m_is_client == true ? "client": "server")));
       
 12432 
       
 12433 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_stream()");
       
 12434 
       
 12435 	if (member_crypto_stream_algorithm == 0)
       
 12436 	{
       
 12437 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12438 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12439 	}
       
 12440 
       
 12441 	if (member_crypto_stream_algorithm->get_is_valid() == false)
       
 12442 	{
       
 12443 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12444 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12445 	}
       
 12446 
       
 12447 	EAP_TRACE_DATA_DEBUG(
       
 12448 		m_am_tools,
       
 12449 		TRACE_FLAGS_DEFAULT,
       
 12450 		(EAPL("STREAM member_key"),
       
 12451 		 member_key->get_data(member_key->get_data_length()),
       
 12452 		 member_key->get_data_length()));
       
 12453 
       
 12454 	eap_status_e status = member_crypto_stream_algorithm->set_key(member_key);
       
 12455 	if (status != eap_status_ok)
       
 12456 	{
       
 12457 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12458 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 12459 	}
       
 12460 
       
 12461 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12462 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 12463 }
       
 12464 
       
 12465 //--------------------------------------------------
       
 12466 
       
 12467 EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_hmac_sha1(const bool send_when_true)
       
 12468 {
       
 12469 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 12470 	EAP_TRACE_DEBUG(
       
 12471 		m_am_tools,
       
 12472 		TRACE_FLAGS_DEFAULT,
       
 12473 		(EAPL("TLS: %s:     key_function: starts: tls_record_c::cipher_suite_initialization_hmac_sha1()\n"),
       
 12474 		(m_is_client == true ? "client": "server")));
       
 12475 
       
 12476 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_hmac_sha1()");
       
 12477 
       
 12478 	reset_hmac_algorithms(send_when_true);
       
 12479 
       
 12480 	eap_status_e status = eap_status_ok;
       
 12481 
       
 12482 	if (send_when_true == true)
       
 12483 	{
       
 12484 		crypto_sha1_c * const sha1 = new crypto_sha1_c(m_am_tools);
       
 12485 		if (sha1 == 0)
       
 12486 		{
       
 12487 			delete sha1;
       
 12488 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12489 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12490 		}
       
 12491 
       
 12492 		m_send_hmac_algorithm = new crypto_hmac_c(m_am_tools, sha1, true);
       
 12493 
       
 12494 		status = cipher_suite_initialization_hmac(
       
 12495 			m_send_hmac_algorithm,
       
 12496 			&m_send_mac_key);
       
 12497 		if (status != eap_status_ok)
       
 12498 		{
       
 12499 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12500 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12501 		}
       
 12502 	}
       
 12503 	else
       
 12504 	{
       
 12505 		crypto_sha1_c * const sha1 = new crypto_sha1_c(m_am_tools);
       
 12506 		if (sha1 == 0)
       
 12507 		{
       
 12508 			delete sha1;
       
 12509 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12510 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12511 		}
       
 12512 
       
 12513 		m_receive_hmac_algorithm = new crypto_hmac_c(m_am_tools, sha1, true);
       
 12514 
       
 12515 		status = cipher_suite_initialization_hmac(
       
 12516 			m_receive_hmac_algorithm,
       
 12517 			&m_receive_mac_key);
       
 12518 		if (status != eap_status_ok)
       
 12519 		{
       
 12520 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12521 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12522 		}
       
 12523 	}
       
 12524 
       
 12525 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12526 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 12527 }
       
 12528 
       
 12529 //--------------------------------------------------
       
 12530 
       
 12531 EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization_hmac_md5(const bool send_when_true)
       
 12532 {
       
 12533 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 12534 	EAP_TRACE_DEBUG(
       
 12535 		m_am_tools,
       
 12536 		TRACE_FLAGS_DEFAULT,
       
 12537 		(EAPL("TLS: %s:     key_function: starts: cipher_suite_initialization_hmac_md5()\n"),
       
 12538 		(m_is_client == true ? "client": "server")));
       
 12539 
       
 12540 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization_hmac_md5()");
       
 12541 
       
 12542 	reset_hmac_algorithms(send_when_true);
       
 12543 
       
 12544 	eap_status_e status = eap_status_ok;
       
 12545 
       
 12546 	if (send_when_true == true)
       
 12547 	{
       
 12548 		crypto_md5_c * const md5 = new crypto_md5_c(m_am_tools);
       
 12549 		if (md5 == 0)
       
 12550 		{
       
 12551 			delete md5;
       
 12552 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12553 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12554 		}
       
 12555 
       
 12556 		m_send_hmac_algorithm = new crypto_hmac_c(m_am_tools, md5, true);
       
 12557 
       
 12558 		status = cipher_suite_initialization_hmac(
       
 12559 			m_send_hmac_algorithm,
       
 12560 			&m_send_mac_key);
       
 12561 		if (status != eap_status_ok)
       
 12562 		{
       
 12563 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12564 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12565 		}
       
 12566 	}
       
 12567 	else
       
 12568 	{
       
 12569 		crypto_md5_c * const md5 = new crypto_md5_c(m_am_tools);
       
 12570 		if (md5 == 0)
       
 12571 		{
       
 12572 			delete md5;
       
 12573 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12574 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12575 		}
       
 12576 
       
 12577 		m_receive_hmac_algorithm = new crypto_hmac_c(m_am_tools, md5, true);
       
 12578 
       
 12579 		status = cipher_suite_initialization_hmac(
       
 12580 			m_receive_hmac_algorithm,
       
 12581 			&m_receive_mac_key);
       
 12582 		if (status != eap_status_ok)
       
 12583 		{
       
 12584 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12585 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12586 		}
       
 12587 	}
       
 12588 
       
 12589 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12590 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 12591 }
       
 12592 
       
 12593 //--------------------------------------------------
       
 12594 
       
 12595 EAP_FUNC_EXPORT eap_status_e tls_record_c::cipher_suite_initialization(
       
 12596 	const bool send_when_true)
       
 12597 {
       
 12598 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 12599 
       
 12600 	EAP_TRACE_DEBUG(
       
 12601 		m_am_tools,
       
 12602 		TRACE_FLAGS_DEFAULT,
       
 12603 		(EAPL("TLS: %s:     key_function: starts: tls_record_c::cipher_suite_initialization(), cipher suite %s: %s\n"),
       
 12604 		 (m_is_client == true ? "client": "server"),
       
 12605 		 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite),
       
 12606 		 (send_when_true == true ? "send": "receive")));
       
 12607 
       
 12608 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::cipher_suite_initialization()");
       
 12609 
       
 12610 	reset_block_ciphers(send_when_true);
       
 12611 
       
 12612 	reset_stream_ciphers(send_when_true);
       
 12613 
       
 12614 
       
 12615 	EAP_TRACE_DATA_DEBUG(
       
 12616 		m_am_tools,
       
 12617 		TRACE_FLAGS_DEFAULT,
       
 12618 		(EAPL("m_send_encryption_key"),
       
 12619 		 m_send_encryption_key.get_data(),
       
 12620 		 m_send_encryption_key.get_data_length()));
       
 12621 
       
 12622 	EAP_TRACE_DATA_DEBUG(
       
 12623 		m_am_tools,
       
 12624 		TRACE_FLAGS_DEFAULT,
       
 12625 		(EAPL("m_receive_encryption_key"),
       
 12626 		 m_receive_encryption_key.get_data(),
       
 12627 		 m_receive_encryption_key.get_data_length()));
       
 12628 
       
 12629 
       
 12630 	EAP_TRACE_DATA_DEBUG(
       
 12631 		m_am_tools,
       
 12632 		TRACE_FLAGS_DEFAULT,
       
 12633 		(EAPL("m_send_mac_key"),
       
 12634 		 m_send_mac_key.get_data(),
       
 12635 		 m_send_mac_key.get_data_length()));
       
 12636 
       
 12637 	EAP_TRACE_DATA_DEBUG(
       
 12638 		m_am_tools,
       
 12639 		TRACE_FLAGS_DEFAULT,
       
 12640 		(EAPL("m_receive_mac_key"),
       
 12641 		 m_receive_mac_key.get_data(),
       
 12642 		 m_receive_mac_key.get_data_length()));
       
 12643 
       
 12644 	EAP_TRACE_DATA_DEBUG(
       
 12645 		m_am_tools,
       
 12646 		TRACE_FLAGS_DEFAULT,
       
 12647 		(EAPL("m_send_iv"),
       
 12648 		 m_send_iv.get_data(),
       
 12649 		 m_send_iv.get_data_length()));
       
 12650 
       
 12651 	EAP_TRACE_DATA_DEBUG(
       
 12652 		m_am_tools,
       
 12653 		TRACE_FLAGS_DEFAULT,
       
 12654 		(EAPL("m_receive_iv"),
       
 12655 		 m_receive_iv.get_data(),
       
 12656 		 m_receive_iv.get_data_length()));
       
 12657 
       
 12658 
       
 12659 	eap_status_e status = eap_status_ok;
       
 12660 
       
 12661 	if (cipher_suite_is_3DES_EDE_CBC_SHA(m_selected_cipher_suite) == true)
       
 12662 	{
       
 12663 		if (send_when_true == true)
       
 12664 		{
       
 12665 			crypto_3des_ede_c * des3 = new crypto_3des_ede_c(m_am_tools);
       
 12666 
       
 12667 			status = cipher_suite_initialization_cbc(
       
 12668 				&m_send_block_cipher,
       
 12669 				des3,
       
 12670 				&m_send_iv,
       
 12671 				&m_send_encryption_key,
       
 12672 				true);
       
 12673 			if (status != eap_status_ok)
       
 12674 			{
       
 12675 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12676 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12677 			}
       
 12678 		}
       
 12679 		else
       
 12680 		{
       
 12681 			crypto_3des_ede_c * des3 = new crypto_3des_ede_c(m_am_tools);
       
 12682 
       
 12683 			status = cipher_suite_initialization_cbc(
       
 12684 				&m_receive_block_cipher,
       
 12685 				des3,
       
 12686 				&m_receive_iv,
       
 12687 				&m_receive_encryption_key,
       
 12688 				false);
       
 12689 			if (status != eap_status_ok)
       
 12690 			{
       
 12691 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12692 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12693 			}
       
 12694 		}
       
 12695 
       
 12696 		status = cipher_suite_initialization_hmac_sha1(send_when_true);
       
 12697 		if (status != eap_status_ok)
       
 12698 		{
       
 12699 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12700 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12701 		}
       
 12702 	}
       
 12703 	else if (cipher_suite_is_AES_128_CBC_SHA(m_selected_cipher_suite) == true)
       
 12704 	{
       
 12705 		if (send_when_true == true)
       
 12706 		{
       
 12707 			crypto_aes_c * aes = new crypto_aes_c(m_am_tools);
       
 12708 
       
 12709 			status = cipher_suite_initialization_cbc(
       
 12710 				&m_send_block_cipher,
       
 12711 				aes,
       
 12712 				&m_send_iv,
       
 12713 				&m_send_encryption_key,
       
 12714 				true);
       
 12715 			if (status != eap_status_ok)
       
 12716 			{
       
 12717 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12718 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12719 			}
       
 12720 		}
       
 12721 		else
       
 12722 		{
       
 12723 			crypto_aes_c * aes = new crypto_aes_c(m_am_tools);
       
 12724 
       
 12725 			status = cipher_suite_initialization_cbc(
       
 12726 				&m_receive_block_cipher,
       
 12727 				aes,
       
 12728 				&m_receive_iv,
       
 12729 				&m_receive_encryption_key,
       
 12730 				false);
       
 12731 			if (status != eap_status_ok)
       
 12732 			{
       
 12733 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12734 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12735 			}
       
 12736 		}
       
 12737 
       
 12738 		status = cipher_suite_initialization_hmac_sha1(send_when_true);
       
 12739 		if (status != eap_status_ok)
       
 12740 		{
       
 12741 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12742 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12743 		}
       
 12744 	}
       
 12745 	else if (cipher_suite_is_RC4_128_MD5(m_selected_cipher_suite) == true)
       
 12746 	{
       
 12747 		if (send_when_true == true)
       
 12748 		{
       
 12749 			m_send_stream_cipher = new crypto_rc4_c(m_am_tools);
       
 12750 
       
 12751 			status = cipher_suite_initialization_stream(
       
 12752 				m_send_stream_cipher,
       
 12753 				&m_send_encryption_key,
       
 12754 				true);
       
 12755 			if (status != eap_status_ok)
       
 12756 			{
       
 12757 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12758 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12759 			}
       
 12760 		}
       
 12761 		else
       
 12762 		{
       
 12763 			m_receive_stream_cipher = new crypto_rc4_c(m_am_tools);
       
 12764 
       
 12765 			status = cipher_suite_initialization_stream(
       
 12766 				m_receive_stream_cipher,
       
 12767 				&m_receive_encryption_key,
       
 12768 				false);
       
 12769 			if (status != eap_status_ok)
       
 12770 			{
       
 12771 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12772 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12773 			}
       
 12774 		}
       
 12775 
       
 12776 		status = cipher_suite_initialization_hmac_md5(send_when_true);
       
 12777 		if (status != eap_status_ok)
       
 12778 		{
       
 12779 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12780 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12781 		}
       
 12782 	}
       
 12783 	else if (cipher_suite_is_RC4_128_SHA(m_selected_cipher_suite) == true)
       
 12784 	{
       
 12785 		if (send_when_true == true)
       
 12786 		{
       
 12787 			m_send_stream_cipher = new crypto_rc4_c(m_am_tools);
       
 12788 
       
 12789 			status = cipher_suite_initialization_stream(
       
 12790 				m_send_stream_cipher,
       
 12791 				&m_send_encryption_key,
       
 12792 				true);
       
 12793 			if (status != eap_status_ok)
       
 12794 			{
       
 12795 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12796 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12797 			}
       
 12798 		}
       
 12799 		else
       
 12800 		{
       
 12801 			m_receive_stream_cipher = new crypto_rc4_c(m_am_tools);
       
 12802 
       
 12803 			status = cipher_suite_initialization_stream(
       
 12804 				m_receive_stream_cipher,
       
 12805 				&m_receive_encryption_key,
       
 12806 				false);
       
 12807 			if (status != eap_status_ok)
       
 12808 			{
       
 12809 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12810 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12811 			}
       
 12812 		}
       
 12813 
       
 12814 		status = cipher_suite_initialization_hmac_sha1(send_when_true);
       
 12815 		if (status != eap_status_ok)
       
 12816 		{
       
 12817 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12818 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12819 		}
       
 12820 	}
       
 12821 	else
       
 12822 	{
       
 12823 		status = eap_status_illegal_cipher_suite;
       
 12824 	}
       
 12825 
       
 12826 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12827 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 12828 }
       
 12829 
       
 12830 //--------------------------------------------------
       
 12831 
       
 12832 EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_key_material()
       
 12833 {
       
 12834 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12835 
       
 12836 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 12837 	EAP_TRACE_DEBUG(
       
 12838 		m_am_tools,
       
 12839 		TRACE_FLAGS_DEFAULT,
       
 12840 		(EAPL("TLS: %s:     tls_record_c::generate_key_material()\n"),
       
 12841 		 (m_is_client == true) ? "client": "server"));
       
 12842 
       
 12843 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_key_material()");
       
 12844 
       
 12845 	eap_status_e status = eap_status_illegal_cipher_suite;
       
 12846 
       
 12847 	if (m_key_material_generated == true)
       
 12848 	{
       
 12849 		// Already generated.
       
 12850 		status = eap_status_ok;
       
 12851 	}
       
 12852 	else
       
 12853 	{
       
 12854 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 12855 		EAP_TRACE_DEBUG(
       
 12856 			m_am_tools,
       
 12857 			TRACE_FLAGS_DEFAULT,
       
 12858 			(EAPL("TLS: %s:     key_function: starts: tls_record_c::generate_key_material()\n"),
       
 12859 			 (m_is_client == true) ? "client": "server"));
       
 12860 
       
 12861 		if (m_master_secret.get_is_valid_data() == false
       
 12862 			|| m_client_handshake_random_value.get_is_valid_data() == false
       
 12863 			|| m_server_handshake_random_value.get_is_valid_data() == false)
       
 12864 		{
       
 12865 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12866 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 12867 		}
       
 12868 
       
 12869 		u32_t mac_key_length = 0ul;
       
 12870 		u32_t encryption_key_length = 0ul;
       
 12871 		u32_t iv_length = 0ul;
       
 12872 		u32_t session_key_seed_length = 0ul;
       
 12873 		u32_t mschapv2_challenges_length = 0ul;
       
 12874 
       
 12875 		u32_t key_expansion_size = get_key_expansion_size(
       
 12876 			&mac_key_length,
       
 12877 			&encryption_key_length,
       
 12878 			&iv_length,
       
 12879 			&session_key_seed_length,
       
 12880 			&mschapv2_challenges_length);
       
 12881 
       
 12882 		if (key_expansion_size == 0ul)
       
 12883 		{
       
 12884 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12885 			return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
 12886 		}
       
 12887 
       
 12888 		eap_variable_data_c label(m_am_tools);
       
 12889 		if (label.get_is_valid() == false)
       
 12890 		{
       
 12891 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12892 		}
       
 12893 
       
 12894 		status = label.add_data(
       
 12895 			TLS_PEAP_KEY_EXPANSION_LABEL,
       
 12896 			TLS_PEAP_KEY_EXPANSION_LABEL_LENGTH);
       
 12897 		if (status != eap_status_ok)
       
 12898 		{
       
 12899 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12900 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12901 		}
       
 12902 
       
 12903 		eap_variable_data_c seed(m_am_tools);
       
 12904 		if (seed.get_is_valid() == false)
       
 12905 		{
       
 12906 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 12907 		}
       
 12908 		status = seed.set_copy_of_buffer(&m_server_handshake_random_value);
       
 12909 		if (status != eap_status_ok)
       
 12910 		{
       
 12911 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12912 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12913 		}
       
 12914 
       
 12915 		status = seed.add_data(&m_client_handshake_random_value);
       
 12916 		if (status != eap_status_ok)
       
 12917 		{
       
 12918 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12919 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12920 		}
       
 12921 
       
 12922 		EAP_TRACE_DEBUG(
       
 12923 			m_am_tools,
       
 12924 			TRACE_FLAGS_DEFAULT,
       
 12925 			(EAPL("TLS: %s:     prf_function: tls_prf.tls_prf_output()\n"),
       
 12926 			(m_is_client == true ? "client": "server")));
       
 12927 
       
 12928 		crypto_tls_prf_c tls_prf(m_am_tools);
       
 12929 
       
 12930 		status = tls_prf.tls_prf_init(
       
 12931 			&m_master_secret,
       
 12932 			&label,
       
 12933 			&seed);
       
 12934 		if (status != eap_status_ok)
       
 12935 		{
       
 12936 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12937 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12938 		}
       
 12939 
       
 12940 		eap_variable_data_c key_expansion(m_am_tools);
       
 12941 
       
 12942 		status = key_expansion.set_buffer_length(key_expansion_size);
       
 12943 		if (status != eap_status_ok)
       
 12944 		{
       
 12945 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12946 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12947 		}
       
 12948 		key_expansion.set_data_length(key_expansion_size);
       
 12949 
       
 12950 		status = tls_prf.tls_prf_output(
       
 12951 			key_expansion.get_data(key_expansion.get_data_length()),
       
 12952 			key_expansion.get_data_length());
       
 12953 		if (status != eap_status_ok)
       
 12954 		{
       
 12955 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12956 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12957 		}
       
 12958 
       
 12959 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 12960 
       
 12961 		u32_t key_offset = 0ul;
       
 12962 
       
 12963 		eap_variable_data_c *send_mac_key = &m_new_send_mac_key;
       
 12964 		eap_variable_data_c *receive_mac_key = &m_new_receive_mac_key;
       
 12965 		eap_variable_data_c *send_encryption_key = &m_new_send_encryption_key;
       
 12966 		eap_variable_data_c *receive_encryption_key = &m_new_receive_encryption_key;
       
 12967 		eap_variable_data_c *send_iv = &m_new_send_iv;
       
 12968 		eap_variable_data_c *receive_iv = &m_new_receive_iv;
       
 12969 
       
 12970 		if (m_is_client == false)
       
 12971 		{
       
 12972 			send_mac_key = &m_new_receive_mac_key;
       
 12973 			receive_mac_key = &m_new_send_mac_key;
       
 12974 			send_encryption_key = &m_new_receive_encryption_key;
       
 12975 			receive_encryption_key = &m_new_send_encryption_key;
       
 12976 			send_iv = &m_new_receive_iv;
       
 12977 			receive_iv = &m_new_send_iv;
       
 12978 		}
       
 12979 
       
 12980 		status = send_mac_key->set_copy_of_buffer(
       
 12981 			key_expansion.get_data_offset(key_offset, mac_key_length),
       
 12982 			mac_key_length);
       
 12983 		if (status != eap_status_ok)
       
 12984 		{
       
 12985 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12986 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12987 		}
       
 12988 		key_offset += mac_key_length;
       
 12989 
       
 12990 		status = receive_mac_key->set_copy_of_buffer(
       
 12991 			key_expansion.get_data_offset(key_offset, mac_key_length),
       
 12992 			mac_key_length);
       
 12993 		if (status != eap_status_ok)
       
 12994 		{
       
 12995 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 12996 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 12997 		}
       
 12998 		key_offset += mac_key_length;
       
 12999 
       
 13000 		status = send_encryption_key->set_copy_of_buffer(
       
 13001 			key_expansion.get_data_offset(key_offset, encryption_key_length),
       
 13002 			encryption_key_length);
       
 13003 		if (status != eap_status_ok)
       
 13004 		{
       
 13005 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13006 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 13007 		}
       
 13008 		key_offset += encryption_key_length;
       
 13009 
       
 13010 		status = receive_encryption_key->set_copy_of_buffer(
       
 13011 			key_expansion.get_data_offset(key_offset, encryption_key_length),
       
 13012 			encryption_key_length);
       
 13013 		if (status != eap_status_ok)
       
 13014 		{
       
 13015 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13016 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 13017 		}
       
 13018 		key_offset += encryption_key_length;
       
 13019 
       
 13020 		if (iv_length > 0ul)
       
 13021 		{
       
 13022 			status = send_iv->set_copy_of_buffer(
       
 13023 				key_expansion.get_data_offset(key_offset, iv_length),
       
 13024 				iv_length);
       
 13025 			if (status != eap_status_ok)
       
 13026 			{
       
 13027 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13028 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13029 			}
       
 13030 			key_offset += iv_length;
       
 13031 		}
       
 13032 		else
       
 13033 		{
       
 13034 			status = send_iv->init(0ul);
       
 13035 			if (status != eap_status_ok)
       
 13036 			{
       
 13037 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13038 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13039 			}
       
 13040 			send_iv->set_is_valid();
       
 13041 		}
       
 13042 
       
 13043 		if (iv_length > 0ul)
       
 13044 		{
       
 13045 			status = receive_iv->set_copy_of_buffer(
       
 13046 				key_expansion.get_data_offset(key_offset, iv_length),
       
 13047 				iv_length);
       
 13048 			if (status != eap_status_ok)
       
 13049 			{
       
 13050 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13051 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13052 			}
       
 13053 			key_offset += iv_length;
       
 13054 		}
       
 13055 		else
       
 13056 		{
       
 13057 			status = receive_iv->init(0ul);
       
 13058 			if (status != eap_status_ok)
       
 13059 			{
       
 13060 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13061 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13062 			}
       
 13063 			receive_iv->set_is_valid();
       
 13064 		}
       
 13065 
       
 13066 #if defined(USE_FAST_EAP_TYPE)
       
 13067 		if (session_key_seed_length > 0ul)
       
 13068 		{
       
 13069 			status = m_session_key_seed.set_copy_of_buffer(
       
 13070 				key_expansion.get_data_offset(key_offset, session_key_seed_length),
       
 13071 				session_key_seed_length);
       
 13072 			if (status != eap_status_ok)
       
 13073 			{
       
 13074 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13075 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13076 			}
       
 13077 			key_offset += session_key_seed_length;
       
 13078 		}
       
 13079 
       
 13080 		if (mschapv2_challenges_length > 0ul)
       
 13081 		{
       
 13082 			status = m_mschapv2_challenges.set_copy_of_buffer(
       
 13083 				key_expansion.get_data_offset(key_offset, mschapv2_challenges_length),
       
 13084 				mschapv2_challenges_length);
       
 13085 			if (status != eap_status_ok)
       
 13086 			{
       
 13087 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13088 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13089 			}
       
 13090 			key_offset += mschapv2_challenges_length;
       
 13091 		}
       
 13092 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 13093 
       
 13094 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 13095 
       
 13096 		EAP_TRACE_DATA_DEBUG(
       
 13097 			m_am_tools,
       
 13098 			TRACE_FLAGS_DEFAULT,
       
 13099 			(EAPL("TLS: generate_key_material(): m_master_secret"),
       
 13100 			 m_master_secret.get_data(),
       
 13101 			 m_master_secret.get_data_length()));
       
 13102 
       
 13103 		EAP_TRACE_DATA_DEBUG(
       
 13104 			m_am_tools,
       
 13105 			TRACE_FLAGS_DEFAULT,
       
 13106 			(EAPL("TLS: generate_key_material(): m_client_handshake_random_value"),
       
 13107 			 m_client_handshake_random_value.get_data(),
       
 13108 			 m_client_handshake_random_value.get_data_length()));
       
 13109 
       
 13110 		EAP_TRACE_DATA_DEBUG(
       
 13111 			m_am_tools,
       
 13112 			TRACE_FLAGS_DEFAULT,
       
 13113 			(EAPL("TLS: generate_key_material(): m_server_handshake_random_value"),
       
 13114 			 m_server_handshake_random_value.get_data(),
       
 13115 			 m_server_handshake_random_value.get_data_length()));
       
 13116 
       
 13117 		EAP_TRACE_DATA_DEBUG(
       
 13118 			m_am_tools,
       
 13119 			TRACE_FLAGS_DEFAULT,
       
 13120 			(EAPL("TLS: generate_key_material(): key_expansion"),
       
 13121 			 key_expansion.get_data(),
       
 13122 			 key_expansion.get_data_length()));
       
 13123 
       
 13124 
       
 13125 
       
 13126 		EAP_TRACE_DATA_DEBUG(
       
 13127 			m_am_tools,
       
 13128 			TRACE_FLAGS_DEFAULT,
       
 13129 			(EAPL("TLS: generate_key_material(): m_new_send_mac_key"),
       
 13130 			 m_new_send_mac_key.get_data(),
       
 13131 			 m_new_send_mac_key.get_data_length()));
       
 13132 
       
 13133 		EAP_TRACE_DATA_DEBUG(
       
 13134 			m_am_tools,
       
 13135 			TRACE_FLAGS_DEFAULT,
       
 13136 			(EAPL("TLS: generate_key_material(): m_new_receive_mac_key"),
       
 13137 			 m_new_receive_mac_key.get_data(),
       
 13138 			 m_new_receive_mac_key.get_data_length()));
       
 13139 
       
 13140 		EAP_TRACE_DATA_DEBUG(
       
 13141 			m_am_tools,
       
 13142 			TRACE_FLAGS_DEFAULT,
       
 13143 			(EAPL("TLS: generate_key_material(): m_new_send_encryption_key"),
       
 13144 			 m_new_send_encryption_key.get_data(),
       
 13145 			 m_new_send_encryption_key.get_data_length()));
       
 13146 
       
 13147 		EAP_TRACE_DATA_DEBUG(
       
 13148 			m_am_tools,
       
 13149 			TRACE_FLAGS_DEFAULT,
       
 13150 			(EAPL("TLS: generate_key_material(): m_new_receive_encryption_key"),
       
 13151 			 m_new_receive_encryption_key.get_data(),
       
 13152 			 m_new_receive_encryption_key.get_data_length()));
       
 13153 
       
 13154 		EAP_TRACE_DATA_DEBUG(
       
 13155 			m_am_tools,
       
 13156 			TRACE_FLAGS_DEFAULT,
       
 13157 			(EAPL("TLS: generate_key_material(): m_new_send_iv"),
       
 13158 			 m_new_send_iv.get_data(),
       
 13159 			 m_new_send_iv.get_data_length()));
       
 13160 
       
 13161 		EAP_TRACE_DATA_DEBUG(
       
 13162 			m_am_tools,
       
 13163 			TRACE_FLAGS_DEFAULT,
       
 13164 			(EAPL("TLS: generate_key_material(): m_new_receive_iv"),
       
 13165 			 m_new_receive_iv.get_data(),
       
 13166 			 m_new_receive_iv.get_data_length()));
       
 13167 
       
 13168 		if (m_session_key_seed.get_is_valid_data() == true)
       
 13169 		{
       
 13170 			EAP_TRACE_DATA_DEBUG(
       
 13171 				m_am_tools,
       
 13172 				TRACE_FLAGS_DEFAULT,
       
 13173 				(EAPL("TLS: generate_key_material(): m_session_key_seed"),
       
 13174 				 m_session_key_seed.get_data(),
       
 13175 				 m_session_key_seed.get_data_length()));
       
 13176 		}
       
 13177 
       
 13178 #if defined(USE_FAST_EAP_TYPE)
       
 13179 		if (m_mschapv2_challenges.get_is_valid_data() == true)
       
 13180 		{
       
 13181 			EAP_TRACE_DATA_DEBUG(
       
 13182 				m_am_tools,
       
 13183 				TRACE_FLAGS_DEFAULT,
       
 13184 				(EAPL("TLS: generate_key_material(): server_mschapv2_challenge"),
       
 13185 				 m_mschapv2_challenges.get_data(),
       
 13186 				 EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH));
       
 13187 
       
 13188 			EAP_TRACE_DATA_DEBUG(
       
 13189 				m_am_tools,
       
 13190 				TRACE_FLAGS_DEFAULT,
       
 13191 				(EAPL("TLS: generate_key_material(): client_mschapv2_challenge"),
       
 13192 				 m_mschapv2_challenges.get_data_offset(EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH, EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH),
       
 13193 				 EAP_FAST_MSCHAPV2_CHALLENGE_LENGTH));
       
 13194 		}
       
 13195 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 13196 
       
 13197 		m_key_material_generated = true;
       
 13198 
       
 13199 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 13200 	}
       
 13201 
       
 13202 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13203 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13204 }
       
 13205 
       
 13206 //--------------------------------------------------
       
 13207 
       
 13208 //
       
 13209 EAP_FUNC_EXPORT eap_status_e tls_record_c::set_tls_master_secret(
       
 13210 	const eap_variable_data_c * const master_secret,
       
 13211 	const eap_variable_data_c * const client_random,
       
 13212 	const eap_variable_data_c * const server_random)
       
 13213 {
       
 13214 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13215 
       
 13216 	EAP_TRACE_DEBUG(
       
 13217 		m_am_tools,
       
 13218 		TRACE_FLAGS_DEFAULT,
       
 13219 		(EAPL("TLS: this = 0x%08x, %s:     key_function: starts: tls_record_c::set_tls_master_secret()\n"),
       
 13220 		 this,
       
 13221 		 (m_is_client == true) ? "client": "server"));
       
 13222 
       
 13223 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_tls_master_secret()");
       
 13224 
       
 13225 	eap_variable_data_c label(m_am_tools);
       
 13226 	if (label.get_is_valid() == false)
       
 13227 	{
       
 13228 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 13229 	}
       
 13230 
       
 13231 	eap_status_e status = eap_status_process_general_error;
       
 13232 
       
 13233 	if (m_eap_type == eap_type_ttls)
       
 13234 	{
       
 13235 		status = label.add_data(
       
 13236 			EAP_TTLS_KEY_EXPANSION_LABEL,
       
 13237 			EAP_TTLS_KEY_EXPANSION_LABEL_LENGTH);
       
 13238 	}
       
 13239 	else if (m_eap_type == eap_type_peap
       
 13240 		&& m_peap_version == peap_version_1
       
 13241 		&& m_use_tppd_tls_peap == false)
       
 13242 	{
       
 13243 		status = label.add_data(
       
 13244 			EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_V1_DRAFT_5,
       
 13245 			EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_V1_DRAFT_5_LENGTH);
       
 13246 	}
       
 13247 	else
       
 13248 	{
       
 13249 		status = label.add_data(
       
 13250 			EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL,
       
 13251 			EAP_TLS_PEAP_CLIENT_ENCRYPTION_LABEL_LENGTH);
       
 13252 	}
       
 13253 
       
 13254 	if (status != eap_status_ok)
       
 13255 	{
       
 13256 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13257 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13258 	}
       
 13259 
       
 13260 
       
 13261 	status = get_tls_prf_data(
       
 13262 		master_secret,
       
 13263 		client_random,
       
 13264 		server_random,
       
 13265 		&label,
       
 13266 		&m_eap_master_session_key,
       
 13267 		EAP_TLS_PEAP_MASTER_SESSION_KEY_SIZE);
       
 13268 	if (status != eap_status_ok)
       
 13269 	{
       
 13270 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13271 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13272 	}
       
 13273 
       
 13274 	EAP_TRACE_DATA_DEBUG(
       
 13275 		m_am_tools,
       
 13276 		TRACE_FLAGS_DEFAULT,
       
 13277 		(EAPL("tls_record_c::set_tls_master_secret(): TLS_MSK"),
       
 13278 		 m_eap_master_session_key.get_data(EAP_TLS_PEAP_MSK_SIZE),
       
 13279 		 EAP_TLS_PEAP_MSK_SIZE));
       
 13280 
       
 13281 	EAP_TRACE_DATA_DEBUG(
       
 13282 		m_am_tools,
       
 13283 		TRACE_FLAGS_DEFAULT,
       
 13284 		(EAPL("tls_record_c::set_tls_master_secret(): TLS_EMSK"),
       
 13285 		 m_eap_master_session_key.get_data_offset(EAP_TLS_PEAP_MSK_SIZE, EAP_TLS_PEAP_EMSK_SIZE),
       
 13286 		 EAP_TLS_PEAP_EMSK_SIZE));
       
 13287 
       
 13288 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13289 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13290 }
       
 13291 
       
 13292 //--------------------------------------------------
       
 13293 
       
 13294 //
       
 13295 EAP_FUNC_EXPORT eap_status_e tls_record_c::get_ttls_implicit_challenge(
       
 13296 	eap_variable_data_c * const ttls_implicit_challenge,
       
 13297 	const u32_t required_ttls_implicit_challenge_length)
       
 13298 {
       
 13299 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13300 
       
 13301 	EAP_TRACE_DEBUG(
       
 13302 		m_am_tools,
       
 13303 		TRACE_FLAGS_DEFAULT,
       
 13304 		(EAPL("TLS: this = 0x%08x, %s:     key_function: starts: tls_record_c::get_ttls_implicit_challenge()\n"),
       
 13305 		 this,
       
 13306 		 (m_is_client == true) ? "client": "server"));
       
 13307 
       
 13308 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_ttls_implicit_challenge()");
       
 13309 
       
 13310 	eap_variable_data_c label(m_am_tools);
       
 13311 	if (label.get_is_valid() == false)
       
 13312 	{
       
 13313 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 13314 	}
       
 13315 
       
 13316 
       
 13317 	eap_status_e status = eap_status_process_general_error;
       
 13318 
       
 13319 	status = label.add_data(
       
 13320 		EAP_TTLS_IMPLICIT_CHALLENGE_LABEL,
       
 13321 		EAP_TTLS_IMPLICIT_CHALLENGE_LABEL_LENGTH);
       
 13322 	if (status != eap_status_ok)
       
 13323 	{
       
 13324 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13325 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13326 	}
       
 13327 
       
 13328 	status = get_tls_prf_data(
       
 13329 		&m_master_secret,
       
 13330 		&m_client_handshake_random_value,
       
 13331 		&m_server_handshake_random_value,
       
 13332 		&label,
       
 13333 		ttls_implicit_challenge,
       
 13334 		required_ttls_implicit_challenge_length);
       
 13335 	if (status != eap_status_ok)
       
 13336 	{
       
 13337 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13338 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13339 	}
       
 13340 
       
 13341 	EAP_TRACE_DATA_DEBUG(
       
 13342 		m_am_tools,
       
 13343 		TRACE_FLAGS_DEFAULT,
       
 13344 		(EAPL("tls_record_c::get_ttls_implicit_challenge(): ttls_implicit_challenge"),
       
 13345 		 ttls_implicit_challenge->get_data(),
       
 13346 		 ttls_implicit_challenge->get_data_length()));
       
 13347 
       
 13348 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13349 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13350 }
       
 13351 
       
 13352 //--------------------------------------------------
       
 13353 
       
 13354 //
       
 13355 EAP_FUNC_EXPORT eap_status_e tls_record_c::get_tls_prf_data(
       
 13356 	const eap_variable_data_c * const master_secret,
       
 13357 	const eap_variable_data_c * const client_random,
       
 13358 	const eap_variable_data_c * const server_random,
       
 13359 	const eap_variable_data_c * const label,
       
 13360 	eap_variable_data_c * const prf_data,
       
 13361 	const u32_t required_prf_data_length)
       
 13362 {
       
 13363 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13364 
       
 13365 	EAP_TRACE_DEBUG(
       
 13366 		m_am_tools,
       
 13367 		TRACE_FLAGS_DEFAULT,
       
 13368 		(EAPL("TLS: this = 0x%08x, %s:     key_function: starts: tls_record_c::get_tls_prf_data()\n"),
       
 13369 		 this,
       
 13370 		 (m_is_client == true) ? "client": "server"));
       
 13371 
       
 13372 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_tls_prf_data()");
       
 13373 
       
 13374 	eap_status_e status = eap_status_process_general_error;
       
 13375 
       
 13376 	eap_variable_data_c seed(m_am_tools);
       
 13377 	if (seed.get_is_valid() == false)
       
 13378 	{
       
 13379 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 13380 	}
       
 13381 
       
 13382 	status = seed.set_copy_of_buffer(client_random);
       
 13383 	if (status != eap_status_ok)
       
 13384 	{
       
 13385 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13386 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13387 	}
       
 13388 
       
 13389 	status = seed.add_data(server_random);
       
 13390 	if (status != eap_status_ok)
       
 13391 	{
       
 13392 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13393 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13394 	}
       
 13395 
       
 13396 	crypto_tls_prf_c tls_prf(m_am_tools);
       
 13397 
       
 13398 	status = tls_prf.tls_prf_init(
       
 13399 		master_secret,
       
 13400 		label,
       
 13401 		&seed);
       
 13402 	if (status != eap_status_ok)
       
 13403 	{
       
 13404 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13405 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13406 	}
       
 13407 
       
 13408 	status = prf_data->set_buffer_length(
       
 13409 		required_prf_data_length);
       
 13410 	if (status != eap_status_ok)
       
 13411 	{
       
 13412 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13413 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13414 	}
       
 13415 	prf_data->set_data_length(required_prf_data_length);
       
 13416 
       
 13417 	status = tls_prf.tls_prf_output(
       
 13418 		prf_data->get_data(),
       
 13419 		prf_data->get_data_length());
       
 13420 	if (status != eap_status_ok)
       
 13421 	{
       
 13422 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13423 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13424 	}
       
 13425 
       
 13426 	EAP_TRACE_DATA_DEBUG(
       
 13427 		m_am_tools,
       
 13428 		TRACE_FLAGS_DEFAULT,
       
 13429 		(EAPL("tls_record_c::get_tls_prf_data(): prf_data"),
       
 13430 		 prf_data->get_data(),
       
 13431 		 prf_data->get_data_length()));
       
 13432 
       
 13433 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13434 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13435 }
       
 13436 
       
 13437 //--------------------------------------------------
       
 13438 
       
 13439 EAP_FUNC_EXPORT eap_status_e tls_record_c::change_cipher_spec(
       
 13440 	const bool send_when_true)
       
 13441 {
       
 13442 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13443 
       
 13444 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 13445 	EAP_TRACE_DEBUG(
       
 13446 		m_am_tools,
       
 13447 		TRACE_FLAGS_DEFAULT,
       
 13448 		(EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::change_cipher_spec(%s)\n"),
       
 13449 		 this,
       
 13450 		 (m_is_client == true) ? "client": "server",
       
 13451 		 (send_when_true == true) ? "send": "receive"));
       
 13452 
       
 13453 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::change_cipher_spec()");
       
 13454 
       
 13455 	eap_status_e status = eap_status_illegal_cipher_suite;
       
 13456 
       
 13457 	if (m_selected_cipher_suite != tls_cipher_suites_none)
       
 13458 	{
       
 13459 		status = eap_status_ok;
       
 13460 
       
 13461 		if (send_when_true == true)
       
 13462 		{
       
 13463 			status = set_send_cipher_suite(m_selected_cipher_suite);
       
 13464 			if (status != eap_status_ok)
       
 13465 			{
       
 13466 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13467 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13468 			}
       
 13469 
       
 13470 			EAP_TRACE_DEBUG(m_am_tools, 
       
 13471 					TRACE_FLAGS_DEFAULT,
       
 13472 					(EAPL("TLS: change_cipher_spec(): send to %s\n"),
       
 13473 						eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite)));
       
 13474 
       
 13475 		}
       
 13476 		else
       
 13477 		{
       
 13478 			status = set_receive_cipher_suite(m_selected_cipher_suite);
       
 13479 			if (status != eap_status_ok)
       
 13480 			{
       
 13481 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13482 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 13483 			}
       
 13484 
       
 13485 			EAP_TRACE_DEBUG(m_am_tools, 
       
 13486 					TRACE_FLAGS_DEFAULT,
       
 13487 					(EAPL("TLS: change_cipher_spec(): receive to %s\n"),
       
 13488 						eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite)));
       
 13489 		}
       
 13490 
       
 13491 		// This will initialize encryption, decryption and MAC algorithms.
       
 13492 		status = cipher_suite_initialization(send_when_true);
       
 13493 		if (status != eap_status_ok)
       
 13494 		{
       
 13495 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13496 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 13497 		}
       
 13498 	}
       
 13499 
       
 13500 	if (status == eap_status_ok)
       
 13501 	{
       
 13502 		if (send_when_true == true)
       
 13503 		{
       
 13504 			m_send_compression_method = m_selected_compression_method;
       
 13505 
       
 13506 			EAP_TRACE_DEBUG(m_am_tools, 
       
 13507 					TRACE_FLAGS_DEFAULT,
       
 13508 					(EAPL("TLS: change_cipher_spec() send to %s\n"),
       
 13509 						eap_tls_trace_string_c::get_compression_method_string(
       
 13510 							m_send_compression_method)));
       
 13511 		}
       
 13512 		else
       
 13513 		{
       
 13514 			m_receive_compression_method = m_selected_compression_method;
       
 13515 
       
 13516 			EAP_TRACE_DEBUG(m_am_tools, 
       
 13517 					TRACE_FLAGS_DEFAULT,
       
 13518 					(EAPL("TLS: change_cipher_spec() receive to %s\n"),
       
 13519 						eap_tls_trace_string_c::get_compression_method_string(
       
 13520 							m_receive_compression_method)));
       
 13521 		}
       
 13522 	}
       
 13523 
       
 13524 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13525 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13526 }
       
 13527 
       
 13528 //--------------------------------------------------
       
 13529 
       
 13530 EAP_FUNC_EXPORT eap_status_e tls_record_c::new_record_message(
       
 13531 	tls_record_message_c ** const tls_record_message,
       
 13532 	const tls_record_protocol_e protocol)
       
 13533 {
       
 13534 	EAP_TRACE_DEBUG(
       
 13535 		m_am_tools,
       
 13536 		TRACE_FLAGS_DEFAULT,
       
 13537 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::new_record_message()\n"),
       
 13538 		(m_is_client == true ? "client": "server")));
       
 13539 
       
 13540 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::new_record_message()");
       
 13541 
       
 13542 	bool add_new_record = false;
       
 13543 
       
 13544 	eap_automatic_variable_c<tls_record_message_c> automatic_tls_record_message(
       
 13545 		m_am_tools,
       
 13546 		0);
       
 13547 
       
 13548 	eap_status_e status = eap_status_process_general_error;
       
 13549 
       
 13550 
       
 13551 	*tls_record_message = m_new_tls_message.get_last_record_message();
       
 13552 	if (*tls_record_message != 0
       
 13553 		&& (*tls_record_message)->get_protocol() != protocol)
       
 13554 	{
       
 13555 		// We need a new different protocol.
       
 13556 		*tls_record_message = 0;
       
 13557 	}
       
 13558 
       
 13559 	if (m_use_separate_tls_record == true)
       
 13560 	{
       
 13561 		// Every message is in separate TLS-record.
       
 13562 		*tls_record_message = 0;
       
 13563 	}
       
 13564 
       
 13565 	if (*tls_record_message == 0)
       
 13566 	{
       
 13567 		*tls_record_message = new tls_record_message_c(m_am_tools, this, m_is_client);
       
 13568 			
       
 13569 		automatic_tls_record_message.set_variable(*tls_record_message);
       
 13570 		
       
 13571 		if (*tls_record_message == 0
       
 13572 			|| (*tls_record_message)->get_is_valid() == false)
       
 13573 		{
       
 13574 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13575 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 13576 		}
       
 13577 		
       
 13578 		status = (*tls_record_message)->set_protocol(protocol);
       
 13579 		if (status != eap_status_ok)
       
 13580 		{
       
 13581 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13582 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 13583 		}
       
 13584 		
       
 13585 		status = (*tls_record_message)->set_version(tls_version_3_1);
       
 13586 		if (status != eap_status_ok)
       
 13587 		{
       
 13588 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13589 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 13590 		}
       
 13591 		
       
 13592 		add_new_record = true;
       
 13593 	}
       
 13594 	
       
 13595 	if (add_new_record == true)
       
 13596 	{
       
 13597 		// Note m_new_tls_message free message on any case.
       
 13598 		automatic_tls_record_message.do_not_free_variable();
       
 13599 
       
 13600 		bool includes_tls_handshake_message = false;
       
 13601 
       
 13602 		if (protocol == tls_record_protocol_handshake)
       
 13603 		{
       
 13604 			includes_tls_handshake_message = true;
       
 13605 		}
       
 13606 
       
 13607 		status = m_new_tls_message.add_record_message(
       
 13608 			(*tls_record_message),
       
 13609 			true,
       
 13610 			includes_tls_handshake_message);
       
 13611 		if (status != eap_status_ok)
       
 13612 		{
       
 13613 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13614 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 13615 		}
       
 13616 	}
       
 13617 	else
       
 13618 	{
       
 13619 		status = eap_status_ok;
       
 13620 	}
       
 13621 
       
 13622 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13623 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13624 }
       
 13625 
       
 13626 //--------------------------------------------------
       
 13627 
       
 13628 EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message(
       
 13629 	tls_handshake_message_c * const tls_handshake_message)
       
 13630 {
       
 13631 	EAP_TRACE_DEBUG(
       
 13632 		m_am_tools,
       
 13633 		TRACE_FLAGS_DEFAULT,
       
 13634 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"),
       
 13635 		(m_is_client == true ? "client": "server")));
       
 13636 
       
 13637 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()");
       
 13638 
       
 13639 	tls_record_message_c *tls_record_message = 0;
       
 13640 
       
 13641 	eap_status_e status = new_record_message(
       
 13642 		&tls_record_message,
       
 13643 		tls_record_protocol_handshake);
       
 13644 	if (status != eap_status_ok
       
 13645 		|| tls_record_message == 0)
       
 13646 	{
       
 13647 		delete tls_handshake_message;
       
 13648 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13649 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13650 	}
       
 13651 
       
 13652 	status = tls_record_message->add_handshake_message(
       
 13653 		tls_handshake_message,
       
 13654 		true);
       
 13655 	if (status != eap_status_ok)
       
 13656 	{
       
 13657 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13658 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13659 	}
       
 13660 
       
 13661 	status = tls_handshake_message->create_message_data();
       
 13662 	if (status != eap_status_ok)
       
 13663 	{
       
 13664 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13665 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13666 	}
       
 13667 
       
 13668 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13669 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13670 }
       
 13671 
       
 13672 //--------------------------------------------------
       
 13673 
       
 13674 EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message(
       
 13675 	tls_change_cipher_spec_message_c * const change_cipher_spec_message)
       
 13676 {
       
 13677 	EAP_TRACE_DEBUG(
       
 13678 		m_am_tools,
       
 13679 		TRACE_FLAGS_DEFAULT,
       
 13680 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"),
       
 13681 		(m_is_client == true ? "client": "server")));
       
 13682 
       
 13683 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()");
       
 13684 
       
 13685 	tls_record_message_c *tls_record_message = 0;
       
 13686 
       
 13687 	eap_status_e status = new_record_message(
       
 13688 		&tls_record_message,
       
 13689 		tls_record_protocol_change_cipher_spec);
       
 13690 	if (status != eap_status_ok
       
 13691 		|| tls_record_message == 0)
       
 13692 	{
       
 13693 		delete change_cipher_spec_message;
       
 13694 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13695 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13696 	}
       
 13697 
       
 13698 	status = tls_record_message->add_change_cipher_spec_message(
       
 13699 		change_cipher_spec_message,
       
 13700 		true);
       
 13701 	if (status != eap_status_ok)
       
 13702 	{
       
 13703 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13704 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13705 	}
       
 13706 
       
 13707 	status = change_cipher_spec_message->create_message_data();
       
 13708 	if (status != eap_status_ok)
       
 13709 	{
       
 13710 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13711 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13712 	}
       
 13713 
       
 13714 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13715 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13716 }
       
 13717 
       
 13718 //--------------------------------------------------
       
 13719 
       
 13720 EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message(
       
 13721 	tls_alert_message_c * const alert_message)
       
 13722 {
       
 13723 	EAP_TRACE_DEBUG(
       
 13724 		m_am_tools,
       
 13725 		TRACE_FLAGS_DEFAULT,
       
 13726 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"),
       
 13727 		(m_is_client == true ? "client": "server")));
       
 13728 
       
 13729 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()");
       
 13730 
       
 13731 	tls_record_message_c *tls_record_message = 0;
       
 13732 
       
 13733 	eap_status_e status = new_record_message(
       
 13734 		&tls_record_message,
       
 13735 		tls_record_protocol_alert);
       
 13736 	if (status != eap_status_ok
       
 13737 		|| tls_record_message == 0)
       
 13738 	{
       
 13739 		delete alert_message;
       
 13740 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13741 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13742 	}
       
 13743 
       
 13744 	status = tls_record_message->add_alert_message(
       
 13745 		alert_message,
       
 13746 		true);
       
 13747 	if (status != eap_status_ok)
       
 13748 	{
       
 13749 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13750 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13751 	}
       
 13752 
       
 13753 	status = alert_message->create_message_data();
       
 13754 	if (status != eap_status_ok)
       
 13755 	{
       
 13756 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13757 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13758 	}
       
 13759 
       
 13760 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13761 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13762 }
       
 13763 
       
 13764 //--------------------------------------------------
       
 13765 
       
 13766 EAP_FUNC_EXPORT eap_status_e tls_record_c::add_record_message(
       
 13767 	tls_application_data_message_c * const application_data_message)
       
 13768 {
       
 13769 	EAP_TRACE_DEBUG(
       
 13770 		m_am_tools,
       
 13771 		TRACE_FLAGS_DEFAULT,
       
 13772 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::add_record_message()\n"),
       
 13773 		(m_is_client == true ? "client": "server")));
       
 13774 
       
 13775 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::add_record_message()");
       
 13776 
       
 13777 	tls_record_message_c *tls_record_message = 0;
       
 13778 
       
 13779 	eap_status_e status = new_record_message(
       
 13780 		&tls_record_message,
       
 13781 		tls_record_protocol_application_data);
       
 13782 	if (status != eap_status_ok
       
 13783 		|| tls_record_message == 0)
       
 13784 	{
       
 13785 		delete application_data_message;
       
 13786 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13787 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13788 	}
       
 13789 
       
 13790 	status = tls_record_message->add_application_data_message(
       
 13791 		application_data_message,
       
 13792 		true);
       
 13793 	if (status != eap_status_ok)
       
 13794 	{
       
 13795 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13796 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13797 	}
       
 13798 
       
 13799 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13800 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13801 }
       
 13802 
       
 13803 //--------------------------------------------------
       
 13804 
       
 13805 EAP_FUNC_EXPORT eap_status_e tls_record_c::allocate_handshake_message(
       
 13806 	tls_handshake_message_c ** const tls_handshake_message,
       
 13807 	eap_automatic_variable_c<tls_handshake_message_c> * const automatic_tls_handshake_message,
       
 13808 	const tls_handshake_type_e handshake_type)
       
 13809 {
       
 13810 	EAP_TRACE_DEBUG(
       
 13811 		m_am_tools,
       
 13812 		TRACE_FLAGS_DEFAULT,
       
 13813 		(EAPL("TLS: %s: receive_function: starts: tls_record_c::allocate_handshake_message()\n"),
       
 13814 		(m_is_client == true ? "client": "server")));
       
 13815 
       
 13816 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::allocate_handshake_message()");
       
 13817 
       
 13818 	*tls_handshake_message
       
 13819 		= new tls_handshake_message_c(m_am_tools, this, m_is_client);
       
 13820 	
       
 13821 	automatic_tls_handshake_message->set_variable(*tls_handshake_message);
       
 13822 
       
 13823 	if (*tls_handshake_message == 0
       
 13824 		|| (*tls_handshake_message)->get_is_valid() == false)
       
 13825 	{
       
 13826 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13827 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 13828 	}
       
 13829 
       
 13830 	eap_status_e status = (*tls_handshake_message)->set_handshake_type(
       
 13831 		handshake_type);
       
 13832 
       
 13833 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13834 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13835 }
       
 13836 
       
 13837 //--------------------------------------------------
       
 13838 
       
 13839 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_hello_request()
       
 13840 {
       
 13841 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13842 
       
 13843 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 13844 	EAP_TRACE_DEBUG(
       
 13845 		m_am_tools,
       
 13846 		TRACE_FLAGS_DEFAULT,
       
 13847 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_hello_request()\n"),
       
 13848 		 this,
       
 13849 		 (m_is_client == true ? "client": "server")));
       
 13850 
       
 13851 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_hello_request()");
       
 13852 
       
 13853 	// This is an empty message.
       
 13854 
       
 13855 	tls_handshake_message_c *tls_handshake_message = 0;
       
 13856 
       
 13857 	eap_automatic_variable_c<tls_handshake_message_c>
       
 13858 		automatic_tls_handshake_message(m_am_tools);
       
 13859 
       
 13860 	eap_status_e status = allocate_handshake_message(
       
 13861 		&tls_handshake_message,
       
 13862 		&automatic_tls_handshake_message,
       
 13863 		tls_handshake_type_hello_request);
       
 13864 
       
 13865 	// Note add_record_message() frees message on any case.
       
 13866 	automatic_tls_handshake_message.do_not_free_variable();
       
 13867 
       
 13868 	status = add_record_message(tls_handshake_message);
       
 13869 	if (status != eap_status_ok)
       
 13870 	{
       
 13871 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13872 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13873 	}
       
 13874 
       
 13875 	set_state(tls_peap_state_wait_handshake_type_client_hello);
       
 13876 
       
 13877 	// --------------------------------------------------------------------
       
 13878 
       
 13879 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13880 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 13881 }
       
 13882 
       
 13883 //--------------------------------------------------
       
 13884 
       
 13885 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_client_hello()
       
 13886 {
       
 13887 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13888 
       
 13889 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 13890 
       
 13891 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 13892 	EAP_TRACE_DEBUG(
       
 13893 		m_am_tools,
       
 13894 		TRACE_FLAGS_DEFAULT,
       
 13895 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_client_hello(): privacy_handshake_state=%d=%s, session_type=%s\n"),
       
 13896 		 this,
       
 13897 		 (m_is_client == true ? "client": "server"),
       
 13898 		 m_tls_identity_privacy_handshake_state,
       
 13899 		 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(m_tls_identity_privacy_handshake_state),
       
 13900 		 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)));
       
 13901 #else
       
 13902 	EAP_TRACE_DEBUG(
       
 13903 		m_am_tools,
       
 13904 		TRACE_FLAGS_DEFAULT,
       
 13905 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_client_hello(): privacy_handshake_state=%d=%s\n"),
       
 13906 		this,
       
 13907 		(m_is_client == true ? "client": "server"),
       
 13908 		0,
       
 13909 		""));
       
 13910 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 13911 
       
 13912 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_client_hello()");
       
 13913 
       
 13914 	// 0                   1                   2                   3   
       
 13915 	//  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 
       
 13916 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 13917 	//                 | Version: 3    | Version: 1    |               |
       
 13918 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 13919 	// |                                                               |
       
 13920 	// +                                                               +
       
 13921 	// |                                                               |
       
 13922 	// +                                                               +
       
 13923 	// |          ClientRandomValue                                    |
       
 13924 	// +              (32 bytes)                       +-+-+-+-+-+-+-+-+
       
 13925 	// |                                               | ID length     |
       
 13926 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 13927 	// |                                                               |
       
 13928 	// +                                                               +
       
 13929 	// |                Session ID                                     |
       
 13930 	// +             (maximum 32 bytes)                                +
       
 13931 	// |                                                               |
       
 13932 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 13933 	// | CipherSuite length            | CipherSuite 1                 |
       
 13934 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 13935 	// | CipherSuite 2                 | CipherSuite 3                 |
       
 13936 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 13937 	// | CipherSuite 4                 | Cmp length    | Cmp 1         |
       
 13938 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 13939 	// | Cmp 2         | Cmp 3         |  extensions ...               |
       
 13940 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 13941 
       
 13942 	eap_status_e status(eap_status_ok);
       
 13943 
       
 13944 	status = message_hash_init();
       
 13945 	if (status != eap_status_ok)
       
 13946 	{
       
 13947 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13948 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13949 	}
       
 13950 
       
 13951 	tls_handshake_message_c *tls_handshake_message = 0;
       
 13952 
       
 13953 	eap_automatic_variable_c<tls_handshake_message_c>
       
 13954 		automatic_tls_handshake_message(m_am_tools);
       
 13955 
       
 13956 	status = allocate_handshake_message(
       
 13957 		&tls_handshake_message,
       
 13958 		&automatic_tls_handshake_message,
       
 13959 		tls_handshake_type_client_hello);
       
 13960 	if (status != eap_status_ok)
       
 13961 	{
       
 13962 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13963 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13964 	}
       
 13965 
       
 13966 	u32_t tmp_gmt_unix_time_network_order = eap_htonl(m_am_tools->get_gmt_unix_time());
       
 13967 	eap_variable_data_c tmp_client_random(m_am_tools);
       
 13968 
       
 13969 	status = tmp_client_random.set_buffer_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE);
       
 13970 	if (status != eap_status_ok)
       
 13971 	{
       
 13972 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13973 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13974 	}
       
 13975 	tmp_client_random.set_data_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE);
       
 13976 
       
 13977 	crypto_random_c rand(m_am_tools);
       
 13978 
       
 13979 	status = rand.get_rand_bytes(
       
 13980 		tmp_client_random.get_data(tmp_client_random.get_data_length()),
       
 13981 		tmp_client_random.get_data_length());
       
 13982 	if (status != eap_status_ok)
       
 13983 	{
       
 13984 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13985 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 13986 	}
       
 13987 
       
 13988 	// Sets the first bytes to GMT unix time.
       
 13989 	u8_t *p_gmt_unix_time = reinterpret_cast<u8_t *>(tmp_client_random.get_data(sizeof(u32_t)));
       
 13990 	if (p_gmt_unix_time == 0)
       
 13991 	{
       
 13992 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 13993 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 13994 	}
       
 13995 	m_am_tools->memmove(p_gmt_unix_time, &tmp_gmt_unix_time_network_order, sizeof(tmp_gmt_unix_time_network_order));
       
 13996 
       
 13997 
       
 13998 	status = m_client_handshake_random_value.set_copy_of_buffer(
       
 13999 		&tmp_client_random);
       
 14000 	if (status != eap_status_ok)
       
 14001 	{
       
 14002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14003 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14004 	}
       
 14005 
       
 14006 
       
 14007 	status = tls_handshake_message->set_random_value(
       
 14008 		&tmp_client_random);
       
 14009 	if (status != eap_status_ok)
       
 14010 	{
       
 14011 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14012 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14013 	}
       
 14014 
       
 14015 	if (m_tls_session_type == tls_session_type_original_session_resumption
       
 14016 		&& m_session_id.get_is_valid_data() == true)
       
 14017 	{
       
 14018 		status = tls_handshake_message->set_session_id(
       
 14019 			&m_session_id);
       
 14020 		if (status != eap_status_ok)
       
 14021 		{
       
 14022 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14023 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14024 		}
       
 14025 	}
       
 14026 
       
 14027 	// --------------------------------------------------------------------
       
 14028 
       
 14029 	// This copies proposed cipher suites to tls_handshake_message.
       
 14030 	status = tls_handshake_message->set_cipher_suites(&m_proposed_cipher_suites);
       
 14031 	if (status != eap_status_ok)
       
 14032 	{
       
 14033 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14034 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14035 	}
       
 14036 
       
 14037 	// --------------------------------------------------------------------
       
 14038 
       
 14039 	status = tls_handshake_message->set_compression_methods(&m_proposed_compression_methods);
       
 14040 	if (status != eap_status_ok)
       
 14041 	{
       
 14042 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14043 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14044 	}
       
 14045 
       
 14046 	// --------------------------------------------------------------------
       
 14047 
       
 14048 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 14049 
       
 14050 	{
       
 14051 		status = tls_handshake_message->set_tls_extensions(&m_supported_tls_extensions);
       
 14052 		if (status != eap_status_ok)
       
 14053 		{
       
 14054 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14055 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14056 		}
       
 14057 
       
 14058 	}
       
 14059 
       
 14060 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 14061 
       
 14062 	// --------------------------------------------------------------------
       
 14063 
       
 14064 	// Note add_record_message() frees message on any case.
       
 14065 	automatic_tls_handshake_message.do_not_free_variable();
       
 14066 
       
 14067 	status = add_record_message(tls_handshake_message);
       
 14068 	if (status != eap_status_ok)
       
 14069 	{
       
 14070 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14071 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14072 	}
       
 14073 
       
 14074 	// --------------------------------------------------------------------
       
 14075 
       
 14076 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14077 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 14078 }
       
 14079 
       
 14080 //--------------------------------------------------
       
 14081 
       
 14082 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_server_hello(
       
 14083 	const u16_t /*selected_cipher_suite*/,
       
 14084 	const u8_t /*selected_compression_method*/)
       
 14085 {
       
 14086 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14087 
       
 14088 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 14089 	EAP_TRACE_DEBUG(
       
 14090 		m_am_tools,
       
 14091 		TRACE_FLAGS_DEFAULT,
       
 14092 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_server_hello()\n"),
       
 14093 		 this,
       
 14094 		(m_is_client == true ? "client": "server")));
       
 14095 
       
 14096 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_server_hello()");
       
 14097 
       
 14098 	// 0                   1                   2                   3   
       
 14099 	//  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 
       
 14100 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14101 	//                 | Version: 3    | Version: 1    |               |
       
 14102 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 14103 	// |                                                               |
       
 14104 	// +                                                               +
       
 14105 	// |                                                               |
       
 14106 	// +                                                               +
       
 14107 	// |          ServerRandomValue                                    |
       
 14108 	// +              (32 bytes)                       +-+-+-+-+-+-+-+-+
       
 14109 	// |                                               | ID length     |
       
 14110 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14111 	// |                                                               |
       
 14112 	// +                                                               +
       
 14113 	// |                Session ID                                     |
       
 14114 	// +             (maximum 32 bytes)                                +
       
 14115 	// |                                                               |
       
 14116 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14117 	// | CipherSuite                   | Cmp           | extensions ... 
       
 14118 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14119 
       
 14120 	tls_handshake_message_c *tls_handshake_message = 0;
       
 14121 
       
 14122 	eap_automatic_variable_c<tls_handshake_message_c>
       
 14123 		automatic_tls_handshake_message(m_am_tools);
       
 14124 
       
 14125 	eap_status_e status = allocate_handshake_message(
       
 14126 		&tls_handshake_message,
       
 14127 		&automatic_tls_handshake_message,
       
 14128 		tls_handshake_type_server_hello);
       
 14129 	if (status != eap_status_ok)
       
 14130 	{
       
 14131 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14132 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14133 	}
       
 14134 
       
 14135 	// --------------------------------------------------------------------
       
 14136 
       
 14137 	u32_t tmp_gmt_unix_time_network_order = eap_htonl(m_am_tools->get_gmt_unix_time());
       
 14138 	eap_variable_data_c tmp_server_random(m_am_tools);
       
 14139 
       
 14140 	status = tmp_server_random.set_buffer_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE);
       
 14141 	if (status != eap_status_ok)
       
 14142 	{
       
 14143 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14144 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14145 	}
       
 14146 	tmp_server_random.set_data_length(TLS_HANDSHAKE_RANDOM_VALUE_SIZE);
       
 14147 
       
 14148 	crypto_random_c rand(m_am_tools);
       
 14149 
       
 14150 	status = rand.get_rand_bytes(
       
 14151 		tmp_server_random.get_data(tmp_server_random.get_data_length()),
       
 14152 		tmp_server_random.get_data_length());
       
 14153 	if (status != eap_status_ok)
       
 14154 	{
       
 14155 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14156 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14157 	}
       
 14158 
       
 14159 	// Sets the first bytes to GMT unix time.
       
 14160 	u8_t *p_gmt_unix_time = reinterpret_cast<u8_t *>(tmp_server_random.get_data(sizeof(u32_t)));
       
 14161 	if (p_gmt_unix_time == 0)
       
 14162 	{
       
 14163 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14164 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 14165 	}
       
 14166 	m_am_tools->memmove(p_gmt_unix_time, &tmp_gmt_unix_time_network_order, sizeof(tmp_gmt_unix_time_network_order));
       
 14167 
       
 14168 	status = m_server_handshake_random_value.set_copy_of_buffer(
       
 14169 		&tmp_server_random);
       
 14170 	if (status != eap_status_ok)
       
 14171 	{
       
 14172 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14173 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14174 	}
       
 14175 
       
 14176 	// --------------------------------------------------------------------
       
 14177 
       
 14178 	status = tls_handshake_message->set_random_value(
       
 14179 		&tmp_server_random);
       
 14180 	if (status != eap_status_ok)
       
 14181 	{
       
 14182 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14183 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14184 	}
       
 14185 
       
 14186 	// --------------------------------------------------------------------
       
 14187 
       
 14188 	if ((m_tls_session_type == tls_session_type_full_authentication
       
 14189 #if defined(USE_FAST_EAP_TYPE)	
       
 14190 		 || m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP
       
 14191 #endif //#if defined(USE_FAST_EAP_TYPE)		 
       
 14192 		 )		 
       
 14193 		&& m_server_offers_new_session_id == true)
       
 14194 	{
       
 14195 		// We create a new session.
       
 14196 		status = m_session_id.set_buffer_length(TLS_SESSION_ID_SIZE);
       
 14197 		if (status != eap_status_ok)
       
 14198 		{
       
 14199 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14200 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14201 		}
       
 14202 		m_session_id.set_data_length(TLS_SESSION_ID_SIZE);
       
 14203 
       
 14204 		status = rand.get_rand_bytes(
       
 14205 			m_session_id.get_data(m_session_id.get_data_length()),
       
 14206 			m_session_id.get_data_length());
       
 14207 		if (status != eap_status_ok)
       
 14208 		{
       
 14209 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14210 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14211 		}
       
 14212 	}
       
 14213 
       
 14214 	// --------------------------------------------------------------------
       
 14215 
       
 14216 	status = tls_handshake_message->set_session_id(
       
 14217 		&m_session_id);
       
 14218 	if (status != eap_status_ok)
       
 14219 	{
       
 14220 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14221 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14222 	}
       
 14223 
       
 14224 	// --------------------------------------------------------------------
       
 14225 
       
 14226 	{
       
 14227 		EAP_TRACE_DEBUG(
       
 14228 			m_am_tools,
       
 14229 			TRACE_FLAGS_DEFAULT,
       
 14230 			(EAPL("%s: TLS/PEAP selected cipher_suite %s\n"),
       
 14231 			 (m_is_client == true ? "client": "server"),
       
 14232 			 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite)));
       
 14233 	}
       
 14234 
       
 14235 	status = tls_handshake_message->set_selected_cipher_suite(
       
 14236 		m_selected_cipher_suite);
       
 14237 	if (status != eap_status_ok)
       
 14238 	{
       
 14239 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14240 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14241 	}
       
 14242 
       
 14243 	// --------------------------------------------------------------------
       
 14244 
       
 14245 	status = tls_handshake_message->set_selected_compression_method(
       
 14246 		m_selected_compression_method);
       
 14247 	if (status != eap_status_ok)
       
 14248 	{
       
 14249 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14250 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14251 	}
       
 14252 
       
 14253 	// --------------------------------------------------------------------
       
 14254 
       
 14255 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 14256 
       
 14257 #if defined(USE_FAST_EAP_TYPE)
       
 14258 	if (m_eap_type != eap_type_fast) // EAP-FAST does not use session ticket in ServerHello message.
       
 14259 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 14260 	{
       
 14261 		status = tls_handshake_message->set_tls_extensions(&m_supported_tls_extensions);
       
 14262 		if (status != eap_status_ok)
       
 14263 		{
       
 14264 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14265 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14266 		}
       
 14267 	}
       
 14268 
       
 14269 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 14270 
       
 14271 	// --------------------------------------------------------------------
       
 14272 
       
 14273 	if (m_tls_session_type == tls_session_type_original_session_resumption
       
 14274 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 14275 		|| m_tls_session_type == tls_session_type_stateless_session_resumption
       
 14276 #if defined(USE_FAST_EAP_TYPE)
       
 14277 		|| m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption
       
 14278 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 14279 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 14280 		)
       
 14281 	{
       
 14282 
       
 14283 #if defined(USE_FAST_EAP_TYPE)
       
 14284 		if (m_eap_type == eap_type_fast
       
 14285 			&& m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
 14286 		{
       
 14287 			// Generates master secret from PAC-Key.
       
 14288 			// Parameter resumed_master_secret includes PAC-Key.
       
 14289 			status = generate_eap_fast_master_secret_from_pac_key(
       
 14290 				&m_eap_fast_pac_key);
       
 14291 
       
 14292 			m_eap_fast_pac_key.reset();
       
 14293 
       
 14294 			if (status != eap_status_ok)
       
 14295 			{
       
 14296 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14297 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 14298 			}
       
 14299 		}
       
 14300 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 14301 
       
 14302 		// We must generate the key material.
       
 14303 		status = generate_key_material();
       
 14304 		if (status != eap_status_ok)
       
 14305 		{
       
 14306 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14307 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14308 		}
       
 14309 
       
 14310 	}
       
 14311 
       
 14312 	// --------------------------------------------------------------------
       
 14313 
       
 14314 	// Note add_record_message() frees message on any case.
       
 14315 	automatic_tls_handshake_message.do_not_free_variable();
       
 14316 
       
 14317 	status = add_record_message(tls_handshake_message);
       
 14318 	if (status != eap_status_ok)
       
 14319 	{
       
 14320 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14321 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14322 	}
       
 14323 
       
 14324 	// --------------------------------------------------------------------
       
 14325 
       
 14326 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14327 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 14328 }
       
 14329 
       
 14330 //--------------------------------------------------
       
 14331 
       
 14332 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_certificate(
       
 14333 	EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_chain)
       
 14334 {
       
 14335 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14336 
       
 14337 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 14338 
       
 14339 	tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = 
       
 14340 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 14341 		m_tls_identity_privacy_handshake_state;
       
 14342 #else
       
 14343 		tls_identity_privacy_handshake_state_none;
       
 14344 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 14345 	EAP_UNREFERENCED_PARAMETER(tmp_identity_privacy_handshake_state);
       
 14346 
       
 14347 	EAP_TRACE_DEBUG(
       
 14348 		m_am_tools,
       
 14349 		TRACE_FLAGS_DEFAULT,
       
 14350 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_certificate(): state=%d=%s, privacy_handshake_state=%d=%s, session_type=%s\n"),
       
 14351 		 this,
       
 14352 		 (m_is_client == true ? "client": "server"),
       
 14353 		 m_tls_peap_state,
       
 14354 		 eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 14355 		 tmp_identity_privacy_handshake_state,
       
 14356 		 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state),
       
 14357 		 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)));
       
 14358 
       
 14359 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_certificate()");
       
 14360 
       
 14361 	// 0                   1                   2                   3   
       
 14362 	//  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 
       
 14363 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14364 	//                 | Certificate Chain Length                      |
       
 14365 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14366 	// | Certificate 1 Length                          |               |
       
 14367 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 14368 	// |                                                               |
       
 14369 	// +                                                               +
       
 14370 	// |          Certificate 1                                        |
       
 14371 	// +                                                               +
       
 14372 	// |                                                               |
       
 14373 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14374 	// .                    ...                                        .
       
 14375 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14376 	// | Certificate n Length                          |               |
       
 14377 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 14378 	// |                                                               |
       
 14379 	// +                                                               +
       
 14380 	// |          Certificate n                                        |
       
 14381 	// +                                                               +
       
 14382 	// |                                                               |
       
 14383 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14384 
       
 14385 	tls_handshake_message_c *tls_handshake_message = 0;
       
 14386 
       
 14387 	eap_automatic_variable_c<tls_handshake_message_c>
       
 14388 		automatic_tls_handshake_message(m_am_tools);
       
 14389 
       
 14390 	eap_status_e status = allocate_handshake_message(
       
 14391 		&tls_handshake_message,
       
 14392 		&automatic_tls_handshake_message,
       
 14393 		tls_handshake_type_certificate);
       
 14394 	if (status != eap_status_ok)
       
 14395 	{
       
 14396 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14397 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14398 	}
       
 14399 
       
 14400 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 14401 	// Certificate chain is included when TLS identity privacy is not used,
       
 14402 	// or send cipher is not NULL
       
 14403 	// or sender is server
       
 14404 	if (m_tls_session_type == tls_session_type_full_authentication
       
 14405 		&& (m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none
       
 14406 			|| m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs
       
 14407 			|| m_is_client == false))
       
 14408 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 14409 	{
       
 14410 		status = tls_handshake_message->set_certificate_chain(
       
 14411 			certificate_chain);
       
 14412 		if (status != eap_status_ok)
       
 14413 		{
       
 14414 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14415 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14416 		}
       
 14417 	}
       
 14418 
       
 14419 	// --------------------------------------------------------------------
       
 14420 
       
 14421 	// Note add_record_message() frees message on any case.
       
 14422 	automatic_tls_handshake_message.do_not_free_variable();
       
 14423 
       
 14424 	status = add_record_message(tls_handshake_message);
       
 14425 	if (status != eap_status_ok)
       
 14426 	{
       
 14427 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14428 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14429 	}
       
 14430 
       
 14431 	// --------------------------------------------------------------------
       
 14432 
       
 14433 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14434 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 14435 }
       
 14436 
       
 14437 //--------------------------------------------------
       
 14438 
       
 14439 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_certificate_request(
       
 14440 	EAP_TEMPLATE_CONST eap_array_c<u8_t> * const certificate_types,
       
 14441 	EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_authorities)
       
 14442 {
       
 14443 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14444 
       
 14445 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 14446 	EAP_TRACE_DEBUG(
       
 14447 		m_am_tools,
       
 14448 		TRACE_FLAGS_DEFAULT,
       
 14449 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_certificate_request()\n"),
       
 14450 		 this,
       
 14451 		 (m_is_client == true ? "client": "server")));
       
 14452 
       
 14453 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_certificate_request()");
       
 14454 
       
 14455 	// 0                   1                   2                   3   
       
 14456 	//  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 
       
 14457 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14458 	//                 | CT length     | CT 1          | CT 2          |
       
 14459 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14460 	// | CT 3          | CT 4          | CAs length                    |
       
 14461 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14462 	// | CA 1 length                   |                               |
       
 14463 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 14464 	// |                                                               |
       
 14465 	// +                                                               +
       
 14466 	// |      Distinguished name of Certificate Authority 1            |
       
 14467 	// +                                                               +
       
 14468 	// |                                                               |
       
 14469 	// +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14470 	// |                               | CA 2 length                   |
       
 14471 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14472 	// |                                                               |
       
 14473 	// +                                                               +
       
 14474 	// |      Distinguished name of Certificate Authority 2            |
       
 14475 	// +                                                               +
       
 14476 	// |                                                               |
       
 14477 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 14478 
       
 14479 	tls_handshake_message_c *tls_handshake_message = 0;
       
 14480 
       
 14481 	eap_automatic_variable_c<tls_handshake_message_c>
       
 14482 		automatic_tls_handshake_message(m_am_tools);
       
 14483 
       
 14484 	eap_status_e status = allocate_handshake_message(
       
 14485 		&tls_handshake_message,
       
 14486 		&automatic_tls_handshake_message,
       
 14487 		tls_handshake_type_certificate_request);
       
 14488 	if (status != eap_status_ok)
       
 14489 	{
       
 14490 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14491 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14492 	}
       
 14493 
       
 14494 	status = tls_handshake_message->set_certificate_types(
       
 14495 		certificate_types);
       
 14496 	if (status != eap_status_ok)
       
 14497 	{
       
 14498 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14499 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14500 	}
       
 14501 
       
 14502 	if (m_server_sends_empty_certificate_authorities_list == false)
       
 14503 	{
       
 14504 		status = tls_handshake_message->set_certificate_authorities(
       
 14505 			certificate_authorities);
       
 14506 		if (status != eap_status_ok)
       
 14507 		{
       
 14508 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14509 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 14510 		}
       
 14511 	}
       
 14512 
       
 14513 	// --------------------------------------------------------------------
       
 14514 
       
 14515 	// Note add_record_message() frees message on any case.
       
 14516 	automatic_tls_handshake_message.do_not_free_variable();
       
 14517 
       
 14518 	status = add_record_message(tls_handshake_message);
       
 14519 	if (status != eap_status_ok)
       
 14520 	{
       
 14521 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14522 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14523 	}
       
 14524 
       
 14525 	// --------------------------------------------------------------------
       
 14526 
       
 14527 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14528 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 14529 }
       
 14530 
       
 14531 //--------------------------------------------------
       
 14532 
       
 14533 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_server_hello_done()
       
 14534 {
       
 14535 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14536 
       
 14537 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 14538 	EAP_TRACE_DEBUG(
       
 14539 		m_am_tools,
       
 14540 		TRACE_FLAGS_DEFAULT,
       
 14541 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_server_hello_done()\n"),
       
 14542 		 this,
       
 14543 		 (m_is_client == true ? "client": "server")));
       
 14544 
       
 14545 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_server_hello_done()");
       
 14546 
       
 14547 	// 0                   1                   2                   3   
       
 14548 	//  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 
       
 14549 	//
       
 14550 	// ServerHelloDone message does not include payload.
       
 14551 
       
 14552 	tls_handshake_message_c *tls_handshake_message = 0;
       
 14553 
       
 14554 	eap_automatic_variable_c<tls_handshake_message_c>
       
 14555 		automatic_tls_handshake_message(m_am_tools);
       
 14556 
       
 14557 	eap_status_e status = allocate_handshake_message(
       
 14558 		&tls_handshake_message,
       
 14559 		&automatic_tls_handshake_message,
       
 14560 		tls_handshake_type_server_hello_done);
       
 14561 	if (status != eap_status_ok)
       
 14562 	{
       
 14563 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14564 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14565 	}
       
 14566 
       
 14567 	// --------------------------------------------------------------------
       
 14568 
       
 14569 	// Note add_record_message() frees message on any case.
       
 14570 	automatic_tls_handshake_message.do_not_free_variable();
       
 14571 
       
 14572 	status = add_record_message(tls_handshake_message);
       
 14573 	if (status != eap_status_ok)
       
 14574 	{
       
 14575 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14576 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14577 	}
       
 14578 
       
 14579 	// --------------------------------------------------------------------
       
 14580 
       
 14581 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14582 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 14583 }
       
 14584 
       
 14585 //--------------------------------------------------
       
 14586 
       
 14587 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_server_key_exchange_sha1_hash(
       
 14588 	const eap_variable_data_c * const dhe_prime,
       
 14589 	const eap_variable_data_c * const dhe_group_generator,
       
 14590 	const eap_variable_data_c * const public_dhe_key,
       
 14591 	eap_variable_data_c * const hash)
       
 14592 {
       
 14593 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 14594 	EAP_TRACE_DEBUG(
       
 14595 		m_am_tools,
       
 14596 		TRACE_FLAGS_DEFAULT,
       
 14597 		(EAPL("TLS: this = 0x%08x, %s:    hash_function: starts: tls_record_c::create_server_key_exchange_sha1_hash()\n"),
       
 14598 		 this,
       
 14599 		 (m_is_client == true ? "client": "server")));
       
 14600 
       
 14601 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_server_key_exchange_sha1_hash()");
       
 14602 
       
 14603 	if (m_client_handshake_random_value.get_is_valid_data() == false)
       
 14604 	{
       
 14605 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14606 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 14607 	}
       
 14608 
       
 14609 	if (m_server_handshake_random_value.get_is_valid_data() == false)
       
 14610 	{
       
 14611 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14612 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 14613 	}
       
 14614 
       
 14615 	u16_t dhe_prime_length_network_order 
       
 14616 		= eap_htons(static_cast<u16_t>(dhe_prime->get_data_length()));
       
 14617 
       
 14618 	u16_t dhe_group_generator_length_network_order 
       
 14619 		= eap_htons(static_cast<u16_t>(dhe_group_generator->get_data_length()));
       
 14620 
       
 14621 	u16_t public_dhe_key_length_network_order 
       
 14622 		= eap_htons(static_cast<u16_t>(public_dhe_key->get_data_length()));
       
 14623 
       
 14624 	crypto_sha1_c sha1(m_am_tools);
       
 14625 
       
 14626 	eap_status_e status = sha1.hash_init();
       
 14627 	if (status != eap_status_ok)
       
 14628 	{
       
 14629 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14630 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14631 	}
       
 14632 
       
 14633 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14634 
       
 14635 	EAP_TRACE_DATA_DEBUG(
       
 14636 		m_am_tools,
       
 14637 		TRACE_FLAGS_DEFAULT,
       
 14638 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): client random"),
       
 14639 		m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14640 		m_client_handshake_random_value.get_data_length()));
       
 14641 
       
 14642 	status = sha1.hash_update(
       
 14643 		m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14644 		m_client_handshake_random_value.get_data_length());
       
 14645 	if (status != eap_status_ok)
       
 14646 	{
       
 14647 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14648 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14649 	}
       
 14650 
       
 14651 	EAP_TRACE_DATA_DEBUG(
       
 14652 		m_am_tools,
       
 14653 		TRACE_FLAGS_DEFAULT,
       
 14654 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): server random"),
       
 14655 		m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14656 		m_server_handshake_random_value.get_data_length()));
       
 14657 
       
 14658 	status = sha1.hash_update(
       
 14659 		m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14660 		m_server_handshake_random_value.get_data_length());
       
 14661 	if (status != eap_status_ok)
       
 14662 	{
       
 14663 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14664 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14665 	}
       
 14666 
       
 14667 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14668 
       
 14669 	EAP_TRACE_DATA_DEBUG(
       
 14670 		m_am_tools,
       
 14671 		TRACE_FLAGS_DEFAULT,
       
 14672 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): dhe_prime_length_network_order"),
       
 14673 		&dhe_prime_length_network_order,
       
 14674 		sizeof(dhe_prime_length_network_order)));
       
 14675 
       
 14676 	EAP_TRACE_DATA_DEBUG(
       
 14677 		m_am_tools,
       
 14678 		TRACE_FLAGS_DEFAULT,
       
 14679 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): dhe_prime"),
       
 14680 		dhe_prime->get_data(dhe_prime->get_data_length()),
       
 14681 		dhe_prime->get_data_length()));
       
 14682 
       
 14683 	status = sha1.hash_update(
       
 14684 		&dhe_prime_length_network_order,
       
 14685 		sizeof(dhe_prime_length_network_order));
       
 14686 	if (status != eap_status_ok)
       
 14687 	{
       
 14688 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14689 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14690 	}
       
 14691 
       
 14692 	status = sha1.hash_update(
       
 14693 		dhe_prime->get_data(
       
 14694 			dhe_prime->get_data_length()),
       
 14695 		dhe_prime->get_data_length());
       
 14696 	if (status != eap_status_ok)
       
 14697 	{
       
 14698 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14699 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14700 	}
       
 14701 
       
 14702 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14703 
       
 14704 	EAP_TRACE_DATA_DEBUG(
       
 14705 		m_am_tools,
       
 14706 		TRACE_FLAGS_DEFAULT,
       
 14707 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): ")
       
 14708 		 EAPL("dhe_group_generator_length_network_order"),
       
 14709 		&dhe_group_generator_length_network_order,
       
 14710 		sizeof(dhe_group_generator_length_network_order)));
       
 14711 
       
 14712 	EAP_TRACE_DATA_DEBUG(
       
 14713 		m_am_tools,
       
 14714 		TRACE_FLAGS_DEFAULT,
       
 14715 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): dhe_group_generator"),
       
 14716 		dhe_group_generator->get_data(dhe_group_generator->get_data_length()),
       
 14717 		dhe_group_generator->get_data_length()));
       
 14718 
       
 14719 	status = sha1.hash_update(
       
 14720 		&dhe_group_generator_length_network_order,
       
 14721 		sizeof(dhe_group_generator_length_network_order));
       
 14722 	if (status != eap_status_ok)
       
 14723 	{
       
 14724 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14725 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14726 	}
       
 14727 
       
 14728 	status = sha1.hash_update(
       
 14729 		dhe_group_generator->get_data(
       
 14730 			dhe_group_generator->get_data_length()),
       
 14731 		dhe_group_generator->get_data_length());
       
 14732 	if (status != eap_status_ok)
       
 14733 	{
       
 14734 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14735 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14736 	}
       
 14737 
       
 14738 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14739 
       
 14740 	EAP_TRACE_DATA_DEBUG(
       
 14741 		m_am_tools,
       
 14742 		TRACE_FLAGS_DEFAULT,
       
 14743 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): public_dhe_key_length_network_order"),
       
 14744 		&public_dhe_key_length_network_order,
       
 14745 		sizeof(public_dhe_key_length_network_order)));
       
 14746 
       
 14747 	EAP_TRACE_DATA_DEBUG(
       
 14748 		m_am_tools,
       
 14749 		TRACE_FLAGS_DEFAULT,
       
 14750 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): public_dhe_key"),
       
 14751 		public_dhe_key->get_data(public_dhe_key->get_data_length()),
       
 14752 		public_dhe_key->get_data_length()));
       
 14753 
       
 14754 	status = sha1.hash_update(
       
 14755 		&public_dhe_key_length_network_order,
       
 14756 		sizeof(public_dhe_key_length_network_order));
       
 14757 	if (status != eap_status_ok)
       
 14758 	{
       
 14759 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14760 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14761 	}
       
 14762 
       
 14763 	status = sha1.hash_update(
       
 14764 		public_dhe_key->get_data(
       
 14765 			public_dhe_key->get_data_length()),
       
 14766 		public_dhe_key->get_data_length());
       
 14767 	if (status != eap_status_ok)
       
 14768 	{
       
 14769 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14770 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14771 	}
       
 14772 
       
 14773 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14774 
       
 14775 	status = hash->set_buffer_length(sha1.get_digest_length());
       
 14776 	if (status != eap_status_ok)
       
 14777 	{
       
 14778 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14779 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14780 	}
       
 14781 	hash->set_data_length(sha1.get_digest_length());
       
 14782 
       
 14783 	u32_t digest_length = hash->get_data_length();
       
 14784 	status = sha1.hash_final(
       
 14785 		hash->get_data(hash->get_data_length()),
       
 14786 		&digest_length);
       
 14787 	if (digest_length != sha1.get_digest_length())
       
 14788 	{
       
 14789 		status = eap_status_process_general_error;
       
 14790 	}
       
 14791 	if (status != eap_status_ok)
       
 14792 	{
       
 14793 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14794 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14795 	}
       
 14796 
       
 14797 	EAP_TRACE_DATA_DEBUG(
       
 14798 		m_am_tools,
       
 14799 		TRACE_FLAGS_DEFAULT,
       
 14800 		(EAPL("TLS: create_server_key_exchange_sha1_hash(): hash"),
       
 14801 		hash->get_data(hash->get_data_length()),
       
 14802 		hash->get_data_length()));
       
 14803 
       
 14804 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14805 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 14806 }
       
 14807 
       
 14808 //--------------------------------------------------
       
 14809 
       
 14810 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_server_key_exchange_md5_hash(
       
 14811 	const eap_variable_data_c * const dhe_prime,
       
 14812 	const eap_variable_data_c * const dhe_group_generator,
       
 14813 	const eap_variable_data_c * const public_dhe_key,
       
 14814 	eap_variable_data_c * const hash)
       
 14815 {
       
 14816 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 14817 	EAP_TRACE_DEBUG(
       
 14818 		m_am_tools,
       
 14819 		TRACE_FLAGS_DEFAULT,
       
 14820 		(EAPL("TLS: this = 0x%08x, %s:    hash_function: starts: tls_record_c::create_server_key_exchange_md5_hash()\n"),
       
 14821 		 this,
       
 14822 		 (m_is_client == true ? "client": "server")));
       
 14823 
       
 14824 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_server_key_exchange_md5_hash()");
       
 14825 
       
 14826 	if (m_client_handshake_random_value.get_is_valid_data() == false)
       
 14827 	{
       
 14828 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14829 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 14830 	}
       
 14831 
       
 14832 	if (m_server_handshake_random_value.get_is_valid_data() == false)
       
 14833 	{
       
 14834 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14835 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 14836 	}
       
 14837 
       
 14838 	u16_t dhe_prime_length_network_order 
       
 14839 		= eap_htons(static_cast<u16_t>(dhe_prime->get_data_length()));
       
 14840 
       
 14841 	u16_t dhe_group_generator_length_network_order 
       
 14842 		= eap_htons(static_cast<u16_t>(dhe_group_generator->get_data_length()));
       
 14843 
       
 14844 	u16_t public_dhe_key_length_network_order 
       
 14845 		= eap_htons(static_cast<u16_t>(public_dhe_key->get_data_length()));
       
 14846 
       
 14847 	crypto_md5_c md5(m_am_tools);
       
 14848 
       
 14849 	eap_status_e status = md5.hash_init();
       
 14850 	if (status != eap_status_ok)
       
 14851 	{
       
 14852 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14853 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14854 	}
       
 14855 
       
 14856 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14857 
       
 14858 	EAP_TRACE_DATA_DEBUG(
       
 14859 		m_am_tools,
       
 14860 		TRACE_FLAGS_DEFAULT,
       
 14861 		(EAPL("TLS: create_server_key_exchange_md5_hash(): client random"),
       
 14862 		m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14863 		m_client_handshake_random_value.get_data_length()));
       
 14864 
       
 14865 	status = md5.hash_update(
       
 14866 		m_client_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14867 		m_client_handshake_random_value.get_data_length());
       
 14868 	if (status != eap_status_ok)
       
 14869 	{
       
 14870 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14871 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14872 	}
       
 14873 
       
 14874 	EAP_TRACE_DATA_DEBUG(
       
 14875 		m_am_tools,
       
 14876 		TRACE_FLAGS_DEFAULT,
       
 14877 		(EAPL("TLS: create_server_key_exchange_md5_hash(): server random"),
       
 14878 		m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14879 		m_server_handshake_random_value.get_data_length()));
       
 14880 
       
 14881 	status = md5.hash_update(
       
 14882 		m_server_handshake_random_value.get_data(m_client_handshake_random_value.get_data_length()),
       
 14883 		m_server_handshake_random_value.get_data_length());
       
 14884 	if (status != eap_status_ok)
       
 14885 	{
       
 14886 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14887 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14888 	}
       
 14889 
       
 14890 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14891 
       
 14892 	EAP_TRACE_DATA_DEBUG(
       
 14893 		m_am_tools,
       
 14894 		TRACE_FLAGS_DEFAULT,
       
 14895 		(EAPL("TLS: create_server_key_exchange_md5_hash(): dhe_prime_length_network_order"),
       
 14896 		&dhe_prime_length_network_order,
       
 14897 		sizeof(dhe_prime_length_network_order)));
       
 14898 
       
 14899 	EAP_TRACE_DATA_DEBUG(
       
 14900 		m_am_tools,
       
 14901 		TRACE_FLAGS_DEFAULT,
       
 14902 		(EAPL("TLS: create_server_key_exchange_md5_hash(): dhe_prime"),
       
 14903 		dhe_prime->get_data(dhe_prime->get_data_length()),
       
 14904 		dhe_prime->get_data_length()));
       
 14905 
       
 14906 	status = md5.hash_update(
       
 14907 		&dhe_prime_length_network_order,
       
 14908 		sizeof(dhe_prime_length_network_order));
       
 14909 	if (status != eap_status_ok)
       
 14910 	{
       
 14911 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14912 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14913 	}
       
 14914 
       
 14915 	status = md5.hash_update(
       
 14916 		dhe_prime->get_data(
       
 14917 			dhe_prime->get_data_length()),
       
 14918 		dhe_prime->get_data_length());
       
 14919 	if (status != eap_status_ok)
       
 14920 	{
       
 14921 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14922 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14923 	}
       
 14924 
       
 14925 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14926 
       
 14927 	EAP_TRACE_DATA_DEBUG(
       
 14928 		m_am_tools,
       
 14929 		TRACE_FLAGS_DEFAULT,
       
 14930 		(EAPL("TLS: create_server_key_exchange_md5_hash(): ")
       
 14931 		 EAPL("dhe_group_generator_length_network_order"),
       
 14932 		&dhe_group_generator_length_network_order,
       
 14933 		sizeof(dhe_group_generator_length_network_order)));
       
 14934 
       
 14935 	EAP_TRACE_DATA_DEBUG(
       
 14936 		m_am_tools,
       
 14937 		TRACE_FLAGS_DEFAULT,
       
 14938 		(EAPL("TLS: create_server_key_exchange_md5_hash(): dhe_group_generator"),
       
 14939 		dhe_group_generator->get_data(dhe_group_generator->get_data_length()),
       
 14940 		dhe_group_generator->get_data_length()));
       
 14941 
       
 14942 	status = md5.hash_update(
       
 14943 		&dhe_group_generator_length_network_order,
       
 14944 		sizeof(dhe_group_generator_length_network_order));
       
 14945 	if (status != eap_status_ok)
       
 14946 	{
       
 14947 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14948 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14949 	}
       
 14950 
       
 14951 	status = md5.hash_update(
       
 14952 		dhe_group_generator->get_data(
       
 14953 			dhe_group_generator->get_data_length()),
       
 14954 		dhe_group_generator->get_data_length());
       
 14955 	if (status != eap_status_ok)
       
 14956 	{
       
 14957 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14958 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14959 	}
       
 14960 
       
 14961 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14962 
       
 14963 	EAP_TRACE_DATA_DEBUG(
       
 14964 		m_am_tools,
       
 14965 		TRACE_FLAGS_DEFAULT,
       
 14966 		(EAPL("TLS: create_server_key_exchange_md5_hash(): public_dhe_key_length_network_order"),
       
 14967 		&public_dhe_key_length_network_order,
       
 14968 		sizeof(public_dhe_key_length_network_order)));
       
 14969 
       
 14970 	EAP_TRACE_DATA_DEBUG(
       
 14971 		m_am_tools,
       
 14972 		TRACE_FLAGS_DEFAULT,
       
 14973 		(EAPL("TLS: create_server_key_exchange_md5_hash(): public_dhe_key"),
       
 14974 		public_dhe_key->get_data(public_dhe_key->get_data_length()),
       
 14975 		public_dhe_key->get_data_length()));
       
 14976 
       
 14977 	status = md5.hash_update(
       
 14978 		&public_dhe_key_length_network_order,
       
 14979 		sizeof(public_dhe_key_length_network_order));
       
 14980 	if (status != eap_status_ok)
       
 14981 	{
       
 14982 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14983 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14984 	}
       
 14985 
       
 14986 	status = md5.hash_update(
       
 14987 		public_dhe_key->get_data(
       
 14988 			public_dhe_key->get_data_length()),
       
 14989 		public_dhe_key->get_data_length());
       
 14990 	if (status != eap_status_ok)
       
 14991 	{
       
 14992 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 14993 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 14994 	}
       
 14995 
       
 14996 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 14997 
       
 14998 	status = hash->set_buffer_length(md5.get_digest_length());
       
 14999 	if (status != eap_status_ok)
       
 15000 	{
       
 15001 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15002 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15003 	}
       
 15004 	hash->set_data_length(md5.get_digest_length());
       
 15005 
       
 15006 	u32_t digest_length = hash->get_data_length();
       
 15007 	status = md5.hash_final(
       
 15008 		hash->get_data(hash->get_data_length()),
       
 15009 		&digest_length);
       
 15010 	if (digest_length != md5.get_digest_length())
       
 15011 	{
       
 15012 		status = eap_status_process_general_error;
       
 15013 	}
       
 15014 	if (status != eap_status_ok)
       
 15015 	{
       
 15016 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15017 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15018 	}
       
 15019 
       
 15020 	EAP_TRACE_DATA_DEBUG(
       
 15021 		m_am_tools,
       
 15022 		TRACE_FLAGS_DEFAULT,
       
 15023 		(EAPL("TLS: create_server_key_exchange_md5_hash(): hash"),
       
 15024 		hash->get_data(hash->get_data_length()),
       
 15025 		hash->get_data_length()));
       
 15026 
       
 15027 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15028 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 15029 }
       
 15030 
       
 15031 //--------------------------------------------------
       
 15032 
       
 15033 EAP_FUNC_EXPORT eap_status_e tls_record_c::verify_signature_of_server_key_exchange(
       
 15034 	const eap_variable_data_c * const signed_server_key_exchange_hash)
       
 15035 {
       
 15036 	EAP_TRACE_DEBUG(
       
 15037 		m_am_tools,
       
 15038 		TRACE_FLAGS_DEFAULT,
       
 15039 		(EAPL("TLS: this = 0x%08x, %s:    hash_function: starts: tls_record_c::verify_signature_of_server_key_exchange()\n"),
       
 15040 		 this,
       
 15041 		 (m_is_client == true ? "client": "server")));
       
 15042 
       
 15043 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::verify_signature_of_server_key_exchange()");
       
 15044 
       
 15045 	eap_status_e status = eap_status_not_supported;
       
 15046 
       
 15047 	eap_variable_data_c hash(m_am_tools);
       
 15048 
       
 15049 
       
 15050 	if (cipher_suite_is_TLS_DHE_DSS() == true)
       
 15051 	{
       
 15052 		status = create_server_key_exchange_sha1_hash(
       
 15053 			&m_dhe_prime,
       
 15054 			&m_dhe_group_generator,
       
 15055 			&m_peer_public_dhe_key,
       
 15056 			&hash);
       
 15057 		if (status != eap_status_ok)
       
 15058 		{
       
 15059 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15060 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15061 		}
       
 15062 	}
       
 15063 	else if (cipher_suite_is_TLS_DHE_RSA() == true)
       
 15064 	{
       
 15065 		eap_variable_data_c md5_hash(m_am_tools);
       
 15066 
       
 15067 		status = create_server_key_exchange_md5_hash(
       
 15068 			&m_dhe_prime,
       
 15069 			&m_dhe_group_generator,
       
 15070 			&m_peer_public_dhe_key,
       
 15071 			&md5_hash);
       
 15072 		if (status != eap_status_ok)
       
 15073 		{
       
 15074 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15075 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15076 		}
       
 15077 
       
 15078 		eap_variable_data_c sha1_hash(m_am_tools);
       
 15079 
       
 15080 		status = create_server_key_exchange_sha1_hash(
       
 15081 			&m_dhe_prime,
       
 15082 			&m_dhe_group_generator,
       
 15083 			&m_peer_public_dhe_key,
       
 15084 			&sha1_hash);
       
 15085 		if (status != eap_status_ok)
       
 15086 		{
       
 15087 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15088 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15089 		}
       
 15090 
       
 15091 		status = hash.add_data(&md5_hash);
       
 15092 		if (status != eap_status_ok)
       
 15093 		{
       
 15094 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15095 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15096 		}
       
 15097 
       
 15098 		status = hash.add_data(&sha1_hash);
       
 15099 		if (status != eap_status_ok)
       
 15100 		{
       
 15101 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15102 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15103 		}
       
 15104 	}
       
 15105 	else
       
 15106 	{
       
 15107 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15108 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
 15109 	}
       
 15110 
       
 15111 
       
 15112 	EAP_TRACE_DATA_DEBUG(
       
 15113 		m_am_tools,
       
 15114 		TRACE_FLAGS_DEFAULT,
       
 15115 		(EAPL("TLS: verify_signature_of_server_key_exchange(): hash"),
       
 15116 		hash.get_data(hash.get_data_length()),
       
 15117 		hash.get_data_length()));
       
 15118 
       
 15119 	EAP_TRACE_DATA_DEBUG(
       
 15120 		m_am_tools,
       
 15121 		TRACE_FLAGS_DEFAULT,
       
 15122 		(EAPL("TLS: verify_signature_of_server_key_exchange(): signed_server_key_exchange_hash"),
       
 15123 		signed_server_key_exchange_hash->get_data(
       
 15124 			signed_server_key_exchange_hash->get_data_length()),
       
 15125 		signed_server_key_exchange_hash->get_data_length()));
       
 15126 
       
 15127 	EAP_TRACE_DEBUG(
       
 15128 		m_am_tools,
       
 15129 		TRACE_FLAGS_DEFAULT,
       
 15130 		(EAPL("TLS: %s:     pki_function: verify_with_public_key()\n"),
       
 15131 		(m_is_client == true ? "client": "server")));
       
 15132 
       
 15133 	status = m_am_tls_services->verify_with_public_key(
       
 15134 		&hash,
       
 15135 		signed_server_key_exchange_hash);
       
 15136 	if (status == eap_status_pending_request)
       
 15137 	{
       
 15138 		// This is pending query, that will be completed by complete_query_certificate_chain() call.
       
 15139 		m_pending_verify_with_public_key = true;
       
 15140 	}
       
 15141 	else if (status == eap_status_completed_request)
       
 15142 	{
       
 15143 		// This is already completed by complete_query_certificate_chain() call.
       
 15144 	}
       
 15145 	else if (status == eap_status_ok)
       
 15146 	{
       
 15147 		// This is also an error case, because this call is always completed on success. 
       
 15148 		status = eap_status_process_general_error;
       
 15149 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15150 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15151 	}
       
 15152 	else // All other status values means error, because this call is always completed on success.
       
 15153 	{
       
 15154 		// This is an error case.
       
 15155 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15156 		return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
 15157 	}
       
 15158 
       
 15159 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15160 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 15161 }
       
 15162 
       
 15163 //--------------------------------------------------
       
 15164 
       
 15165 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_create_handshake_type_server_key_exchange()
       
 15166 {
       
 15167 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 15168 	EAP_TRACE_DEBUG(
       
 15169 		m_am_tools,
       
 15170 		TRACE_FLAGS_DEFAULT,
       
 15171 		(EAPL("TLS: this = 0x%08x, %s: parse_function: starts: tls_record_c::complete_create_handshake_type_server_key_exchange()\n"),
       
 15172 		 this,
       
 15173 		 (m_is_client == true ? "client": "server")));
       
 15174 
       
 15175 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_create_handshake_type_server_key_exchange()");
       
 15176 
       
 15177 	tls_handshake_message_c *tls_handshake_message = 0;
       
 15178 
       
 15179 	eap_automatic_variable_c<tls_handshake_message_c>
       
 15180 		automatic_tls_handshake_message(m_am_tools);
       
 15181 
       
 15182 	eap_status_e status = allocate_handshake_message(
       
 15183 		&tls_handshake_message,
       
 15184 		&automatic_tls_handshake_message,
       
 15185 		tls_handshake_type_server_key_exchange);
       
 15186 	if (status != eap_status_ok)
       
 15187 	{
       
 15188 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15189 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15190 	}
       
 15191 
       
 15192 #if EAP_TLS_UNSUPPORTED_CIPHER_SUITE
       
 15193 	#error This one needs more code. RSA key exchange with different parameters is NOT supported.
       
 15194 	if (cipher_suite_is_TLS_RSA() == true)
       
 15195 	{
       
 15196 		// RSA modulus and exponent are included when selected cipher suite is
       
 15197 		// using RSA key exchange
       
 15198 		// and parameters are different than included in the certificate.
       
 15199 		// 0                   1                   2                   3   
       
 15200 		//  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 
       
 15201 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15202 		//                 | rsa_modulus length            |               |
       
 15203 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15204 		// |                                                               |
       
 15205 		// +                                                               +
       
 15206 		// |          rsa_modulus                                          |
       
 15207 		// +                                                               +
       
 15208 		// |                                                               |
       
 15209 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15210 		// |  rsa_exponent length          |                               |
       
 15211 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15212 		// |                                                               |
       
 15213 		// +                  rsa_exponent                                 +
       
 15214 		// |                                                               |
       
 15215 		// +                                                               +
       
 15216 		// |                                                               |
       
 15217 		// +                                                               +
       
 15218 		// |                                                               |
       
 15219 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15220 		// |                                                               |
       
 15221 		// +                                                               +
       
 15222 		// |       digitally-signed MD5 hash 16 bytes                      |
       
 15223 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15224 		// |                                                               |
       
 15225 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15226 		// |                                                               |
       
 15227 		// +                                                               +
       
 15228 		// |       digitally-signed SHA-1 hash 20 bytes                    |
       
 15229 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15230 		// |                                                               |
       
 15231 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15232 
       
 15233 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15234 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
 15235 	}
       
 15236 	else
       
 15237 #endif
       
 15238 	if (cipher_suite_is_TLS_DHE_DSS() == true)
       
 15239 	{
       
 15240 		// Diffie-Hellman prime modulus, generator and server's
       
 15241 		// Diffie-Hellman public value (g^X mod p)
       
 15242 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
 15243 		// 0                   1                   2                   3   
       
 15244 		//  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 
       
 15245 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15246 		//                 | DH p length                   |               |
       
 15247 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15248 		// |                                                               |
       
 15249 		// +                                                               +
       
 15250 		// |                DH p value (prime modulus)                     |
       
 15251 		// +                                                               +
       
 15252 		// |                                                               |
       
 15253 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15254 		// |  DH g length                  |                               |
       
 15255 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15256 		// |                                                               |
       
 15257 		// +                                                               +
       
 15258 		// |                DH g value (generator)                         |
       
 15259 		// +                                                               +
       
 15260 		// |                                                               |
       
 15261 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15262 		// |  DH Ys length                 |                               |
       
 15263 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15264 		// |                                                               |
       
 15265 		// +                                                               +
       
 15266 		// |                DH Ys value                                    |
       
 15267 		// +         (server's Diffie-Hellman public value)                +
       
 15268 		// |                                                               |
       
 15269 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15270 		// |                                                               |
       
 15271 		// +                                                               +
       
 15272 		// |       digitally-signed SHA-1 hash 47 bytes                    |
       
 15273 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15274 		// |                                                               |
       
 15275 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15276 
       
 15277 		EAP_TRACE_DATA_DEBUG(
       
 15278 			m_am_tools,
       
 15279 			TRACE_FLAGS_DEFAULT,
       
 15280 			(EAPL("TLS: complete_create_handshake_type_server_key_exchange(): m_signed_message_hash"),
       
 15281 			m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
       
 15282 			m_signed_message_hash.get_data_length()));
       
 15283 
       
 15284 		status = tls_handshake_message->set_signed_message_hash(
       
 15285 			&m_signed_message_hash);
       
 15286 		if (status != eap_status_ok)
       
 15287 		{
       
 15288 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15289 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15290 		}
       
 15291 	}
       
 15292 	else if (cipher_suite_is_TLS_DHE_RSA() == true)
       
 15293 	{
       
 15294 		// Diffie-Hellman prime modulus, generator and server's
       
 15295 		// Diffie-Hellman public value (g^X mod p)
       
 15296 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
 15297 		// 0                   1                   2                   3   
       
 15298 		//  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 
       
 15299 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15300 		//                 | DH p length                   |               |
       
 15301 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15302 		// |                                                               |
       
 15303 		// +                                                               +
       
 15304 		// |                DH p value (prime modulus)                     |
       
 15305 		// +                                                               +
       
 15306 		// |                                                               |
       
 15307 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15308 		// |  DH g length                  |                               |
       
 15309 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15310 		// |                                                               |
       
 15311 		// +                                                               +
       
 15312 		// |                DH g value (generator)                         |
       
 15313 		// +                                                               +
       
 15314 		// |                                                               |
       
 15315 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15316 		// |  DH Ys length                 |                               |
       
 15317 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15318 		// |                                                               |
       
 15319 		// +                                                               +
       
 15320 		// |                DH Ys value                                    |
       
 15321 		// +         (server's Diffie-Hellman public value)                +
       
 15322 		// |                                                               |
       
 15323 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15324 		// |                                                               |
       
 15325 		// +                                                               +
       
 15326 		// |       digitally-signed MD5 hash 16 bytes                      |
       
 15327 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15328 		// |                                                               |
       
 15329 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15330 		// |                                                               |
       
 15331 		// +                                                               +
       
 15332 		// |       digitally-signed SHA-1 hash 47 bytes                    |
       
 15333 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15334 		// |                                                               |
       
 15335 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15336 
       
 15337 		EAP_TRACE_DATA_DEBUG(
       
 15338 			m_am_tools,
       
 15339 			TRACE_FLAGS_DEFAULT,
       
 15340 			(EAPL("TLS: complete_create_handshake_type_server_key_exchange(): m_signed_message_hash"),
       
 15341 			m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
       
 15342 			m_signed_message_hash.get_data_length()));
       
 15343 
       
 15344 		status = tls_handshake_message->set_signed_message_hash(
       
 15345 			&m_signed_message_hash);
       
 15346 		if (status != eap_status_ok)
       
 15347 		{
       
 15348 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15349 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15350 		}
       
 15351 	}
       
 15352 #if defined(USE_FAST_EAP_TYPE)
       
 15353 	else if (m_eap_type == eap_type_fast
       
 15354 		&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
 15355 		&& cipher_suite_is_TLS_DH_anon() == true)
       
 15356 	{
       
 15357 		// Diffie-Hellman prime modulus, generator and server's
       
 15358 		// Diffie-Hellman public value (g^X mod p)
       
 15359 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
 15360 		// NOTE: Here are no signed hash. This is not authenticated at all and vulnerable to
       
 15361 		// man-in-the-middle attacks.
       
 15362 		// 0                   1                   2                   3   
       
 15363 		//  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 
       
 15364 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15365 		//                 | DH p length                   |               |
       
 15366 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15367 		// |                                                               |
       
 15368 		// +                                                               +
       
 15369 		// |                DH p value (prime modulus)                     |
       
 15370 		// +                                                               +
       
 15371 		// |                                                               |
       
 15372 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15373 		// |  DH g length                  |                               |
       
 15374 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15375 		// |                                                               |
       
 15376 		// +                                                               +
       
 15377 		// |                DH g value (generator)                         |
       
 15378 		// +                                                               +
       
 15379 		// |                                                               |
       
 15380 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15381 		// |  DH Ys length                 |                               |
       
 15382 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15383 		// |                                                               |
       
 15384 		// +                                                               +
       
 15385 		// |                DH Ys value                                    |
       
 15386 		// +         (server's Diffie-Hellman public value)                +
       
 15387 		// |                                                               |
       
 15388 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15389 
       
 15390 		EAP_TRACE_DEBUG(
       
 15391 			m_am_tools,
       
 15392 			TRACE_FLAGS_DEFAULT,
       
 15393 			(EAPL("TLS: complete_create_handshake_type_server_key_exchange() no m_signed_message_hash\n")));
       
 15394 	}
       
 15395 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 15396 	else
       
 15397 	{
       
 15398 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15399 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
 15400 	}
       
 15401 
       
 15402 	// --------------------------------------------------------------------
       
 15403 
       
 15404 
       
 15405 	status = tls_handshake_message->set_dhe_prime(
       
 15406 		&m_dhe_prime);
       
 15407 	if (status != eap_status_ok)
       
 15408 	{
       
 15409 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15410 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15411 	}
       
 15412 
       
 15413 	status = tls_handshake_message->set_dhe_group_generator(
       
 15414 		&m_dhe_group_generator);
       
 15415 	if (status != eap_status_ok)
       
 15416 	{
       
 15417 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15418 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15419 	}
       
 15420 
       
 15421 	status = tls_handshake_message->set_public_dhe_key(
       
 15422 		&m_own_public_dhe_key);
       
 15423 	if (status != eap_status_ok)
       
 15424 	{
       
 15425 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15426 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15427 	}
       
 15428 
       
 15429 	// --------------------------------------------------------------------
       
 15430 
       
 15431 	// Note add_record_message() frees message on any case.
       
 15432 	automatic_tls_handshake_message.do_not_free_variable();
       
 15433 
       
 15434 	status = add_record_message(tls_handshake_message);
       
 15435 	if (status != eap_status_ok)
       
 15436 	{
       
 15437 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15438 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15439 	}
       
 15440 
       
 15441 	// --------------------------------------------------------------------
       
 15442 
       
 15443 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15444 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 15445 }
       
 15446 
       
 15447 //--------------------------------------------------
       
 15448 
       
 15449 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_server_key_exchange()
       
 15450 {
       
 15451 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15452 
       
 15453 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 15454 	EAP_TRACE_DEBUG(
       
 15455 		m_am_tools,
       
 15456 		TRACE_FLAGS_DEFAULT,
       
 15457 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_server_key_exchange()\n"),
       
 15458 		 this,
       
 15459 		 (m_is_client == true ? "client": "server")));
       
 15460 
       
 15461 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_server_key_exchange()");
       
 15462 
       
 15463 	eap_status_e status = eap_status_process_general_error;
       
 15464 	eap_variable_data_c hash(m_am_tools);
       
 15465 
       
 15466 
       
 15467 #if EAP_TLS_UNSUPPORTED_CIPHER_SUITE
       
 15468 	#error This one needs more code. RSA key exchange with different parameters is NOT supported.
       
 15469 	if (cipher_suite_is_TLS_RSA() == true)
       
 15470 	{
       
 15471 		// RSA modulus and exponent are included when selected
       
 15472 		// cipher suite is using RSA key exchange
       
 15473 		// and parameters are different than included in the certificate.
       
 15474 		// 0                   1                   2                   3   
       
 15475 		//  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 
       
 15476 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15477 		//                 | rsa_modulus length            |               |
       
 15478 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15479 		// |                                                               |
       
 15480 		// +                                                               +
       
 15481 		// |          rsa_modulus                                          |
       
 15482 		// +                                                               +
       
 15483 		// |                                                               |
       
 15484 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15485 		// |  rsa_exponent length          |                               |
       
 15486 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15487 		// |                                                               |
       
 15488 		// +                  rsa_exponent                                 +
       
 15489 		// |                                                               |
       
 15490 		// +                                                               +
       
 15491 		// |                                                               |
       
 15492 		// +                                                               +
       
 15493 		// |                                                               |
       
 15494 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15495 		// |                                                               |
       
 15496 		// +                                                               +
       
 15497 		// |       digitally-signed MD5 hash 16 bytes                      |
       
 15498 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15499 		// |                                                               |
       
 15500 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15501 		// |                                                               |
       
 15502 		// +                                                               +
       
 15503 		// |       digitally-signed SHA-1 hash 20 bytes                    |
       
 15504 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15505 		// |                                                               |
       
 15506 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15507 
       
 15508 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15509 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
 15510 	}
       
 15511 	else
       
 15512 #endif
       
 15513 	if (cipher_suite_is_TLS_DHE_DSS() == true)
       
 15514 	{
       
 15515 		// Diffie-Hellman prime modulus, generator and server's
       
 15516 		// Diffie-Hellman public value (g^X mod p)
       
 15517 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
 15518 		// 0                   1                   2                   3   
       
 15519 		//  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 
       
 15520 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15521 		//                 | DH p length                   |               |
       
 15522 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15523 		// |                                                               |
       
 15524 		// +                                                               +
       
 15525 		// |                DH p value (prime modulus)                     |
       
 15526 		// +                                                               +
       
 15527 		// |                                                               |
       
 15528 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15529 		// |  DH g length                  |                               |
       
 15530 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15531 		// |                                                               |
       
 15532 		// +                                                               +
       
 15533 		// |                DH g value (generator)                         |
       
 15534 		// +                                                               +
       
 15535 		// |                                                               |
       
 15536 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15537 		// |  DH Ys length                 |                               |
       
 15538 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15539 		// |                                                               |
       
 15540 		// +                                                               +
       
 15541 		// |                DH Ys value                                    |
       
 15542 		// +         (server's Diffie-Hellman public value)                +
       
 15543 		// |                                                               |
       
 15544 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15545 		// |                                                               |
       
 15546 		// +                                                               +
       
 15547 		// |       digitally-signed SHA-1 hash 47 bytes                    |
       
 15548 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15549 		// |                                                               |
       
 15550 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15551 
       
 15552 		status = create_server_key_exchange_sha1_hash(
       
 15553 			&m_dhe_prime,
       
 15554 			&m_dhe_group_generator,
       
 15555 			&m_own_public_dhe_key,
       
 15556 			&hash);
       
 15557 		if (status != eap_status_ok)
       
 15558 		{
       
 15559 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15560 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15561 		}
       
 15562 
       
 15563 		EAP_TRACE_DATA_DEBUG(
       
 15564 			m_am_tools,
       
 15565 			TRACE_FLAGS_DEFAULT,
       
 15566 			(EAPL("TLS: create_handshake_type_server_key_exchange(): hash"),
       
 15567 			hash.get_data(hash.get_data_length()),
       
 15568 			hash.get_data_length()));
       
 15569 	}
       
 15570 	else if (cipher_suite_is_TLS_DHE_RSA() == true)
       
 15571 	{
       
 15572 		// Diffie-Hellman prime modulus, generator and server's
       
 15573 		// Diffie-Hellman public value (g^X mod p)
       
 15574 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
 15575 		// 0                   1                   2                   3   
       
 15576 		//  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 
       
 15577 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15578 		//                 | DH p length                   |               |
       
 15579 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15580 		// |                                                               |
       
 15581 		// +                                                               +
       
 15582 		// |                DH p value (prime modulus)                     |
       
 15583 		// +                                                               +
       
 15584 		// |                                                               |
       
 15585 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15586 		// |  DH g length                  |                               |
       
 15587 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15588 		// |                                                               |
       
 15589 		// +                                                               +
       
 15590 		// |                DH g value (generator)                         |
       
 15591 		// +                                                               +
       
 15592 		// |                                                               |
       
 15593 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15594 		// |  DH Ys length                 |                               |
       
 15595 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15596 		// |                                                               |
       
 15597 		// +                                                               +
       
 15598 		// |                DH Ys value                                    |
       
 15599 		// +         (server's Diffie-Hellman public value)                +
       
 15600 		// |                                                               |
       
 15601 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15602 		// |                                                               |
       
 15603 		// +                                                               +
       
 15604 		// |       digitally-signed MD5 hash 16 bytes                      |
       
 15605 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15606 		// |                                                               |
       
 15607 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15608 		// |                                                               |
       
 15609 		// +                                                               +
       
 15610 		// |       digitally-signed SHA-1 hash 47 bytes                    |
       
 15611 		// +    (ClientHello.random + ServerHello.random + ServerParams)   +
       
 15612 		// |                                                               |
       
 15613 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15614 
       
 15615 		eap_variable_data_c md5_hash(m_am_tools);
       
 15616 
       
 15617 		status = create_server_key_exchange_md5_hash(
       
 15618 			&m_dhe_prime,
       
 15619 			&m_dhe_group_generator,
       
 15620 			&m_own_public_dhe_key,
       
 15621 			&md5_hash);
       
 15622 		if (status != eap_status_ok)
       
 15623 		{
       
 15624 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15625 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15626 		}
       
 15627 
       
 15628 		EAP_TRACE_DATA_DEBUG(
       
 15629 			m_am_tools,
       
 15630 			TRACE_FLAGS_DEFAULT,
       
 15631 			(EAPL("TLS: create_handshake_type_server_key_exchange() md5_hash"),
       
 15632 			md5_hash.get_data(md5_hash.get_data_length()),
       
 15633 			md5_hash.get_data_length()));
       
 15634 
       
 15635 		eap_variable_data_c sha1_hash(m_am_tools);
       
 15636 
       
 15637 		status = create_server_key_exchange_sha1_hash(
       
 15638 			&m_dhe_prime,
       
 15639 			&m_dhe_group_generator,
       
 15640 			&m_own_public_dhe_key,
       
 15641 			&sha1_hash);
       
 15642 		if (status != eap_status_ok)
       
 15643 		{
       
 15644 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15645 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15646 		}
       
 15647 
       
 15648 		EAP_TRACE_DATA_DEBUG(
       
 15649 			m_am_tools,
       
 15650 			TRACE_FLAGS_DEFAULT,
       
 15651 			(EAPL("TLS: create_handshake_type_server_key_exchange() sha1_hash"),
       
 15652 			sha1_hash.get_data(sha1_hash.get_data_length()),
       
 15653 			sha1_hash.get_data_length()));
       
 15654 
       
 15655 		status = hash.add_data(&md5_hash);
       
 15656 		if (status != eap_status_ok)
       
 15657 		{
       
 15658 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15659 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15660 		}
       
 15661 
       
 15662 		status = hash.add_data(&sha1_hash);
       
 15663 		if (status != eap_status_ok)
       
 15664 		{
       
 15665 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15666 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15667 		}
       
 15668 
       
 15669 		EAP_TRACE_DATA_DEBUG(
       
 15670 			m_am_tools,
       
 15671 			TRACE_FLAGS_DEFAULT,
       
 15672 			(EAPL("TLS: create_handshake_type_server_key_exchange(): hash"),
       
 15673 			hash.get_data(hash.get_data_length()),
       
 15674 			hash.get_data_length()));
       
 15675 	}
       
 15676 #if defined(USE_FAST_EAP_TYPE)
       
 15677 	else if (m_eap_type == eap_type_fast
       
 15678 		&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
 15679 		&& cipher_suite_is_TLS_DH_anon() == true)
       
 15680 	{
       
 15681 		// Diffie-Hellman prime modulus, generator and server's
       
 15682 		// Diffie-Hellman public value (g^X mod p)
       
 15683 		// are included when selected cipher suite is ephemeral Diffie-Hellman key exchange.
       
 15684 		// NOTE: Here are no signed hash. This is not authenticated at all and vulnerable to
       
 15685 		// man-in-the-middle attacks.
       
 15686 		// 0                   1                   2                   3   
       
 15687 		//  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 
       
 15688 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15689 		//                 | DH p length                   |               |
       
 15690 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15691 		// |                                                               |
       
 15692 		// +                                                               +
       
 15693 		// |                DH p value (prime modulus)                     |
       
 15694 		// +                                                               +
       
 15695 		// |                                                               |
       
 15696 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15697 		// |  DH g length                  |                               |
       
 15698 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15699 		// |                                                               |
       
 15700 		// +                                                               +
       
 15701 		// |                DH g value (generator)                         |
       
 15702 		// +                                                               +
       
 15703 		// |                                                               |
       
 15704 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15705 		// |  DH Ys length                 |                               |
       
 15706 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
       
 15707 		// |                                                               |
       
 15708 		// +                                                               +
       
 15709 		// |                DH Ys value                                    |
       
 15710 		// +         (server's Diffie-Hellman public value)                +
       
 15711 		// |                                                               |
       
 15712 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15713 
       
 15714 
       
 15715 		// NOTE: Here the return value is eap_status_pending_request to avoid error after return.
       
 15716 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15717 		return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request);
       
 15718 	}
       
 15719 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 15720 	else
       
 15721 	{
       
 15722 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15723 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
 15724 	}
       
 15725 
       
 15726 	EAP_TRACE_DEBUG(
       
 15727 		m_am_tools,
       
 15728 		TRACE_FLAGS_DEFAULT,
       
 15729 		(EAPL("TLS: %s:     pki_function: create_handshake_type_server_key_exchange()\n"),
       
 15730 		(m_is_client == true ? "client": "server")));
       
 15731 
       
 15732 	m_signed_message_hash.reset();
       
 15733 
       
 15734 	// NOTE this function is asyncronous. This causes complex control flow.
       
 15735 	// This function call will be completed always.
       
 15736 	status = m_am_tls_services->sign_with_private_key(
       
 15737 		&hash);
       
 15738 	if (status == eap_status_pending_request)
       
 15739 	{
       
 15740 		// This is pending query, that will be completed by complete_sign_with_private_key() call.
       
 15741 		m_pending_sign_with_private_key = true;
       
 15742 	}
       
 15743 	else if (status == eap_status_completed_request)
       
 15744 	{
       
 15745 		// This is already completed by complete_sign_with_private_key() call.
       
 15746 	}
       
 15747 	else if (status == eap_status_ok)
       
 15748 	{
       
 15749 		// This is also an error case, because this call is always completed on success. 
       
 15750 		status = eap_status_process_general_error;
       
 15751 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15752 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15753 	}
       
 15754 	else // All other status values means error, because this call is always completed on success.
       
 15755 	{
       
 15756 		// This is an error case.
       
 15757 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15758 		return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
 15759 	}
       
 15760 
       
 15761 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15762 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 15763 }
       
 15764 
       
 15765 //--------------------------------------------------
       
 15766 
       
 15767 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_create_handshake_type_client_key_exchange()
       
 15768 {
       
 15769 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15770 
       
 15771 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 15772 	EAP_TRACE_DEBUG(
       
 15773 		m_am_tools,
       
 15774 		TRACE_FLAGS_DEFAULT,
       
 15775 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_create_handshake_type_client_key_exchange(): cipher suite=%d=%s\n"),
       
 15776 		 this,
       
 15777 		 (m_is_client == true ? "client": "server"),
       
 15778 		 m_selected_cipher_suite,
       
 15779 		 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite)));
       
 15780 
       
 15781 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_create_handshake_type_client_key_exchange()");
       
 15782 
       
 15783 	tls_handshake_message_c *tls_handshake_message = 0;
       
 15784 
       
 15785 	eap_automatic_variable_c<tls_handshake_message_c>
       
 15786 		automatic_tls_handshake_message(m_am_tools);
       
 15787 
       
 15788 	eap_status_e status = allocate_handshake_message(
       
 15789 		&tls_handshake_message,
       
 15790 		&automatic_tls_handshake_message,
       
 15791 		tls_handshake_type_client_key_exchange);
       
 15792 	if (status != eap_status_ok)
       
 15793 	{
       
 15794 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15795 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15796 	}
       
 15797 
       
 15798 	// --------------------------------------------------------------------
       
 15799 
       
 15800 	if (cipher_suite_is_TLS_RSA() == true)
       
 15801 	{
       
 15802 		// Encrypted premaster secret is included when selected
       
 15803 		// cipher suite is using RSA key exchange.
       
 15804 		// First two bytes are version of TLS.
       
 15805 		// 0                   1                   2                   3   
       
 15806 		//  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 
       
 15807 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15808 		//                 |                                               |
       
 15809 		// +-+-+-+-+-+-+-+-+                                               +
       
 15810 		// |                                                               |
       
 15811 		// +                                                               +
       
 15812 		// |                Encrypted Premaster Secret (48 bytes)          |
       
 15813 		// +                                                               +
       
 15814 		// |                                                               |
       
 15815 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15816 
       
 15817 		if (m_own_encrypted_premaster_secret.get_is_valid_data() == false)
       
 15818 		{
       
 15819 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15820 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
 15821 		}
       
 15822 
       
 15823 		EAP_TRACE_DATA_DEBUG(
       
 15824 			m_am_tools,
       
 15825 			TRACE_FLAGS_DEFAULT,
       
 15826 			(EAPL("TLS: complete_create_handshake_type_client_key_exchange(): encrypted premaster_secret"),
       
 15827 			m_own_encrypted_premaster_secret.get_data(),
       
 15828 			m_own_encrypted_premaster_secret.get_data_length()));
       
 15829 
       
 15830 		status = tls_handshake_message->set_encrypted_premaster_secret(
       
 15831 			&m_own_encrypted_premaster_secret);
       
 15832 		if (status != eap_status_ok)
       
 15833 		{
       
 15834 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15835 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15836 		}
       
 15837 	}
       
 15838 	else if (cipher_suite_is_TLS_DHE_DSS() == true
       
 15839 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
 15840 #if defined(USE_FAST_EAP_TYPE)
       
 15841 		|| (m_eap_type == eap_type_fast
       
 15842 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
 15843 			&& cipher_suite_is_TLS_DH_anon() == true)
       
 15844 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 15845 		)
       
 15846 	{
       
 15847 		// Diffie-Hellman Yc is included when selected cipher suite is
       
 15848 		// ephemeral Diffie-Hellman key exchange.
       
 15849 		// 0                   1                   2                   3   
       
 15850 		//  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 
       
 15851 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15852 		//                 | DH Yc length                  |               |
       
 15853 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15854 		// |                                                               |
       
 15855 		// +                                                               +
       
 15856 		// |                DH Yc value                                    |
       
 15857 		// +                                                               +
       
 15858 		// |                                                               |
       
 15859 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15860 
       
 15861 		if (m_own_public_dhe_key.get_is_valid_data() == false)
       
 15862 		{
       
 15863 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15864 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
 15865 		}
       
 15866 
       
 15867 		status = tls_handshake_message->set_public_dhe_key(
       
 15868 			&m_own_public_dhe_key);
       
 15869 		if (status != eap_status_ok)
       
 15870 		{
       
 15871 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15872 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15873 		}
       
 15874 	}
       
 15875 	else
       
 15876 	{
       
 15877 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15878 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
 15879 	}
       
 15880 
       
 15881 	// --------------------------------------------------------------------
       
 15882 
       
 15883 	// Note add_record_message() frees message on any case.
       
 15884 	automatic_tls_handshake_message.do_not_free_variable();
       
 15885 
       
 15886 	status = add_record_message(tls_handshake_message);
       
 15887 	if (status != eap_status_ok)
       
 15888 	{
       
 15889 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15890 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 15891 	}
       
 15892 
       
 15893 	// --------------------------------------------------------------------
       
 15894 
       
 15895 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15896 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 15897 }
       
 15898 
       
 15899 //--------------------------------------------------
       
 15900 
       
 15901 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_client_key_exchange()
       
 15902 {
       
 15903 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15904 
       
 15905 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 15906 	EAP_TRACE_DEBUG(
       
 15907 		m_am_tools,
       
 15908 		TRACE_FLAGS_DEFAULT,
       
 15909 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_client_key_exchange()\n"),
       
 15910 		 this,
       
 15911 		 (m_is_client == true ? "client": "server")));
       
 15912 
       
 15913 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_client_key_exchange()");
       
 15914 
       
 15915 	eap_status_e status = eap_status_process_general_error;
       
 15916 
       
 15917 	if (cipher_suite_is_TLS_RSA() == true)
       
 15918 	{
       
 15919 		// Encrypted premaster secret is included when selected
       
 15920 		// cipher suite is using RSA key exchange.
       
 15921 		// First two bytes are version of TLS.
       
 15922 		// 0                   1                   2                   3   
       
 15923 		//  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 
       
 15924 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15925 		//                 |                                               |
       
 15926 		// +-+-+-+-+-+-+-+-+                                               +
       
 15927 		// |                                                               |
       
 15928 		// +                                                               +
       
 15929 		// |                Encrypted Premaster Secret (48 bytes)          |
       
 15930 		// +                                                               +
       
 15931 		// |                                                               |
       
 15932 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15933 
       
 15934 		if (m_premaster_secret.get_is_valid_data() == false)
       
 15935 		{
       
 15936 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15937 			return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
 15938 		}
       
 15939 
       
 15940 		EAP_TRACE_DEBUG(
       
 15941 			m_am_tools,
       
 15942 			TRACE_FLAGS_DEFAULT,
       
 15943 			(EAPL("TLS: %s:     pki_function: rsa_encrypt_with_public_key()\n"),
       
 15944 			(m_is_client == true ? "client": "server")));
       
 15945 
       
 15946 		EAP_TRACE_DATA_DEBUG(
       
 15947 			m_am_tools,
       
 15948 			TRACE_FLAGS_DEFAULT,
       
 15949 			(EAPL("TLS: create_handshake_type_client_key_exchange(): premaster_secret"),
       
 15950 			 m_premaster_secret.get_data(),
       
 15951 			 m_premaster_secret.get_data_length()));
       
 15952 
       
 15953 		status = m_am_tls_services->rsa_encrypt_with_public_key(
       
 15954 			&m_premaster_secret);
       
 15955 
       
 15956 		if (status == eap_status_pending_request)
       
 15957 		{
       
 15958 			// This is pending query, that will be completed by
       
 15959 			// complete_rsa_encrypt_with_public_key() call.
       
 15960 			m_pending_rsa_encrypt_with_public_key = true;
       
 15961 		}
       
 15962 		else if (status == eap_status_completed_request)
       
 15963 		{
       
 15964 			// This is already completed by complete_rsa_encrypt_with_public_key() call.
       
 15965 		}
       
 15966 		else if (status == eap_status_ok)
       
 15967 		{
       
 15968 			// This is also an error case, because this call is always completed on success. 
       
 15969 			status = eap_status_process_general_error;
       
 15970 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15971 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 15972 		}
       
 15973 		else // All other status values means error, because this
       
 15974 			// call is always completed on success.
       
 15975 		{
       
 15976 			// This is an error case.
       
 15977 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 15978 			return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
 15979 		}
       
 15980 	}
       
 15981 	else if (cipher_suite_is_TLS_DHE_DSS() == true
       
 15982 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
 15983 #if defined(USE_FAST_EAP_TYPE)
       
 15984 		|| (m_eap_type == eap_type_fast
       
 15985 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
 15986 			&& cipher_suite_is_TLS_DH_anon() == true)
       
 15987 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 15988 		)
       
 15989 	{
       
 15990 		// Diffie-Hellman Yc is included when selected cipher suite is
       
 15991 		// ephemeral Diffie-Hellman key exchange.
       
 15992 		// 0                   1                   2                   3   
       
 15993 		//  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 
       
 15994 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 15995 		//                 | DH Yc length                  |               |
       
 15996 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 15997 		// |                                                               |
       
 15998 		// +                                                               +
       
 15999 		// |                DH Yc value                                    |
       
 16000 		// +                                                               +
       
 16001 		// |                                                               |
       
 16002 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16003 
       
 16004 		// These cipher suites does not need asyncronous operations.
       
 16005 		// Still these cipher suites are completed in
       
 16006 		// complete_create_handshake_type_client_key_exchange().
       
 16007 		status = eap_status_ok;
       
 16008 	}
       
 16009 	else
       
 16010 	{
       
 16011 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16012 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
 16013 	}
       
 16014 
       
 16015 	// --------------------------------------------------------------------
       
 16016 
       
 16017 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16018 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 16019 }
       
 16020 
       
 16021 //--------------------------------------------------
       
 16022 
       
 16023 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_create_handshake_type_certificate_verify()
       
 16024 {
       
 16025 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16026 
       
 16027 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 16028 	EAP_TRACE_DEBUG(
       
 16029 		m_am_tools,
       
 16030 		TRACE_FLAGS_DEFAULT,
       
 16031 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_create_handshake_type_certificate_verify()\n"),
       
 16032 		 this,
       
 16033 		 (m_is_client == true ? "client": "server")));
       
 16034 
       
 16035 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_create_handshake_type_certificate_verify()");
       
 16036 
       
 16037 	tls_handshake_message_c *tls_handshake_message = 0;
       
 16038 
       
 16039 	eap_automatic_variable_c<tls_handshake_message_c>
       
 16040 		automatic_tls_handshake_message(m_am_tools);
       
 16041 
       
 16042 	eap_status_e status = allocate_handshake_message(
       
 16043 		&tls_handshake_message,
       
 16044 		&automatic_tls_handshake_message,
       
 16045 		tls_handshake_type_certificate_verify);
       
 16046 	if (status != eap_status_ok)
       
 16047 	{
       
 16048 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16049 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16050 	}
       
 16051 
       
 16052 	EAP_TRACE_DATA_DEBUG(
       
 16053 		m_am_tools,
       
 16054 		TRACE_FLAGS_DEFAULT,
       
 16055 		(EAPL("TLS: complete_create_handshake_type_certificate_verify(): m_signed_message_hash"),
       
 16056 		m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
       
 16057 		m_signed_message_hash.get_data_length()));
       
 16058 
       
 16059 	status = tls_handshake_message->set_signed_message_hash(
       
 16060 		&m_signed_message_hash);
       
 16061 	if (status != eap_status_ok)
       
 16062 	{
       
 16063 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16064 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16065 	}
       
 16066 
       
 16067 	// --------------------------------------------------------------------
       
 16068 
       
 16069 	// Note add_record_message() frees message on any case.
       
 16070 	automatic_tls_handshake_message.do_not_free_variable();
       
 16071 
       
 16072 	status = add_record_message(tls_handshake_message);
       
 16073 	if (status != eap_status_ok)
       
 16074 	{
       
 16075 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16076 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16077 	}
       
 16078 
       
 16079 	// --------------------------------------------------------------------
       
 16080 
       
 16081 	// --------------------------------------------------------------------
       
 16082 
       
 16083 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16084 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 16085 }
       
 16086 
       
 16087 
       
 16088 //--------------------------------------------------
       
 16089 
       
 16090 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_certificate_verify()
       
 16091 {
       
 16092 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16093 
       
 16094 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 16095 	EAP_TRACE_DEBUG(
       
 16096 		m_am_tools,
       
 16097 		TRACE_FLAGS_DEFAULT,
       
 16098 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_certificate_verify()\n"),
       
 16099 		 this,
       
 16100 		 (m_is_client == true ? "client": "server")));
       
 16101 
       
 16102 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_certificate_verify()");
       
 16103 
       
 16104 	// --------------------------------------------------------------------
       
 16105 
       
 16106 	if (cipher_suite_is_TLS_RSA() == true)
       
 16107 	{
       
 16108 		// 0                   1                   2                   3   
       
 16109 		//  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 
       
 16110 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16111 		//                 |                                               |
       
 16112 		// +-+-+-+-+-+-+-+-+                                               +
       
 16113 		// |                                                               |
       
 16114 		// +                   Signed MD5 hash                             +
       
 16115 		// |                    (16 bytes)                                 |
       
 16116 		// +                                                               +
       
 16117 		// |                                                               |
       
 16118 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16119 		// |                                                               |
       
 16120 		// +                   Signed SHA hash                             +
       
 16121 		// |                    (20 bytes)                                 |
       
 16122 		// +                                                               +
       
 16123 		// |                                                               |
       
 16124 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16125 
       
 16126 		// this will be created in tls_handshake_message_c::add_message_data().
       
 16127 	}
       
 16128 	else if (cipher_suite_is_TLS_DHE_DSS() == true
       
 16129 		|| cipher_suite_is_TLS_DHE_RSA() == true)
       
 16130 	{
       
 16131 		// 0                   1                   2                   3   
       
 16132 		//  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 
       
 16133 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16134 		//                 |                                               |
       
 16135 		// +-+-+-+-+-+-+-+-+                                               +
       
 16136 		// |                                                               |
       
 16137 		// +                   Signed SHA hash                             +
       
 16138 		// |                    (48 bytes)                                 |
       
 16139 		// +                                                               +
       
 16140 		// |                                                               |
       
 16141 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16142 
       
 16143 		// this will be created in tls_handshake_message_c::add_message_data().
       
 16144 	}
       
 16145 	else
       
 16146 	{
       
 16147 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16148 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
 16149 	}
       
 16150 
       
 16151 	eap_status_e status = message_hash_save_certificate_verify();
       
 16152 	if (status != eap_status_ok)
       
 16153 	{
       
 16154 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16155 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16156 	}
       
 16157 
       
 16158 	eap_variable_data_c message_hash(m_am_tools);
       
 16159 
       
 16160 	status = message_hash_create(
       
 16161 		false,
       
 16162 		tls_handshake_type_certificate_verify,
       
 16163 		&message_hash,
       
 16164 		m_is_client);
       
 16165 	if (status != eap_status_ok)
       
 16166 	{
       
 16167 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16168 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16169 	}
       
 16170 
       
 16171 	EAP_TRACE_DEBUG(
       
 16172 		m_am_tools,
       
 16173 		TRACE_FLAGS_DEFAULT,
       
 16174 		(EAPL("TLS: %s:     pki_function: sign_with_private_key()\n"),
       
 16175 		(m_is_client == true ? "client": "server")));
       
 16176 
       
 16177 	EAP_TRACE_DATA_DEBUG(
       
 16178 		m_am_tools,
       
 16179 		TRACE_FLAGS_DEFAULT,
       
 16180 		(EAPL("TLS: create_handshake_type_certificate_verify() message_hash"),
       
 16181 		message_hash.get_data(message_hash.get_data_length()),
       
 16182 		message_hash.get_data_length()));
       
 16183 
       
 16184 	// NOTE this function is asyncronous. This causes complex control flow.
       
 16185 	status = m_am_tls_services->sign_with_private_key(
       
 16186 		&message_hash);
       
 16187 	if (status == eap_status_pending_request)
       
 16188 	{
       
 16189 		// This is pending query, that will be completed by complete_query_certificate_chain() call.
       
 16190 		m_pending_sign_with_private_key = true;
       
 16191 	}
       
 16192 	else if (status == eap_status_completed_request)
       
 16193 	{
       
 16194 		// This is already completed by complete_query_certificate_chain() call.
       
 16195 	}
       
 16196 	else if (status == eap_status_ok)
       
 16197 	{
       
 16198 		// This is also an error case, because this call is always completed on success. 
       
 16199 		status = eap_status_process_general_error;
       
 16200 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16201 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16202 	}
       
 16203 	else // All other status values means error, because this call is always completed on success.
       
 16204 	{
       
 16205 		// This is an error case.
       
 16206 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16207 		return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
 16208 	}
       
 16209 
       
 16210 	// --------------------------------------------------------------------
       
 16211 
       
 16212 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16213 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 16214 }
       
 16215 
       
 16216 
       
 16217 //--------------------------------------------------
       
 16218 
       
 16219 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_finished()
       
 16220 {
       
 16221 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16222 
       
 16223 	EAP_TRACE_DEBUG(
       
 16224 		m_am_tools,
       
 16225 		TRACE_FLAGS_DEFAULT,
       
 16226 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_finished()\n"),
       
 16227 		 this,
       
 16228 		 (m_is_client == true ? "client": "server")));
       
 16229 
       
 16230 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_finished()");
       
 16231 
       
 16232 	// 0                   1                   2                   3   
       
 16233 	//  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 
       
 16234 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16235 	//                 |                                               |
       
 16236 	// +-+-+-+-+-+-+-+-+                                               +
       
 16237 	// |                                                               |
       
 16238 	// +                                                               +
       
 16239 	// |         PRF(master_secret, finished_label,                    |
       
 16240 	// +             MD5(handshake_messages) +                         +
       
 16241 	// |             SHA-1(handshake_messages)) [0..11]                |
       
 16242 	// +                                                               +
       
 16243 	// |                                                               |
       
 16244 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16245 
       
 16246 	tls_handshake_message_c *tls_handshake_message = 0;
       
 16247 
       
 16248 	eap_automatic_variable_c<tls_handshake_message_c>
       
 16249 		automatic_tls_handshake_message(m_am_tools);
       
 16250 
       
 16251 	eap_status_e status = allocate_handshake_message(
       
 16252 		&tls_handshake_message,
       
 16253 		&automatic_tls_handshake_message,
       
 16254 		tls_handshake_type_finished);
       
 16255 	if (status != eap_status_ok)
       
 16256 	{
       
 16257 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16258 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16259 	}
       
 16260 
       
 16261 	// --------------------------------------------------------------------
       
 16262 
       
 16263 	// Note add_record_message() frees message on any case.
       
 16264 	automatic_tls_handshake_message.do_not_free_variable();
       
 16265 
       
 16266 	status = add_record_message(tls_handshake_message);
       
 16267 	if (status != eap_status_ok)
       
 16268 	{
       
 16269 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16270 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16271 	}
       
 16272 
       
 16273 	// --------------------------------------------------------------------
       
 16274 
       
 16275 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16276 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 16277 }
       
 16278 
       
 16279 //--------------------------------------------------
       
 16280 
       
 16281 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 16282 
       
 16283 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_handshake_type_new_session_ticket()
       
 16284 {
       
 16285 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16286 
       
 16287 	EAP_TRACE_DEBUG(
       
 16288 		m_am_tools,
       
 16289 		TRACE_FLAGS_DEFAULT,
       
 16290 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_handshake_type_new_session_ticket()\n"),
       
 16291 		 this,
       
 16292 		 (m_is_client == true ? "client": "server")));
       
 16293 
       
 16294 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_handshake_type_new_session_ticket()");
       
 16295 
       
 16296 	// 0                   1                   2                   3   
       
 16297 	//  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 
       
 16298 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16299 	//                 |      ticket lifetime hint (4 bytes)       ... |
       
 16300 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16301 	// | ...           | opaque ticket ...  n bytes                    
       
 16302 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 16303 
       
 16304 	tls_handshake_message_c *tls_handshake_message = 0;
       
 16305 
       
 16306 	eap_automatic_variable_c<tls_handshake_message_c>
       
 16307 		automatic_tls_handshake_message(m_am_tools);
       
 16308 
       
 16309 	eap_status_e status = allocate_handshake_message(
       
 16310 		&tls_handshake_message,
       
 16311 		&automatic_tls_handshake_message,
       
 16312 		tls_handshake_type_new_session_ticket);
       
 16313 	if (status != eap_status_ok)
       
 16314 	{
       
 16315 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16316 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16317 	}
       
 16318 
       
 16319 	// --------------------------------------------------------------------
       
 16320 
       
 16321 
       
 16322 	const tls_extension_c * const p_new_session_ticket = tls_extension_c::get_tls_extension(
       
 16323 		tls_extension_type_session_ticket,
       
 16324 		&m_supported_tls_extensions,
       
 16325 		m_am_tools);
       
 16326 
       
 16327 	if (p_new_session_ticket != 0)
       
 16328 	{
       
 16329 		eap_array_c<tls_extension_c> session_ticket_extension_array(m_am_tools);
       
 16330 
       
 16331 		tls_extension_c * const p_new_session_ticket_copy = p_new_session_ticket->copy();
       
 16332 		if (p_new_session_ticket_copy == 0)
       
 16333 		{
       
 16334 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16335 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 16336 		}
       
 16337 
       
 16338 		status = session_ticket_extension_array.add_object(p_new_session_ticket_copy, true);
       
 16339 		if (status != eap_status_ok)
       
 16340 		{
       
 16341 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16342 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 16343 		}
       
 16344 
       
 16345 		status = tls_handshake_message->set_tls_extensions(&session_ticket_extension_array);
       
 16346 		if (status != eap_status_ok)
       
 16347 		{
       
 16348 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16349 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 16350 		}
       
 16351 	}
       
 16352 
       
 16353 	// --------------------------------------------------------------------
       
 16354 
       
 16355 	// Note add_record_message() frees message on any case.
       
 16356 	automatic_tls_handshake_message.do_not_free_variable();
       
 16357 
       
 16358 	status = add_record_message(tls_handshake_message);
       
 16359 	if (status != eap_status_ok)
       
 16360 	{
       
 16361 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16362 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16363 	}
       
 16364 
       
 16365 	// --------------------------------------------------------------------
       
 16366 
       
 16367 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16368 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 16369 }
       
 16370 
       
 16371 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 16372 
       
 16373 //--------------------------------------------------
       
 16374 
       
 16375 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_change_cipher_spec_type_change_cipher_spec()
       
 16376 {
       
 16377 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16378 
       
 16379 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 16380 	EAP_TRACE_DEBUG(
       
 16381 		m_am_tools,
       
 16382 		TRACE_FLAGS_DEFAULT,
       
 16383 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_change_cipher_spec_type_change_cipher_spec()\n"),
       
 16384 		 this,
       
 16385 		 (m_is_client == true ? "client": "server")));
       
 16386 
       
 16387 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_change_cipher_spec_type_change_cipher_spec()");
       
 16388 
       
 16389 	// 0                   1                   2                   3   
       
 16390 	//  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 
       
 16391 	//                 +-+-+-+-+-+-+-+-+                                
       
 16392 	//                 | CCS: 1        |                                
       
 16393 	//                 +-+-+-+-+-+-+-+-+                                
       
 16394 
       
 16395 	tls_change_cipher_spec_message_c * const tls_change_cipher_spec_message
       
 16396 		= new tls_change_cipher_spec_message_c(m_am_tools, this, m_is_client);
       
 16397 
       
 16398 	eap_automatic_variable_c<tls_change_cipher_spec_message_c>
       
 16399 		automatic_tls_change_cipher_spec_message(
       
 16400 		m_am_tools, tls_change_cipher_spec_message);
       
 16401 
       
 16402 	if (tls_change_cipher_spec_message == 0
       
 16403 		|| tls_change_cipher_spec_message->get_is_valid() == false)
       
 16404 	{
       
 16405 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16406 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 16407 	}
       
 16408 
       
 16409 	eap_status_e status = tls_change_cipher_spec_message->set_change_cipher_spec_type(
       
 16410 		tls_change_cipher_spec_type_change_cipher_spec);
       
 16411 	if (status != eap_status_ok)
       
 16412 	{
       
 16413 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16414 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16415 	}
       
 16416 
       
 16417 	// --------------------------------------------------------------------
       
 16418 
       
 16419 	// Note add_record_message() frees message on any case.
       
 16420 	automatic_tls_change_cipher_spec_message.do_not_free_variable();
       
 16421 
       
 16422 	status = add_record_message(tls_change_cipher_spec_message);
       
 16423 	if (status != eap_status_ok)
       
 16424 	{
       
 16425 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16426 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 16427 	}
       
 16428 
       
 16429 	// --------------------------------------------------------------------
       
 16430 
       
 16431 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16432 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 16433 }
       
 16434 
       
 16435 //--------------------------------------------------
       
 16436 
       
 16437 EAP_FUNC_EXPORT eap_status_e tls_record_c::finish_handshake()
       
 16438 {
       
 16439 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16440 
       
 16441 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 16442 
       
 16443 	EAP_TRACE_DEBUG(
       
 16444 		m_am_tools,
       
 16445 		TRACE_FLAGS_DEFAULT,
       
 16446 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::finish_handshake(): m_tls_session_type=%d=%s, state=%d=%s\n"),
       
 16447 		 this,
       
 16448 		 (m_is_client == true ? "client": "server"),
       
 16449 		 m_tls_session_type,
       
 16450 		 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16451 		 m_tls_peap_state,
       
 16452 		 eap_tls_trace_string_c::get_state_string(m_tls_peap_state)));
       
 16453 
       
 16454 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::finish_handshake()");
       
 16455 
       
 16456 	EAP_TRACE_DATA_DEBUG(
       
 16457 		m_am_tools,
       
 16458 		TRACE_FLAGS_DEFAULT,
       
 16459 		(EAPL("TLS: finish_handshake(): m_master_secret"),
       
 16460 		 m_master_secret.get_data(),
       
 16461 		 m_master_secret.get_data_length()));
       
 16462 
       
 16463 	EAP_TRACE_DATA_DEBUG(
       
 16464 		m_am_tools,
       
 16465 		TRACE_FLAGS_DEFAULT,
       
 16466 		(EAPL("TLS: finish_handshake(): m_client_handshake_random_value"),
       
 16467 		 m_client_handshake_random_value.get_data(),
       
 16468 		 m_client_handshake_random_value.get_data_length()));
       
 16469 
       
 16470 	EAP_TRACE_DATA_DEBUG(
       
 16471 		m_am_tools,
       
 16472 		TRACE_FLAGS_DEFAULT,
       
 16473 		(EAPL("TLS: finish_handshake(): m_server_handshake_random_value"),
       
 16474 		 m_server_handshake_random_value.get_data(),
       
 16475 		 m_server_handshake_random_value.get_data_length()));
       
 16476 
       
 16477 
       
 16478 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 16479 
       
 16480 	eap_status_e status(eap_status_ok);
       
 16481 
       
 16482 	tls_identity_privacy_handshake_state_e tmp_identity_privacy_handshake_state = 
       
 16483 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 16484 		m_tls_identity_privacy_handshake_state;
       
 16485 #else
       
 16486 		tls_identity_privacy_handshake_state_none;
       
 16487 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 16488 
       
 16489 
       
 16490 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 16491 	if (m_tls_use_identity_privacy == false
       
 16492 		|| tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs
       
 16493 		|| m_tls_session_type != tls_session_type_full_authentication)
       
 16494 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 16495 	{
       
 16496 		status = set_tls_master_secret(
       
 16497 			&m_master_secret,
       
 16498 			&m_client_handshake_random_value,
       
 16499 			&m_server_handshake_random_value);
       
 16500 		if (status != eap_status_ok)
       
 16501 		{
       
 16502 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16503 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 16504 		}
       
 16505 	}
       
 16506 
       
 16507 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 16508 
       
 16509 #if defined(USE_EAP_DEBUG_TRACE)
       
 16510 	// These are for debug break points.
       
 16511 
       
 16512 	if (m_is_client == true)
       
 16513 	{
       
 16514 		if (m_tls_session_type == tls_session_type_full_authentication)
       
 16515 		{
       
 16516 			EAP_TRACE_DEBUG(
       
 16517 				m_am_tools,
       
 16518 				TRACE_FLAGS_DEFAULT,
       
 16519 				(EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16520 				m_tls_session_type,
       
 16521 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16522 				m_tls_peap_state,
       
 16523 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16524 				tmp_identity_privacy_handshake_state,
       
 16525 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16526 
       
 16527 		}
       
 16528 		else if (m_tls_session_type == tls_session_type_original_session_resumption)
       
 16529 		{
       
 16530 			EAP_TRACE_DEBUG(
       
 16531 				m_am_tools,
       
 16532 				TRACE_FLAGS_DEFAULT,
       
 16533 				(EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16534 				m_tls_session_type,
       
 16535 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16536 				m_tls_peap_state,
       
 16537 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16538 				tmp_identity_privacy_handshake_state,
       
 16539 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16540 
       
 16541 		}
       
 16542 		else if (m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 16543 		{
       
 16544 			EAP_TRACE_DEBUG(
       
 16545 				m_am_tools,
       
 16546 				TRACE_FLAGS_DEFAULT,
       
 16547 				(EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16548 				m_tls_session_type,
       
 16549 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16550 				m_tls_peap_state,
       
 16551 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16552 				tmp_identity_privacy_handshake_state,
       
 16553 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16554 		}
       
 16555 #if defined(USE_FAST_EAP_TYPE)
       
 16556 		else if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
 16557 		{
       
 16558 			EAP_TRACE_DEBUG(
       
 16559 				m_am_tools,
       
 16560 				TRACE_FLAGS_DEFAULT,
       
 16561 				(EAPL("TLS: client, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16562 				m_tls_session_type,
       
 16563 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16564 				m_tls_peap_state,
       
 16565 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16566 				tmp_identity_privacy_handshake_state,
       
 16567 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16568 		}
       
 16569 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16570 	}
       
 16571 	else // if (m_is_client == false)
       
 16572 	{
       
 16573 		if (m_tls_session_type == tls_session_type_full_authentication)
       
 16574 		{
       
 16575 			EAP_TRACE_DEBUG(
       
 16576 				m_am_tools,
       
 16577 				TRACE_FLAGS_DEFAULT,
       
 16578 				(EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16579 				m_tls_session_type,
       
 16580 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16581 				m_tls_peap_state,
       
 16582 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16583 				tmp_identity_privacy_handshake_state,
       
 16584 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16585 
       
 16586 		}
       
 16587 		else if (m_tls_session_type == tls_session_type_original_session_resumption)
       
 16588 		{
       
 16589 			EAP_TRACE_DEBUG(
       
 16590 				m_am_tools,
       
 16591 				TRACE_FLAGS_DEFAULT,
       
 16592 				(EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16593 				m_tls_session_type,
       
 16594 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16595 				m_tls_peap_state,
       
 16596 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16597 				tmp_identity_privacy_handshake_state,
       
 16598 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16599 
       
 16600 		}
       
 16601 		else if (m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 16602 		{
       
 16603 			EAP_TRACE_DEBUG(
       
 16604 				m_am_tools,
       
 16605 				TRACE_FLAGS_DEFAULT,
       
 16606 				(EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16607 				m_tls_session_type,
       
 16608 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16609 				m_tls_peap_state,
       
 16610 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16611 				tmp_identity_privacy_handshake_state,
       
 16612 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16613 		}
       
 16614 #if defined(USE_FAST_EAP_TYPE)
       
 16615 		else if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
 16616 		{
       
 16617 			EAP_TRACE_DEBUG(
       
 16618 				m_am_tools,
       
 16619 				TRACE_FLAGS_DEFAULT,
       
 16620 				(EAPL("TLS: server, m_tls_session_type=%d=%s, state=%d=%s, privacy_handshake_state=%d=%s\n"),
       
 16621 				m_tls_session_type,
       
 16622 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 16623 				m_tls_peap_state,
       
 16624 				eap_tls_trace_string_c::get_state_string(m_tls_peap_state),
       
 16625 				tmp_identity_privacy_handshake_state,
       
 16626 				eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(tmp_identity_privacy_handshake_state)));
       
 16627 		}
       
 16628 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16629 	}
       
 16630 #endif //#if defined(USE_EAP_DEBUG_TRACE)
       
 16631 
       
 16632 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 16633 
       
 16634 	if (m_application != 0)
       
 16635 	{
       
 16636 		m_application->set_tunneled_state(
       
 16637 			m_tls_session_type);
       
 16638 	}
       
 16639 
       
 16640 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 16641 
       
 16642 #if defined(USE_FAST_EAP_TYPE)
       
 16643 	if (m_is_client == false
       
 16644 		&& m_eap_type == eap_type_fast
       
 16645 		&& m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
 16646 	{
       
 16647 		// This is server.
       
 16648 		// EAP-FAST is using Tunnel PAC.
       
 16649 		// Here we cannot start tunneled authentication immediately
       
 16650 		// because client migth have sent a User Authorization PAC.
       
 16651 		// We must process the optional TLS Application message(s)
       
 16652 		// to see did client send the User Authorization PAC.
       
 16653 		set_state(tls_peap_state_wait_tunneled_authentication_start);
       
 16654 
       
 16655 		eap_status_e tunnel_ready_status = m_application->peap_tunnel_ready();
       
 16656 		if (tunnel_ready_status != eap_status_ok)
       
 16657 		{
       
 16658 			// This is an error case.
       
 16659 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16660 			return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status);
       
 16661 		}
       
 16662 
       
 16663 		tunnel_ready_status = get_type_partner()->peap_tunnel_ready();
       
 16664 		if (tunnel_ready_status != eap_status_ok)
       
 16665 		{
       
 16666 			// This is an error case.
       
 16667 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16668 			return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status);
       
 16669 		}
       
 16670 	}
       
 16671 	else 
       
 16672 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16673 	if (get_is_tunneled_tls() == false
       
 16674 		|| ((m_tls_session_type == tls_session_type_original_session_resumption
       
 16675 				|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 16676 			&& (
       
 16677 #if defined(USE_FAST_EAP_TYPE)
       
 16678 				m_eap_type == eap_type_fast
       
 16679 				|| 
       
 16680 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16681 				m_eap_type == eap_type_ttls
       
 16682 				|| (m_eap_type == eap_type_peap
       
 16683 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16684 					&& m_peap_version > peap_version_1
       
 16685 #else
       
 16686 					&& m_peap_version > peap_version_0_xp
       
 16687 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16688 					&&  m_peap_version < peap_version_2))))
       
 16689 	{
       
 16690 		if (m_tls_session_type == tls_session_type_full_authentication
       
 16691 			&& tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_negotiates)
       
 16692 		{
       
 16693 			// TLS-privacy negotiation running.
       
 16694 		}
       
 16695 		else
       
 16696 		{
       
 16697 			set_state(tls_peap_state_tls_success);
       
 16698 		}
       
 16699 
       
 16700 		// PEAPv2 does not use m_eap_master_session_key directly.
       
 16701 		// PEAPv2 does derive an other master session key.
       
 16702 		// EAP-TLS, PEAPv0 and PEAPv1 does use m_eap_master_session_key.
       
 16703 		if (m_eap_type == eap_type_tls // Plain EAP-TLS.
       
 16704 			|| m_eap_type == eap_type_ttls
       
 16705 #if defined(USE_FAST_EAP_TYPE)
       
 16706 			|| m_eap_type == eap_type_fast
       
 16707 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16708 			|| (m_eap_type == eap_type_peap
       
 16709 				&& (m_peap_version == peap_version_0_xp
       
 16710 					|| m_peap_version == peap_version_1)))
       
 16711 		{
       
 16712 			status = get_type_partner()->set_tls_master_secret(&m_eap_master_session_key);
       
 16713 			if (status != eap_status_ok)
       
 16714 			{
       
 16715 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16716 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 16717 			}
       
 16718 		}
       
 16719 
       
 16720 		if ((
       
 16721 #if defined(USE_FAST_EAP_TYPE)
       
 16722 			m_eap_type == eap_type_fast
       
 16723 				||
       
 16724 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16725 				m_eap_type == eap_type_ttls)
       
 16726 			&& (m_tls_session_type == tls_session_type_original_session_resumption
       
 16727 					|| m_tls_session_type == tls_session_type_stateless_session_resumption))
       
 16728 		{
       
 16729 			eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state);
       
 16730 			if (notification_status != eap_status_ok)
       
 16731 			{
       
 16732 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16733 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 16734 			}
       
 16735 		}
       
 16736 	}
       
 16737 	else if (tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none
       
 16738 		|| tmp_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_runs)
       
 16739 	{
       
 16740 		if ((m_eap_type == eap_type_peap
       
 16741 				&& m_peap_version >= peap_version_0_xp
       
 16742 				&& m_peap_version <= peap_version_2)
       
 16743 			|| m_eap_type == eap_type_ttls
       
 16744 #if defined(USE_FAST_EAP_TYPE)
       
 16745 			|| m_eap_type == eap_type_fast
       
 16746 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16747 			)
       
 16748 		{
       
 16749 			if (m_application == 0)
       
 16750 			{
       
 16751 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16752 				return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
 16753 			}
       
 16754 
       
 16755 			set_state(tls_peap_state_peap_tunnel_ready);
       
 16756 
       
 16757 			eap_status_e tunnel_ready_status = m_application->peap_tunnel_ready();
       
 16758 			if (tunnel_ready_status != eap_status_ok)
       
 16759 			{
       
 16760 				// This is an error case.
       
 16761 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16762 				return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status);
       
 16763 			}
       
 16764 
       
 16765 			tunnel_ready_status = get_type_partner()->peap_tunnel_ready();
       
 16766 			if (tunnel_ready_status != eap_status_ok)
       
 16767 			{
       
 16768 				// This is an error case.
       
 16769 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16770 				return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status);
       
 16771 			}
       
 16772 
       
 16773 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16774 			if ((m_tls_session_type == tls_session_type_original_session_resumption
       
 16775 					|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 16776 				&& m_use_tppd_tls_peap == true
       
 16777 				&& m_peap_version == peap_version_1
       
 16778 				&& m_use_tppd_peapv1_acknowledge_hack == true)
       
 16779 			{
       
 16780 				status = get_type_partner()->set_tls_master_secret(&m_eap_master_session_key);
       
 16781 				if (status != eap_status_ok)
       
 16782 				{
       
 16783 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16784 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 16785 				}
       
 16786 			}
       
 16787 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16788 
       
 16789 
       
 16790 			if (m_is_client == true
       
 16791 				&& m_eap_type == eap_type_ttls)
       
 16792 			{
       
 16793 				// EAP-TTLS client starts the tunneled authentication.
       
 16794 
       
 16795 				// Here we swap the addresses.
       
 16796 				eap_am_network_id_c receive_network_id(m_am_tools,
       
 16797 					m_send_network_id.get_destination_id(),
       
 16798 					m_send_network_id.get_source_id(),
       
 16799 					m_send_network_id.get_type());
       
 16800 
       
 16801 				status = m_application->start_ttls_tunneled_authentication(
       
 16802 					&receive_network_id,
       
 16803 					m_received_eap_identifier);
       
 16804 				if (status != eap_status_ok
       
 16805 					&& status != eap_status_pending_request)
       
 16806 				{
       
 16807 					// This is an error case.
       
 16808 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16809 					return EAP_STATUS_RETURN(m_am_tools, tunnel_ready_status);
       
 16810 				}
       
 16811 			}
       
 16812 
       
 16813 
       
 16814 #if defined(USE_EAP_CORE_SERVER)
       
 16815 			if (m_is_client == false)
       
 16816 			{
       
 16817 				// Server
       
 16818 
       
 16819 				if (
       
 16820 #if defined(USE_FAST_EAP_TYPE)
       
 16821 					m_eap_type == eap_type_fast
       
 16822 					|| 
       
 16823 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16824 					(m_eap_type == eap_type_peap
       
 16825 						&& (m_peap_version >= peap_version_2
       
 16826 							|| ((m_tls_session_type == tls_session_type_original_session_resumption
       
 16827 								|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 16828 								&& (
       
 16829 									m_peap_version == peap_version_0_xp
       
 16830 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16831 									|| m_peap_version == peap_version_1
       
 16832 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16833 									)
       
 16834 								)
       
 16835 							)
       
 16836 						)
       
 16837 					)
       
 16838 				{
       
 16839 #if defined(USE_FAST_EAP_TYPE)
       
 16840 					if (m_eap_type == eap_type_fast
       
 16841 						&& m_send_piggypacked_eap_identity_request == false
       
 16842 						&& (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP
       
 16843 							|| m_tls_session_type == tls_session_type_full_authentication))
       
 16844 					{
       
 16845 						// Server does not start tunneled authentication yet.
       
 16846 						// Instead server waits empty EAP-FAST acnowledge message from client.
       
 16847 
       
 16848 						eap_state_notification_c notification(
       
 16849 							m_am_tools,
       
 16850 							&m_send_network_id,
       
 16851 							m_is_client,
       
 16852 							eap_state_notification_eap,
       
 16853 							eap_protocol_layer_eap,
       
 16854 							m_eap_type,
       
 16855 							eap_state_none,
       
 16856 							eap_state_authentication_wait_eap_fast_empty_acknowledge,
       
 16857 							m_received_eap_identifier,
       
 16858 							false);
       
 16859 						get_type_partner()->state_notification(&notification);
       
 16860 						status = eap_status_ok;
       
 16861 					}
       
 16862 					else
       
 16863 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16864 					{
       
 16865 						// Here we swap the addresses.
       
 16866 						eap_am_network_id_c receive_network_id(m_am_tools,
       
 16867 							m_send_network_id.get_destination_id(),
       
 16868 							m_send_network_id.get_source_id(),
       
 16869 							m_send_network_id.get_type());
       
 16870 
       
 16871 						set_state(tls_peap_state_wait_tunneled_authentication_start);
       
 16872 
       
 16873 						// Here we must start the tunneled EAP-type.
       
 16874 						status = start_peap_tunneled_authentication(
       
 16875 							&receive_network_id,
       
 16876 							m_received_eap_identifier,
       
 16877 							m_tls_session_type);
       
 16878 						if (status != eap_status_ok)
       
 16879 						{
       
 16880 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16881 							return EAP_STATUS_RETURN(m_am_tools, status);
       
 16882 						}
       
 16883 					}
       
 16884 				}
       
 16885 			}
       
 16886 			else
       
 16887 #endif //#if defined(USE_EAP_CORE_SERVER)
       
 16888 			{
       
 16889 				// Client
       
 16890 
       
 16891 #if defined(USE_FAST_EAP_TYPE)
       
 16892 				if (m_eap_type == eap_type_fast)
       
 16893 				{
       
 16894 					// Here we swap the addresses.
       
 16895 					eap_am_network_id_c receive_network_id(m_am_tools,
       
 16896 						m_send_network_id.get_destination_id(),
       
 16897 						m_send_network_id.get_source_id(),
       
 16898 						m_send_network_id.get_type());
       
 16899 
       
 16900 					// Here we must start the tunneled EAP-type.
       
 16901 					status = start_peap_tunneled_authentication(
       
 16902 						&receive_network_id,
       
 16903 						m_received_eap_identifier,
       
 16904 						m_tls_session_type);
       
 16905 					if (status != eap_status_ok)
       
 16906 					{
       
 16907 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16908 						return EAP_STATUS_RETURN(m_am_tools, status);
       
 16909 					}
       
 16910 				}
       
 16911 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 16912 
       
 16913 			}
       
 16914 
       
 16915 
       
 16916 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16917 			if ((m_tls_session_type == tls_session_type_original_session_resumption
       
 16918 					|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 16919 				&& m_use_tppd_tls_peap == true
       
 16920 				&& m_peap_version == peap_version_1
       
 16921 				&& m_use_tppd_peapv1_acknowledge_hack == true)
       
 16922 			{
       
 16923 				if (m_is_client == true)
       
 16924 				{
       
 16925 					eap_state_notification_c notification(
       
 16926 						m_am_tools,
       
 16927 						&m_send_network_id,
       
 16928 						m_is_client,
       
 16929 						eap_state_notification_eap,
       
 16930 						eap_protocol_layer_internal_type,
       
 16931 						m_eap_type,
       
 16932 						eap_state_none,
       
 16933 						tls_peap_state_tppd_peapv1_waits_eap_success_or_tunneled_packet,
       
 16934 						m_received_eap_identifier,
       
 16935 						false);
       
 16936 					get_type_partner()->state_notification(&notification);
       
 16937 				}
       
 16938 			}
       
 16939 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
 16940 
       
 16941 		}
       
 16942 		else
       
 16943 		{
       
 16944 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16945 			return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
 16946 		}
       
 16947 	}
       
 16948 
       
 16949 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 16950 
       
 16951 	if (m_tls_peap_state == tls_peap_state_tls_success)
       
 16952 	{
       
 16953 		// Notify lower layer that TLS/PEAP ended successfully
       
 16954 
       
 16955 		if (get_is_tunneled_tls() == false
       
 16956 			|| (get_is_tunneled_tls() == true
       
 16957 				&& m_tunneled_eap_type_authentication_state
       
 16958 				== eap_state_authentication_finished_successfully)
       
 16959 			|| (get_is_tunneled_tls() == true
       
 16960 				&& m_tls_session_type == tls_session_type_original_session_resumption))
       
 16961 		{
       
 16962 			eap_status_e save_status = m_am_tls_services->save_tls_session(
       
 16963 				&m_session_id,
       
 16964 				&m_master_secret,
       
 16965 				m_selected_cipher_suite
       
 16966 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 16967 				, tls_extension_c::get_tls_extension(
       
 16968 					tls_extension_type_session_ticket,
       
 16969 					&m_received_tls_extensions,
       
 16970 					m_am_tools)
       
 16971 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
 16972 				);
       
 16973 			if (save_status != eap_status_ok)
       
 16974 			{
       
 16975 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16976 				return EAP_STATUS_RETURN(m_am_tools, save_status);
       
 16977 			}
       
 16978 
       
 16979 			eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state);
       
 16980 			if (notification_status != eap_status_ok)
       
 16981 			{
       
 16982 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16983 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 16984 			}
       
 16985 		}
       
 16986 	}
       
 16987 	else if (m_tls_peap_state == tls_peap_state_peap_tunnel_ready)
       
 16988 	{
       
 16989 		// Notify lower layer that TLS tunnel is ready.
       
 16990 
       
 16991 		eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state);
       
 16992 		if (notification_status != eap_status_ok)
       
 16993 		{
       
 16994 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 16995 			return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 16996 		}
       
 16997 
       
 16998 		// Change state that only one indication is sent to lower layer.
       
 16999 		if (m_is_client == true)
       
 17000 		{
       
 17001 			set_state(tls_peap_state_wait_application_data);
       
 17002 		}
       
 17003 		else
       
 17004 		{
       
 17005 			set_state(tls_peap_state_wait_tunneled_authentication_start);
       
 17006 		}
       
 17007 	}
       
 17008 	else if (m_tls_peap_state == tls_peap_state_failure)
       
 17009 	{
       
 17010 		eap_status_e notification_status = indicate_state_to_lower_layer(m_tls_peap_state);
       
 17011 		if (notification_status != eap_status_ok)
       
 17012 		{
       
 17013 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17014 			return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 17015 		}
       
 17016 	}
       
 17017 	else
       
 17018 	{
       
 17019 		EAP_TRACE_DEBUG(
       
 17020 			m_am_tools,
       
 17021 			TRACE_FLAGS_DEFAULT,
       
 17022 			(EAPL("TLS: tls_record_c::finish_handshake(): No notification, m_tls_session_type=%d=%s, state=%d=%s\n"),
       
 17023 			m_tls_session_type,
       
 17024 			eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
 17025 			m_tls_peap_state,
       
 17026 			eap_tls_trace_string_c::get_state_string(m_tls_peap_state)));
       
 17027 	}
       
 17028 
       
 17029 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 17030 
       
 17031 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17032 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
 17033 }
       
 17034 
       
 17035 //--------------------------------------------------
       
 17036 
       
 17037 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_tls_protocol_alert(
       
 17038 	const tls_alert_description_e par_alert_description,
       
 17039 	const tls_alert_level_e par_alert_level,
       
 17040 	const eap_status_e par_result)
       
 17041 {
       
 17042 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17043 
       
 17044 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 17045 	EAP_TRACE_DEBUG(
       
 17046 		m_am_tools,
       
 17047 		TRACE_FLAGS_DEFAULT,
       
 17048 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_tls_protocol_alert()\n"),
       
 17049 		 this,
       
 17050 		 (m_is_client == true ? "client": "server")));
       
 17051 
       
 17052 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_tls_protocol_alert()");
       
 17053 
       
 17054 	eap_status_e status = eap_status_authentication_failure;
       
 17055 
       
 17056 	//--------------------------------------------------------------------
       
 17057 
       
 17058 	tls_alert_level_e alert_level = par_alert_level;
       
 17059 	tls_alert_description_e alert_description = par_alert_description;
       
 17060 
       
 17061 	if (alert_level == tls_alert_level_none)
       
 17062 	{
       
 17063 		alert_level = tls_alert_level_fatal;
       
 17064 	}
       
 17065 
       
 17066 	if (alert_description == tls_alert_description_none)
       
 17067 	{
       
 17068 		// Examine par_result.
       
 17069 		switch(par_result)
       
 17070 		{
       
 17071 #if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17072 		#error Alert descriptions need more code.
       
 17073 		case :
       
 17074 			alert_description = tls_alert_description_close_notify;
       
 17075 			break;
       
 17076 #endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17077 		case eap_status_unexpected_message:
       
 17078 			alert_description = tls_alert_description_unexpected_message;
       
 17079 			break;
       
 17080 		case eap_status_authentication_failure:
       
 17081 			alert_description = tls_alert_description_bad_record_mac;
       
 17082 			break;
       
 17083 		case eap_status_decryption_failure:
       
 17084 		case eap_status_illegal_padding:
       
 17085 			alert_description = tls_alert_description_decryption_failed;
       
 17086 			break;
       
 17087 #if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17088 		case :
       
 17089 			alert_description = tls_alert_description_record_overflow;
       
 17090 			break;
       
 17091 		case :
       
 17092 			alert_description = tls_alert_description_decompression_failure;
       
 17093 			break;
       
 17094 #endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17095 		case eap_status_illegal_cipher_suite:
       
 17096 			alert_description = tls_alert_description_handshake_failure;
       
 17097 			break;
       
 17098 		case eap_status_illegal_certificate:
       
 17099 		case eap_status_bad_certificate:
       
 17100 			alert_description = tls_alert_description_bad_certificate;
       
 17101 #if defined(USE_FAST_EAP_TYPE)
       
 17102 			if (m_eap_type == eap_type_fast
       
 17103 				&& par_result == eap_status_bad_certificate)
       
 17104 			{
       
 17105 				alert_level = tls_alert_level_fatal;
       
 17106 			}
       
 17107 			else
       
 17108 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 17109 			{
       
 17110 				alert_level = tls_alert_level_warning;
       
 17111 			}
       
 17112 			break;
       
 17113 		case eap_status_unsupported_certificate:
       
 17114 			alert_description = tls_alert_description_unsupported_certificate;
       
 17115 			alert_level = tls_alert_level_warning;
       
 17116 			break;
       
 17117 		case eap_status_certificate_revoked:
       
 17118 			alert_description = tls_alert_description_certificate_revoked;
       
 17119 			alert_level = tls_alert_level_warning;
       
 17120 			break;
       
 17121 		case eap_status_certificate_expired:
       
 17122 			alert_description = tls_alert_description_certificate_expired;
       
 17123 			alert_level = tls_alert_level_warning;
       
 17124 			break;
       
 17125 		case eap_status_user_certificate_unknown:
       
 17126 		case eap_status_ca_certificate_unknown:
       
 17127 			alert_description = tls_alert_description_certificate_unknown;
       
 17128 			alert_level = tls_alert_level_warning;
       
 17129 			break;
       
 17130 		case eap_status_illegal_encryption_parameter_size:
       
 17131 		case eap_status_illegal_parameter:
       
 17132 			alert_description = tls_alert_description_illegal_parameter;
       
 17133 			break;
       
 17134 		case eap_status_unknown_ca:
       
 17135 			alert_description = tls_alert_description_unknown_ca;
       
 17136 			break;
       
 17137 		case eap_status_access_denied:
       
 17138 			alert_description = tls_alert_description_access_denied;
       
 17139 			break;
       
 17140 		case eap_status_process_illegal_packet_error:
       
 17141 		case eap_status_illegal_eap_code:
       
 17142 		case eap_status_illegal_eap_type:
       
 17143 		case eap_status_illegal_eap_identity:
       
 17144 		case eap_status_too_short_message:
       
 17145 		case eap_status_too_long_message:
       
 17146 		case eap_status_wrong_protocol:
       
 17147 		case eap_status_wrong_type:
       
 17148 		case eap_status_data_length_not_aligned_to_block_size:
       
 17149 		case eap_status_illegal_data_payload:
       
 17150 		case eap_status_illegal_payload:
       
 17151 		case eap_status_header_corrupted:
       
 17152 		case eap_status_illegal_nai:
       
 17153 		case eap_status_illegal_nai_payload:
       
 17154 			alert_description = tls_alert_description_decode_error;
       
 17155 			break;
       
 17156 #if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17157 		case :
       
 17158 			alert_description = tls_alert_description_decrypt_error;
       
 17159 			break;
       
 17160 		case :
       
 17161 			alert_description = tls_alert_description_export_restriction;
       
 17162 			break;
       
 17163 #endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17164 		case eap_status_no_matching_protocol_version:
       
 17165 			alert_description = tls_alert_description_protocol_version;
       
 17166 			break;
       
 17167 		case eap_status_insufficient_security:
       
 17168 			alert_description = tls_alert_description_insufficient_security;
       
 17169 			break;
       
 17170 		case eap_status_allocation_error:
       
 17171 		case eap_status_not_supported:
       
 17172 		case eap_status_process_general_error:
       
 17173 		case eap_status_type_does_not_exists_error:
       
 17174 		case eap_status_timed_out:
       
 17175 		case eap_status_hardware_not_ready:
       
 17176 			alert_description = tls_alert_description_internal_error;
       
 17177 			break;
       
 17178 #if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17179 		case :
       
 17180 			alert_description = tls_alert_description_user_canceled;
       
 17181 			break;
       
 17182 		case :
       
 17183 			alert_description = tls_alert_description_no_renegotiation;
       
 17184 			break;
       
 17185 #endif //#if EAP_TLS_UNSUPPORTED_ALERT_DESCRIPTION
       
 17186 		default:
       
 17187 			alert_description = tls_alert_description_internal_error;
       
 17188 			break;
       
 17189 		}
       
 17190 	}
       
 17191 	else
       
 17192 	{
       
 17193 		alert_description = par_alert_description;
       
 17194 	}
       
 17195 
       
 17196 	if (alert_level == tls_alert_level_fatal
       
 17197 		&& m_could_send_fatal_alert_message == false)
       
 17198 	{
       
 17199 		// If alert message is received or we have sent a fatal alert, we do not send alert anymore.
       
 17200 
       
 17201 		EAP_TRACE_DEBUG(
       
 17202 			m_am_tools,
       
 17203 			TRACE_FLAGS_DEFAULT,
       
 17204 			(EAPL("TLS: %s: message_function: create_tls_protocol_alert(), ")
       
 17205 			 EAPL("do not send fatal alert message\n"),
       
 17206 			 (m_is_client == true ? "client": "server")));
       
 17207 
       
 17208 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17209 		return EAP_STATUS_RETURN(m_am_tools, par_result);
       
 17210 	}
       
 17211 
       
 17212 	if (alert_level == tls_alert_level_warning
       
 17213 		&& m_could_send_warning_alert_message == false)
       
 17214 	{
       
 17215 		// If alert message is received or we have sent a warning alert,
       
 17216 		// we do not send alert anymore.
       
 17217 
       
 17218 		EAP_TRACE_DEBUG(
       
 17219 			m_am_tools,
       
 17220 			TRACE_FLAGS_DEFAULT,
       
 17221 			(EAPL("TLS: %s: message_function: create_tls_protocol_alert(), ")
       
 17222 			 EAPL("do not send warning alert message\n"),
       
 17223 			 (m_is_client == true ? "client": "server")));
       
 17224 
       
 17225 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17226 		return EAP_STATUS_RETURN(m_am_tools, par_result);
       
 17227 	}
       
 17228 
       
 17229 	//--------------------------------------------------------------------
       
 17230 
       
 17231 
       
 17232 	set_state(tls_peap_state_failure);
       
 17233 
       
 17234 	// This will cause the session terminate immediately.
       
 17235 	status = get_type_partner()->set_session_timeout(0ul);
       
 17236 	if (status != eap_status_ok)
       
 17237 	{
       
 17238 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17239 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17240 	}
       
 17241 
       
 17242 	// 0                   1                   2                   3   
       
 17243 	//  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 
       
 17244 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               
       
 17245 	//                 | alert level   | alert descrip.|               
       
 17246 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                
       
 17247 
       
 17248 	tls_alert_message_c * const tls_alert_message
       
 17249 		= new tls_alert_message_c(m_am_tools, m_is_client);
       
 17250 
       
 17251 	eap_automatic_variable_c<tls_alert_message_c>
       
 17252 		automatic_tls_alert_message(m_am_tools, tls_alert_message);
       
 17253 
       
 17254 	if (tls_alert_message == 0
       
 17255 		|| tls_alert_message->get_is_valid() == false)
       
 17256 	{
       
 17257 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17258 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17259 	}
       
 17260 
       
 17261 	// --------------------------------------------------------------------
       
 17262 
       
 17263 	EAP_TRACE_ERROR(
       
 17264 		m_am_tools,
       
 17265 		TRACE_FLAGS_DEFAULT,
       
 17266 		(EAPL("TLS: %s: message_function: create_tls_protocol_alert(): Alert message %s:%s\n"),
       
 17267 		(m_is_client == true ? "client": "server"),
       
 17268 		 eap_tls_trace_string_c::get_alert_level_string(alert_level),
       
 17269 		 eap_tls_trace_string_c::get_alert_description_string(alert_description)));
       
 17270 
       
 17271 
       
 17272 	status = tls_alert_message->set_alert_level(alert_level);
       
 17273 	if (status != eap_status_ok)
       
 17274 	{
       
 17275 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17276 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17277 	}
       
 17278 
       
 17279 	status = tls_alert_message->set_alert_description(alert_description);
       
 17280 	if (status != eap_status_ok)
       
 17281 	{
       
 17282 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17283 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17284 	}
       
 17285 
       
 17286 	// --------------------------------------------------------------------
       
 17287 
       
 17288 	// Note add_record_message() frees message on any case.
       
 17289 	automatic_tls_alert_message.do_not_free_variable();
       
 17290 
       
 17291 	status = add_record_message(tls_alert_message);
       
 17292 	if (status != eap_status_ok)
       
 17293 	{
       
 17294 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17295 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17296 	}
       
 17297 
       
 17298 	// --------------------------------------------------------------------
       
 17299 
       
 17300 	m_force_tls_message_send = true;
       
 17301 
       
 17302 	if (alert_level == tls_alert_level_fatal)
       
 17303 	{
       
 17304 		m_could_send_fatal_alert_message = false;
       
 17305 	}
       
 17306 
       
 17307 	if (alert_level == tls_alert_level_warning)
       
 17308 	{
       
 17309 		m_could_send_warning_alert_message = false;
       
 17310 	}
       
 17311 
       
 17312 
       
 17313 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17314 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 17315 }
       
 17316 
       
 17317 
       
 17318 //--------------------------------------------------
       
 17319 
       
 17320 EAP_FUNC_EXPORT eap_status_e tls_record_c::create_tls_application_data(
       
 17321 	eap_buf_chain_wr_c * const sent_packet,
       
 17322 	const u32_t header_offset)
       
 17323 {
       
 17324 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17325 
       
 17326 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 17327 	EAP_TRACE_DEBUG(
       
 17328 		m_am_tools,
       
 17329 		TRACE_FLAGS_DEFAULT,
       
 17330 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::create_tls_application_data()\n"),
       
 17331 		 this,
       
 17332 		 (m_is_client == true ? "client": "server")));
       
 17333 
       
 17334 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::create_tls_application_data()");
       
 17335 
       
 17336 	// 0                   1                   2                   3   
       
 17337 	//  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 
       
 17338 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 17339 	//                 | Application data n bytes                      |
       
 17340 	//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 17341 
       
 17342 	tls_application_data_message_c * const tls_application_data_message
       
 17343 		= new tls_application_data_message_c(m_am_tools, m_is_client);
       
 17344 
       
 17345 	eap_automatic_variable_c<tls_application_data_message_c>
       
 17346 		automatic_tls_application_data_message(
       
 17347 			m_am_tools, tls_application_data_message);
       
 17348 
       
 17349 	if (tls_application_data_message == 0
       
 17350 		|| tls_application_data_message->get_is_valid() == false)
       
 17351 	{
       
 17352 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17353 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17354 	}
       
 17355 
       
 17356 	if (sent_packet->get_data_length() < header_offset)
       
 17357 	{
       
 17358 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17359 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
 17360 	}
       
 17361 
       
 17362 	u32_t packet_length = sent_packet->get_data_length()-header_offset;
       
 17363 
       
 17364 	eap_status_e status = tls_application_data_message->set_application_data(
       
 17365 		sent_packet->get_data_offset(header_offset, packet_length),
       
 17366 		packet_length);
       
 17367 	if (status != eap_status_ok)
       
 17368 	{
       
 17369 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17370 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17371 	}
       
 17372 
       
 17373 	// --------------------------------------------------------------------
       
 17374 
       
 17375 	// Note add_record_message() frees message on any case.
       
 17376 	automatic_tls_application_data_message.do_not_free_variable();
       
 17377 
       
 17378 	status = add_record_message(tls_application_data_message);
       
 17379 	if (status != eap_status_ok)
       
 17380 	{
       
 17381 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17382 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17383 	}
       
 17384 
       
 17385 	// --------------------------------------------------------------------
       
 17386 
       
 17387 	if (status == eap_status_ok)
       
 17388 	{
       
 17389 		status = check_sent_tls_message();
       
 17390 		if (status != eap_status_ok)
       
 17391 		{
       
 17392 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17393 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 17394 		}
       
 17395 	}
       
 17396 
       
 17397 	// --------------------------------------------------------------------
       
 17398 
       
 17399 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17400 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 17401 }
       
 17402 
       
 17403 
       
 17404 //--------------------------------------------------
       
 17405 
       
 17406 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_3DES_EDE_CBC_SHA(
       
 17407 	tls_cipher_suites_e cipher_suite) const
       
 17408 {
       
 17409 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17410 
       
 17411 	if (cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
       
 17412 		|| cipher_suite == tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA
       
 17413 		|| cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
       
 17414 	{
       
 17415 		return true;
       
 17416 	}
       
 17417 
       
 17418 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17419 	return false;
       
 17420 }
       
 17421 
       
 17422 //--------------------------------------------------
       
 17423 
       
 17424 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_AES_128_CBC_SHA(
       
 17425 	tls_cipher_suites_e cipher_suite) const
       
 17426 {
       
 17427 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17428 
       
 17429 	if (cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA
       
 17430 		|| cipher_suite == tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA
       
 17431 		|| cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
       
 17432 #if defined(USE_FAST_EAP_TYPE)
       
 17433 		|| cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA
       
 17434 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 17435 		)
       
 17436 	{
       
 17437 		return true;
       
 17438 	}
       
 17439 
       
 17440 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17441 	return false;
       
 17442 }
       
 17443 
       
 17444 //--------------------------------------------------
       
 17445 
       
 17446 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_RC4_128_MD5(
       
 17447 	tls_cipher_suites_e cipher_suite) const
       
 17448 {
       
 17449 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17450 
       
 17451 	if (cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5)
       
 17452 	{
       
 17453 		return true;
       
 17454 	}
       
 17455 
       
 17456 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17457 	return false;
       
 17458 }
       
 17459 
       
 17460 //--------------------------------------------------
       
 17461 
       
 17462 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_RC4_128_SHA(
       
 17463 	tls_cipher_suites_e cipher_suite) const
       
 17464 {
       
 17465 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17466 
       
 17467 	if (cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA)
       
 17468 	{
       
 17469 		return true;
       
 17470 	}
       
 17471 
       
 17472 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17473 	return false;
       
 17474 }
       
 17475 
       
 17476 //--------------------------------------------------
       
 17477 
       
 17478 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_RSA() const
       
 17479 {
       
 17480 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17481 
       
 17482 	if (m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_3DES_EDE_CBC_SHA
       
 17483 		|| m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_AES_128_CBC_SHA
       
 17484 		|| m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_MD5
       
 17485 		|| m_selected_cipher_suite == tls_cipher_suites_TLS_RSA_WITH_RC4_128_SHA)
       
 17486 	{
       
 17487 		return true;
       
 17488 	}
       
 17489 
       
 17490 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17491 	return false;
       
 17492 }
       
 17493 
       
 17494 //--------------------------------------------------
       
 17495 
       
 17496 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DHE_RSA() const
       
 17497 {
       
 17498 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17499 
       
 17500 	if (m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
       
 17501 		|| m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
       
 17502 	{
       
 17503 		return true;
       
 17504 	}
       
 17505 
       
 17506 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17507 	return false;
       
 17508 }
       
 17509 
       
 17510 //--------------------------------------------------
       
 17511 
       
 17512 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DHE_DSS() const
       
 17513 {
       
 17514 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17515 
       
 17516 	if (m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
       
 17517 		|| m_selected_cipher_suite == tls_cipher_suites_TLS_DHE_DSS_WITH_AES_128_CBC_SHA)
       
 17518 	{
       
 17519 		return true;
       
 17520 	}
       
 17521 
       
 17522 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17523 	return false;
       
 17524 }
       
 17525 
       
 17526 //--------------------------------------------------
       
 17527 
       
 17528 #if defined(USE_FAST_EAP_TYPE)
       
 17529 
       
 17530 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DH_anon() const
       
 17531 {
       
 17532 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17533 
       
 17534 	if (m_selected_cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA)
       
 17535 	{
       
 17536 		return true;
       
 17537 	}
       
 17538 
       
 17539 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17540 	return false;
       
 17541 }
       
 17542 
       
 17543 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 17544 
       
 17545 //--------------------------------------------------
       
 17546 
       
 17547 #if EAP_TLS_UNSUPPORTED_CIPHER_SUITE
       
 17548 #error This one needs more code. Diffie-Hellman sertificate key exchange with different parameters is NOT supported.
       
 17549 EAP_FUNC_EXPORT bool tls_record_c::cipher_suite_is_TLS_DH_DSS() const
       
 17550 {
       
 17551 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17552 
       
 17553 	if (m_selected_cipher_suite == tls_cipher_suites_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA)
       
 17554 	{
       
 17555 		return true;
       
 17556 	}
       
 17557 
       
 17558 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17559 	return false;
       
 17560 }
       
 17561 #endif
       
 17562 
       
 17563 //--------------------------------------------------
       
 17564 
       
 17565 EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_dhe_keys()
       
 17566 {
       
 17567 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17568 
       
 17569 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 17570 	EAP_TRACE_DEBUG(
       
 17571 		m_am_tools,
       
 17572 		TRACE_FLAGS_DEFAULT,
       
 17573 		(EAPL("TLS: this = 0x%08x, %s:     key_function: starts: tls_record_c::generate_dhe_keys()\n"),
       
 17574 		 this,
       
 17575 		 (m_is_client == true ? "client": "server")));
       
 17576 
       
 17577 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_dhe_keys()");
       
 17578 
       
 17579 	eap_status_e status = eap_status_not_supported;
       
 17580 
       
 17581 	if (cipher_suite_is_TLS_DHE_DSS() == true
       
 17582 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
 17583 #if defined(USE_FAST_EAP_TYPE)
       
 17584 		|| (m_eap_type == eap_type_fast
       
 17585 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
 17586 			&& cipher_suite_is_TLS_DH_anon() == true)
       
 17587 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 17588 		)
       
 17589 	{
       
 17590 		if (m_dhe_prime.get_is_valid_data() == false
       
 17591 			|| m_dhe_group_generator.get_is_valid_data() == false)
       
 17592 		{
       
 17593 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17594 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
 17595 		}
       
 17596 
       
 17597 		crypto_ephemeral_diffie_hellman_c dhe(m_am_tools);
       
 17598 
       
 17599 		if (dhe.get_is_valid() == false)
       
 17600 		{
       
 17601 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17602 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17603 		}
       
 17604 
       
 17605 		EAP_TRACE_DEBUG(
       
 17606 			m_am_tools,
       
 17607 			TRACE_FLAGS_DEFAULT,
       
 17608 			(EAPL("TLS: %s:     key_function: dhe.generate_diffie_hellman_keys()\n"),
       
 17609 			(m_is_client == true ? "client": "server")));
       
 17610 
       
 17611 		status = dhe.generate_diffie_hellman_keys(
       
 17612 			&m_own_private_dhe_key,
       
 17613 			&m_own_public_dhe_key,
       
 17614 			m_dhe_prime.get_data(m_dhe_prime.get_data_length()),
       
 17615 			m_dhe_prime.get_data_length(),
       
 17616 			m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()),
       
 17617 			m_dhe_group_generator.get_data_length());
       
 17618 		if (status != eap_status_ok)
       
 17619 		{
       
 17620 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17621 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 17622 		}
       
 17623 	}
       
 17624 	else
       
 17625 	{
       
 17626 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17627 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
 17628 	}
       
 17629 
       
 17630 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17631 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 17632 }
       
 17633 
       
 17634 //--------------------------------------------------
       
 17635 
       
 17636 EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_premaster_secret()
       
 17637 {
       
 17638 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17639 
       
 17640 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 17641 	EAP_TRACE_DEBUG(
       
 17642 		m_am_tools,
       
 17643 		TRACE_FLAGS_DEFAULT,
       
 17644 		(EAPL("TLS: this = 0x%08x, %s:     key_function: starts: tls_record_c::generate_premaster_secret()\n"),
       
 17645 		 this,
       
 17646 		 (m_is_client == true ? "client": "server")));
       
 17647 
       
 17648 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_premaster_secret()");
       
 17649 
       
 17650 	eap_status_e status = eap_status_not_supported;
       
 17651 
       
 17652 	m_key_material_generated = false;
       
 17653 
       
 17654 	if (cipher_suite_is_TLS_RSA() == true)
       
 17655 	{
       
 17656 		// Encrypted premaster secret is included when selected
       
 17657 		// cipher suite is using RSA key exchange.
       
 17658 		// First two bytes are version of TLS.
       
 17659 		// 0                   1                   2                   3   
       
 17660 		//  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 
       
 17661 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 17662 		//                 |                                               |
       
 17663 		// +-+-+-+-+-+-+-+-+                                               +
       
 17664 		// |                                                               |
       
 17665 		// +                                                               +
       
 17666 		// |                Encrypted Premaster Secret (48 bytes)          |
       
 17667 		// +                                                               +
       
 17668 		// |                                                               |
       
 17669 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 17670 
       
 17671 		crypto_random_c rand(m_am_tools);
       
 17672 
       
 17673 		status = m_premaster_secret.set_buffer_length(TLS_PREMASTER_SECRET_SIZE);
       
 17674 		if (status != eap_status_ok)
       
 17675 		{
       
 17676 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17677 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 17678 		}
       
 17679 		m_premaster_secret.set_data_length(TLS_PREMASTER_SECRET_SIZE);
       
 17680 
       
 17681 		u16_t version = eap_htons(tls_version_3_1);
       
 17682 		status = m_premaster_secret.add_data_to_offset(0ul, &version, sizeof(version));
       
 17683 		if (status != eap_status_ok)
       
 17684 		{
       
 17685 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17686 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 17687 		}
       
 17688 
       
 17689 		if (m_premaster_secret.get_data_length() < sizeof(version))
       
 17690 		{
       
 17691 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17692 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17693 		}
       
 17694 
       
 17695 		status = rand.get_rand_bytes(
       
 17696 			m_premaster_secret.get_data_offset(
       
 17697 				sizeof(version),
       
 17698 				m_premaster_secret.get_data_length()-sizeof(version)),
       
 17699 			m_premaster_secret.get_data_length()-sizeof(version));
       
 17700 		if (status != eap_status_ok)
       
 17701 		{
       
 17702 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17703 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 17704 		}
       
 17705 
       
 17706 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: m_premaster_secret"),
       
 17707 			m_premaster_secret.get_data(m_premaster_secret.get_data_length()),
       
 17708 			m_premaster_secret.get_data_length()));
       
 17709 	}
       
 17710 	else if (cipher_suite_is_TLS_DHE_DSS() == true
       
 17711 		|| cipher_suite_is_TLS_DHE_RSA() == true
       
 17712 #if defined(USE_FAST_EAP_TYPE)
       
 17713 		|| (m_eap_type == eap_type_fast
       
 17714 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
 17715 			&& cipher_suite_is_TLS_DH_anon() == true)
       
 17716 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 17717 		)
       
 17718 	{
       
 17719 		// Diffie-Hellman Yc is included when selected cipher suite is
       
 17720 		// ephemeral Diffie-Hellman key exchange.
       
 17721 		// 0                   1                   2                   3   
       
 17722 		//  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 
       
 17723 		//                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 17724 		//                 | DH Yc length                  |               |
       
 17725 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
       
 17726 		// |                                                               |
       
 17727 		// +                                                               +
       
 17728 		// |                DH Yc value                                    |
       
 17729 		// +                                                               +
       
 17730 		// |                                                               |
       
 17731 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
 17732 
       
 17733 		if (m_dhe_prime.get_is_valid_data() == false
       
 17734 			|| m_dhe_group_generator.get_is_valid_data() == false
       
 17735 			|| m_peer_public_dhe_key.get_is_valid_data() == false)
       
 17736 		{
       
 17737 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17738 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
 17739 		}
       
 17740 
       
 17741 		crypto_ephemeral_diffie_hellman_c dhe(m_am_tools);
       
 17742 
       
 17743 		if (dhe.get_is_valid() == false)
       
 17744 		{
       
 17745 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17746 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17747 		}
       
 17748 
       
 17749 		EAP_TRACE_DEBUG(
       
 17750 			m_am_tools,
       
 17751 			TRACE_FLAGS_DEFAULT,
       
 17752 			(EAPL("TLS: %s:     key_function: dhe.generate_g_power_to_xy()\n"),
       
 17753 			(m_is_client == true ? "client": "server")));
       
 17754 
       
 17755 		status = dhe.generate_g_power_to_xy(
       
 17756 			&m_own_private_dhe_key,
       
 17757 			&m_peer_public_dhe_key,
       
 17758 			&m_premaster_secret,
       
 17759 			m_dhe_prime.get_data(m_dhe_prime.get_data_length()),
       
 17760 			m_dhe_prime.get_data_length(),
       
 17761 			m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()),
       
 17762 			m_dhe_group_generator.get_data_length());
       
 17763 		if (status != eap_status_ok)
       
 17764 		{
       
 17765 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17766 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 17767 		}
       
 17768 
       
 17769 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: m_premaster_secret"),
       
 17770 			m_premaster_secret.get_data(m_premaster_secret.get_data_length()),
       
 17771 			m_premaster_secret.get_data_length()));
       
 17772 	}
       
 17773 	else
       
 17774 	{
       
 17775 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17776 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
 17777 	}
       
 17778 
       
 17779 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17780 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 17781 }
       
 17782 
       
 17783 //--------------------------------------------------
       
 17784 
       
 17785 EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_master_secret()
       
 17786 {
       
 17787 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17788 
       
 17789 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 17790 	EAP_TRACE_DEBUG(
       
 17791 		m_am_tools,
       
 17792 		TRACE_FLAGS_DEFAULT,
       
 17793 		(EAPL("TLS: this = 0x%08x, %s:     key_function: starts: tls_record_c::generate_master_secret()\n"),
       
 17794 		 this,
       
 17795 		 (m_is_client == true ? "client": "server")));
       
 17796 
       
 17797 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_master_secret()");
       
 17798 
       
 17799 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_master_secret(): m_premaster_secret"),
       
 17800 		m_premaster_secret.get_data(),
       
 17801 		m_premaster_secret.get_data_length()));
       
 17802 
       
 17803 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_master_secret(): m_client_handshake_random_value"),
       
 17804 		m_client_handshake_random_value.get_data(),
       
 17805 		m_client_handshake_random_value.get_data_length()));
       
 17806 
       
 17807 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_master_secret(): m_server_handshake_random_value"),
       
 17808 		m_server_handshake_random_value.get_data(),
       
 17809 		m_server_handshake_random_value.get_data_length()));
       
 17810 
       
 17811 	if (m_premaster_secret.get_is_valid_data() == false
       
 17812 		|| m_client_handshake_random_value.get_is_valid_data() == false
       
 17813 		|| m_server_handshake_random_value.get_is_valid_data() == false)
       
 17814 	{
       
 17815 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17816 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 17817 	}
       
 17818 
       
 17819 	eap_status_e status = eap_status_not_supported;
       
 17820 
       
 17821 	EAP_TRACE_DEBUG(
       
 17822 		m_am_tools,
       
 17823 		TRACE_FLAGS_DEFAULT,
       
 17824 		(EAPL("TLS: %s:     prf_function: tls_prf.tls_prf_output()\n"),
       
 17825 		(m_is_client == true ? "client": "server")));
       
 17826 
       
 17827 	crypto_tls_prf_c tls_prf(m_am_tools);
       
 17828 
       
 17829 	eap_variable_data_c label(m_am_tools);
       
 17830 	if (label.get_is_valid() == false)
       
 17831 	{
       
 17832 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17833 	}
       
 17834 
       
 17835 	status = label.add_data(
       
 17836 		TLS_MASTER_SECRET_LABEL,
       
 17837 		TLS_MASTER_SECRET_LABEL_LENGTH);
       
 17838 	if (status != eap_status_ok)
       
 17839 	{
       
 17840 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17841 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17842 	}
       
 17843 
       
 17844 	eap_variable_data_c seed(m_am_tools);
       
 17845 	if (seed.get_is_valid() == false)
       
 17846 	{
       
 17847 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17848 	}
       
 17849 	status = seed.set_copy_of_buffer(&m_client_handshake_random_value);
       
 17850 	if (status != eap_status_ok)
       
 17851 	{
       
 17852 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17853 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17854 	}
       
 17855 
       
 17856 	status = seed.add_data(&m_server_handshake_random_value);
       
 17857 	if (status != eap_status_ok)
       
 17858 	{
       
 17859 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17860 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17861 	}
       
 17862 
       
 17863 	status = tls_prf.tls_prf_init(
       
 17864 		&m_premaster_secret,
       
 17865 		&label,
       
 17866 		&seed);
       
 17867 	if (status != eap_status_ok)
       
 17868 	{
       
 17869 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17870 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17871 	}
       
 17872 
       
 17873 	status = m_master_secret.set_buffer_length(TLS_MASTER_SECRET_SIZE);
       
 17874 	if (status != eap_status_ok)
       
 17875 	{
       
 17876 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17877 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17878 	}
       
 17879 	m_master_secret.set_data_length(TLS_MASTER_SECRET_SIZE);
       
 17880 
       
 17881 	status = tls_prf.tls_prf_output(
       
 17882 		m_master_secret.get_data(m_master_secret.get_data_length()),
       
 17883 		m_master_secret.get_data_length());
       
 17884 	if (status != eap_status_ok)
       
 17885 	{
       
 17886 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17887 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17888 	}
       
 17889 
       
 17890 	EAP_TRACE_DATA_DEBUG(
       
 17891 		m_am_tools,
       
 17892 		TRACE_FLAGS_DEFAULT,
       
 17893 		(EAPL("TLS: tls_record_c::generate_master_secret(): m_master_secret"),
       
 17894 		m_master_secret.get_data(),
       
 17895 		m_master_secret.get_data_length()));
       
 17896 
       
 17897 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17898 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 17899 }
       
 17900 
       
 17901 //--------------------------------------------------
       
 17902 
       
 17903 #if defined(USE_FAST_EAP_TYPE)
       
 17904 
       
 17905 EAP_FUNC_EXPORT eap_status_e tls_record_c::generate_eap_fast_master_secret_from_pac_key(
       
 17906 	const eap_variable_data_c * const pac_key)
       
 17907 {
       
 17908 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17909 
       
 17910 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 17911 	EAP_TRACE_DEBUG(
       
 17912 		m_am_tools,
       
 17913 		TRACE_FLAGS_DEFAULT,
       
 17914 		(EAPL("TLS: this = 0x%08x, %s:     key_function: starts: tls_record_c::generate_eap_fast_master_secret_from_pac_key()\n"),
       
 17915 		 this,
       
 17916 		 (m_is_client == true ? "client": "server")));
       
 17917 
       
 17918 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::generate_eap_fast_master_secret_from_pac_key()");
       
 17919 
       
 17920 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_eap_fast_master_secret_from_pac_key(): PAC_Key"),
       
 17921 		pac_key->get_data(),
       
 17922 		pac_key->get_data_length()));
       
 17923 
       
 17924 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_eap_fast_master_secret_from_pac_key(): m_server_handshake_random_value"),
       
 17925 		m_server_handshake_random_value.get_data(),
       
 17926 		m_server_handshake_random_value.get_data_length()));
       
 17927 
       
 17928 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: tls_record_c::generate_eap_fast_master_secret_from_pac_key(): m_client_handshake_random_value"),
       
 17929 		m_client_handshake_random_value.get_data(),
       
 17930 		m_client_handshake_random_value.get_data_length()));
       
 17931 
       
 17932 	if (pac_key == 0
       
 17933 		|| pac_key->get_is_valid_data() == false
       
 17934 		|| m_client_handshake_random_value.get_is_valid_data() == false
       
 17935 		|| m_server_handshake_random_value.get_is_valid_data() == false)
       
 17936 	{
       
 17937 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17938 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 17939 	}
       
 17940 
       
 17941 	eap_status_e status(eap_status_not_supported);
       
 17942 
       
 17943 	
       
 17944 	crypto_eap_fast_hmac_sha1_prf_c tls_prf(m_am_tools);
       
 17945 
       
 17946 	eap_variable_data_c label(m_am_tools);
       
 17947 	if (label.get_is_valid() == false)
       
 17948 	{
       
 17949 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17950 	}
       
 17951 
       
 17952 	status = label.add_data(
       
 17953 		EAP_FAST_PAC_TO_MASTER_SECRET_LABEL,
       
 17954 		EAP_FAST_PAC_TO_MASTER_SECRET_LABEL_LENGTH);
       
 17955 	if (status != eap_status_ok)
       
 17956 	{
       
 17957 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17958 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17959 	}
       
 17960 
       
 17961 	eap_variable_data_c seed(m_am_tools);
       
 17962 	if (seed.get_is_valid() == false)
       
 17963 	{
       
 17964 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 17965 	}
       
 17966 
       
 17967 	status = seed.set_copy_of_buffer(&m_server_handshake_random_value);
       
 17968 	if (status != eap_status_ok)
       
 17969 	{
       
 17970 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17971 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17972 	}
       
 17973 
       
 17974 	status = seed.add_data(&m_client_handshake_random_value);
       
 17975 	if (status != eap_status_ok)
       
 17976 	{
       
 17977 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17978 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17979 	}
       
 17980 
       
 17981 	status = tls_prf.t_prf_init(
       
 17982 		pac_key,
       
 17983 		&label,
       
 17984 		&seed);
       
 17985 	if (status != eap_status_ok)
       
 17986 	{
       
 17987 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17988 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17989 	}
       
 17990 
       
 17991 	status = m_master_secret.set_buffer_length(TLS_MASTER_SECRET_SIZE);
       
 17992 	if (status != eap_status_ok)
       
 17993 	{
       
 17994 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 17995 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 17996 	}
       
 17997 	m_master_secret.set_data_length(TLS_MASTER_SECRET_SIZE);
       
 17998 
       
 17999 	status = tls_prf.t_prf_output(
       
 18000 		m_master_secret.get_data(),
       
 18001 		static_cast<u16_t>(m_master_secret.get_data_length()));
       
 18002 	if (status != eap_status_ok)
       
 18003 	{
       
 18004 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18005 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 18006 	}
       
 18007 
       
 18008 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAP-FAST: m_master_secret"),
       
 18009 		m_master_secret.get_data(),
       
 18010 		m_master_secret.get_data_length()));
       
 18011 
       
 18012 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18013 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 18014 }
       
 18015 
       
 18016 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18017 
       
 18018 //--------------------------------------------------
       
 18019 
       
 18020 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_cipher_suites_and_previous_session(
       
 18021 	const tls_session_type_e /* tls_session_type */,
       
 18022 	EAP_TEMPLATE_CONST eap_array_c<u16_t> * const cipher_suites,
       
 18023 	EAP_TEMPLATE_CONST eap_array_c<u8_t> * const compression_methods,
       
 18024 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18025 	EAP_TEMPLATE_CONST eap_array_c<tls_extension_c> * const tls_extensions,
       
 18026 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18027 	const eap_variable_data_c * const resumed_session_id,
       
 18028 	const eap_variable_data_c * const resumed_master_secret,
       
 18029 	const tls_cipher_suites_e resumed_cipher_suite,
       
 18030 	const eap_status_e completion_status)
       
 18031 {
       
 18032 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18033 
       
 18034 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 18035 	EAP_TRACE_DEBUG(
       
 18036 		m_am_tools,
       
 18037 		TRACE_FLAGS_DEFAULT,
       
 18038 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_cipher_suites_and_previous_session()\n"),
       
 18039 		 this,
       
 18040 		 (m_is_client == true ? "client": "server")));
       
 18041 
       
 18042 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_cipher_suites_and_previous_session()");
       
 18043 
       
 18044 	m_pending_query_cipher_suites_and_previous_session = false;
       
 18045 
       
 18046 	m_proposed_cipher_suites.reset();
       
 18047 	m_proposed_compression_methods.reset();
       
 18048 
       
 18049 	eap_status_e status = eap_status_process_general_error;
       
 18050 
       
 18051 
       
 18052 	if (completion_status != eap_status_ok)
       
 18053 	{
       
 18054 		status = create_tls_protocol_alert(
       
 18055 			tls_alert_description_none,
       
 18056 			tls_alert_level_none,
       
 18057 			completion_status);
       
 18058 		if (status != eap_status_ok)
       
 18059 		{
       
 18060 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18061 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 18062 		}
       
 18063 	}
       
 18064 	else
       
 18065 	{
       
 18066 		status = copy_simple<u16_t>(
       
 18067 			cipher_suites,
       
 18068 			&m_proposed_cipher_suites,
       
 18069 			m_am_tools,
       
 18070 			false);
       
 18071 		if (status != eap_status_ok)
       
 18072 		{
       
 18073 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18074 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 18075 		}
       
 18076 
       
 18077 		status = for_each<u16_t>(&m_proposed_cipher_suites, u16_t_to_host_order, m_am_tools, false);
       
 18078 		if (status != eap_status_ok
       
 18079 			|| m_proposed_cipher_suites.get_object_count() == 0ul)
       
 18080 		{
       
 18081 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18082 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 18083 		}
       
 18084 
       
 18085 #if defined(USE_FAST_EAP_TYPE)
       
 18086 		if (m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == false)
       
 18087 		{
       
 18088 			// TLS_DH_anon_WITH_AES_128_CBC_SHA is allowed only with EAP-FAST unauthenticated provisioning mode.
       
 18089 			u16_t illegal_cipher_suite(static_cast<u16_t>(tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA));
       
 18090 
       
 18091 			i32_t index = find_simple(
       
 18092 				&m_proposed_cipher_suites,
       
 18093 				&illegal_cipher_suite,
       
 18094 				m_am_tools);
       
 18095 			if (index >= 0)
       
 18096 			{
       
 18097 				status = m_proposed_cipher_suites.remove_object(index);
       
 18098 				if (status != eap_status_ok)
       
 18099 				{
       
 18100 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18101 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18102 				}
       
 18103 			}
       
 18104 		}
       
 18105 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18106 
       
 18107 		status = copy_simple<u8_t>(
       
 18108 			compression_methods,
       
 18109 			&m_proposed_compression_methods,
       
 18110 			m_am_tools,
       
 18111 			false);
       
 18112 		if (status != eap_status_ok)
       
 18113 		{
       
 18114 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18115 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 18116 		}
       
 18117 
       
 18118 
       
 18119 
       
 18120 #if defined(USE_FAST_EAP_TYPE)
       
 18121 		if (m_eap_type == eap_type_fast
       
 18122 			&& m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
 18123 		{
       
 18124 			// Let's try tunnel PAC authentication.
       
 18125 
       
 18126 			// We will use the first cipher suite as an default one.
       
 18127 			u16_t * cipher_suite = m_proposed_cipher_suites.get_object(0ul);
       
 18128 			if (cipher_suite != 0)
       
 18129 			{
       
 18130 				m_resumed_cipher_suite = static_cast<tls_cipher_suites_e>(*cipher_suite);
       
 18131 			}
       
 18132 			else
       
 18133 			{
       
 18134 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18135 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
 18136 			}
       
 18137 		}
       
 18138 		else
       
 18139 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18140 		if (resumed_session_id != 0
       
 18141 			&& resumed_session_id->get_is_valid_data() == true
       
 18142 			&& resumed_session_id->get_data_length() > 0ul
       
 18143 			&& resumed_master_secret != 0
       
 18144 			&& resumed_master_secret->get_is_valid_data() == true
       
 18145 			&& resumed_master_secret->get_data_length() == TLS_MASTER_SECRET_SIZE
       
 18146 			&& resumed_cipher_suite != tls_cipher_suites_none)
       
 18147 		{
       
 18148 			// Resume previous session.
       
 18149 
       
 18150 			status = m_session_id.set_copy_of_buffer(resumed_session_id);
       
 18151 			if (status != eap_status_ok)
       
 18152 			{
       
 18153 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18154 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18155 			}
       
 18156 
       
 18157 			status = m_master_secret.set_copy_of_buffer(resumed_master_secret);
       
 18158 			if (status != eap_status_ok)
       
 18159 			{
       
 18160 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18161 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18162 			}
       
 18163 
       
 18164 			EAP_TRACE_DEBUG(
       
 18165 				m_am_tools,
       
 18166 				TRACE_FLAGS_DEFAULT,
       
 18167 				(EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ")
       
 18168 				 EAPL("Resume previous session.\n"),
       
 18169 				 (m_is_client == true ? "client": "server")));
       
 18170 
       
 18171 			EAP_TRACE_DATA_DEBUG(
       
 18172 				m_am_tools,
       
 18173 				TRACE_FLAGS_DEFAULT,
       
 18174 				(EAPL("TLS: complete_query_cipher_suites_and_previous_session(): resumed m_master_secret"),
       
 18175 				 m_master_secret.get_data(m_master_secret.get_data_length()),
       
 18176 				 m_master_secret.get_data_length()));
       
 18177 
       
 18178 			m_resumed_cipher_suite = resumed_cipher_suite;
       
 18179 
       
 18180 			set_tls_session_type(tls_session_type_original_session_resumption);
       
 18181 		}
       
 18182 		else
       
 18183 		{
       
 18184 
       
 18185 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 18186 			if (m_is_client == true
       
 18187 				&& m_tls_use_identity_privacy == true
       
 18188 				&& m_tls_identity_privacy_handshake_state == tls_identity_privacy_handshake_state_none)
       
 18189 			{
       
 18190 				set_tls_identity_privacy_handshake_state(tls_identity_privacy_handshake_state_negotiates);
       
 18191 			}
       
 18192 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 18193 
       
 18194 			set_tls_session_type(tls_session_type_full_authentication);
       
 18195 
       
 18196 			EAP_TRACE_DEBUG(
       
 18197 				m_am_tools,
       
 18198 				TRACE_FLAGS_DEFAULT,
       
 18199 				(EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ")
       
 18200 				 EAPL("full authentication.\n"),
       
 18201 				 (m_is_client == true ? "client": "server")));
       
 18202 
       
 18203 			eap_status_e notification_status = indicate_state_to_lower_layer(
       
 18204 				tls_peap_state_full_authentication);
       
 18205 			if (notification_status != eap_status_ok)
       
 18206 			{
       
 18207 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18208 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 18209 			}
       
 18210 		}
       
 18211 
       
 18212 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18213 		if (tls_extensions != 0)
       
 18214 		{
       
 18215 
       
 18216 #if defined(USE_FAST_EAP_TYPE)
       
 18217 			if (m_eap_type == eap_type_fast)
       
 18218 			{
       
 18219 				// Nothing to do.
       
 18220 			}
       
 18221 			else
       
 18222 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18223 			{
       
 18224 				status = copy<tls_extension_c>(
       
 18225 					tls_extensions,
       
 18226 					&m_supported_tls_extensions,
       
 18227 					m_am_tools,
       
 18228 					false);
       
 18229 			}
       
 18230 
       
 18231 			if (status != eap_status_ok)
       
 18232 			{
       
 18233 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18234 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18235 			}
       
 18236 
       
 18237 #if defined(USE_FAST_EAP_TYPE)
       
 18238 			eap_fast_pac_type_e required_pac_type(eap_fast_pac_type_none);
       
 18239 
       
 18240 			if (m_eap_type == eap_type_fast)
       
 18241 			{
       
 18242 				// In EAP-FAST we are interested only Tunnel PAC.
       
 18243 				required_pac_type = eap_fast_pac_type_tunnel_pac;
       
 18244 			}
       
 18245 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18246 
       
 18247 			const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension(
       
 18248 				tls_extension_type_session_ticket,
       
 18249 #if defined(USE_FAST_EAP_TYPE)
       
 18250 				required_pac_type,
       
 18251 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18252 				&m_supported_tls_extensions,
       
 18253 				m_am_tools);
       
 18254 
       
 18255 			if (supported_session_ticket_extension != 0
       
 18256 				&& supported_session_ticket_extension->get_is_valid_data() == true
       
 18257 				&& supported_session_ticket_extension->get_data_length() > 0ul)
       
 18258 			{
       
 18259 #if defined(USE_FAST_EAP_TYPE)
       
 18260 				if (m_eap_type == eap_type_fast)
       
 18261 				{
       
 18262 					EAP_TRACE_DEBUG(
       
 18263 						m_am_tools,
       
 18264 						TRACE_FLAGS_DEFAULT,
       
 18265 						(EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ")
       
 18266 						 EAPL("SST: EAP-FAST PAC stateless session resumption, length = %d.\n"),
       
 18267 						 (m_is_client == true ? "client": "server"),
       
 18268 						 supported_session_ticket_extension->get_data_length()));
       
 18269 				}
       
 18270 				else
       
 18271 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18272 				//if (m_tls_session_type == tls_session_type_original_session_resumption)
       
 18273 				{
       
 18274 					EAP_TRACE_DEBUG(
       
 18275 						m_am_tools,
       
 18276 						TRACE_FLAGS_DEFAULT,
       
 18277 						(EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ")
       
 18278 						 EAPL("SST: stateless session resumption, length = %d.\n"),
       
 18279 						 (m_is_client == true ? "client": "server"),
       
 18280 						 supported_session_ticket_extension->get_data_length()));
       
 18281 
       
 18282 					set_tls_session_type(tls_session_type_stateless_session_resumption);
       
 18283 				}
       
 18284 			}
       
 18285 		}
       
 18286 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18287 
       
 18288 
       
 18289 #if defined(USE_FAST_EAP_TYPE)
       
 18290 		if (m_eap_type == eap_type_fast
       
 18291 			//&& m_tls_session_type == tls_session_type_full_authentication
       
 18292 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true)
       
 18293 		{
       
 18294 			// Try dynamic provisioning of PAC.
       
 18295 
       
 18296 			set_tls_session_type(tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP);
       
 18297 
       
 18298 			EAP_TRACE_DEBUG(
       
 18299 				m_am_tools,
       
 18300 				TRACE_FLAGS_DEFAULT,
       
 18301 				(EAPL("TLS: %s: message_function: complete_query_cipher_suites_and_previous_session(): ")
       
 18302 				 EAPL("server unauthenticated provisioning mode ADHP.\n"),
       
 18303 				 (m_is_client == true ? "client": "server")));
       
 18304 
       
 18305 			m_proposed_cipher_suites.reset();
       
 18306 
       
 18307 			u16_t * const anonymous_cipher_suite = new u16_t;
       
 18308 
       
 18309 			if (anonymous_cipher_suite == 0)
       
 18310 			{
       
 18311 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18312 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 18313 			}
       
 18314 			
       
 18315 			*anonymous_cipher_suite = static_cast<u16_t>(tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA);
       
 18316 
       
 18317 			status = m_proposed_cipher_suites.add_object(
       
 18318 				anonymous_cipher_suite,
       
 18319 				true);
       
 18320 			if (status != eap_status_ok)
       
 18321 			{
       
 18322 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18323 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
 18324 			}
       
 18325 		}
       
 18326 		else
       
 18327 		{
       
 18328 			EAP_TRACE_DEBUG(
       
 18329 				m_am_tools,
       
 18330 				TRACE_FLAGS_DEFAULT,
       
 18331 				(EAPL("TLS: %s: complete_query_cipher_suites_and_previous_session(): ")
       
 18332 				 EAPL("m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP = %d.\n"),
       
 18333 				 (m_is_client == true ? "client": "server"),
       
 18334 				 m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP));
       
 18335 		}
       
 18336 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18337 
       
 18338 
       
 18339 	}
       
 18340 
       
 18341 
       
 18342 	if (status == eap_status_ok)
       
 18343 	{
       
 18344 		status = check_sent_tls_message();
       
 18345 		if (status != eap_status_ok)
       
 18346 		{
       
 18347 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18348 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 18349 		}
       
 18350 
       
 18351 		status = eap_status_completed_request;
       
 18352 	}
       
 18353 
       
 18354 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18355 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 18356 }
       
 18357 
       
 18358 //--------------------------------------------------
       
 18359 
       
 18360 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_select_cipher_suite_and_check_session_id(
       
 18361 	const tls_session_type_e tls_session_type,
       
 18362 	const u16_t selected_cipher_suite,
       
 18363 	const eap_variable_data_c * const resumed_session_id,
       
 18364 	const eap_variable_data_c * const resumed_master_secret,
       
 18365 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18366 	const tls_extension_c * const new_session_ticket_or_null,
       
 18367 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18368 	const eap_status_e completion_status)
       
 18369 {
       
 18370 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18371 	
       
 18372 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 18373 	EAP_TRACE_DEBUG(
       
 18374 		m_am_tools,
       
 18375 		TRACE_FLAGS_DEFAULT,
       
 18376 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_select_cipher_suite_and_check_session_id()\n"),
       
 18377 		 this,
       
 18378 		 (m_is_client == true ? "client": "server")));
       
 18379 
       
 18380 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_select_cipher_suite_and_check_session_id()");
       
 18381 
       
 18382 	EAP_ASSERT_ALWAYS(m_is_client == false);
       
 18383 
       
 18384 	eap_status_e status = eap_status_ok;
       
 18385 
       
 18386 	m_pending_select_cipher_suite_and_check_session_id = false;
       
 18387 
       
 18388 
       
 18389 	if (completion_status != eap_status_ok)
       
 18390 	{
       
 18391 		status = create_tls_protocol_alert(
       
 18392 			tls_alert_description_none,
       
 18393 			tls_alert_level_none,
       
 18394 			completion_status);
       
 18395 		if (status != eap_status_ok)
       
 18396 		{
       
 18397 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18398 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 18399 		}
       
 18400 	}
       
 18401 	else
       
 18402 	{
       
 18403 		set_tls_session_type(tls_session_type);
       
 18404 
       
 18405 		set_selected_cipher_suite(static_cast<tls_cipher_suites_e>(selected_cipher_suite));
       
 18406 		m_selected_compression_method = tls_compression_method_null;
       
 18407 
       
 18408 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 18409 
       
 18410 #if defined(USE_FAST_EAP_TYPE)
       
 18411 		if (m_eap_type == eap_type_fast
       
 18412 			&& m_tls_session_type == tls_session_type_full_authentication
       
 18413 			&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == true
       
 18414 			&& m_selected_cipher_suite == tls_cipher_suites_TLS_DH_anon_WITH_AES_128_CBC_SHA)
       
 18415 		{
       
 18416 			// Try dynamic provisioning of PAC.
       
 18417 
       
 18418 			set_tls_session_type(tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP);
       
 18419 		}
       
 18420 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18421 
       
 18422 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 18423 
       
 18424 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18425 		if (new_session_ticket_or_null != 0)
       
 18426 		{
       
 18427 			// We are using the session ticket payload.
       
 18428 
       
 18429 			tls_extension_c * copy_of_new_session_ticket = new_session_ticket_or_null->copy();
       
 18430 			if (copy_of_new_session_ticket == 0)
       
 18431 			{
       
 18432 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18433 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 18434 			}
       
 18435 
       
 18436 			// Save the new session ticket to be included in next NewSessionTicket message.
       
 18437 			status = m_supported_tls_extensions.add_object(copy_of_new_session_ticket, true);
       
 18438 			if (status != eap_status_ok)
       
 18439 			{
       
 18440 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18441 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18442 			}
       
 18443 		}
       
 18444 
       
 18445 		if (m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 18446 		{
       
 18447 			if (resumed_session_id != 0
       
 18448 				&& resumed_session_id->get_is_valid_data() == true)
       
 18449 			{
       
 18450 				// The session ID is needed if client did include it to the ClientHello.
       
 18451 				status = m_session_id.set_copy_of_buffer(resumed_session_id);
       
 18452 				if (status != eap_status_ok)
       
 18453 				{
       
 18454 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18455 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18456 				}
       
 18457 			}
       
 18458 
       
 18459 			if (resumed_master_secret != 0
       
 18460 				&& resumed_master_secret->get_is_valid_data() == true
       
 18461 				&& resumed_master_secret->get_data_length() == TLS_MASTER_SECRET_SIZE)
       
 18462 			{
       
 18463 				status = m_master_secret.set_copy_of_buffer(resumed_master_secret);
       
 18464 				if (status != eap_status_ok)
       
 18465 				{
       
 18466 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18467 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18468 				}
       
 18469 
       
 18470 				EAP_TRACE_DATA_DEBUG(
       
 18471 					m_am_tools,
       
 18472 					TRACE_FLAGS_DEFAULT,
       
 18473 					(EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): session ticket resumed m_master_secret"),
       
 18474 					 m_master_secret.get_data(m_master_secret.get_data_length()),
       
 18475 					 m_master_secret.get_data_length()));
       
 18476 
       
 18477 				EAP_TRACE_DEBUG(
       
 18478 					m_am_tools,
       
 18479 					TRACE_FLAGS_DEFAULT,
       
 18480 					(EAPL("TLS: %s: message_function: ")
       
 18481 					 EAPL("complete_select_cipher_suite_and_check_session_id(): restores session using session ticket\n"),
       
 18482 					 (m_is_client == true ? "client": "server")));
       
 18483 
       
 18484 				eap_status_e notification_status = indicate_state_to_lower_layer(
       
 18485 					tls_peap_state_original_session_resumption);
       
 18486 				if (notification_status != eap_status_ok)
       
 18487 				{
       
 18488 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18489 					return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 18490 				}
       
 18491 			}
       
 18492 		}
       
 18493 		else
       
 18494 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18495 		if (m_tls_session_type == tls_session_type_original_session_resumption
       
 18496 			&& ((m_eap_type == eap_type_peap
       
 18497 				/** @{ PEAPv2 does not support session resumption yet. } */
       
 18498 				&& m_peap_version != peap_version_2)
       
 18499 				|| m_eap_type == eap_type_tls
       
 18500 				|| m_eap_type == eap_type_ttls
       
 18501 #if defined(USE_FAST_EAP_TYPE)
       
 18502 				|| m_eap_type == eap_type_fast
       
 18503 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18504 				)
       
 18505 			&& resumed_session_id != 0
       
 18506 			&& resumed_session_id->get_is_valid_data() == true
       
 18507 			&& resumed_session_id->get_data_length() > 0ul
       
 18508 			&& resumed_master_secret != 0
       
 18509 			&& resumed_master_secret->get_is_valid_data() == true
       
 18510 			&& resumed_master_secret->get_data_length() == TLS_MASTER_SECRET_SIZE
       
 18511 			)
       
 18512 		{
       
 18513 			// Restore previous session.
       
 18514 
       
 18515 			status = m_session_id.set_copy_of_buffer(resumed_session_id);
       
 18516 			if (status != eap_status_ok)
       
 18517 			{
       
 18518 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18519 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18520 			}
       
 18521 
       
 18522 			status = m_master_secret.set_copy_of_buffer(resumed_master_secret);
       
 18523 			if (status != eap_status_ok)
       
 18524 			{
       
 18525 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18526 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18527 			}
       
 18528 
       
 18529 			EAP_TRACE_DATA_DEBUG(
       
 18530 				m_am_tools,
       
 18531 				TRACE_FLAGS_DEFAULT,
       
 18532 				(EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): resumed m_master_secret"),
       
 18533 				 m_master_secret.get_data(m_master_secret.get_data_length()),
       
 18534 				 m_master_secret.get_data_length()));
       
 18535 
       
 18536 			EAP_TRACE_DEBUG(
       
 18537 				m_am_tools,
       
 18538 				TRACE_FLAGS_DEFAULT,
       
 18539 				(EAPL("TLS: %s: message_function: ")
       
 18540 				 EAPL("complete_select_cipher_suite_and_check_session_id(): restores session\n"),
       
 18541 				 (m_is_client == true ? "client": "server")));
       
 18542 
       
 18543 			eap_status_e notification_status = indicate_state_to_lower_layer(
       
 18544 				tls_peap_state_original_session_resumption);
       
 18545 			if (notification_status != eap_status_ok)
       
 18546 			{
       
 18547 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18548 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 18549 			}
       
 18550 		}
       
 18551 #if defined(USE_FAST_EAP_TYPE)
       
 18552 		else if (m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption)
       
 18553 		{
       
 18554 			EAP_TRACE_DEBUG(
       
 18555 				m_am_tools,
       
 18556 				TRACE_FLAGS_DEFAULT,
       
 18557 				(EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): EAP-FAST server: %s\n"),
       
 18558 				eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)));
       
 18559 
       
 18560 			// Parameter resumed_master_secret includes PAC-Key.
       
 18561 			status = m_eap_fast_pac_key.set_copy_of_buffer(resumed_master_secret);
       
 18562 			if (status != eap_status_ok)
       
 18563 			{
       
 18564 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18565 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18566 			}
       
 18567 
       
 18568 			EAP_TRACE_DATA_DEBUG(
       
 18569 				m_am_tools,
       
 18570 				TRACE_FLAGS_DEFAULT,
       
 18571 				(EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): resumed m_master_secret"),
       
 18572 				 m_master_secret.get_data(m_master_secret.get_data_length()),
       
 18573 				 m_master_secret.get_data_length()));
       
 18574 
       
 18575 			eap_status_e notification_status = indicate_state_to_lower_layer(
       
 18576 				tls_peap_state_original_session_resumption);
       
 18577 			if (notification_status != eap_status_ok)
       
 18578 			{
       
 18579 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18580 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 18581 			}
       
 18582 		}
       
 18583 		else if (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP)
       
 18584 		{
       
 18585 			EAP_TRACE_DEBUG(
       
 18586 				m_am_tools,
       
 18587 				TRACE_FLAGS_DEFAULT,
       
 18588 				(EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): EAP-FAST server unauthenticated provisioning mode\n")));
       
 18589 
       
 18590 			eap_status_e notification_status = indicate_state_to_lower_layer(
       
 18591 				tls_peap_state_full_authentication);
       
 18592 			if (notification_status != eap_status_ok)
       
 18593 			{
       
 18594 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18595 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 18596 			}
       
 18597 		}
       
 18598 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18599 		else
       
 18600 		{
       
 18601 			set_tls_session_type(tls_session_type_full_authentication);
       
 18602 
       
 18603 			EAP_TRACE_DEBUG(
       
 18604 				m_am_tools,
       
 18605 				TRACE_FLAGS_DEFAULT,
       
 18606 				(EAPL("TLS: complete_select_cipher_suite_and_check_session_id(): full authentication\n")));
       
 18607 
       
 18608 			eap_status_e notification_status = indicate_state_to_lower_layer(
       
 18609 				tls_peap_state_full_authentication);
       
 18610 			if (notification_status != eap_status_ok)
       
 18611 			{
       
 18612 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18613 				return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
 18614 			}
       
 18615 		}
       
 18616 
       
 18617 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 18618 
       
 18619 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18620 
       
 18621 #if defined(USE_FAST_EAP_TYPE)
       
 18622 		if (m_eap_type != eap_type_fast)
       
 18623 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18624 		{
       
 18625 			if (m_tls_session_type == tls_session_type_original_session_resumption
       
 18626 				|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
 18627 			{
       
 18628 				const tls_extension_c * const supported_session_ticket_extension = tls_extension_c::get_tls_extension(
       
 18629 						tls_extension_type_session_ticket,
       
 18630 						&m_supported_tls_extensions,
       
 18631 						m_am_tools);
       
 18632 				if (supported_session_ticket_extension != 0)
       
 18633 				{
       
 18634 					EAP_TRACE_DEBUG(
       
 18635 						m_am_tools,
       
 18636 						TRACE_FLAGS_DEFAULT,
       
 18637 						(EAPL("TLS: %s: message_function: complete_select_cipher_suite_and_check_session_id(): ")
       
 18638 						 EAPL("SST: Server will send a new session ticket to client, length = %d.\n"),
       
 18639 						 (m_is_client == true ? "client": "server"),
       
 18640 						 supported_session_ticket_extension->get_data_length()));
       
 18641 
       
 18642 					// Server will send a new session ticket to client.
       
 18643 					status = completion_action_add(
       
 18644 						tls_completion_action_create_handshake_type_new_session_ticket);
       
 18645 					if (status != eap_status_ok)
       
 18646 					{
       
 18647 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18648 						return EAP_STATUS_RETURN(m_am_tools, status);
       
 18649 					}
       
 18650 				}
       
 18651 			}
       
 18652 		}
       
 18653 
       
 18654 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18655 
       
 18656 
       
 18657 		// The following sequence depends on whether the previous
       
 18658 		// session is restored and on the selected cipher suite.
       
 18659 
       
 18660 		if (m_tls_session_type == tls_session_type_original_session_resumption
       
 18661 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18662 			|| m_tls_session_type == tls_session_type_stateless_session_resumption
       
 18663 #if defined(USE_FAST_EAP_TYPE)
       
 18664 			|| m_tls_session_type == tls_session_type_eap_fast_pac_session_resumption
       
 18665 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18666 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18667 			)
       
 18668 		{
       
 18669 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18670 			if (m_will_receive_new_session_ticket == true)
       
 18671 			{
       
 18672 				set_state(tls_peap_state_wait_handshake_type_new_session_ticket);
       
 18673 			}
       
 18674 			else
       
 18675 #endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18676 			{
       
 18677 				set_state(tls_peap_state_wait_change_cipher_spec);
       
 18678 			}
       
 18679 
       
 18680 			status = completion_action_add(
       
 18681 				tls_completion_action_create_change_cipher_spec_type_change_cipher_spec);
       
 18682 			if (status != eap_status_ok)
       
 18683 			{
       
 18684 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18685 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18686 			}
       
 18687 
       
 18688 			status = completion_action_add(tls_completion_action_create_handshake_type_finished);
       
 18689 			if (status != eap_status_ok)
       
 18690 			{
       
 18691 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18692 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18693 			}
       
 18694 		}
       
 18695 #if defined(USE_FAST_EAP_TYPE)
       
 18696 		else if (m_tls_session_type == tls_session_type_eap_fast_server_unauthenticated_provisioning_mode_ADHP)
       
 18697 		{
       
 18698 			// Ephemeral DH key exchange causes creation of server_key_exchange message.
       
 18699 			// Server sends DH public key and related parameters to client.
       
 18700 
       
 18701 			status = completion_action_add(tls_completion_action_query_dh_parameters);
       
 18702 			if (status != eap_status_ok)
       
 18703 			{
       
 18704 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18705 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18706 			}
       
 18707 
       
 18708 			status = completion_action_add(
       
 18709 				tls_completion_action_create_handshake_type_server_key_exchange);
       
 18710 			if (status != eap_status_ok)
       
 18711 			{
       
 18712 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18713 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18714 			}
       
 18715 
       
 18716 			// This will complete creation of handshake_type_server_key_exchange message.
       
 18717 			status = completion_action_add(
       
 18718 				tls_completion_action_complete_create_handshake_type_server_key_exchange);
       
 18719 			if (status != eap_status_ok)
       
 18720 			{
       
 18721 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18722 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18723 			}
       
 18724 
       
 18725 			// Also the other pending messages will be processed after this action is completed.
       
 18726 			eap_status_e compl_status = completion_action_add(
       
 18727 				tls_completion_action_process_tls_records);
       
 18728 			if (compl_status != eap_status_ok)
       
 18729 			{
       
 18730 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18731 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18732 			}
       
 18733 
       
 18734 			status = completion_action_add(
       
 18735 				tls_completion_action_create_handshake_type_server_hello_done);
       
 18736 			if (status != eap_status_ok)
       
 18737 			{
       
 18738 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18739 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18740 			}
       
 18741 
       
 18742 			set_state(tls_peap_state_wait_handshake_type_client_key_exchange);
       
 18743 		}
       
 18744 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 18745 		else
       
 18746 		{
       
 18747 			if (m_tls_peap_server_authenticates_client_config_server == true)
       
 18748 			{
       
 18749 				set_state(tls_peap_state_wait_handshake_type_certificate);
       
 18750 			}
       
 18751 			else
       
 18752 			{
       
 18753 				set_state(tls_peap_state_wait_handshake_type_client_key_exchange);
       
 18754 			}
       
 18755 
       
 18756 			status = completion_action_add(tls_completion_action_create_handshake_type_certificate);
       
 18757 			if (status != eap_status_ok)
       
 18758 			{
       
 18759 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18760 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18761 			}
       
 18762 
       
 18763 			if (cipher_suite_is_TLS_DHE_DSS() == true
       
 18764 				|| cipher_suite_is_TLS_DHE_RSA() == true)
       
 18765 			{
       
 18766 				// Ephemeral DH key exchange causes creation of server_key_exchange message.
       
 18767 				// Server sends DH public key and related parameters to client.
       
 18768 
       
 18769 				status = completion_action_add(tls_completion_action_query_dh_parameters);
       
 18770 				if (status != eap_status_ok)
       
 18771 				{
       
 18772 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18773 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18774 				}
       
 18775 
       
 18776 				status = completion_action_add(
       
 18777 					tls_completion_action_create_handshake_type_server_key_exchange);
       
 18778 				if (status != eap_status_ok)
       
 18779 				{
       
 18780 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18781 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18782 				}
       
 18783 
       
 18784 				// This will complete creation of handshake_type_server_key_exchange message.
       
 18785 				status = completion_action_add(
       
 18786 					tls_completion_action_complete_create_handshake_type_server_key_exchange);
       
 18787 				if (status != eap_status_ok)
       
 18788 				{
       
 18789 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18790 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18791 				}
       
 18792 
       
 18793 				// Also the other pending messages will be processed after this action is completed.
       
 18794 				eap_status_e compl_status = completion_action_add(
       
 18795 					tls_completion_action_process_tls_records);
       
 18796 				if (compl_status != eap_status_ok)
       
 18797 				{
       
 18798 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18799 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18800 				}
       
 18801 			}
       
 18802 
       
 18803 			if (m_tls_peap_server_authenticates_client_config_server == true)
       
 18804 			{
       
 18805 				// Server initiates client authentication.
       
 18806 				status = completion_action_add(
       
 18807 					tls_completion_action_create_handshake_type_certificate_request);
       
 18808 				if (status != eap_status_ok)
       
 18809 				{
       
 18810 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18811 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18812 				}
       
 18813 			}
       
 18814 			
       
 18815 			status = completion_action_add(
       
 18816 				tls_completion_action_create_handshake_type_server_hello_done);
       
 18817 			if (status != eap_status_ok)
       
 18818 			{
       
 18819 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18820 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18821 			}
       
 18822 
       
 18823 			
       
 18824 			EAP_TRACE_DEBUG(
       
 18825 				m_am_tools,
       
 18826 				TRACE_FLAGS_DEFAULT,
       
 18827 				(EAPL("TLS: %s: pki_function: query_certificate_chain()\n"),
       
 18828 				(m_is_client == true ? "client": "server")));
       
 18829 
       
 18830 			status = m_am_tls_services->query_certificate_chain(
       
 18831 				&m_own_certificate_authorities,
       
 18832 				&m_own_certificate_types,
       
 18833 				m_selected_cipher_suite);
       
 18834 			if (status == eap_status_pending_request)
       
 18835 			{
       
 18836 				// This is pending query, that will be completed by
       
 18837 				// complete_query_certificate_chain() call.
       
 18838 				m_pending_query_certificate_chain = true;
       
 18839 			}
       
 18840 			else if (status == eap_status_completed_request)
       
 18841 			{
       
 18842 				// This is already completed by complete_query_certificate_chain() call.
       
 18843 			}
       
 18844 			else if (status == eap_status_ok)
       
 18845 			{
       
 18846 				// This is also an error case, because this call is always completed on success. 
       
 18847 				status = eap_status_process_general_error;
       
 18848 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18849 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 18850 			}
       
 18851 			else // All other status values means error, because this
       
 18852 				// call is always completed on success.
       
 18853 			{
       
 18854 				// This is an error case.
       
 18855 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18856 				return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
 18857 			}
       
 18858 
       
 18859 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 18860 
       
 18861 			if (m_tls_peap_server_authenticates_client_config_server == true)
       
 18862 			{
       
 18863 				// Server initiates client authentication.
       
 18864 				status = m_am_tls_services->query_certificate_authorities_and_types();
       
 18865 				if (status == eap_status_pending_request)
       
 18866 				{
       
 18867 					// This is pending query, that will be completed by
       
 18868 					// complete_query_certificate_authorities_and_types() call.
       
 18869 					m_pending_query_certificate_authorities_and_types = true;
       
 18870 				}
       
 18871 				else if (status == eap_status_completed_request)
       
 18872 				{
       
 18873 					// This is already completed by
       
 18874 					// complete_query_certificate_authorities_and_types() call.
       
 18875 				}
       
 18876 				else if (status == eap_status_ok)
       
 18877 				{
       
 18878 					// This is also an error case, because this call is
       
 18879 					// always completed on success. 
       
 18880 					status = eap_status_process_general_error;
       
 18881 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18882 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 18883 				}
       
 18884 				else // All other status values means error, because this
       
 18885 					// call is always completed on success.
       
 18886 				{
       
 18887 					// This is an error case.
       
 18888 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18889 					return EAP_STATUS_RETURN_AND_CREATE_TLS_PROTOCOL_ALERT(m_am_tools, status);
       
 18890 				}
       
 18891 			}
       
 18892 		}
       
 18893 	}
       
 18894 
       
 18895 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
 18896 
       
 18897 	if (status == eap_status_ok)
       
 18898 	{
       
 18899 		status = check_sent_tls_message();
       
 18900 		if (status != eap_status_ok)
       
 18901 		{
       
 18902 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18903 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 18904 		}
       
 18905 
       
 18906 		status = eap_status_completed_request;
       
 18907 	}
       
 18908 
       
 18909 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18910 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 18911 }
       
 18912 
       
 18913 //--------------------------------------------------
       
 18914 
       
 18915 #if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18916 
       
 18917 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_new_session_ticket(
       
 18918 	const tls_extension_c * const new_session_ticket_or_null)
       
 18919 {
       
 18920 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18921 
       
 18922 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 18923 	EAP_TRACE_DEBUG(
       
 18924 		m_am_tools,
       
 18925 		TRACE_FLAGS_DEFAULT,
       
 18926 		(EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_query_new_session_ticket()\n"),
       
 18927 		 this,
       
 18928 		 (m_is_client == true ? "client": "server")));
       
 18929 
       
 18930 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_new_session_ticket()");
       
 18931 
       
 18932 	eap_status_e status(eap_status_ok);
       
 18933 
       
 18934 	if (new_session_ticket_or_null != 0)
       
 18935 	{
       
 18936 		tls_extension_c * const copy_of_session_ticket = new_session_ticket_or_null->copy();
       
 18937 
       
 18938 		if (copy_of_session_ticket == 0)
       
 18939 		{
       
 18940 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18941 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 18942 		}
       
 18943 
       
 18944 		status = m_supported_tls_extensions.add_object(copy_of_session_ticket, true);
       
 18945 	}
       
 18946 
       
 18947 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18948 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 18949 }
       
 18950 
       
 18951 #endif //#if defined(USE_EAP_TLS_SESSION_TICKET)
       
 18952 
       
 18953 //--------------------------------------------------
       
 18954 
       
 18955 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_verify_certificate_chain(
       
 18956 	const eap_status_e result)
       
 18957 {
       
 18958 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18959 
       
 18960 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 18961 	EAP_TRACE_DEBUG(
       
 18962 		m_am_tools,
       
 18963 		TRACE_FLAGS_DEFAULT,
       
 18964 		(EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_verify_certificate_chain()\n"),
       
 18965 		 this,
       
 18966 		 (m_is_client == true ? "client": "server")));
       
 18967 
       
 18968 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_verify_certificate_chain()");
       
 18969 
       
 18970 	eap_status_e status = result;
       
 18971 
       
 18972 	m_pending_verify_certificate_chain = false;
       
 18973 
       
 18974 	m_peer_certificate_chain_result = result;
       
 18975 
       
 18976 	if (m_peer_certificate_chain_result == eap_status_ok)
       
 18977 	{
       
 18978 		// Ok certificate.
       
 18979 	}
       
 18980 	else
       
 18981 	{
       
 18982 		// Illegal certificate.
       
 18983 
       
 18984 		status = create_tls_protocol_alert(
       
 18985 			tls_alert_description_none,
       
 18986 			tls_alert_level_none,
       
 18987 			m_peer_certificate_chain_result);
       
 18988 		if (status != eap_status_ok)
       
 18989 		{
       
 18990 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 18991 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 18992 		}
       
 18993 	}
       
 18994 
       
 18995 	if (status == eap_status_ok)
       
 18996 	{
       
 18997 		status = check_sent_tls_message();
       
 18998 		if (status != eap_status_ok)
       
 18999 		{
       
 19000 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19001 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19002 		}
       
 19003 
       
 19004 		status = eap_status_completed_request;
       
 19005 	}
       
 19006 
       
 19007 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19008 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19009 }
       
 19010 
       
 19011 //--------------------------------------------------
       
 19012 
       
 19013 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_certificate_chain(
       
 19014 	EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_chain,
       
 19015 	const eap_status_e completion_status)
       
 19016 {
       
 19017 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19018 
       
 19019 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19020 	EAP_TRACE_DEBUG(
       
 19021 		m_am_tools,
       
 19022 		TRACE_FLAGS_DEFAULT,
       
 19023 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_certificate_chain()\n"),
       
 19024 		 this,
       
 19025 		 (m_is_client == true ? "client": "server")));
       
 19026 
       
 19027 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_certificate_chain()");
       
 19028 
       
 19029 	eap_status_e status = eap_status_not_supported;
       
 19030 
       
 19031 	m_pending_query_certificate_chain = false;
       
 19032 
       
 19033 	{
       
 19034 		if (completion_status != eap_status_ok
       
 19035 			|| certificate_chain == 0
       
 19036 			|| certificate_chain->get_object_count() == 0)
       
 19037 		{
       
 19038 			if (completion_status != eap_status_ok)
       
 19039 			{
       
 19040 				(void)EAP_STATUS_RETURN(m_am_tools, completion_status);
       
 19041 			}
       
 19042 
       
 19043 			if (m_is_client == false)
       
 19044 			{
       
 19045 				// Server fails immediately.
       
 19046 
       
 19047 				status = create_tls_protocol_alert(
       
 19048 					tls_alert_description_none,
       
 19049 					tls_alert_level_none,
       
 19050 					completion_status);
       
 19051 				if (status != eap_status_ok)
       
 19052 				{
       
 19053 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19054 					return EAP_STATUS_RETURN(m_am_tools, status);
       
 19055 				}
       
 19056 
       
 19057 				EAP_TRACE_DEBUG(
       
 19058 					m_am_tools,
       
 19059 					TRACE_FLAGS_DEFAULT,
       
 19060 					(EAPL("ERROR: TLS: %s: pki_function: complete_query_certificate_chain(): ")
       
 19061 					 EAPL("Server have illegal sertificate for this cipher suite.\n"),
       
 19062 					(m_is_client == true ? "client": "server")));
       
 19063 			}
       
 19064 			else
       
 19065 			{
       
 19066 				if (m_tls_peap_server_authenticates_client_policy_flag == true
       
 19067 					|| (m_tls_peap_server_authenticates_client_policy_flag == false
       
 19068 						&& completion_status != eap_status_illegal_certificate
       
 19069 						&& completion_status != eap_status_ca_certificate_unknown))
       
 19070 				{
       
 19071 					// Client does fail immediately.
       
 19072 					// This session could NOT use server only authentication.
       
 19073 					if (completion_status == eap_status_illegal_certificate)
       
 19074 					{
       
 19075 						EAP_TRACE_DEBUG(
       
 19076 							m_am_tools,
       
 19077 							TRACE_FLAGS_DEFAULT,
       
 19078 							(EAPL("ERROR: TLS: %s: pki_function: complete_query_certificate_chain(): ")
       
 19079 							 EAPL("Client have illegal sertificate for this cipher suite.\n"),
       
 19080 							(m_is_client == true ? "client": "server")));
       
 19081 
       
 19082 						status = eap_status_illegal_certificate;
       
 19083 						(void)EAP_STATUS_RETURN(m_am_tools, status);
       
 19084 					}
       
 19085 					else
       
 19086 					{
       
 19087 						EAP_TRACE_DEBUG(
       
 19088 							m_am_tools,
       
 19089 							TRACE_FLAGS_DEFAULT,
       
 19090 							(EAPL("ERROR: TLS: %s: pki_function: complete_query_certificate_chain(): ")
       
 19091 							 EAPL("Client does NOT allow anonymous client.\n"),
       
 19092 							(m_is_client == true ? "client": "server")));
       
 19093 
       
 19094 						status = eap_status_insufficient_security;
       
 19095 						(void)EAP_STATUS_RETURN(m_am_tools, status);
       
 19096 					}
       
 19097 
       
 19098 					// This will cause the session terminate immediately.
       
 19099 					status = get_type_partner()->set_session_timeout(0ul);
       
 19100 					if (status != eap_status_ok)
       
 19101 					{
       
 19102 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19103 						return EAP_STATUS_RETURN(m_am_tools, status);
       
 19104 					}
       
 19105 
       
 19106 #if defined(USE_FAST_EAP_TYPE)
       
 19107 					if (m_eap_type == eap_type_fast)
       
 19108 					{
       
 19109 						send_error_notification(eap_status_no_pac_nor_certs_to_authenticate_with_provision_disabled);
       
 19110 
       
 19111 						status = create_tls_protocol_alert(
       
 19112 								tls_alert_description_internal_error,
       
 19113 								tls_alert_level_fatal,
       
 19114 								status);
       
 19115 						if (status != eap_status_ok)
       
 19116 						{
       
 19117 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19118 							return EAP_STATUS_RETURN(m_am_tools, status);
       
 19119 						}
       
 19120 					}
       
 19121 					else
       
 19122 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 19123 					{
       
 19124 						status = create_tls_protocol_alert(
       
 19125 								tls_alert_description_none,
       
 19126 								tls_alert_level_none,
       
 19127 								completion_status);
       
 19128 						if (status != eap_status_ok)
       
 19129 						{
       
 19130 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19131 							return EAP_STATUS_RETURN(m_am_tools, status);
       
 19132 						}
       
 19133 					}
       
 19134 				}
       
 19135 				else
       
 19136 				{
       
 19137 
       
 19138 #if defined(USE_FAST_EAP_TYPE)
       
 19139 					if (m_eap_type == eap_type_fast
       
 19140 						&& m_eap_fast_allow_server_unauthenticated_provisioning_mode_ADHP == false
       
 19141 						&& m_fast_allow_server_authenticated_provisioning_mode == false)
       
 19142 					{
       
 19143 						// No PAC, no sertificate, no provision allowed.
       
 19144 						// This will cause the session terminate immediately.
       
 19145 						status = get_type_partner()->set_session_timeout(0ul);
       
 19146 						if (status != eap_status_ok)
       
 19147 						{
       
 19148 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19149 							return EAP_STATUS_RETURN(m_am_tools, status);
       
 19150 						}
       
 19151 
       
 19152 						send_error_notification(eap_status_no_pac_nor_certs_to_authenticate_with_provision_disabled);
       
 19153 
       
 19154 						status = create_tls_protocol_alert(
       
 19155 								tls_alert_description_internal_error,
       
 19156 								tls_alert_level_fatal,
       
 19157 								status);
       
 19158 						if (status != eap_status_ok)
       
 19159 						{
       
 19160 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19161 							return EAP_STATUS_RETURN(m_am_tools, status);
       
 19162 						}
       
 19163 					}
       
 19164 					else
       
 19165 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 19166 					{
       
 19167 						// Client does not fail immediately.
       
 19168 						// This session could use server only authentication.
       
 19169 						// NOTE, in this case client must send empty certificate message to server.
       
 19170 						EAP_TRACE_DEBUG(
       
 19171 							m_am_tools,
       
 19172 							TRACE_FLAGS_DEFAULT,
       
 19173 							(EAPL("INFO: TLS: %s: pki_function: complete_query_certificate_chain(): ")
       
 19174 							 EAPL("Client allows anonymous client.\n"),
       
 19175 							(m_is_client == true ? "client": "server")));
       
 19176 
       
 19177 						m_tls_peap_server_authenticates_client_action = false;
       
 19178 						status = eap_status_ok;
       
 19179 					}
       
 19180 				}
       
 19181 			}
       
 19182 		}
       
 19183 		else
       
 19184 		{
       
 19185 			status = copy<eap_variable_data_c>(
       
 19186 				certificate_chain,
       
 19187 				&m_own_certificate_chain,
       
 19188 				m_am_tools,
       
 19189 				false);
       
 19190 			if (status != eap_status_ok)
       
 19191 			{
       
 19192 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19193 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 19194 			}
       
 19195 		}
       
 19196 	}
       
 19197 
       
 19198 	if (status == eap_status_ok)
       
 19199 	{
       
 19200 		status = check_sent_tls_message();
       
 19201 		if (status != eap_status_ok)
       
 19202 		{
       
 19203 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19204 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19205 		}
       
 19206 
       
 19207 		status = eap_status_completed_request;
       
 19208 	}
       
 19209 
       
 19210 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19211 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19212 }
       
 19213 
       
 19214 //--------------------------------------------------
       
 19215 
       
 19216 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_certificate_authorities_and_types(
       
 19217 	EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_authorities,
       
 19218 	EAP_TEMPLATE_CONST eap_array_c<u8_t> * const certificate_types,
       
 19219 	const eap_status_e completion_status)
       
 19220 {
       
 19221 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19222 
       
 19223 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19224 	EAP_TRACE_DEBUG(
       
 19225 		m_am_tools,
       
 19226 		TRACE_FLAGS_DEFAULT,
       
 19227 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_certificate_authorities_and_types()\n"),
       
 19228 		 this,
       
 19229 		 (m_is_client == true ? "client": "server")));
       
 19230 
       
 19231 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_certificate_authorities_and_types()");
       
 19232 
       
 19233 	m_pending_query_certificate_authorities_and_types = false;
       
 19234 
       
 19235 	eap_status_e status = eap_status_not_supported;
       
 19236 
       
 19237 	if (completion_status != eap_status_ok)
       
 19238 	{
       
 19239 		status = create_tls_protocol_alert(
       
 19240 			tls_alert_description_none,
       
 19241 			tls_alert_level_none,
       
 19242 			completion_status);
       
 19243 		if (status != eap_status_ok)
       
 19244 		{
       
 19245 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19246 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19247 		}
       
 19248 	}
       
 19249 	else
       
 19250 	{
       
 19251 		status = copy<eap_variable_data_c>(
       
 19252 			certificate_authorities,
       
 19253 			&m_own_certificate_authorities,
       
 19254 			m_am_tools,
       
 19255 			false);
       
 19256 		if (status != eap_status_ok)
       
 19257 		{
       
 19258 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19259 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19260 		}
       
 19261 
       
 19262 		status = copy_simple<u8_t>(
       
 19263 			certificate_types,
       
 19264 			&m_own_certificate_types,
       
 19265 			m_am_tools,
       
 19266 			false);
       
 19267 		if (status != eap_status_ok)
       
 19268 		{
       
 19269 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19270 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19271 		}
       
 19272 	}
       
 19273 
       
 19274 
       
 19275 	if (status == eap_status_ok)
       
 19276 	{
       
 19277 		status = check_sent_tls_message();
       
 19278 		if (status != eap_status_ok)
       
 19279 		{
       
 19280 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19281 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19282 		}
       
 19283 
       
 19284 		status = eap_status_completed_request;
       
 19285 	}
       
 19286 
       
 19287 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19288 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19289 }
       
 19290 
       
 19291 //--------------------------------------------------
       
 19292 
       
 19293 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_dh_parameters(
       
 19294 	const eap_variable_data_c * const dhe_prime,
       
 19295 	const eap_variable_data_c * const dhe_group_generator,
       
 19296 	const eap_status_e completion_status)
       
 19297 {
       
 19298 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19299 
       
 19300 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19301 	EAP_TRACE_DEBUG(
       
 19302 		m_am_tools,
       
 19303 		TRACE_FLAGS_DEFAULT,
       
 19304 		(EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_query_dh_parameters()\n"),
       
 19305 		 this,
       
 19306 		 (m_is_client == true ? "client": "server")));
       
 19307 
       
 19308 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_dh_parameters()");
       
 19309 
       
 19310 	m_pending_query_dh_parameters = false;
       
 19311 
       
 19312 	eap_status_e status = eap_status_not_supported;
       
 19313 
       
 19314 	if (completion_status != eap_status_ok)
       
 19315 	{
       
 19316 		status = create_tls_protocol_alert(
       
 19317 			tls_alert_description_none,
       
 19318 			tls_alert_level_none,
       
 19319 			completion_status);
       
 19320 		if (status != eap_status_ok)
       
 19321 		{
       
 19322 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19323 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19324 		}
       
 19325 	}
       
 19326 	else
       
 19327 	{
       
 19328 		status = m_dhe_prime.set_copy_of_buffer(dhe_prime);
       
 19329 		if (status != eap_status_ok)
       
 19330 		{
       
 19331 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19332 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19333 		}
       
 19334 
       
 19335 		status = m_dhe_group_generator.set_copy_of_buffer(dhe_group_generator);
       
 19336 		if (status != eap_status_ok)
       
 19337 		{
       
 19338 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19339 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19340 		}
       
 19341 	}
       
 19342 
       
 19343 	if (status == eap_status_ok)
       
 19344 	{
       
 19345 		status = check_sent_tls_message();
       
 19346 		if (status != eap_status_ok)
       
 19347 		{
       
 19348 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19349 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19350 		}
       
 19351 
       
 19352 		status = eap_status_completed_request;
       
 19353 	}
       
 19354 
       
 19355 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19356 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19357 }
       
 19358 
       
 19359 //--------------------------------------------------
       
 19360 
       
 19361 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_realm(
       
 19362 	const eap_variable_data_c * const realm,
       
 19363 	const eap_status_e completion_status)
       
 19364 {
       
 19365 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19366 
       
 19367 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19368 	EAP_TRACE_DEBUG(
       
 19369 		m_am_tools,
       
 19370 		TRACE_FLAGS_DEFAULT,
       
 19371 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_realm()\n"),
       
 19372 		 this,
       
 19373 		 (m_is_client == true ? "client": "server")));
       
 19374 
       
 19375 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_realm()");
       
 19376 
       
 19377 	m_pending_query_realm = false;
       
 19378 
       
 19379 	eap_status_e status = eap_status_not_supported;
       
 19380 
       
 19381 	if (completion_status != eap_status_ok)
       
 19382 	{
       
 19383 		status = create_tls_protocol_alert(
       
 19384 			tls_alert_description_none,
       
 19385 			tls_alert_level_none,
       
 19386 			completion_status);
       
 19387 		if (status != eap_status_ok)
       
 19388 		{
       
 19389 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19390 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19391 		}
       
 19392 	}
       
 19393 	else
       
 19394 	{
       
 19395 		status = m_NAI_realm.set_copy_of_buffer(realm);
       
 19396 	}
       
 19397 
       
 19398 	if (status == eap_status_ok)
       
 19399 	{
       
 19400 		status = check_sent_tls_message();
       
 19401 		if (status != eap_status_ok)
       
 19402 		{
       
 19403 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19404 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19405 		}
       
 19406 
       
 19407 		status = eap_status_completed_request;
       
 19408 	}
       
 19409 
       
 19410 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19411 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19412 }
       
 19413 
       
 19414 //--------------------------------------------------
       
 19415 
       
 19416 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_rsa_decrypt_with_private_key(
       
 19417 	const eap_variable_data_c * const premaster_secret,
       
 19418 	const eap_status_e completion_status)
       
 19419 {
       
 19420 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19421 
       
 19422 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19423 	EAP_TRACE_DEBUG(
       
 19424 		m_am_tools,
       
 19425 		TRACE_FLAGS_DEFAULT,
       
 19426 		(EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_rsa_decrypt_with_private_key()\n"),
       
 19427 		 this,
       
 19428 		 (m_is_client == true ? "client": "server")));
       
 19429 
       
 19430 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_rsa_decrypt_with_private_key()");
       
 19431 
       
 19432 	m_pending_rsa_decrypt_with_private_key = false;
       
 19433 
       
 19434 	eap_status_e status = eap_status_not_supported;
       
 19435 
       
 19436 	if (completion_status != eap_status_ok)
       
 19437 	{
       
 19438 		status = create_tls_protocol_alert(
       
 19439 			tls_alert_description_none,
       
 19440 			tls_alert_level_none,
       
 19441 			completion_status);
       
 19442 		if (status != eap_status_ok)
       
 19443 		{
       
 19444 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19445 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19446 		}
       
 19447 	}
       
 19448 	else
       
 19449 	{
       
 19450 		EAP_TRACE_DATA_DEBUG(
       
 19451 			m_am_tools,
       
 19452 			TRACE_FLAGS_DEFAULT,
       
 19453 			(EAPL("TLS: complete_rsa_decrypt_with_private_key(): premaster_secret"),
       
 19454 			 premaster_secret->get_data(),
       
 19455 			 premaster_secret->get_data_length()));
       
 19456 
       
 19457 		status = m_premaster_secret.set_copy_of_buffer(premaster_secret);
       
 19458 		if (status != eap_status_ok)
       
 19459 		{
       
 19460 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19461 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19462 		}
       
 19463 
       
 19464 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS: m_premaster_secret"),
       
 19465 			m_premaster_secret.get_data(m_premaster_secret.get_data_length()),
       
 19466 			m_premaster_secret.get_data_length()));
       
 19467 
       
 19468 		m_key_material_generated = false;
       
 19469 
       
 19470 		// We must generate master secret.
       
 19471 		status = generate_master_secret();
       
 19472 		if (status != eap_status_ok)
       
 19473 		{
       
 19474 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19475 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19476 		}
       
 19477 
       
 19478 		// We must generate the key material.
       
 19479 		status = generate_key_material();
       
 19480 		if (status != eap_status_ok)
       
 19481 		{
       
 19482 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19483 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19484 		}
       
 19485 	}
       
 19486 
       
 19487 	if (status == eap_status_ok)
       
 19488 	{
       
 19489 		status = check_sent_tls_message();
       
 19490 		if (status != eap_status_ok)
       
 19491 		{
       
 19492 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19493 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19494 		}
       
 19495 
       
 19496 		status = eap_status_completed_request;
       
 19497 	}
       
 19498 
       
 19499 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19500 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19501 }
       
 19502 
       
 19503 //--------------------------------------------------
       
 19504 
       
 19505 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_rsa_encrypt_with_public_key(
       
 19506 	const eap_variable_data_c * const encrypted_premaster_secret,
       
 19507 	const eap_status_e completion_status)
       
 19508 {
       
 19509 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19510 
       
 19511 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19512 	EAP_TRACE_DEBUG(
       
 19513 		m_am_tools,
       
 19514 		TRACE_FLAGS_DEFAULT,
       
 19515 		(EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_rsa_encrypt_with_public_key()\n"),
       
 19516 		 this,
       
 19517 		 (m_is_client == true ? "client": "server")));
       
 19518 
       
 19519 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_rsa_encrypt_with_public_key()");
       
 19520 
       
 19521 	m_pending_rsa_encrypt_with_public_key = false;
       
 19522 
       
 19523 	eap_status_e status = eap_status_not_supported;
       
 19524 
       
 19525 	if (completion_status != eap_status_ok)
       
 19526 	{
       
 19527 		status = create_tls_protocol_alert(
       
 19528 			tls_alert_description_none,
       
 19529 			tls_alert_level_none,
       
 19530 			completion_status);
       
 19531 		if (status != eap_status_ok)
       
 19532 		{
       
 19533 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19534 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19535 		}
       
 19536 	}
       
 19537 	else
       
 19538 	{
       
 19539 		EAP_TRACE_DATA_DEBUG(
       
 19540 			m_am_tools,
       
 19541 			TRACE_FLAGS_DEFAULT,
       
 19542 			(EAPL("TLS: complete_rsa_encrypt_with_public_key(): encrypted premaster_secret"),
       
 19543 			 encrypted_premaster_secret->get_data(),
       
 19544 			 encrypted_premaster_secret->get_data_length()));
       
 19545 
       
 19546 		status = m_own_encrypted_premaster_secret.set_copy_of_buffer(encrypted_premaster_secret);
       
 19547 		if (status != eap_status_ok)
       
 19548 		{
       
 19549 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19550 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19551 		}
       
 19552 	}
       
 19553 
       
 19554 	if (status == eap_status_ok)
       
 19555 	{
       
 19556 		status = check_sent_tls_message();
       
 19557 		if (status != eap_status_ok)
       
 19558 		{
       
 19559 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19560 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19561 		}
       
 19562 
       
 19563 		status = eap_status_completed_request;
       
 19564 	}
       
 19565 
       
 19566 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19567 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19568 }
       
 19569 
       
 19570 //--------------------------------------------------
       
 19571 
       
 19572 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_sign_with_private_key(
       
 19573 	const eap_variable_data_c * const signed_message_hash,
       
 19574 	const eap_status_e completion_status)
       
 19575 {
       
 19576 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19577 
       
 19578 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19579 	EAP_TRACE_DEBUG(
       
 19580 		m_am_tools,
       
 19581 		TRACE_FLAGS_DEFAULT,
       
 19582 		(EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_sign_with_private_key()\n"),
       
 19583 		 this,
       
 19584 		 (m_is_client == true ? "client": "server")));
       
 19585 
       
 19586 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_sign_with_private_key()");
       
 19587 
       
 19588 	m_pending_sign_with_private_key = false;
       
 19589 
       
 19590 	eap_status_e status = eap_status_not_supported;
       
 19591 
       
 19592 	if (completion_status != eap_status_ok)
       
 19593 	{
       
 19594 		status = create_tls_protocol_alert(
       
 19595 			tls_alert_description_none,
       
 19596 			tls_alert_level_none,
       
 19597 			completion_status);
       
 19598 		if (status != eap_status_ok)
       
 19599 		{
       
 19600 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19601 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19602 		}
       
 19603 	}
       
 19604 	else
       
 19605 	{
       
 19606 		if (signed_message_hash->get_is_valid_data() == false)
       
 19607 		{
       
 19608 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19609 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
 19610 		}
       
 19611 
       
 19612 		status = m_signed_message_hash.set_copy_of_buffer(signed_message_hash);
       
 19613 		if (status != eap_status_ok)
       
 19614 		{
       
 19615 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19616 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19617 		}
       
 19618 
       
 19619 		EAP_TRACE_DATA_DEBUG(
       
 19620 			m_am_tools,
       
 19621 			TRACE_FLAGS_DEFAULT,
       
 19622 			(EAPL("TLS: complete_sign_with_private_key(): m_signed_message_hash"),
       
 19623 			m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
       
 19624 			m_signed_message_hash.get_data_length()));
       
 19625 	}
       
 19626 
       
 19627 
       
 19628 	if (status == eap_status_ok)
       
 19629 	{
       
 19630 		status = check_sent_tls_message();
       
 19631 		if (status != eap_status_ok)
       
 19632 		{
       
 19633 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19634 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19635 		}
       
 19636 
       
 19637 		status = eap_status_completed_request;
       
 19638 	}
       
 19639 
       
 19640 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19641 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19642 }
       
 19643 
       
 19644 //--------------------------------------------------
       
 19645 
       
 19646 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_verify_with_public_key(
       
 19647 	const eap_status_e verify_status)
       
 19648 {
       
 19649 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19650 
       
 19651 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
 19652 	EAP_TRACE_DEBUG(
       
 19653 		m_am_tools,
       
 19654 		TRACE_FLAGS_DEFAULT,
       
 19655 		(EAPL("TLS: this = 0x%08x, %s: pki_function: starts: tls_record_c::complete_verify_with_public_key()\n"),
       
 19656 		 this,
       
 19657 		 (m_is_client == true ? "client": "server")));
       
 19658 
       
 19659 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_verify_with_public_key()");
       
 19660 
       
 19661 	m_pending_verify_with_public_key = false;
       
 19662 
       
 19663 	eap_status_e status = eap_status_ok;
       
 19664 
       
 19665 	m_verify_signature = verify_status;
       
 19666 
       
 19667 	if (m_verify_signature != eap_status_ok)
       
 19668 	{
       
 19669 		// Verification failed.
       
 19670 
       
 19671 		status = create_tls_protocol_alert(
       
 19672 			tls_alert_description_none,
       
 19673 			tls_alert_level_none,
       
 19674 			m_verify_signature);
       
 19675 		if (status != eap_status_ok)
       
 19676 		{
       
 19677 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19678 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19679 		}
       
 19680 	}
       
 19681 
       
 19682 	if (status == eap_status_ok)
       
 19683 	{
       
 19684 		status = check_sent_tls_message();
       
 19685 		if (status != eap_status_ok)
       
 19686 		{
       
 19687 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19688 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19689 		}
       
 19690 
       
 19691 		status = eap_status_completed_request;
       
 19692 	}
       
 19693 
       
 19694 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19695 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19696 }
       
 19697 
       
 19698 //--------------------------------------------------
       
 19699 
       
 19700 EAP_FUNC_EXPORT eap_status_e tls_record_c::get_eap_tls_master_session_key(
       
 19701 	eap_variable_data_c * const eap_tls_master_session_key,
       
 19702 	eap_variable_data_c * const mschapv2_challenges
       
 19703 	)
       
 19704 {
       
 19705 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19706 
       
 19707 	EAP_TRACE_DEBUG(
       
 19708 		m_am_tools,
       
 19709 		TRACE_FLAGS_DEFAULT,
       
 19710 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::get_eap_tls_master_session_key()\n"),
       
 19711 		 this,
       
 19712 		 (m_is_client == true ? "client": "server")));
       
 19713 
       
 19714 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::get_eap_tls_master_session_key()");
       
 19715 
       
 19716 	eap_status_e status(eap_status_process_general_error);
       
 19717 
       
 19718 #if defined(USE_FAST_EAP_TYPE)
       
 19719 	if (m_eap_type == eap_type_fast)
       
 19720 	{
       
 19721 		status = eap_tls_master_session_key->set_copy_of_buffer(&m_session_key_seed);
       
 19722 		if (status != eap_status_ok)
       
 19723 		{
       
 19724 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19725 			return EAP_STATUS_RETURN(m_am_tools, status);
       
 19726 		}
       
 19727 
       
 19728 		if (mschapv2_challenges != 0
       
 19729 			&& mschapv2_challenges->get_is_valid() == true
       
 19730 			&& m_mschapv2_challenges.get_is_valid_data() == true)
       
 19731 		{
       
 19732 			status = mschapv2_challenges->set_copy_of_buffer(&m_mschapv2_challenges);
       
 19733 		}
       
 19734 	}
       
 19735 	else
       
 19736 #else
       
 19737 	EAP_UNREFERENCED_PARAMETER(mschapv2_challenges);
       
 19738 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 19739 	{
       
 19740 		status = eap_tls_master_session_key->set_copy_of_buffer(&m_eap_master_session_key);
       
 19741 	}
       
 19742 
       
 19743 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19744 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19745 }
       
 19746 
       
 19747 //--------------------------------------------------
       
 19748 
       
 19749 EAP_FUNC_EXPORT eap_status_e tls_record_c::add_rogue_ap(
       
 19750 	eap_array_c<eap_rogue_ap_entry_c> & rogue_ap_list)
       
 19751 {
       
 19752 	return EAP_STATUS_RETURN(m_am_tools, get_type_partner()->add_rogue_ap(rogue_ap_list));
       
 19753 }
       
 19754 
       
 19755 //--------------------------------------------------
       
 19756 
       
 19757 //
       
 19758 EAP_FUNC_EXPORT eap_status_e tls_record_c::set_session_timeout(
       
 19759 	const u32_t session_timeout_ms)
       
 19760 {
       
 19761 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19762 
       
 19763 	eap_status_e status = get_type_partner()->set_session_timeout(session_timeout_ms);
       
 19764 	if (status != eap_status_ok)
       
 19765 	{
       
 19766 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19767 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 19768 	}
       
 19769 
       
 19770 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19771 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19772 }
       
 19773 
       
 19774 //--------------------------------------------------
       
 19775 
       
 19776 EAP_FUNC_EXPORT eap_status_e tls_record_c::set_tls_session_type(const tls_session_type_e tls_session_type)
       
 19777 {
       
 19778 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19779 
       
 19780 	EAP_TRACE_DEBUG(
       
 19781 		m_am_tools,
       
 19782 		TRACE_FLAGS_DEFAULT,
       
 19783 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::set_tls_session_type(): m_tls_session_type=%d=%s\n"),
       
 19784 		 this,
       
 19785 		 (m_is_client == true ? "client": "server"),
       
 19786 		 tls_session_type,
       
 19787 		 eap_tls_trace_string_c::get_tls_session_type_string(tls_session_type)));
       
 19788 
       
 19789 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_tls_session_type()");
       
 19790 
       
 19791 	m_tls_session_type = tls_session_type;
       
 19792 
       
 19793 	eap_status_e status = get_type_partner()->set_tls_session_type(tls_session_type);
       
 19794 
       
 19795 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19796 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19797 }
       
 19798 
       
 19799 //--------------------------------------------------
       
 19800 
       
 19801 EAP_FUNC_EXPORT tls_session_type_e tls_record_c::get_tls_session_type()
       
 19802 {
       
 19803 	return m_tls_session_type;
       
 19804 }
       
 19805 
       
 19806 //--------------------------------------------------
       
 19807 
       
 19808 EAP_FUNC_EXPORT void tls_record_c::set_tls_identity_privacy_handshake_state(const tls_identity_privacy_handshake_state_e state)
       
 19809 {
       
 19810 #if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 19811 	EAP_TRACE_DEBUG(
       
 19812 		m_am_tools,
       
 19813 		TRACE_FLAGS_DEFAULT,
       
 19814 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::set_tls_identity_privacy_handshake_state(): Changes from %d=%s to %d=%s\n"),
       
 19815 		 this,
       
 19816 		 (m_is_client == true ? "client": "server"),
       
 19817 		 m_tls_identity_privacy_handshake_state,
       
 19818 		 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(m_tls_identity_privacy_handshake_state),
       
 19819 		 state,
       
 19820 		 eap_tls_trace_string_c::get_tls_identity_privacy_handshake_state_string(state)));
       
 19821 
       
 19822 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::set_tls_identity_privacy_handshake_state()");
       
 19823 
       
 19824 	m_tls_identity_privacy_handshake_state = state;
       
 19825 #else
       
 19826 	EAP_UNREFERENCED_PARAMETER(state);
       
 19827 #endif //#if defined(USE_EAP_TLS_IDENTITY_PRIVACY)
       
 19828 }
       
 19829 
       
 19830 //--------------------------------------------------
       
 19831 
       
 19832 EAP_FUNC_EXPORT void tls_record_c::set_selected_cipher_suite(const tls_cipher_suites_e cipher_suite)
       
 19833 {
       
 19834 	EAP_TRACE_DEBUG(
       
 19835 		m_am_tools,
       
 19836 		TRACE_FLAGS_DEFAULT,
       
 19837 		(EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::set_selected_cipher_suite(): Changes from %d=%s to %d=%s\n"),
       
 19838 		 this,
       
 19839 		 (m_is_client == true ? "client": "server"),
       
 19840 		 m_selected_cipher_suite,
       
 19841 		 eap_tls_trace_string_c::get_cipher_suite_string(m_selected_cipher_suite),
       
 19842 		 cipher_suite,
       
 19843 		 eap_tls_trace_string_c::get_cipher_suite_string(cipher_suite)));
       
 19844 
       
 19845 	m_selected_cipher_suite = cipher_suite;
       
 19846 }
       
 19847 
       
 19848 //--------------------------------------------------
       
 19849 
       
 19850 EAP_FUNC_EXPORT eap_status_e tls_record_c::set_receive_cipher_suite(const tls_cipher_suites_e cipher_suite)
       
 19851 {
       
 19852 	EAP_TRACE_DEBUG(
       
 19853 		m_am_tools,
       
 19854 		TRACE_FLAGS_DEFAULT,
       
 19855 		(EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::set_receive_cipher_suite(): Changes from %d=%s to %d=%s\n"),
       
 19856 		 this,
       
 19857 		 (m_is_client == true ? "client": "server"),
       
 19858 		 m_receive_cipher_suite,
       
 19859 		 eap_tls_trace_string_c::get_cipher_suite_string(m_receive_cipher_suite),
       
 19860 		 cipher_suite,
       
 19861 		 eap_tls_trace_string_c::get_cipher_suite_string(cipher_suite)));
       
 19862 
       
 19863 	m_receive_cipher_suite = cipher_suite;
       
 19864 
       
 19865 	m_receive_record_sequence_number = 0ul;
       
 19866 
       
 19867 
       
 19868 	EAP_TRACE_DATA_DEBUG(
       
 19869 		m_am_tools,
       
 19870 		TRACE_FLAGS_DEFAULT,
       
 19871 		(EAPL("set_receive_cipher_suite(): m_receive_encryption_key"),
       
 19872 		 m_receive_encryption_key.get_data(),
       
 19873 		 m_receive_encryption_key.get_data_length()));
       
 19874 
       
 19875 	EAP_TRACE_DATA_DEBUG(
       
 19876 		m_am_tools,
       
 19877 		TRACE_FLAGS_DEFAULT,
       
 19878 		(EAPL("set_receive_cipher_suite(): m_new_receive_encryption_key"),
       
 19879 		 m_new_receive_encryption_key.get_data(),
       
 19880 		 m_new_receive_encryption_key.get_data_length()));
       
 19881 
       
 19882 	EAP_TRACE_DATA_DEBUG(
       
 19883 		m_am_tools,
       
 19884 		TRACE_FLAGS_DEFAULT,
       
 19885 		(EAPL("set_receive_cipher_suite(): m_receive_mac_key"),
       
 19886 		 m_receive_mac_key.get_data(),
       
 19887 		 m_receive_mac_key.get_data_length()));
       
 19888 
       
 19889 	EAP_TRACE_DATA_DEBUG(
       
 19890 		m_am_tools,
       
 19891 		TRACE_FLAGS_DEFAULT,
       
 19892 		(EAPL("set_receive_cipher_suite(): m_new_receive_mac_key"),
       
 19893 		 m_new_receive_mac_key.get_data(),
       
 19894 		 m_new_receive_mac_key.get_data_length()));
       
 19895 
       
 19896 	EAP_TRACE_DATA_DEBUG(
       
 19897 		m_am_tools,
       
 19898 		TRACE_FLAGS_DEFAULT,
       
 19899 		(EAPL("set_receive_cipher_suite(): m_receive_iv"),
       
 19900 		 m_receive_iv.get_data(),
       
 19901 		 m_receive_iv.get_data_length()));
       
 19902 
       
 19903 	EAP_TRACE_DATA_DEBUG(
       
 19904 		m_am_tools,
       
 19905 		TRACE_FLAGS_DEFAULT,
       
 19906 		(EAPL("set_receive_cipher_suite(): m_new_receive_iv"),
       
 19907 		 m_new_receive_iv.get_data(),
       
 19908 		 m_new_receive_iv.get_data_length()));
       
 19909 
       
 19910 
       
 19911 	eap_status_e status = m_receive_mac_key.set_copy_of_buffer(&m_new_receive_mac_key);
       
 19912 	if (status != eap_status_ok)
       
 19913 	{
       
 19914 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19915 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 19916 	}
       
 19917 
       
 19918 	status = m_receive_encryption_key.set_copy_of_buffer(&m_new_receive_encryption_key);
       
 19919 	if (status != eap_status_ok)
       
 19920 	{
       
 19921 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19922 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 19923 	}
       
 19924 
       
 19925 	status = m_receive_iv.set_copy_of_buffer(&m_new_receive_iv);
       
 19926 	if (status != eap_status_ok)
       
 19927 	{
       
 19928 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19929 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 19930 	}
       
 19931 
       
 19932 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 19933 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 19934 }
       
 19935 
       
 19936 //--------------------------------------------------
       
 19937 
       
 19938 EAP_FUNC_EXPORT eap_status_e tls_record_c::set_send_cipher_suite(const tls_cipher_suites_e cipher_suite)
       
 19939 {
       
 19940 	EAP_TRACE_DEBUG(
       
 19941 		m_am_tools,
       
 19942 		TRACE_FLAGS_DEFAULT,
       
 19943 		(EAPL("TLS: this = 0x%08x, %s: suite_function: starts: tls_record_c::set_send_cipher_suite(): Changes from %d=%s to %d=%s\n"),
       
 19944 		 this,
       
 19945 		 (m_is_client == true ? "client": "server"),
       
 19946 		 m_send_cipher_suite,
       
 19947 		 eap_tls_trace_string_c::get_cipher_suite_string(m_send_cipher_suite),
       
 19948 		 cipher_suite,
       
 19949 		 eap_tls_trace_string_c::get_cipher_suite_string(cipher_suite)));
       
 19950 
       
 19951 	m_send_cipher_suite = cipher_suite;
       
 19952 
       
 19953 	m_send_record_sequence_number = 0ul;
       
 19954 
       
 19955 
       
 19956 	EAP_TRACE_DATA_DEBUG(
       
 19957 		m_am_tools,
       
 19958 		TRACE_FLAGS_DEFAULT,
       
 19959 		(EAPL("set_send_cipher_suite(): m_send_encryption_key"),
       
 19960 		 m_send_encryption_key.get_data(),
       
 19961 		 m_send_encryption_key.get_data_length()));
       
 19962 
       
 19963 	EAP_TRACE_DATA_DEBUG(
       
 19964 		m_am_tools,
       
 19965 		TRACE_FLAGS_DEFAULT,
       
 19966 		(EAPL("set_send_cipher_suite(): m_new_send_encryption_key"),
       
 19967 		 m_new_send_encryption_key.get_data(),
       
 19968 		 m_new_send_encryption_key.get_data_length()));
       
 19969 
       
 19970 	EAP_TRACE_DATA_DEBUG(
       
 19971 		m_am_tools,
       
 19972 		TRACE_FLAGS_DEFAULT,
       
 19973 		(EAPL("set_send_cipher_suite(): m_send_mac_key"),
       
 19974 		 m_send_mac_key.get_data(),
       
 19975 		 m_send_mac_key.get_data_length()));
       
 19976 
       
 19977 	EAP_TRACE_DATA_DEBUG(
       
 19978 		m_am_tools,
       
 19979 		TRACE_FLAGS_DEFAULT,
       
 19980 		(EAPL("set_send_cipher_suite(): m_new_send_mac_key"),
       
 19981 		 m_new_send_mac_key.get_data(),
       
 19982 		 m_new_send_mac_key.get_data_length()));
       
 19983 
       
 19984 	EAP_TRACE_DATA_DEBUG(
       
 19985 		m_am_tools,
       
 19986 		TRACE_FLAGS_DEFAULT,
       
 19987 		(EAPL("set_send_cipher_suite(): m_send_iv"),
       
 19988 		 m_send_iv.get_data(),
       
 19989 		 m_send_iv.get_data_length()));
       
 19990 
       
 19991 	EAP_TRACE_DATA_DEBUG(
       
 19992 		m_am_tools,
       
 19993 		TRACE_FLAGS_DEFAULT,
       
 19994 		(EAPL("set_send_cipher_suite(): m_new_send_iv"),
       
 19995 		 m_new_send_iv.get_data(),
       
 19996 		 m_new_send_iv.get_data_length()));
       
 19997 
       
 19998 
       
 19999 	eap_status_e status = m_send_mac_key.set_copy_of_buffer(&m_new_send_mac_key);
       
 20000 	if (status != eap_status_ok)
       
 20001 	{
       
 20002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20003 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 20004 	}
       
 20005 
       
 20006 	status = m_send_encryption_key.set_copy_of_buffer(&m_new_send_encryption_key);
       
 20007 	if (status != eap_status_ok)
       
 20008 	{
       
 20009 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20010 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 20011 	}
       
 20012 
       
 20013 	status = m_send_iv.set_copy_of_buffer(&m_new_send_iv);
       
 20014 	if (status != eap_status_ok)
       
 20015 	{
       
 20016 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20017 		return EAP_STATUS_RETURN(m_am_tools, status);
       
 20018 	}
       
 20019 
       
 20020 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20021 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 20022 }
       
 20023 
       
 20024 //--------------------------------------------------
       
 20025 
       
 20026 EAP_FUNC_EXPORT eap_status_e tls_record_c::read_authority_identity(eap_variable_data_c * const authority_identity_payload)
       
 20027 {
       
 20028 	return m_application->read_authority_identity(authority_identity_payload);
       
 20029 }
       
 20030 
       
 20031 //--------------------------------------------------
       
 20032 
       
 20033 #if defined(USE_FAST_EAP_TYPE)
       
 20034 
       
 20035 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_tunnel_PAC(
       
 20036 	const eap_status_e in_completion_status,
       
 20037 	const eap_fast_pac_type_e in_pac_type,
       
 20038 	const eap_fast_variable_data_c * const in_tunnel_PAC_key_tlv,
       
 20039 	const eap_fast_variable_data_c * const in_tunnel_PAC_opaque_tlv)
       
 20040 {
       
 20041 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20042 
       
 20043 	EAP_TRACE_DEBUG(
       
 20044 		m_am_tools,
       
 20045 		TRACE_FLAGS_DEFAULT,
       
 20046 		(EAPL("TLS: this = 0x%08x, %s: message_function: starts: tls_record_c::complete_query_tunnel_PAC(): m_tls_session_type=%d=%s\n"),
       
 20047 		 this,
       
 20048 		 (m_is_client == true ? "client": "server"),
       
 20049 		 m_tls_session_type,
       
 20050 		 eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type)));
       
 20051 
       
 20052 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_record_c::complete_query_tunnel_PAC()");
       
 20053 
       
 20054 	eap_status_e status(eap_status_process_general_error);
       
 20055 
       
 20056 	m_pending_query_tunnel_PAC = false;
       
 20057 
       
 20058 	if (in_completion_status == eap_status_ok)
       
 20059 	{
       
 20060 		tls_extension_c extension(m_am_tools);
       
 20061 		if (extension.get_is_valid() == false)
       
 20062 		{
       
 20063 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20064 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
 20065 		}
       
 20066 
       
 20067 		if (in_tunnel_PAC_opaque_tlv != 0
       
 20068 			&& in_tunnel_PAC_opaque_tlv->get_is_valid_data() == true)
       
 20069 		{
       
 20070 			status = extension.set_copy_of_buffer(in_tunnel_PAC_opaque_tlv->get_full_tlv_buffer());
       
 20071 			if (status != eap_status_ok)
       
 20072 			{
       
 20073 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20074 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 20075 			}
       
 20076 
       
 20077 			extension.set_type(tls_extension_type_session_ticket);
       
 20078 			extension.set_pac_type(in_pac_type);
       
 20079 
       
 20080 			status = m_supported_tls_extensions.add_object(extension.copy(), true);
       
 20081 			if (status != eap_status_ok)
       
 20082 			{
       
 20083 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20084 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 20085 			}
       
 20086 		}
       
 20087 
       
 20088 		if (in_tunnel_PAC_key_tlv != 0
       
 20089 			&& in_tunnel_PAC_key_tlv->get_is_valid_data() == true)
       
 20090 		{
       
 20091 			status = m_eap_fast_pac_key.set_copy_of_buffer(
       
 20092 				in_tunnel_PAC_key_tlv->get_data(in_tunnel_PAC_key_tlv->get_data_length()),
       
 20093 				in_tunnel_PAC_key_tlv->get_data_length());
       
 20094 			if (status != eap_status_ok)
       
 20095 			{
       
 20096 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20097 				return EAP_STATUS_RETURN(m_am_tools, status);
       
 20098 			}
       
 20099 		}
       
 20100 
       
 20101 		set_tls_session_type(tls_session_type_eap_fast_pac_session_resumption);
       
 20102 
       
 20103 		if (m_application != 0)
       
 20104 		{
       
 20105 			m_application->set_tunneled_state(get_tls_session_type());
       
 20106 		}
       
 20107 	}
       
 20108 
       
 20109 	status = check_sent_tls_message();
       
 20110 
       
 20111 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20112 	return EAP_STATUS_RETURN(m_am_tools, eap_status_completed_request);
       
 20113 }
       
 20114 
       
 20115 #endif //#if defined(USE_FAST_EAP_TYPE)
       
 20116 
       
 20117 //--------------------------------------------------
       
 20118 
       
 20119 
       
 20120 EAP_FUNC_EXPORT eap_status_e tls_record_c::query_ttls_pap_username_and_password(
       
 20121 	const eap_variable_data_c * const reply_message)
       
 20122 {
       
 20123 	eap_status_e status(eap_status_process_general_error);
       
 20124 
       
 20125 	status = m_am_tls_services->query_ttls_pap_username_and_password(reply_message);
       
 20126 
       
 20127 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20128 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 20129 }
       
 20130 
       
 20131 
       
 20132 //--------------------------------------------------
       
 20133 
       
 20134 
       
 20135 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_query_ttls_pap_username_and_password(
       
 20136 	const eap_variable_data_c * const ttls_pap_username,
       
 20137 	const eap_variable_data_c * const ttls_pap_password,
       
 20138 	const eap_status_e query_result)
       
 20139 {
       
 20140 	eap_status_e status(eap_status_process_general_error);
       
 20141 
       
 20142 	status = m_application->complete_query_ttls_pap_username_and_password(
       
 20143 		ttls_pap_username,
       
 20144 		ttls_pap_password,
       
 20145 		query_result);
       
 20146 
       
 20147 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20148 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 20149 }
       
 20150 
       
 20151 
       
 20152 //--------------------------------------------------
       
 20153 
       
 20154 
       
 20155 EAP_FUNC_EXPORT eap_status_e tls_record_c::verify_ttls_pap_username_and_password(
       
 20156 	const eap_variable_data_c * const user_name,
       
 20157 	const eap_variable_data_c * const user_password)
       
 20158 {
       
 20159 	eap_status_e status(eap_status_process_general_error);
       
 20160 
       
 20161 	status = m_am_tls_services->verify_ttls_pap_username_and_password(
       
 20162 		user_name,
       
 20163 		user_password);
       
 20164 
       
 20165 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20166 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 20167 }
       
 20168 
       
 20169 
       
 20170 //--------------------------------------------------
       
 20171 
       
 20172 
       
 20173 EAP_FUNC_EXPORT eap_status_e tls_record_c::complete_verify_ttls_pap_username_and_password(
       
 20174 	const eap_status_e authentication_result,
       
 20175 	const eap_variable_data_c * const ttls_pap_reply_message)
       
 20176 {
       
 20177 	eap_status_e status(eap_status_process_general_error);
       
 20178 
       
 20179 	status = m_application->complete_verify_ttls_pap_username_and_password(
       
 20180 		authentication_result,
       
 20181 		ttls_pap_reply_message);
       
 20182 
       
 20183 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
 20184 	return EAP_STATUS_RETURN(m_am_tools, status);
       
 20185 }
       
 20186 
       
 20187 
       
 20188 //--------------------------------------------------
       
 20189 
       
 20190 // End.