eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap_header.cpp
changeset 0 c8830336c852
child 2 1c7bc153c08e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/eapol_common/type/tls_peap/eap/src/eap_type_tls_peap_header.cpp	Thu Dec 17 08:47:43 2009 +0200
@@ -0,0 +1,513 @@
+/*
+* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  EAP and WLAN authentication protocols.
+*
+*/
+
+
+// This is enumeration of EAPOL source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 120 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+
+#include "eap_type_tls_peap_header.h"
+#include "eap_header_string.h"
+
+/** @file */
+
+EAP_FUNC_EXPORT eap_tls_peap_header_c::~eap_tls_peap_header_c()
+{
+}
+
+// 
+EAP_FUNC_EXPORT eap_tls_peap_header_c::eap_tls_peap_header_c(
+	abs_eap_am_tools_c * const tools,
+	u8_t * const header_begin,
+	const u32_t header_buffer_length)
+	: eap_header_base_c(tools, header_begin, header_buffer_length)
+	, m_am_tools(tools)
+{
+}
+
+EAP_FUNC_EXPORT eap_code_value_e eap_tls_peap_header_c::get_eap_code() const
+{
+	return eap_header_base_c::get_code();
+}
+
+EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_eap_identifier() const
+{
+	return eap_header_base_c::get_identifier();
+}
+
+EAP_FUNC_EXPORT u16_t eap_tls_peap_header_c::get_eap_length() const
+{
+	return eap_header_base_c::get_length();
+}
+
+EAP_FUNC_EXPORT eap_type_value_e eap_tls_peap_header_c::get_eap_type() const
+{
+	return eap_header_base_c::get_type();
+}
+
+EAP_FUNC_EXPORT u16_t eap_tls_peap_header_c::get_data_length() const
+{
+	if (get_flag_tls_length_included() == true
+		&& get_eap_length() > static_cast<u16_t>(get_header_length()))
+	{
+		return static_cast<u16_t>(get_eap_length()-static_cast<u16_t>(get_header_length()));
+	}
+	else if (get_flag_tls_length_included() == false
+			 && get_eap_length() > static_cast<u16_t>(get_header_length()))
+	{
+		return static_cast<u16_t>(get_eap_length()-static_cast<u16_t>(get_header_length()));
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_min_header_length() const
+{
+	return eap_header_base_c::get_header_length()
+		+ eap_header_base_c::get_type_field_length()
+		+ m_tls_length_delta_offset;
+}
+
+EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_max_header_length()
+{
+	return eap_header_base_c::get_header_length()
+		+ eap_header_base_c::get_expanded_type_field_length()
+		+ m_tls_length_delta_offset
+		+ TLS_MESSAGE_LENGTH_FIELD_SIZE;
+}
+
+EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_header_length() const
+{
+	u32_t length = get_tls_min_header_length();
+
+	if (get_flag_tls_length_included() == true)
+	{
+		return length+TLS_MESSAGE_LENGTH_FIELD_SIZE;
+	}
+	else
+	{
+		return length;
+	}
+}
+
+EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_start_offset_of_data() const
+{
+	return get_header_length();
+}
+
+EAP_FUNC_EXPORT u8_t * eap_tls_peap_header_c::get_data_offset(
+	abs_eap_am_tools_c * const m_am_tools,
+	const u32_t offset,
+	const u32_t contignuous_bytes) const
+{
+	EAP_UNREFERENCED_PARAMETER(m_am_tools);
+
+	u32_t data_length = get_data_length(); // Here is removed optional TLS message length.
+
+	if (data_length >= offset+contignuous_bytes)
+	{
+		// get_header_length() handles optional TLS message length field.
+		u32_t offset_of_data = get_start_offset_of_data();
+		u8_t * const data = get_header_offset(offset_of_data, offset+contignuous_bytes);
+		if (data != 0)
+		{
+			return data+offset; // Data begins after the header.
+		}
+		else
+		{
+			return 0;
+		}
+	}
+	else
+	{
+		EAP_ASSERT_ALWAYS(get_data_length() > 0u);
+	}
+	return 0;
+}
+
+
+EAP_FUNC_EXPORT u8_t * eap_tls_peap_header_c::get_data(
+	abs_eap_am_tools_c * const m_am_tools,
+	const u32_t contignuous_bytes) const
+{
+	return get_data_offset(m_am_tools, 0u, contignuous_bytes);
+}
+
+EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_flags_offset() const
+{
+	return eap_header_base_c::get_header_length() + eap_header_base_c::get_type_field_length();
+}
+
+EAP_FUNC_EXPORT u32_t eap_tls_peap_header_c::get_tls_length_offset() const
+{
+	return get_tls_flags_offset() + m_tls_length_delta_offset;
+}
+
+EAP_FUNC_EXPORT u8_t * eap_tls_peap_header_c::get_tls_flags() const
+{
+	u32_t flag_offset(get_tls_flags_offset()+m_flag_delta_offset);
+
+	return get_header_offset(flag_offset, sizeof(u8_t));
+}
+
+EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_tls_flag_bit(const u32_t mask) const
+{
+	const u8_t * const flag = get_tls_flags();
+
+	if (flag != 0
+		&& ((*flag) & mask))
+	{
+		return true;
+	}
+	return false;
+}
+
+EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_tls_flag_value(const u32_t mask, const u32_t shift) const
+{
+	const u8_t * const flag = get_tls_flags();
+
+	if (flag != 0)
+	{
+		return static_cast<u8_t>(((*flag) & mask) >> shift);
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_flag_tls_length_included() const
+{
+	return get_tls_flag_bit(m_flag_mask_tls_length_included);
+}
+
+EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_flag_more_fragments() const
+{
+	return get_tls_flag_bit(m_flag_mask_more_fragments);
+}
+
+EAP_FUNC_EXPORT bool eap_tls_peap_header_c::get_flag_start() const
+{
+	return get_tls_flag_bit(m_flag_mask_start);
+}
+	
+EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_flag_reserved() const
+{
+	return get_tls_flag_value(m_flag_mask_reserved, m_flag_shift_reserved);
+}
+
+EAP_FUNC_EXPORT u8_t eap_tls_peap_header_c::get_flag_version() const
+{
+	return get_tls_flag_value(m_flag_mask_version, m_flag_shift_version);
+}
+
+EAP_FUNC_EXPORT eap_status_e eap_tls_peap_header_c::get_tls_message_length(u32_t * const tls_length) const
+{
+	if (get_flag_tls_length_included() == false)
+	{
+		// TLS data length is NOT included.
+		*tls_length = 0u;
+		return eap_status_ok;
+	}
+	
+	u8_t * const data = get_header_offset(get_tls_length_offset(), sizeof(u32_t));
+	if (data != 0)
+	{
+		u32_t tls_message_length =
+			eap_read_u32_t_network_order(data, sizeof(u32_t));
+		
+		*tls_length = tls_message_length;
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+}
+
+
+EAP_FUNC_EXPORT eap_status_e eap_tls_peap_header_c::check_header(
+	abs_eap_am_tools_c * const tools,
+	const eap_type_value_e required_eap_type,
+	const bool is_client_when_true,
+	const peap_version_e peap_version,
+	const bool check_peap_version_when_true) const
+{
+	eap_status_e status = eap_status_ok;
+
+	if (get_eap_type() != required_eap_type)
+	{
+		EAP_UNREFERENCED_PARAMETER(tools);
+		status = EAP_STATUS_RETURN(tools, eap_status_header_corrupted);
+	}
+	else if (get_flag_reserved() != static_cast<u16_t>(0ul))
+	{
+		status = EAP_STATUS_RETURN(tools, eap_status_header_corrupted);
+	}
+	else if ((get_eap_type() == eap_type_tls
+			  || get_eap_type() == eap_type_ttls)
+			 && get_flag_version() != static_cast<u16_t>(0ul))
+	{
+		status = EAP_STATUS_RETURN(tools, eap_status_header_corrupted);
+	}
+	else if (get_eap_type() == eap_type_peap
+			 && check_peap_version_when_true == true
+			 && peap_version == peap_version_0_xp
+			 && get_flag_version() != static_cast<u16_t>(peap_version_0_xp))
+	{
+		// In version negotiation this check will fail.
+		// Do not add error traces here.
+		status = eap_status_no_matching_protocol_version;
+	}
+	else if (get_eap_type() == eap_type_peap
+			 && check_peap_version_when_true == true
+			 && peap_version == peap_version_1
+			 && get_flag_version() != static_cast<u16_t>(peap_version_1))
+	{
+		// In version negotiation this check will fail.
+		// Do not add error traces here.
+		status = eap_status_no_matching_protocol_version;
+	}
+	else if (get_eap_type() == eap_type_peap
+			 && check_peap_version_when_true == true
+			 && peap_version == peap_version_2
+			 && get_flag_version() != static_cast<u16_t>(peap_version_2))
+	{
+		// In version negotiation this check will fail.
+		// Do not add error traces here.
+		status = eap_status_no_matching_protocol_version;
+	}
+	
+	if (status != eap_status_ok)
+	{
+		EAP_UNREFERENCED_PARAMETER(is_client_when_true);
+		
+		// In version negotiation this check will fail.
+		// Do not add error traces here.
+		eap_status_string_c status_string;
+		EAP_UNREFERENCED_PARAMETER(status_string);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
+			(EAPL("WARNING: EAP_type_TLS_PEAP: check_header(): failed, %s, required_eap_type 0x%08x, ")
+			 EAPL("peap_version %d, check_peap_version_when_true %d, get_eap_type() 0x%08x, get_flag_reserved() %d, get_flag_version() %d, status %s\n"),
+			 (is_client_when_true == true) ? "client": "server",
+			 convert_eap_type_to_u32_t(required_eap_type),
+			 peap_version,
+			 check_peap_version_when_true,
+			 convert_eap_type_to_u32_t(get_eap_type()),
+			 get_flag_reserved(),
+			 get_flag_version(),
+			 status_string.get_status_string(status)));
+	}
+	
+	if (status == eap_status_no_matching_protocol_version)
+	{
+		// In version negotiation this check will fail.
+		// Do not add error traces here.
+		return status;
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(tools, status);
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string eap_tls_peap_header_c::get_code_string() const
+{
+	return eap_header_string_c::get_eap_code_string(get_eap_code());
+}
+
+EAP_FUNC_EXPORT eap_const_string eap_tls_peap_header_c::get_eap_type_string() const
+{
+	if (get_eap_length() <= eap_header_base_c::get_header_length())
+	{
+		return EAPL("No EAP-type");
+	}
+
+	return eap_header_string_c::get_eap_type_string(get_eap_type());
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_code(const eap_code_value_e p_code)
+{
+	eap_header_base_c::set_code(p_code);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_identifier(const u8_t p_identifier)
+{
+	eap_header_base_c::set_identifier(p_identifier);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_length(
+	const u16_t p_length,
+	const bool expanded_type_when_true)
+{
+	eap_header_base_c::set_length(
+		p_length,
+		expanded_type_when_true);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_eap_type(
+	const eap_type_value_e p_type,
+	const bool expanded_type_when_true)
+{
+	eap_header_base_c::set_type(p_type, expanded_type_when_true);
+}
+
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_tls_flag_value(const u8_t value, const u32_t mask, const u32_t shift) const
+{
+	u8_t *flag = get_tls_flags();
+
+	if (flag != 0)
+	{
+		(*flag) = static_cast<u8_t>(((*flag) & ~mask) | ((value << shift) & mask));
+	}
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_tls_flag_bit(const bool flag, u32_t mask) const
+{
+	u8_t *p_flag = get_tls_flags();
+	
+	if (p_flag != 0)
+	{
+		if (flag == true)
+		{
+			(*p_flag) = static_cast<u8_t>((*p_flag) | mask);
+		}
+		else
+		{
+			(*p_flag) = static_cast<u8_t>((*p_flag) & ~mask);
+		}
+	}
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_reserved(const u8_t reserved)
+{
+	set_tls_flag_value(reserved, m_flag_mask_reserved, m_flag_shift_reserved);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_version(const u8_t version)
+{
+	set_tls_flag_value(version, m_flag_mask_version, m_flag_shift_version);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_tls_length_included(const bool tls_length_included)
+{
+	set_tls_flag_bit(tls_length_included, m_flag_mask_tls_length_included);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_more_fragments(const bool more_fragments)
+{
+	set_tls_flag_bit(more_fragments, m_flag_mask_more_fragments);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_flag_start(const bool start)
+{
+	set_tls_flag_bit(start, m_flag_mask_start);
+}
+
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_data_length(
+	const u32_t p_data_length,
+	const bool expanded_type_when_true)
+{
+	EAP_ASSERT_ALWAYS(p_data_length+get_header_length() <= 0xffff);
+	
+	set_eap_length(
+		static_cast<u16_t>(p_data_length+get_header_length()),
+		expanded_type_when_true);
+}
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::set_tls_message_length(const u32_t tls_length)
+{
+	EAP_ASSERT_ALWAYS(get_flag_tls_length_included() == true);
+
+	u8_t * const data = get_header_offset(get_tls_length_offset(), sizeof(u32_t));
+
+	EAP_ASSERT(data != 0);
+
+	data[0] = static_cast<u8_t>((tls_length & 0xff000000) >> 24);
+	data[1] = static_cast<u8_t>((tls_length & 0x00ff0000) >> 16);
+	data[2] = static_cast<u8_t>((tls_length & 0x0000ff00) >> 8);
+	data[3] = static_cast<u8_t>((tls_length & 0x000000ff) >> 0);
+}
+
+
+EAP_FUNC_EXPORT void eap_tls_peap_header_c::reset_header(
+	abs_eap_am_tools_c * const m_am_tools,
+	const eap_type_value_e required_eap_type,
+	const u32_t buffer_length,
+	const peap_version_e peap_version,
+	const bool expanded_type_when_true)
+{
+	EAP_UNREFERENCED_PARAMETER(m_am_tools);
+
+	eap_header_base_c::set_length(
+		static_cast<u16_t>(buffer_length),
+		expanded_type_when_true);
+
+	set_eap_code(eap_code_none);
+	set_eap_identifier(0u);
+	set_eap_type(
+		required_eap_type,
+		expanded_type_when_true);
+
+	set_flag_tls_length_included(false);
+	set_flag_more_fragments(false);
+	set_flag_start(false);
+	
+	set_flag_reserved(0u);
+		
+#if defined(USE_FAST_EAP_TYPE)
+	if (required_eap_type == eap_type_fast)
+	{
+		set_flag_version(static_cast<u8_t>(peap_version));
+	}
+	else
+#endif //#if defined(USE_FAST_EAP_TYPE)
+	if (required_eap_type == eap_type_peap)
+	{
+		if (peap_version >= peap_version_0_xp
+			&& peap_version <= peap_version_2)
+		{
+			set_flag_version(static_cast<u8_t>(peap_version));
+		}
+		else
+		{
+			EAP_ASSERT_ALWAYS((peap_version >= peap_version_0_xp) && (peap_version <= peap_version_2));
+		}
+	}
+	else
+	{
+		// All other EAP-methods.
+		set_flag_version(0u);
+	}
+}
+
+
+
+
+// End.