diff -r 000000000000 -r c8830336c852 eapol/eapol_framework/eapol_common/am/common/eap_am_memory_store.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eapol/eapol_framework/eapol_common/am/common/eap_am_memory_store.cpp Thu Dec 17 08:47:43 2009 +0200 @@ -0,0 +1,645 @@ +/* +* 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 10 + #undef EAP_FILE_NUMBER_DATE + #define EAP_FILE_NUMBER_DATE 1127594498 +#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) + + +#include "eap_am_memory.h" +#include "eap_am_memory_store.h" +#include "eap_crypto_api.h" +#include "eap_automatic_variable.h" + +//#if !defined(NO_EAP_AM_MEMORY_STORE) + +const u32_t EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH = 256ul; + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_am_memory_store_c::~eap_am_memory_store_c() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::~eap_am_memory_store_c(): this = 0x%08x.\n"), + this)); +} + +//------------------------------------------------------------------- + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list +#endif + +EAP_FUNC_EXPORT eap_am_memory_store_c::eap_am_memory_store_c( + abs_eap_am_tools_c * const tools) + : m_am_tools(tools) + , m_store_new(tools, this) + , m_timer_id_counter(0ul) + , m_is_valid(false) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::eap_am_memory_store_c(): this = 0x%08x.\n"), + this)); + + set_is_valid(); +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::shutdown() +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::shutdown(): begins this = 0x%08x.\n"), + this)); + + return eap_status_ok; + +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT void eap_am_memory_store_c::set_is_valid() +{ + m_is_valid = true; +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT bool eap_am_memory_store_c::get_is_valid() +{ + return m_is_valid; +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::add_data( + const eap_variable_data_c * const key, + const eap_tlv_message_data_c * const data, + const u32_t timeout) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): data = 0x%08x.\n"), + data)); + + if (key == 0 + || data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_am_memory_store_tlv_data_c * const tlv_data = new eap_am_memory_store_tlv_data_c(m_am_tools); + if (tlv_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eap_automatic_variable_c automatic_tlv_data( + m_am_tools, + tlv_data); + + eap_status_e status = tlv_data->copy_message_data( + data, + ++m_timer_id_counter); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + eap_variable_data_c crypted_key(m_am_tools); + status = crypted_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This encryption hides the plain text data. + // This is lame hidden operation of credentials. + // @{ The key should be crypted lamely too.} + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + crypted_key.get_data(), + crypted_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); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + tlv_data->get_message_data(), + tlv_data->get_message_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_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): timeout %d, timer id %d, data = 0x%08x.\n"), + timeout, + tlv_data->get_timer_id(), + data)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): crypted key"), + crypted_key.get_data(), + crypted_key.get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): plain text data"), + data->get_message_data(), + data->get_message_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::add_data(): hidden data"), + tlv_data->get_message_data(), + tlv_data->get_message_data_length())); + + status = m_store_new.add_handler(&crypted_key, tlv_data); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + automatic_tlv_data.do_not_free_variable(); + + if (timeout != 0ul) + { + eap_variable_data_c * const copy_key = key->copy(); + if (copy_key == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = m_am_tools->am_set_timer( + this, + tlv_data->get_timer_id(), + copy_key, + timeout); + 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_status_e eap_am_memory_store_c::get_data( + const eap_variable_data_c * const key, + eap_tlv_message_data_c * const data) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + if (key == 0 + || data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); + } + + eap_variable_data_c crypted_key(m_am_tools); + eap_status_e status = crypted_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This encryption restores lamely hidden key of data. + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + crypted_key.get_data(), + crypted_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("eap_am_memory_store_c::get_data(): key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): crypted key"), + crypted_key.get_data(), + crypted_key.get_data_length())); + + eap_am_memory_store_tlv_data_c * const tlv_data = m_store_new.get_handler(&crypted_key); + + if (tlv_data == 0) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + else + { + status = data->copy_message_data( + tlv_data->get_message_data_length(), + tlv_data->get_message_data()); + + { + // This encryption restores lamely hidden plain text data. + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.decrypt_data( + data->get_message_data(), + data->get_message_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_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): timer id %d, data = 0x%08x.\n"), + tlv_data->get_timer_id(), + data)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): hidden data"), + tlv_data->get_message_data(), + tlv_data->get_message_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::get_data(): plain text data"), + data->get_message_data(), + data->get_message_data_length())); + + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +} + +//------------------------------------------------------------------- + +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::remove_data( + const eap_variable_data_c * const key) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): key"), + key->get_data(), + key->get_data_length())); + + eap_status_e status(eap_status_ok); + + { + eap_variable_data_c crypted_key(m_am_tools); + eap_status_e status = crypted_key.set_copy_of_buffer(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + { + // This encryption restores lamely hidden key of data. + crypto_rc4_c rc4(m_am_tools); + if (rc4.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = rc4.set_key(key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.discard_stream(EAP_MEMORY_STORE_RC4_KEY_STREAM_DISCARD_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = rc4.encrypt_data( + crypted_key.get_data(), + crypted_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("eap_am_memory_store_c::remove_data(): crypted key"), + crypted_key.get_data(), + crypted_key.get_data_length())); + + eap_am_memory_store_tlv_data_c * const data = m_store_new.get_handler(&crypted_key); + if (data != 0) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): timer id %d, data = 0x%08x.\n"), + data->get_timer_id(), + data)); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): key"), + key->get_data(), + key->get_data_length())); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): hidden data"), + data->get_message_data(), + data->get_message_data_length())); + + (void) m_am_tools->am_cancel_timer( + this, + data->get_timer_id()); + + status = m_store_new.remove_handler(&crypted_key, true); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eap_am_memory_store_c::remove_data(): key not found"), + crypted_key.get_data(), + crypted_key.get_data_length())); + } + } + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::remove_data(): returns %d\n"), + status)); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//------------------------------------------------------------------- + +/** + * Function timer_expired() is called after the timer is elapsed. + * @param id and data are set by caller of abs_eap_am_tools::set_timer() function. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::timer_expired( + const u32_t id, void *data) +{ + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_expired(): id %d, data 0x%08x\n"), + id, + data)); + + if (data != 0) + { + eap_variable_data_c * const key = reinterpret_cast(data); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_expired(): key"), + key->get_data(), + key->get_data_length())); + + eap_am_memory_store_tlv_data_c * const tlv_data = m_store_new.get_handler(key); + if (tlv_data != 0) + { + if (id == tlv_data->get_timer_id()) + { + eap_status_e status = remove_data(key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eap_am_memory_store_c::timer_expired(): id %d != tlv_data->id %d, tlv_data 0x%08x\n"), + id, + tlv_data->get_timer_id(), + tlv_data)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); + } + } + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------------------- + +/** + * This function is called when timer event is deleted. + * Initialiser of the data must delete the data. + * Only the initializer knows the real type of data. + * @param id could be used to separate different timer events. + * @param data could be pointer to any data that is needed in timer processing. + */ +EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::timer_delete_data( + const u32_t id, void *data) +{ + EAP_UNREFERENCED_PARAMETER(id); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_delete_data(): id %d, data 0x%08x\n"), + id, + data)); + + if (data != 0) + { + eap_variable_data_c * const key = reinterpret_cast(data); + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("eap_am_memory_store_c::timer_delete_data(): key"), + key->get_data(), + key->get_data_length())); + + delete key; + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); +} + +//------------------------------------------------------------------- + +//#endif //#if !defined(NO_EAP_AM_MEMORY_STORE) + +// End.