eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_message.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 131 
       
    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_tools.h"
       
    31 #include "eap_array.h"
       
    32 #include "tls_message.h"
       
    33 #include "tls_peap_types.h"
       
    34 #include "eap_automatic_variable.h"
       
    35 
       
    36 /** @file */
       
    37 
       
    38 
       
    39 //--------------------------------------------------
       
    40 
       
    41 EAP_FUNC_EXPORT tls_message_c::~tls_message_c()
       
    42 {
       
    43 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    44 
       
    45 	m_record_messages.reset();
       
    46 
       
    47 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    48 }
       
    49 
       
    50 //--------------------------------------------------
       
    51 
       
    52 EAP_FUNC_EXPORT tls_message_c::tls_message_c(
       
    53 	abs_eap_am_tools_c * const tools,
       
    54 	abs_tls_message_hash_c * const message_hash,
       
    55 	abs_tls_apply_cipher_spec_c * const apply_cipher_spec,
       
    56 	abs_tls_change_cipher_spec_c * change_cipher_spec,
       
    57 	const bool is_client)
       
    58 : m_am_tools(tools)
       
    59 , m_message_hash(message_hash)
       
    60 , m_apply_cipher_spec(apply_cipher_spec)
       
    61 , m_change_cipher_spec(change_cipher_spec)
       
    62 , m_tls_message_data(tools)
       
    63 , m_received_eap_identifier(0ul)
       
    64 , m_analyse_index(0ul)
       
    65 , m_record_messages(tools)
       
    66 , m_is_client(is_client)
       
    67 , m_includes_tls_handshake_message(false)
       
    68 {
       
    69 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    70 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    71 }
       
    72 
       
    73 //--------------------------------------------------
       
    74 
       
    75 EAP_FUNC_EXPORT eap_status_e tls_message_c::reset()
       
    76 {
       
    77 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    78 
       
    79 	m_analyse_index = 0ul;
       
    80 	m_received_eap_identifier = 0ul;
       
    81 	m_includes_tls_handshake_message = false;
       
    82 
       
    83 	eap_status_e status = m_record_messages.reset();
       
    84 
       
    85 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    86 	return EAP_STATUS_RETURN(m_am_tools, status);
       
    87 }
       
    88 
       
    89 //--------------------------------------------------
       
    90 
       
    91 EAP_FUNC_EXPORT u32_t tls_message_c::get_analyse_index() const
       
    92 {
       
    93 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    94 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    95 	return m_analyse_index;
       
    96 }
       
    97 
       
    98 //--------------------------------------------------
       
    99 
       
   100 EAP_FUNC_EXPORT void tls_message_c::save_analyse_index(const u32_t analyse_index)
       
   101 {
       
   102 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   103 
       
   104 	m_analyse_index = analyse_index;
       
   105 
       
   106 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   107 }
       
   108 
       
   109 //--------------------------------------------------
       
   110 
       
   111 EAP_FUNC_EXPORT eap_status_e tls_message_c::set_tls_message_data(
       
   112 	eap_variable_data_c * const tls_message_data,
       
   113 	u8_t received_eap_identifier)
       
   114 {
       
   115 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   116 
       
   117 	eap_status_e status = m_tls_message_data.set_copy_of_buffer(tls_message_data);
       
   118 	if (status != eap_status_ok)
       
   119 	{
       
   120 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   121 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   122 	}
       
   123 
       
   124 	m_received_eap_identifier = received_eap_identifier;
       
   125 
       
   126 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   127 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   128 }
       
   129 
       
   130 //--------------------------------------------------
       
   131 
       
   132 EAP_FUNC_EXPORT eap_variable_data_c * tls_message_c::get_tls_message_data()
       
   133 {
       
   134 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   135 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   136 	return &m_tls_message_data;
       
   137 }
       
   138 
       
   139 //--------------------------------------------------
       
   140 
       
   141 EAP_FUNC_EXPORT u8_t tls_message_c::get_received_eap_identifier()
       
   142 {
       
   143 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   144 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   145 	return m_received_eap_identifier;
       
   146 }
       
   147 
       
   148 //--------------------------------------------------
       
   149 
       
   150 EAP_FUNC_EXPORT eap_status_e tls_message_c::add_record_message(
       
   151 	tls_record_message_c * const record,
       
   152 	const bool free_record,
       
   153 	const bool includes_tls_handshake_message)
       
   154 {
       
   155 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   156 
       
   157 	if (m_includes_tls_handshake_message == false)
       
   158 	{
       
   159 		m_includes_tls_handshake_message = includes_tls_handshake_message;
       
   160 	}
       
   161 
       
   162 	eap_status_e status = m_record_messages.add_object(record, free_record);
       
   163 
       
   164 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   165 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   166 }
       
   167 
       
   168 //--------------------------------------------------
       
   169 
       
   170 EAP_FUNC_EXPORT eap_status_e tls_message_c::fragment_tls_records(
       
   171 	tls_record_message_c * const tls_record_message,
       
   172 	eap_array_c<tls_record_message_c> * const tls_fragments)
       
   173 {
       
   174 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   175 
       
   176 	eap_status_e status = eap_status_ok;
       
   177 
       
   178 	// Here we assume data included in tls_record_message does not include TLS-record header.
       
   179 	// Only data TLS-protocol messages are included. All TLS-protocol messages are same protocol.
       
   180 	// This function fragments TLS-protocol messages to one or more TLS-record messages.
       
   181 
       
   182 	u32_t size_of_data = tls_record_message->get_data_length();
       
   183 	u32_t offset_of_data = 0ul;
       
   184 
       
   185 	while(size_of_data > 0ul)
       
   186 	{
       
   187 		tls_record_message_c * const fragment = new tls_record_message_c(
       
   188 			m_am_tools, m_message_hash, m_is_client);
       
   189 
       
   190 		eap_automatic_variable_c<tls_record_message_c>
       
   191 			automatic_fragment(m_am_tools, fragment);
       
   192 
       
   193 		if (fragment == 0
       
   194 			|| fragment->get_is_valid() == false)
       
   195 		{
       
   196 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   197 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   198 		}
       
   199 
       
   200 		u32_t fragment_length = size_of_data;
       
   201 		if (fragment_length > TLS_PEAP_MAX_RECORD_FRAGMENT_LENGTH)
       
   202 		{
       
   203 			fragment_length = TLS_PEAP_MAX_RECORD_FRAGMENT_LENGTH;
       
   204 		}
       
   205 
       
   206 
       
   207 		// Adds TLS-record header.
       
   208 		status = fragment->get_record_message_data()->set_buffer_length(tls_record_header_c::get_header_length()+fragment_length);
       
   209 		if (status != eap_status_ok)
       
   210 		{
       
   211 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   212 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   213 		}
       
   214 
       
   215 		tls_record_header_c tmp_tls_record_header_on_tls_message_buffer(
       
   216 			m_am_tools,
       
   217 			fragment->get_record_message_data()->get_buffer(tls_record_header_c::get_header_length()+fragment_length),
       
   218 			tls_record_header_c::get_header_length()+fragment_length);
       
   219 
       
   220 		if (tmp_tls_record_header_on_tls_message_buffer.get_is_valid() == false)
       
   221 		{
       
   222 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   223 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message);
       
   224 		}
       
   225 
       
   226 		// Note this is the length of the TLS-record header.
       
   227 		fragment->get_record_message_data()->set_data_length(tls_record_header_c::get_header_length());
       
   228 		fragment->set_protocol(tls_record_message->get_protocol());
       
   229 		fragment->set_version(tls_record_message->get_version());
       
   230 		// Note this is the length of the TLS-record header and TLS-record data.
       
   231 		// The length of the TLS-record data is the length of the fragment.
       
   232 		fragment->add_data_length(tls_record_header_c::get_header_length()+fragment_length);
       
   233 		fragment->set_tls_record_header_is_included(true);
       
   234 
       
   235 		tmp_tls_record_header_on_tls_message_buffer.reset_header(0ul, tls_record_message->get_version());
       
   236 		tmp_tls_record_header_on_tls_message_buffer.set_protocol(tls_record_message->get_protocol());
       
   237 		tmp_tls_record_header_on_tls_message_buffer.set_data_length(static_cast<u16_t>(fragment_length));
       
   238 
       
   239 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
   240 		EAP_TRACE_DEBUG(
       
   241 			m_am_tools, 
       
   242 			TRACE_FLAGS_DEFAULT, 
       
   243 			(EAPL("TLS: %s: tls_message_c::fragment_tls_records(): %s fragment %d bytes from %d bytes.\n"),
       
   244 			(m_is_client == true ? "client": "server"),
       
   245 			tmp_tls_record_header_on_tls_message_buffer.get_tls_protocol_string(),
       
   246 			 fragment_length,
       
   247 			 tls_record_message->get_data_length()));
       
   248 
       
   249 		// Adds TLS-record data, this includes TLS-protocol messages.
       
   250 		status = fragment->get_record_message_data()->add_data(
       
   251 			tls_record_message->get_record_message_data()->get_data_offset(
       
   252 				offset_of_data, fragment_length),
       
   253 			fragment_length);
       
   254 		if (status != eap_status_ok)
       
   255 		{
       
   256 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   257 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   258 		}
       
   259 
       
   260 		size_of_data -= fragment_length;
       
   261 		offset_of_data += fragment_length;
       
   262 
       
   263 		automatic_fragment.do_not_free_variable();
       
   264 
       
   265 		status = tls_fragments->add_object(fragment, true);
       
   266 		if (status != eap_status_ok)
       
   267 		{
       
   268 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   269 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   270 		}
       
   271 
       
   272 	} // while()
       
   273 
       
   274 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   275 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   276 }
       
   277 
       
   278 //--------------------------------------------------
       
   279 
       
   280 EAP_FUNC_EXPORT eap_status_e tls_message_c::add_message_data(
       
   281 	eap_variable_data_c * const tls_message_buffer,
       
   282 	bool * const includes_tls_handshake_message)
       
   283 {
       
   284 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   285 
       
   286 	eap_status_e status = eap_status_ok;
       
   287 
       
   288 	tls_message_buffer->reset();
       
   289 	status = tls_message_buffer->set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH);
       
   290 	if (status != eap_status_ok)
       
   291 	{
       
   292 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   293 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   294 	}
       
   295 
       
   296 	for (u32_t ind = 0ul; ind < m_record_messages.get_object_count(); ind++)
       
   297 	{
       
   298 		tls_record_message_c * const tls_record_message = m_record_messages.get_object(ind);
       
   299 		if (tls_record_message == 0)
       
   300 		{
       
   301 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   302 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   303 		}
       
   304 
       
   305 		if (tls_record_message->get_record_message_data()->get_is_valid() == false
       
   306 			|| tls_record_message->get_record_message_data()->get_buffer_length() < TLS_PEAP_DEFAULT_RECORD_LENGTH)
       
   307 		{
       
   308 			status = tls_record_message->get_record_message_data()->set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH);
       
   309 			if (status != eap_status_ok)
       
   310 			{
       
   311 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   312 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   313 			}
       
   314 		}
       
   315 
       
   316 		tls_record_message->get_record_message_data()->set_data_length(0ul);
       
   317 
       
   318 		// This function creates data of TLS-protocol message to internal buffer (tls_record_message->get_record_message_data()).
       
   319 		status = tls_record_message->add_message_data();
       
   320 		if (status != eap_status_ok)
       
   321 		{
       
   322 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   323 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   324 		}
       
   325 
       
   326 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   327 
       
   328 		EAP_ASSERT(tls_record_message->get_tls_record_header_is_included() == false);
       
   329 
       
   330 		EAP_TRACE_DATA_DEBUG(
       
   331 			m_am_tools,
       
   332 			EAP_TRACE_FLAGS_MESSAGE_DATA,
       
   333 			(EAPL("TLS-record data"),
       
   334 			tls_record_message->get_record_message_data()->get_data(
       
   335 				tls_record_message->get_record_message_data()->get_data_length()),
       
   336 			tls_record_message->get_record_message_data()->get_data_length()));
       
   337 
       
   338 		// Fragmentation checks the TLS-record is not too long, data more than 2^14 bytes.
       
   339 		// It fragments TLS-record to two or more TLS-records.
       
   340 		// TLS-records could be stored to object of type of eap_array_c<tls_record_message_c>.
       
   341 		// In a case the TLS-record cannot be fragmented the whole TLS-message must be dropped.
       
   342 		eap_array_c<tls_record_message_c> tls_fragments(m_am_tools);
       
   343 		status = fragment_tls_records(
       
   344 				tls_record_message,
       
   345 				&tls_fragments);
       
   346 		if (status != eap_status_ok)
       
   347 		{
       
   348 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   349 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   350 		}
       
   351 
       
   352 		// After the fragmentation cipher suite can be applied to every fragment.
       
   353 		for (u32_t ind_frag = 0ul; ind_frag < tls_fragments.get_object_count(); ind_frag++)
       
   354 		{
       
   355 			tls_record_message_c * const fragment = tls_fragments.get_object(ind_frag);
       
   356 			if (fragment == 0)
       
   357 			{
       
   358 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   359 				return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
   360 			}
       
   361 
       
   362 			EAP_ASSERT(fragment->get_data_length() == fragment->get_record_message_data()->get_data_length());
       
   363 
       
   364 			status = m_apply_cipher_spec->apply_send_cipher_suite(fragment->get_record_message_data());
       
   365 			if (status != eap_status_ok)
       
   366 			{
       
   367 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   368 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   369 			}
       
   370 
       
   371 			if (ind_frag == 0ul)
       
   372 			{
       
   373 				if (fragment->get_protocol() == tls_record_protocol_change_cipher_spec)
       
   374 				{
       
   375 					// This is the right place to change the send cipher spec.
       
   376 					status = m_change_cipher_spec->change_cipher_spec(true);
       
   377 					if (status != eap_status_ok)
       
   378 					{
       
   379 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   380 						return EAP_STATUS_RETURN(m_am_tools, status);
       
   381 					}
       
   382 				}
       
   383 			}
       
   384 
       
   385 			status = tls_message_buffer->add_data(fragment->get_record_message_data());
       
   386 			if (status != eap_status_ok)
       
   387 			{
       
   388 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   389 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   390 			}
       
   391 		} // for()
       
   392 
       
   393 	} // for()
       
   394 
       
   395 	*includes_tls_handshake_message = m_includes_tls_handshake_message;
       
   396 
       
   397 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   398 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   399 }
       
   400 
       
   401 //--------------------------------------------------
       
   402 
       
   403 EAP_FUNC_EXPORT u32_t tls_message_c::get_record_message_count() const
       
   404 {
       
   405 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   406 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   407 	return m_record_messages.get_object_count();
       
   408 }
       
   409 
       
   410 //--------------------------------------------------
       
   411 
       
   412 EAP_FUNC_EXPORT tls_record_message_c * tls_message_c::get_record_message(
       
   413 	const u32_t index) const
       
   414 {
       
   415 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   416 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   417 	return m_record_messages.get_object(index);
       
   418 }
       
   419 
       
   420 //--------------------------------------------------
       
   421 
       
   422 EAP_FUNC_EXPORT eap_status_e tls_message_c::remove_record_message(
       
   423 	const u32_t index)
       
   424 {
       
   425 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   426 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   427 	return m_record_messages.remove_object(index);
       
   428 }
       
   429 
       
   430 //--------------------------------------------------
       
   431 
       
   432 EAP_FUNC_EXPORT tls_record_message_c * tls_message_c::get_last_record_message() const
       
   433 {
       
   434 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   435 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   436 	return m_record_messages.get_last_object();
       
   437 }
       
   438 
       
   439 //--------------------------------------------------
       
   440 
       
   441 
       
   442 
       
   443 // End.