--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_handshake_message.cpp Thu Dec 17 08:47:43 2009 +0200
@@ -0,0 +1,1611 @@
+/*
+* 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 130
+ #undef EAP_FILE_NUMBER_DATE
+ #define EAP_FILE_NUMBER_DATE 1127594498
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+
+#include "eap_tools.h"
+#include "eap_array.h"
+#include "eap_array_algorithms.h"
+#include "tls_handshake_message.h"
+#include "tls_record_header.h"
+#include "eap_crypto_api.h"
+#include "eap_automatic_variable.h"
+
+/** @file */
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT tls_handshake_message_c::~tls_handshake_message_c()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT tls_handshake_message_c::tls_handshake_message_c(
+ abs_eap_am_tools_c * const tools,
+ abs_tls_message_hash_c * const message_hash,
+ const bool is_client)
+: m_am_tools(tools)
+, m_message_hash(message_hash)
+, m_tls_handshake_message_buffer(tools)
+, m_unix_time(tools)
+, m_random_value(tools)
+, m_session_id(tools)
+, m_cipher_suites(tools)
+, m_compression_methods(tools)
+#if defined(USE_EAP_TLS_SESSION_TICKET)
+, m_tls_extensions(tools)
+#endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
+, m_certificate_chain(tools)
+, m_certificate_authorities(tools)
+, m_certificate_types(tools)
+, m_encrypted_premaster_secret(tools)
+, m_public_dhe_key(tools)
+, m_dhe_prime(tools)
+, m_dhe_group_generator(tools)
+, m_signed_message_hash(tools)
+, m_finished_data(tools)
+, m_selected_cipher_suite(tls_cipher_suites_none)
+, m_selected_compression_method(tls_compression_method_none)
+, m_handshake_type(tls_handshake_type_none)
+, m_is_analysed(false)
+, m_is_valid(false)
+, m_is_client(is_client)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ set_is_valid();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void tls_handshake_message_c::set_is_valid()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_is_valid = true;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool tls_handshake_message_c::get_is_valid()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void tls_handshake_message_c::set_is_analysed()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_is_analysed = true;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool tls_handshake_message_c::get_is_analysed()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_is_analysed;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_handshake_type(tls_handshake_type_e type)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_handshake_type = type;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_handshake_header_copy(
+ const tls_handshake_header_c * const tls_handshake_header)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_handshake_type = tls_handshake_header->get_handshake_type();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT tls_handshake_type_e tls_handshake_message_c::get_handshake_type() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_handshake_type;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_cipher_suites(
+ EAP_TEMPLATE_CONST eap_array_c<u16_t> * const cipher_suites)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_cipher_suites.reset();
+
+ eap_status_e status = copy_simple<u16_t>(
+ cipher_suites,
+ &m_cipher_suites,
+ m_am_tools,
+ false);
+
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c<u16_t> * tls_handshake_message_c::get_cipher_suites() EAP_TEMPLATE_CONST
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_cipher_suites;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_compression_methods(
+ EAP_TEMPLATE_CONST eap_array_c<u8_t> * const compression_methods)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = copy_simple<u8_t>(
+ compression_methods,
+ &m_compression_methods,
+ m_am_tools,
+ false);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c<u8_t> * tls_handshake_message_c::get_compression_methods() EAP_TEMPLATE_CONST
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_compression_methods;
+}
+
+//--------------------------------------------------
+
+#if defined(USE_EAP_TLS_SESSION_TICKET)
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_tls_extensions(
+ EAP_TEMPLATE_CONST eap_array_c<tls_extension_c> * const tls_extensionss)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = copy<tls_extension_c>(
+ tls_extensionss,
+ &m_tls_extensions,
+ m_am_tools,
+ false);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
+
+//--------------------------------------------------
+
+#if defined(USE_EAP_TLS_SESSION_TICKET)
+
+EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c<tls_extension_c> * tls_handshake_message_c::get_tls_extensions() EAP_TEMPLATE_CONST
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_tls_extensions;
+}
+
+#endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_random_value(
+ const eap_variable_data_c * const random_value)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_random_value.set_copy_of_buffer(random_value);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_random_value() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_random_value;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_session_id(
+ const eap_variable_data_c * const session_id)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_session_id.set_copy_of_buffer(session_id);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_session_id() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_session_id;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_certificate_chain(
+ EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_chain)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = copy<eap_variable_data_c>(
+ certificate_chain,
+ &m_certificate_chain,
+ m_am_tools,
+ false);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * tls_handshake_message_c::get_certificate_chain() EAP_TEMPLATE_CONST
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_certificate_chain;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_certificate_authorities(
+ EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const certificate_authorities)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = copy<eap_variable_data_c>(
+ certificate_authorities,
+ &m_certificate_authorities,
+ m_am_tools,
+ false);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * tls_handshake_message_c::get_certificate_authorities() EAP_TEMPLATE_CONST
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_certificate_authorities;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_certificate_types(
+ EAP_TEMPLATE_CONST eap_array_c<u8_t> * const certificate_types)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = copy_simple<u8_t>(
+ certificate_types,
+ &m_certificate_types,
+ m_am_tools,
+ false);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT EAP_TEMPLATE_CONST eap_array_c<u8_t> * tls_handshake_message_c::get_certificate_types() EAP_TEMPLATE_CONST
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_certificate_types;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_selected_cipher_suite(const tls_cipher_suites_e selected_cipher_suite)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_selected_cipher_suite = selected_cipher_suite;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+EAP_FUNC_EXPORT tls_cipher_suites_e tls_handshake_message_c::get_selected_cipher_suite() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_selected_cipher_suite;
+}
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_selected_compression_method(const tls_compression_method_e selected_compression_method)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_selected_compression_method = selected_compression_method;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+EAP_FUNC_EXPORT tls_compression_method_e tls_handshake_message_c::get_selected_compression_method() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_selected_compression_method;
+}
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_public_dhe_key(const eap_variable_data_c * const public_dhe_key)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_public_dhe_key.set_copy_of_buffer(public_dhe_key);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_public_dhe_key() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_public_dhe_key;
+}
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_encrypted_premaster_secret(const eap_variable_data_c * const encrypted_premaster_secret)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_encrypted_premaster_secret.set_copy_of_buffer(encrypted_premaster_secret);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_encrypted_premaster_secret() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_encrypted_premaster_secret;
+}
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_dhe_prime(const eap_variable_data_c * const dhe_prime)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_dhe_prime.set_copy_of_buffer(dhe_prime);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_dhe_prime() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_dhe_prime;
+}
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_dhe_group_generator(const eap_variable_data_c * const dhe_group_generator)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_dhe_group_generator.set_copy_of_buffer(dhe_group_generator);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_dhe_group_generator() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_dhe_group_generator;
+}
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_signed_message_hash(const eap_variable_data_c * const signed_message_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_signed_message_hash.set_copy_of_buffer(signed_message_hash);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_signed_message_hash() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_signed_message_hash;
+}
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::set_finished_data(const eap_variable_data_c * const finished_data)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = m_finished_data.set_copy_of_buffer(finished_data);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+EAP_FUNC_EXPORT const eap_variable_data_c * tls_handshake_message_c::get_finished_data() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return &m_finished_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::u16_t_to_network_order(
+ u16_t * const value,
+ abs_eap_am_tools_c * const m_am_tools)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_UNREFERENCED_PARAMETER(m_am_tools);
+
+ *value = eap_htons(*value);
+
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::create_message_data()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status = eap_status_ok;
+
+ m_tls_handshake_message_buffer.reset();
+ status = m_tls_handshake_message_buffer.set_buffer_length(TLS_PEAP_DEFAULT_RECORD_LENGTH);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ const u32_t offset_of_tmp_tls_handshake_header = m_tls_handshake_message_buffer.get_data_length();
+
+ m_tls_handshake_message_buffer.set_data_length(
+ m_tls_handshake_message_buffer.get_data_length() + tls_handshake_header_c::get_header_length());
+
+ tls_handshake_header_c tmp_tls_handshake_header_on_tls_message_buffer(
+ m_am_tools,
+ m_tls_handshake_message_buffer.get_data_offset(
+ offset_of_tmp_tls_handshake_header, tls_handshake_header_c::get_header_length()),
+ tls_handshake_header_c::get_header_length());
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message);
+ }
+
+ tmp_tls_handshake_header_on_tls_message_buffer.reset_header(0ul);
+ tmp_tls_handshake_header_on_tls_message_buffer.set_handshake_type(get_handshake_type());
+
+ EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS: %s: data_function: tls_handshake_message_c::create_message_data(): %s\n"),
+ (m_is_client == true ? "client": "server"),
+ tmp_tls_handshake_header_on_tls_message_buffer.get_tls_handshake_string()));
+
+ EAP_TRACE_DATA_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS-handshake tls_handshake_header"),
+ tmp_tls_handshake_header_on_tls_message_buffer.get_header_buffer(
+ tls_handshake_header_c::get_header_length()),
+ tls_handshake_header_c::get_header_length()));
+
+ const u32_t handshake_data_length_start = m_tls_handshake_message_buffer.get_data_length();
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello
+ || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello)
+ {
+ u16_t version = eap_htons(tls_version_3_1);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &version,
+ sizeof(version));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake version"),
+ &version,
+ sizeof(version)));
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello
+ || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello)
+ {
+ if (m_random_value.get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+ }
+ else
+ {
+ status = m_tls_handshake_message_buffer.add_data(
+ m_random_value.get_data(m_random_value.get_data_length()),
+ m_random_value.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake random"),
+ m_random_value.get_data(m_random_value.get_data_length()),
+ m_random_value.get_data_length()));
+ }
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello
+ || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello)
+ {
+ u8_t session_id_length = 0ul;
+
+ if (m_session_id.get_is_valid_data() == true
+ && m_session_id.get_data_length() > 0ul)
+ {
+ session_id_length = static_cast<u8_t>(m_session_id.get_data_length());
+ }
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &session_id_length,
+ sizeof(session_id_length));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake session_id_length"),
+ &session_id_length,
+ sizeof(session_id_length)));
+
+ if (m_session_id.get_is_valid_data() == true
+ && m_session_id.get_data_length() > 0ul)
+ {
+ status = m_tls_handshake_message_buffer.add_data(
+ m_session_id.get_data(m_session_id.get_data_length()),
+ m_session_id.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake session_id"),
+ m_session_id.get_data(m_session_id.get_data_length()),
+ m_session_id.get_data_length()));
+ }
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello)
+ {
+ u16_t data_size = static_cast<u16_t>(m_cipher_suites.get_object_count() * sizeof(u16_t));
+ u16_t data_size_network_order = eap_htons(data_size);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &data_size_network_order,
+ sizeof(data_size_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake cipher_suite_length"),
+ &data_size_network_order,
+ sizeof(data_size_network_order)));
+
+ if (m_cipher_suites.get_object_count() > 0ul)
+ {
+ // Copy cipher suites and change them to network order.
+ eap_array_c<u16_t> * const tmp_cipher_suites = new eap_array_c<u16_t>(m_am_tools);
+
+ eap_automatic_variable_c<eap_array_c<u16_t> > automatic_tmp_cipher_suites(m_am_tools, tmp_cipher_suites);
+
+ if (tmp_cipher_suites == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ status = copy_simple<u16_t>(
+ &m_cipher_suites,
+ tmp_cipher_suites,
+ m_am_tools,
+ false);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ status = for_each<u16_t>(tmp_cipher_suites, u16_t_to_network_order, m_am_tools, false);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ status = add_simple_data(tmp_cipher_suites, &m_tls_handshake_message_buffer, m_am_tools);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello)
+ {
+ u16_t selected_cipher_suite_network_order = eap_htons(static_cast<u8_t>(m_selected_cipher_suite));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &selected_cipher_suite_network_order,
+ sizeof(selected_cipher_suite_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake selected_cipher_suite"),
+ &selected_cipher_suite_network_order,
+ sizeof(selected_cipher_suite_network_order)));
+
+ u8_t selected_compression_method_network_order = static_cast<u8_t>(m_selected_compression_method);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &selected_compression_method_network_order,
+ sizeof(selected_compression_method_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake selected_compression_method"),
+ &selected_compression_method_network_order,
+ sizeof(selected_compression_method_network_order)));
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello)
+ {
+ u8_t data_size = static_cast<u8_t>(m_compression_methods.get_object_count() * sizeof(u8_t));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &data_size,
+ sizeof(data_size));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS-handshake compression_methods length"),
+ &data_size,
+ sizeof(data_size)));
+
+ if (m_compression_methods.get_object_count() > 0ul)
+ {
+ status = add_simple_data(&m_compression_methods, &m_tls_handshake_message_buffer, m_am_tools);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+ }
+
+
+#if defined(USE_EAP_TLS_SESSION_TICKET)
+
+ if (m_tls_extensions.get_object_count() > 0
+ && (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_hello
+ || tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello))
+ {
+ u32_t data_size(0ul);
+ u32_t ind(0ul);
+
+ for (ind = 0ul; ind < m_tls_extensions.get_object_count(); ++ind)
+ {
+ const tls_extension_c * const extension = m_tls_extensions.get_object(ind);
+ if (extension == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ // Session ticket is always empty in ServerHello message.
+ const bool add_extension_data =
+ ((extension->get_type() == tls_extension_type_session_ticket
+ && tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello))
+ == false;
+
+ // Extension list is formatted as:
+ // 0 1 2 3
+ // 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
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | extension list length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | extension 1 type | extension 1 data length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | extension 1 data ...
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | extension 2 type | extension 2 data length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | extension 2 data ...
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ data_size += 2 * sizeof(u16_t);
+
+ if (add_extension_data == true)
+ {
+ data_size += extension->get_data_length();
+ }
+
+ } // for()
+
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS-handshake extensions list length = %d\n"),
+ data_size));
+
+ if (data_size > 0x0000ffff)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ u8_t data_size_array[2];
+ data_size_array[0] = static_cast<u8_t>((data_size & 0x0000ff00) >> 8);
+ data_size_array[1] = static_cast<u8_t>(data_size & 0x000000ff);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &data_size_array,
+ sizeof(data_size_array));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ for (ind = 0ul; ind < m_tls_extensions.get_object_count(); ++ind)
+ {
+ const tls_extension_c * const extension = m_tls_extensions.get_object(ind);
+ if (extension == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ // Session ticket is always empty in ServerHello message.
+ const bool add_extension_data =
+ ((extension->get_type() == tls_extension_type_session_ticket
+ && tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_hello))
+ == false;
+
+ tls_extension_type_e type = extension->get_type();
+ u16_t network_order_type(eap_htons(type));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &network_order_type,
+ sizeof(network_order_type));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+
+ if (add_extension_data == true)
+ {
+ data_size = extension->get_data_length();
+ }
+ else
+ {
+ data_size = 0ul;
+ }
+
+ data_size_array[0] = static_cast<u8_t>((data_size & 0x0000ff00) >> 8);
+ data_size_array[1] = static_cast<u8_t>(data_size & 0x000000ff);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &data_size_array,
+ sizeof(data_size_array));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS-handshake extension type = %s, length = %d\n"),
+ extension->get_type_string(extension->get_type()),
+ data_size));
+
+ if (add_extension_data == true)
+ {
+ EAP_TRACE_DATA_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS-handshake extension data"),
+ extension->get_data(),
+ extension->get_data_length()));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ extension);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+ } // for()
+ }
+
+#endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
+
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate)
+ {
+ u32_t data_size = 0ul;
+ u32_t ind = 0ul;
+
+ for (ind = 0ul; ind < m_certificate_chain.get_object_count(); ind++)
+ {
+ const eap_variable_data_c * const certificate = m_certificate_chain.get_object(ind);
+ if (certificate == 0
+ || certificate->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ // Data size includes certificate length field and certificate data.
+ data_size += (3ul + certificate->get_data_length());
+ }
+
+ if (data_size > 0x00ffffff)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ u8_t data_size_array[3];
+ data_size_array[0] = static_cast<u8_t>((data_size & 0x00ff0000) >> 16);
+ data_size_array[1] = static_cast<u8_t>((data_size & 0x0000ff00) >> 8);
+ data_size_array[2] = static_cast<u8_t>(data_size & 0x000000ff);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ data_size_array,
+ sizeof(data_size_array));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_chain length"),
+ data_size_array,
+ sizeof(data_size_array)));
+
+
+ for (ind = 0ul; ind < m_certificate_chain.get_object_count(); ind++)
+ {
+ const eap_variable_data_c * const certificate = m_certificate_chain.get_object(ind);
+ if (certificate == 0
+ || certificate->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ data_size = certificate->get_data_length();
+ u8_t data_size_array[3];
+ data_size_array[0] = static_cast<u8_t>((data_size & 0x00ff0000) >> 16);
+ data_size_array[1] = static_cast<u8_t>((data_size & 0x0000ff00) >> 8);
+ data_size_array[2] = static_cast<u8_t>(data_size & 0x000000ff);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ data_size_array,
+ sizeof(data_size_array));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate length"),
+ data_size_array,
+ sizeof(data_size_array)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ certificate->get_data(certificate->get_data_length()),
+ certificate->get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate"),
+ certificate->get_data(certificate->get_data_length()),
+ certificate->get_data_length()));
+ }
+ }
+
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_server_key_exchange)
+ {
+ if (m_dhe_prime.get_is_valid_data() == true)
+ {
+ u16_t dhe_prime_length_network_order = eap_htons(static_cast<u16_t>(m_dhe_prime.get_data_length()));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &dhe_prime_length_network_order,
+ sizeof(dhe_prime_length_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_prime_length"),
+ &dhe_prime_length_network_order,
+ sizeof(dhe_prime_length_network_order)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ m_dhe_prime.get_data(m_dhe_prime.get_data_length()),
+ m_dhe_prime.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_prime"),
+ m_dhe_prime.get_data(m_dhe_prime.get_data_length()),
+ m_dhe_prime.get_data_length()));
+ }
+ else if (m_dhe_group_generator.get_is_valid_data() == true
+ || m_public_dhe_key.get_is_valid_data() == true
+ || m_signed_message_hash.get_is_valid_data() == true)
+ {
+ // all parameters m_dhe_prime, m_dhe_group_generator and m_public_dhe_key are needed.
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+ }
+
+ if (m_dhe_group_generator.get_is_valid_data() == true)
+ {
+ u16_t dhe_group_generator_length_network_order = eap_htons(static_cast<u16_t>(m_dhe_group_generator.get_data_length()));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &dhe_group_generator_length_network_order,
+ sizeof(dhe_group_generator_length_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_group_generator_length"),
+ &dhe_group_generator_length_network_order,
+ sizeof(dhe_group_generator_length_network_order)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()),
+ m_dhe_group_generator.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake dhe_group_generator"),
+ m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()),
+ m_dhe_group_generator.get_data_length()));
+ }
+ else if (m_dhe_prime.get_is_valid_data() == true
+ || m_public_dhe_key.get_is_valid_data() == true
+ || m_signed_message_hash.get_is_valid_data() == true)
+ {
+ // all parameters m_dhe_prime, m_dhe_group_generator and m_public_dhe_key are needed.
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+ }
+
+ if (m_public_dhe_key.get_is_valid_data() == true)
+ {
+ u16_t public_dhe_key_length_network_order = eap_htons(static_cast<u16_t>(m_public_dhe_key.get_data_length()));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &public_dhe_key_length_network_order,
+ sizeof(public_dhe_key_length_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key_length"),
+ &public_dhe_key_length_network_order,
+ sizeof(public_dhe_key_length_network_order)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()),
+ m_public_dhe_key.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key"),
+ m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()),
+ m_public_dhe_key.get_data_length()));
+ }
+ else if (m_dhe_prime.get_is_valid_data() == true
+ || m_dhe_group_generator.get_is_valid_data() == true
+ || m_signed_message_hash.get_is_valid_data() == true)
+ {
+ // all parameters m_dhe_prime, m_dhe_group_generator and m_public_dhe_key are needed.
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+ }
+
+ if (m_signed_message_hash.get_is_valid_data() == true)
+ {
+ if (m_signed_message_hash.get_data_length() == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ status = m_tls_handshake_message_buffer.add_data(
+ m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
+ m_signed_message_hash.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake signed_message_hash"),
+ m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
+ m_signed_message_hash.get_data_length()));
+ }
+ }
+
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_client_key_exchange)
+ {
+ if (m_encrypted_premaster_secret.get_is_valid_data() == true)
+ {
+ u16_t length_of_encrypted_premaster_secret_network_order
+ = eap_htons(static_cast<u16_t>(m_encrypted_premaster_secret.get_data_length()));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &length_of_encrypted_premaster_secret_network_order,
+ sizeof(length_of_encrypted_premaster_secret_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake encrypted premaster_secret"),
+ &length_of_encrypted_premaster_secret_network_order,
+ sizeof(length_of_encrypted_premaster_secret_network_order)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ m_encrypted_premaster_secret.get_data(m_encrypted_premaster_secret.get_data_length()),
+ m_encrypted_premaster_secret.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake encrypted premaster_secret"),
+ m_encrypted_premaster_secret.get_data(m_encrypted_premaster_secret.get_data_length()),
+ m_encrypted_premaster_secret.get_data_length()));
+ }
+ else if (m_encrypted_premaster_secret.get_is_valid_data() == false
+ && m_public_dhe_key.get_is_valid_data() == false)
+ {
+ // Either parameters m_encrypted_premaster_secret or m_public_dhe_key is needed.
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+ }
+
+ if (m_public_dhe_key.get_is_valid_data() == true)
+ {
+ u16_t length_of_public_dhe_key_length_network_order = eap_htons(static_cast<u16_t>(m_public_dhe_key.get_data_length()));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &length_of_public_dhe_key_length_network_order,
+ sizeof(length_of_public_dhe_key_length_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key_length"),
+ &length_of_public_dhe_key_length_network_order,
+ sizeof(length_of_public_dhe_key_length_network_order)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()),
+ m_public_dhe_key.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake public_dhe_key"),
+ m_public_dhe_key.get_data(m_public_dhe_key.get_data_length()),
+ m_public_dhe_key.get_data_length()));
+ }
+ else if (m_encrypted_premaster_secret.get_is_valid_data() == false
+ && m_public_dhe_key.get_is_valid_data() == false)
+ {
+ // Either parameters m_encrypted_premaster_secret or m_public_dhe_key is needed.
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+ }
+ }
+
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate_request)
+ {
+ u32_t data_size = m_certificate_types.get_object_count() * sizeof(u8_t);
+
+ if (data_size > 0x000000ff)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ u8_t data_size_u8_t = static_cast<u8_t>(data_size & 0x000000ff);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &data_size_u8_t,
+ sizeof(data_size_u8_t));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_types length"),
+ &data_size_u8_t,
+ sizeof(data_size_u8_t)));
+
+ if (data_size_u8_t > 0ul)
+ {
+ status = add_simple_data(&m_certificate_types, &m_tls_handshake_message_buffer, m_am_tools);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate_request)
+ {
+ u32_t data_size = 0ul;
+ u32_t ind = 0ul;
+
+ for (ind = 0ul; ind < m_certificate_authorities.get_object_count(); ind++)
+ {
+ const eap_variable_data_c * const certificate_authority = m_certificate_authorities.get_object(ind);
+ if (certificate_authority == 0
+ || certificate_authority->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+ data_size += certificate_authority->get_data_length();
+ }
+
+ if (data_size > 0x0000ffff)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ u8_t data_size_array[2];
+ data_size_array[0] = static_cast<u8_t>((data_size & 0x0000ff00) >> 8);
+ data_size_array[1] = static_cast<u8_t>(data_size & 0x000000ff);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ data_size_array,
+ sizeof(data_size_array));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_authorities length"),
+ data_size_array,
+ sizeof(data_size_array)));
+
+
+ for (ind = 0ul; ind < m_certificate_authorities.get_object_count(); ind++)
+ {
+ const eap_variable_data_c * const certificate_authority = m_certificate_authorities.get_object(ind);
+ if (certificate_authority == 0
+ || certificate_authority->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ data_size = certificate_authority->get_data_length();
+ u8_t data_size_array[2];
+ data_size_array[0] = static_cast<u8_t>((data_size & 0x0000ff00) >> 8);
+ data_size_array[1] = static_cast<u8_t>(data_size & 0x000000ff);
+
+ status = m_tls_handshake_message_buffer.add_data(
+ data_size_array,
+ sizeof(data_size_array));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_authority length"),
+ data_size_array,
+ sizeof(data_size_array)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ certificate_authority->get_data(certificate_authority->get_data_length()),
+ certificate_authority->get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake certificate_authority"),
+ certificate_authority->get_data(certificate_authority->get_data_length()),
+ certificate_authority->get_data_length()));
+ }
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_certificate_verify)
+ {
+ u16_t length_of_certificate_verify_network_order = eap_htons(static_cast<u16_t>(m_signed_message_hash.get_data_length()));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &length_of_certificate_verify_network_order,
+ sizeof(length_of_certificate_verify_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS-handshake certificate_verify"),
+ &length_of_certificate_verify_network_order,
+ sizeof(length_of_certificate_verify_network_order)));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
+ m_signed_message_hash.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake signed_message_hash"),
+ m_signed_message_hash.get_data(m_signed_message_hash.get_data_length()),
+ m_signed_message_hash.get_data_length()));
+
+ }
+
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_finished)
+ {
+ eap_variable_data_c signed_message_hash(m_am_tools);
+
+ status = m_message_hash->message_hash_save_finished(m_is_client);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ status = m_message_hash->message_hash_create_finished(m_is_client, &signed_message_hash);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ status = m_tls_handshake_message_buffer.add_data(
+ signed_message_hash.get_data(signed_message_hash.get_data_length()),
+ signed_message_hash.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("TLS-handshake signed_message_hash"),
+ signed_message_hash.get_data(signed_message_hash.get_data_length()),
+ signed_message_hash.get_data_length()));
+
+ }
+
+
+#if defined(USE_EAP_TLS_SESSION_TICKET)
+
+ if (m_tls_extensions.get_object_count() > 0
+ && tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type() == tls_handshake_type_new_session_ticket)
+ {
+ const tls_extension_c * const p_new_session_ticket = tls_extension_c::get_tls_extension(
+ tls_extension_type_session_ticket,
+ &m_tls_extensions,
+ m_am_tools);
+
+ if (p_new_session_ticket != 0)
+ {
+ u32_t ticket_lifetime_hint_network_order = eap_htonl(p_new_session_ticket->get_lifetime_hint());
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &ticket_lifetime_hint_network_order,
+ sizeof(ticket_lifetime_hint_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ u32_t length_of_opaque_ticket = p_new_session_ticket->get_data_length();
+ u16_t length_of_opaque_ticket_network_order = eap_htons(static_cast<u16_t>(length_of_opaque_ticket));
+
+ status = m_tls_handshake_message_buffer.add_data(
+ &length_of_opaque_ticket_network_order,
+ sizeof(length_of_opaque_ticket_network_order));
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ if (length_of_opaque_ticket > 0ul)
+ {
+ status = m_tls_handshake_message_buffer.add_data(
+ p_new_session_ticket);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+ }
+ }
+
+#endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ if (status == eap_status_ok)
+ {
+ u32_t handshake_data_length = m_tls_handshake_message_buffer.get_data_length() - handshake_data_length_start;
+
+ EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("handshake length %d bytes.\n"),
+ handshake_data_length));
+
+ if (handshake_data_length <= 0x00ffffff)
+ {
+ // NOTE the address of tmp_tls_handshake_header_on_tls_message_buffer must be queried again.
+ // The whole buffer might be allocated from other address.
+ tmp_tls_handshake_header_on_tls_message_buffer.set_header_buffer(
+ m_tls_handshake_message_buffer.get_data_offset(
+ offset_of_tmp_tls_handshake_header,
+ tls_handshake_header_c::get_header_length()+handshake_data_length),
+ tls_handshake_header_c::get_header_length()+handshake_data_length);
+ if (tmp_tls_handshake_header_on_tls_message_buffer.get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message);
+ }
+ tmp_tls_handshake_header_on_tls_message_buffer.set_data_length(handshake_data_length);
+
+
+ switch (tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type())
+ {
+ case tls_handshake_type_hello_request:
+ // This message is NOT included to TLS-message hash.
+ break;
+ case tls_handshake_type_client_hello:
+ case tls_handshake_type_server_hello:
+ case tls_handshake_type_certificate:
+ case tls_handshake_type_server_key_exchange:
+ case tls_handshake_type_certificate_request:
+ case tls_handshake_type_server_hello_done:
+ case tls_handshake_type_certificate_verify:
+ case tls_handshake_type_client_key_exchange:
+ case tls_handshake_type_finished:
+#if defined(USE_EAP_TLS_SESSION_TICKET)
+ case tls_handshake_type_new_session_ticket:
+#endif // #if defined(USE_EAP_TLS_SESSION_TICKET)
+ {
+ status = m_message_hash->message_hash_update(
+ false,
+ tmp_tls_handshake_header_on_tls_message_buffer.get_handshake_type(),
+ tmp_tls_handshake_header_on_tls_message_buffer.get_header_buffer(
+ tmp_tls_handshake_header_on_tls_message_buffer.get_header_length()
+ + tmp_tls_handshake_header_on_tls_message_buffer.get_data_length()),
+ tmp_tls_handshake_header_on_tls_message_buffer.get_header_length()
+ + tmp_tls_handshake_header_on_tls_message_buffer.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ break;
+ }
+ default:
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+ } // switch()
+ }
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e tls_handshake_message_c::add_message_data(
+ eap_variable_data_c * const tls_message_buffer)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("\n")));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TLS: %s: data_function: tls_handshake_message_c::add_message_data(): %s\n"),
+ (m_is_client == true ? "client": "server"),
+ tls_handshake_header_c::get_tls_handshake_string(get_handshake_type())));
+
+ eap_status_e status = eap_status_ok;
+
+ if (m_tls_handshake_message_buffer.get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+ }
+
+ status = tls_message_buffer->add_data(
+ m_tls_handshake_message_buffer.get_data(m_tls_handshake_message_buffer.get_data_length()),
+ m_tls_handshake_message_buffer.get_data_length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+
+
+// End.