From 4a492a8d1fa35edf2acce370f68676dbb3212e2e Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Mon, 20 Jun 2011 16:30:23 +0200 Subject: [PATCH] created empty imc_attestation and imv_attestation plugin hulls --- configure.in | 14 +- src/libimcv/Makefile.am | 10 +- .../plugins/imc_attestation/Makefile.am | 16 ++ .../plugins/imc_attestation/imc_attestation.c | 248 ++++++++++++++++ .../imc_attestation/imc_attestation_state.c | 84 ++++++ .../imc_attestation/imc_attestation_state.h | 48 ++++ .../plugins/imv_attestation/Makefile.am | 16 ++ .../plugins/imv_attestation/imv_attestation.c | 265 ++++++++++++++++++ .../imv_attestation/imv_attestation_state.c | 177 ++++++++++++ .../imv_attestation/imv_attestation_state.h | 52 ++++ src/libimcv/tcg/tcg_attr.c | 132 +++++++++ src/libimcv/tcg/tcg_attr.h | 72 +++++ 12 files changed, 1132 insertions(+), 2 deletions(-) create mode 100644 src/libimcv/plugins/imc_attestation/Makefile.am create mode 100644 src/libimcv/plugins/imc_attestation/imc_attestation.c create mode 100644 src/libimcv/plugins/imc_attestation/imc_attestation_state.c create mode 100644 src/libimcv/plugins/imc_attestation/imc_attestation_state.h create mode 100644 src/libimcv/plugins/imv_attestation/Makefile.am create mode 100644 src/libimcv/plugins/imv_attestation/imv_attestation.c create mode 100644 src/libimcv/plugins/imv_attestation/imv_attestation_state.c create mode 100644 src/libimcv/plugins/imv_attestation/imv_attestation_state.h create mode 100644 src/libimcv/tcg/tcg_attr.c create mode 100644 src/libimcv/tcg/tcg_attr.h diff --git a/configure.in b/configure.in index 67d1c2a89..d3fe78bef 100644 --- a/configure.in +++ b/configure.in @@ -137,8 +137,13 @@ ARG_ENABL_SET([tnccs-20], [enable TNCCS 2.0 protocol module.]) ARG_ENABL_SET([tnccs-dynamic], [enable dynamic TNCCS protocol discovery module.]) ARG_ENABL_SET([imc-test], [enable IMC test module.]) ARG_ENABL_SET([imv-test], [enable IMV test module.]) +<<<<<<< HEAD ARG_ENABL_SET([imc-scanner], [enable IMC port scanner module.]) ARG_ENABL_SET([imv-scanner], [enable IMV port scanner module.]) +======= +ARG_ENABL_SET([imc-attestation],[enable IMC attestation module.]) +ARG_ENABL_SET([imv-attestation],[enable IMV attestation module.]) +>>>>>>> created empty imc_attestation and imv_attestation plugin hulls ARG_DISBL_SET([kernel-netlink], [disable the netlink kernel interface.]) ARG_ENABL_SET([kernel-pfkey], [enable the PF_KEY kernel interface.]) ARG_ENABL_SET([kernel-pfroute], [enable the PF_ROUTE kernel interface.]) @@ -248,7 +253,7 @@ if test x$eap_tls = xtrue -o x$eap_ttls = xtrue -o x$eap_peap = xtrue; then tls=true; fi -if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue; then +if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue -o x$imc_attestation = xtrue -o x$imv_attestation = xtrue; then imcv=true; fi @@ -945,8 +950,13 @@ AM_CONDITIONAL(USE_TNCCS_20, test x$tnccs_20 = xtrue) AM_CONDITIONAL(USE_TNCCS_DYNAMIC, test x$tnccs_dynamic = xtrue) AM_CONDITIONAL(USE_IMC_TEST, test x$imc_test = xtrue) AM_CONDITIONAL(USE_IMV_TEST, test x$imv_test = xtrue) +<<<<<<< HEAD AM_CONDITIONAL(USE_IMC_SCANNER, test x$imc_scanner = xtrue) AM_CONDITIONAL(USE_IMV_SCANNER, test x$imv_scanner = xtrue) +======= +AM_CONDITIONAL(USE_IMC_ATTESTATION, test x$imc_attestation = xtrue) +AM_CONDITIONAL(USE_IMV_ATTESTATION, test x$imv_attestation = xtrue) +>>>>>>> created empty imc_attestation and imv_attestation plugin hulls AM_CONDITIONAL(USE_SOCKET_DEFAULT, test x$socket_default = xtrue) AM_CONDITIONAL(USE_SOCKET_RAW, test x$socket_raw = xtrue) AM_CONDITIONAL(USE_SOCKET_DYNAMIC, test x$socket_dynamic = xtrue) @@ -1080,6 +1090,8 @@ AC_OUTPUT( src/libimcv/plugins/imv_test/Makefile src/libimcv/plugins/imc_scanner/Makefile src/libimcv/plugins/imv_scanner/Makefile + src/libimcv/plugins/imc_attestation/Makefile + src/libimcv/plugins/imv_attestation/Makefile src/pluto/Makefile src/pluto/plugins/xauth/Makefile src/whack/Makefile diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am index db78f55ca..c6a273f5d 100644 --- a/src/libimcv/Makefile.am +++ b/src/libimcv/Makefile.am @@ -14,7 +14,8 @@ libimcv_la_SOURCES = \ ietf/ietf_attr_port_filter.h ietf/ietf_attr_port_filter.c \ ita/ita_attr_command.h ita/ita_attr_command.c \ pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \ - pa_tnc/pa_tnc_attr.h pa_tnc/pa_tnc_attr.c + pa_tnc/pa_tnc_attr.h pa_tnc/pa_tnc_attr.c \ + tcg/tcg_attr.h tcg/tcg_attr.c SUBDIRS = . @@ -32,4 +33,11 @@ endif if USE_IMV_SCANNER SUBDIRS += plugins/imv_scanner + +if USE_IMC_ATTESTATION + SUBDIRS += plugins/imc_attestation +endif + +if USE_IMV_ATTESTATION + SUBDIRS += plugins/imv_attestation endif diff --git a/src/libimcv/plugins/imc_attestation/Makefile.am b/src/libimcv/plugins/imc_attestation/Makefile.am new file mode 100644 index 000000000..e5ba87621 --- /dev/null +++ b/src/libimcv/plugins/imc_attestation/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libimcv + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-imc-attestation.la + +libstrongswan_imc_attestation_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la + +libstrongswan_imc_attestation_la_SOURCES = imc_attestation.c \ + imc_attestation_state.h imc_attestation_state.c + +libstrongswan_imc_attestation_la_LDFLAGS = -module -avoid-version + diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation.c b/src/libimcv/plugins/imc_attestation/imc_attestation.c new file mode 100644 index 000000000..89735fc79 --- /dev/null +++ b/src/libimcv/plugins/imc_attestation/imc_attestation.c @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2011 Sansar Choinyambuu + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "imc_attestation_state.h" + +#include +#include +#include +#include +#include + +#include + +#include + +/* IMC definitions */ + +static const char imc_name[] = "Attestation"; + +#define IMC_VENDOR_ID PEN_ITA +#define IMC_SUBTYPE 0x02 + +static imc_agent_t *imc_attestation; + +/** + * see section 3.7.1 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id, + TNC_Version min_version, + TNC_Version max_version, + TNC_Version *actual_version) +{ + if (imc_attestation) + { + DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name); + return TNC_RESULT_ALREADY_INITIALIZED; + } + imc_attestation = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE, + imc_id, actual_version); + if (!imc_attestation) + { + return TNC_RESULT_FATAL; + } + if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1) + { + DBG1(DBG_IMC, "no common IF-IMC version"); + return TNC_RESULT_NO_COMMON_VERSION; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.2 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_ConnectionState new_state) +{ + imc_state_t *state; + imc_attestation_state_t *test_state; + + if (!imc_attestation) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + switch (new_state) + { + case TNC_CONNECTION_STATE_CREATE: + state = imc_attestation_state_create(connection_id); + return imc_attestation->create_state(imc_attestation, state); + case TNC_CONNECTION_STATE_DELETE: + return imc_attestation->delete_state(imc_attestation, connection_id); + case TNC_CONNECTION_STATE_ACCESS_ISOLATED: + case TNC_CONNECTION_STATE_ACCESS_NONE: + default: + return imc_attestation->change_state(imc_attestation, connection_id, new_state); + } +} + +static TNC_Result send_message(TNC_ConnectionID connection_id) +{ + pa_tnc_msg_t *msg; + pa_tnc_attr_t *attr; + imc_state_t *state; + imc_attestation_state_t *test_state; + TNC_Result result; + + if (!imc_attestation->get_state(imc_attestation, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + test_state = (imc_attestation_state_t*)state; + msg = pa_tnc_msg_create(); + /** + * add TCG PTS attributes + */ + msg->build(msg); + result = imc_attestation->send_message(imc_attestation, connection_id, + msg->get_encoding(msg)); + msg->destroy(msg); + + return result; +} + +/** + * see section 3.7.3 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id, + TNC_ConnectionID connection_id) +{ + if (!imc_attestation) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return send_message(connection_id); +} + +/** + * see section 3.7.4 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_MessageType msg_type) +{ + pa_tnc_msg_t *pa_tnc_msg; + pa_tnc_attr_t *attr; + enumerator_t *enumerator; + TNC_Result result; + bool fatal_error = FALSE; + + if (!imc_attestation) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + + /* parse received PA-TNC message and automatically handle any errors */ + result = imc_attestation->receive_message(imc_attestation, connection_id, + chunk_create(msg, msg_len), msg_type, + &pa_tnc_msg); + + /* no parsed PA-TNC attributes available if an error occurred */ + if (!pa_tnc_msg) + { + return result; + } + + /* analyze PA-TNC attributes */ + enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + if (attr->get_vendor_id(attr) == PEN_IETF && + attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR) + { + ietf_attr_pa_tnc_error_t *error_attr; + pa_tnc_error_code_t error_code; + chunk_t msg_info, attr_info; + + error_attr = (ietf_attr_pa_tnc_error_t*)attr; + error_code = error_attr->get_error_code(error_attr); + msg_info = error_attr->get_msg_info(error_attr); + + DBG1(DBG_IMC, "received PA-TNC error '%N' concerning message %#B", + pa_tnc_error_code_names, error_code, &msg_info); + switch (error_code) + { + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + attr_info = error_attr->get_attr_info(error_attr); + DBG1(DBG_IMC, " unsupported attribute %#B", &attr_info); + break; + default: + break; + } + fatal_error = TRUE; + } + else if (attr->get_vendor_id(attr) == PEN_TCG) + { + /** + * Handle TCG PTS attributes + */ + } + } + enumerator->destroy(enumerator); + pa_tnc_msg->destroy(pa_tnc_msg); + + /* if no error occurred then always return the same response */ + return fatal_error ? TNC_RESULT_FATAL : send_message(connection_id); +} + +/** + * see section 3.7.5 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id, + TNC_ConnectionID connection_id) +{ + if (!imc_attestation) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.6 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id) +{ + if (!imc_attestation) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + imc_attestation->destroy(imc_attestation); + imc_attestation = NULL; + + return TNC_RESULT_SUCCESS; +} + +/** + * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id, + TNC_TNCC_BindFunctionPointer bind_function) +{ + if (!imc_attestation) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imc_attestation->bind_functions(imc_attestation, bind_function); +} diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation_state.c b/src/libimcv/plugins/imc_attestation/imc_attestation_state.c new file mode 100644 index 000000000..19a8a1b6d --- /dev/null +++ b/src/libimcv/plugins/imc_attestation/imc_attestation_state.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 Sansar Choinyambuu + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "imc_attestation_state.h" + +#include + +typedef struct private_imc_attestation_state_t private_imc_attestation_state_t; + +/** + * Private data of an imc_attestation_state_t object. + */ +struct private_imc_attestation_state_t { + + /** + * Public members of imc_attestation_state_t + */ + imc_attestation_state_t public; + + /** + * TNCCS connection ID + */ + TNC_ConnectionID connection_id; + + /** + * TNCCS connection state + */ + TNC_ConnectionState state; + +}; + +METHOD(imc_state_t, get_connection_id, TNC_ConnectionID, + private_imc_attestation_state_t *this) +{ + return this->connection_id; +} + +METHOD(imc_state_t, change_state, void, + private_imc_attestation_state_t *this, TNC_ConnectionState new_state) +{ + this->state = new_state; +} + +METHOD(imc_state_t, destroy, void, + private_imc_attestation_state_t *this) +{ + free(this); +} + +/** + * Described in header. + */ +imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id) +{ + private_imc_attestation_state_t *this; + + INIT(this, + .public = { + .interface = { + .get_connection_id = _get_connection_id, + .change_state = _change_state, + .destroy = _destroy, + }, + }, + .state = TNC_CONNECTION_STATE_CREATE, + .connection_id = connection_id, + ); + + return &this->public.interface; +} + + diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation_state.h b/src/libimcv/plugins/imc_attestation/imc_attestation_state.h new file mode 100644 index 000000000..1001c784d --- /dev/null +++ b/src/libimcv/plugins/imc_attestation/imc_attestation_state.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * + * @defgroup imc_attestation_state_t imc_attestation_state + * @{ @ingroup imc_attestation_state + */ + +#ifndef IMC_ATTESTATION_STATE_H_ +#define IMC_ATTESTATION_STATE_H_ + +#include +#include + +typedef struct imc_attestation_state_t imc_attestation_state_t; + +/** + * Internal state of an imc_attestation_t connection instance + */ +struct imc_attestation_state_t { + + /** + * imc_state_t interface + */ + imc_state_t interface; +}; + +/** + * Create an imc_attestation_state_t instance + * + * @param id connection ID + * @param rounds total number of IMC re-measurements + */ +imc_state_t* imc_attestation_state_create(TNC_ConnectionID id); + +#endif /** IMC_ATTESTATION_STATE_H_ @}*/ diff --git a/src/libimcv/plugins/imv_attestation/Makefile.am b/src/libimcv/plugins/imv_attestation/Makefile.am new file mode 100644 index 000000000..97c734623 --- /dev/null +++ b/src/libimcv/plugins/imv_attestation/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libimcv + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-imv-attestation.la + +libstrongswan_imv_attestation_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la + +libstrongswan_imv_attestation_la_SOURCES = imv_attestation.c \ + imv_attestation_state.h imv_attestation_state.c + +libstrongswan_imv_attestation_la_LDFLAGS = -module -avoid-version + diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c new file mode 100644 index 000000000..b594378dd --- /dev/null +++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2011 Sansar Choinyambuu + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "imv_attestation_state.h" + +#include +#include +#include +#include +#include + +#include + +#include + +/* IMV definitions */ + +static const char imv_name[] = "Attestation"; + +#define IMV_VENDOR_ID PEN_ITA +#define IMV_SUBTYPE 0x02 + +static imv_agent_t *imv_attestation; + +/** + * see section 3.7.1 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id, + TNC_Version min_version, + TNC_Version max_version, + TNC_Version *actual_version) +{ + if (imv_attestation) + { + DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name); + return TNC_RESULT_ALREADY_INITIALIZED; + } + imv_attestation = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE, + imv_id, actual_version); + if (!imv_attestation) + { + return TNC_RESULT_FATAL; + } + if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1) + { + DBG1(DBG_IMV, "no common IF-IMV version"); + return TNC_RESULT_NO_COMMON_VERSION; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.2 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id, + TNC_ConnectionID connection_id, + TNC_ConnectionState new_state) +{ + imv_state_t *state; + imv_attestation_state_t *attestation_state; + + if (!imv_attestation) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + switch (new_state) + { + case TNC_CONNECTION_STATE_CREATE: + state = imv_attestation_state_create(connection_id); + return imv_attestation->create_state(imv_attestation, state); + case TNC_CONNECTION_STATE_DELETE: + return imv_attestation->delete_state(imv_attestation, connection_id); + case TNC_CONNECTION_STATE_HANDSHAKE: + if (!imv_attestation->get_state(imv_attestation, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + state->change_state(state, new_state); + attestation_state = (imv_attestation_state_t*)state; + /** + * do any attestation specific configuration here + */ + return TNC_RESULT_SUCCESS; + default: + return imv_attestation->change_state(imv_attestation, connection_id, new_state); + } +} + +static TNC_Result send_message(TNC_ConnectionID connection_id) +{ + pa_tnc_msg_t *msg; + pa_tnc_attr_t *attr; + TNC_Result result; + + msg = pa_tnc_msg_create(); + /** + * add TCG PTS attributes + */ + msg->build(msg); + result = imv_attestation->send_message(imv_attestation, connection_id, + msg->get_encoding(msg)); + msg->destroy(msg); + + return result; +} + +/** + * see section 3.7.3 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, + TNC_ConnectionID connection_id, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_MessageType msg_type) +{ + pa_tnc_msg_t *pa_tnc_msg; + pa_tnc_attr_t *attr; + imv_state_t *state; + imv_attestation_state_t *imv_attestation_state; + enumerator_t *enumerator; + TNC_Result result; + bool fatal_error = FALSE; + + if (!imv_attestation) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + + /* get current IMV state */ + if (!imv_attestation->get_state(imv_attestation, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + + /* parse received PA-TNC message and automatically handle any errors */ + result = imv_attestation->receive_message(imv_attestation, connection_id, + chunk_create(msg, msg_len), msg_type, + &pa_tnc_msg); + + /* no parsed PA-TNC attributes available if an error occurred */ + if (!pa_tnc_msg) + { + return result; + } + + /* analyze PA-TNC attributes */ + enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + if (attr->get_vendor_id(attr) == PEN_IETF && + attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR) + { + ietf_attr_pa_tnc_error_t *error_attr; + pa_tnc_error_code_t error_code; + chunk_t msg_info, attr_info; + + error_attr = (ietf_attr_pa_tnc_error_t*)attr; + error_code = error_attr->get_error_code(error_attr); + msg_info = error_attr->get_msg_info(error_attr); + + DBG1(DBG_IMV, "received PA-TNC error '%N' concerning message %#B", + pa_tnc_error_code_names, error_code, &msg_info); + switch (error_code) + { + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + attr_info = error_attr->get_attr_info(error_attr); + DBG1(DBG_IMV, " unsupported attribute %#B", &attr_info); + break; + default: + break; + } + fatal_error = TRUE; + } + else if (attr->get_vendor_id(attr) == PEN_TCG) + { + /** + * Handle TCG PTS attributes + */ + } + } + enumerator->destroy(enumerator); + pa_tnc_msg->destroy(pa_tnc_msg); + + if (fatal_error) + { + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, + TNC_IMV_EVALUATION_RESULT_ERROR); + return imv_attestation->provide_recommendation(imv_attestation, connection_id); + } + + return imv_attestation->provide_recommendation(imv_attestation, connection_id); +} + +/** + * see section 3.7.4 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id, + TNC_ConnectionID connection_id) +{ + if (!imv_attestation) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imv_attestation->provide_recommendation(imv_attestation, connection_id); +} + +/** + * see section 3.7.5 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, + TNC_ConnectionID connection_id) +{ + if (!imv_attestation) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.6 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id) +{ + if (!imv_attestation) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + imv_attestation->destroy(imv_attestation); + imv_attestation = NULL; + + return TNC_RESULT_SUCCESS; +} + +/** + * see section 4.2.8.1 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_ProvideBindFunction(TNC_IMVID imv_id, + TNC_TNCS_BindFunctionPointer bind_function) +{ + if (!imv_attestation) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imv_attestation->bind_functions(imv_attestation, bind_function); +} diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_state.c b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c new file mode 100644 index 000000000..3c278a6ea --- /dev/null +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2011 Sansar Choinyambuu + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "imv_attestation_state.h" + +#include +#include + +typedef struct private_imv_attestation_state_t private_imv_attestation_state_t; + +/** + * Private data of an imv_attestation_state_t object. + */ +struct private_imv_attestation_state_t { + + /** + * Public members of imv_attestation_state_t + */ + imv_attestation_state_t public; + + /** + * TNCCS connection ID + */ + TNC_ConnectionID connection_id; + + /** + * TNCCS connection state + */ + TNC_ConnectionState state; + + /** + * IMV action recommendation + */ + TNC_IMV_Action_Recommendation rec; + + /** + * IMV evaluation result + */ + TNC_IMV_Evaluation_Result eval; +}; + +typedef struct entry_t entry_t; + +/** + * Define an internal reason string entry + */ +struct entry_t { + char *lang; + char *string; +}; + +/** + * Table of multi-lingual reason string entries + */ +static entry_t reasons[] = { + { "en", "IMC Attestation ..." }, + { "mn", "IMC Attestation ..." }, + { "de", "IMC Attestation ..." }, +}; + +METHOD(imv_state_t, get_connection_id, TNC_ConnectionID, + private_imv_attestation_state_t *this) +{ + return this->connection_id; +} + +METHOD(imv_state_t, change_state, void, + private_imv_attestation_state_t *this, TNC_ConnectionState new_state) +{ + this->state = new_state; +} + +METHOD(imv_state_t, get_recommendation, void, + private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation *rec, + TNC_IMV_Evaluation_Result *eval) +{ + *rec = this->rec; + *eval = this->eval; +} + +METHOD(imv_state_t, set_recommendation, void, + private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation rec, + TNC_IMV_Evaluation_Result eval) +{ + this->rec = rec; + this->eval = eval; +} + +METHOD(imv_state_t, get_reason_string, bool, + private_imv_attestation_state_t *this, chunk_t preferred_language, + chunk_t *reason_string, chunk_t *reason_language) +{ + chunk_t pref_lang, lang; + u_char *pos; + int i; + + while (eat_whitespace(&preferred_language)) + { + if (!extract_token(&pref_lang, ',', &preferred_language)) + { + /* last entry in a comma-separated list or single entry */ + pref_lang = preferred_language; + } + + /* eat trailing whitespace */ + pos = pref_lang.ptr + pref_lang.len - 1; + while (pref_lang.len && *pos-- == ' ') + { + pref_lang.len--; + } + + for (i = 0 ; i < countof(reasons); i++) + { + lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang)); + if (chunk_equals(lang, pref_lang)) + { + *reason_language = lang; + *reason_string = chunk_create(reasons[i].string, + strlen(reasons[i].string)); + return TRUE; + } + } + } + + /* no preferred language match found - use the default language */ + *reason_string = chunk_create(reasons[0].string, + strlen(reasons[0].string)); + *reason_language = chunk_create(reasons[0].lang, + strlen(reasons[0].lang)); + return TRUE; +} + +METHOD(imv_state_t, destroy, void, + private_imv_attestation_state_t *this) +{ + free(this); +} + +/** + * Described in header. + */ +imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id) +{ + private_imv_attestation_state_t *this; + + INIT(this, + .public = { + .interface = { + .get_connection_id = _get_connection_id, + .change_state = _change_state, + .get_recommendation = _get_recommendation, + .set_recommendation = _set_recommendation, + .get_reason_string = _get_reason_string, + .destroy = _destroy, + }, + }, + .state = TNC_CONNECTION_STATE_CREATE, + .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, + .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW, + ); + + return &this->public.interface; +} + + diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_state.h b/src/libimcv/plugins/imv_attestation/imv_attestation_state.h new file mode 100644 index 000000000..b2898846f --- /dev/null +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_state.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 Sansar Choinyambuu + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * + * @defgroup imv_attestation_state_t imv_attestation_state + * @{ @ingroup imv_attestation_state + */ + +#ifndef IMV_ATTESTATION_STATE_H_ +#define IMV_ATTESTATION_STATE_H_ + +#include +#include + +typedef struct imv_attestation_state_t imv_attestation_state_t; + +/** + * Internal state of an imv_attestation_t connection instance + */ +struct imv_attestation_state_t { + + /** + * imv_state_t interface + */ + imv_state_t interface; + + /** + * Add any setters and getters here + */ +}; + +/** + * Create an imv_attestation_state_t instance + * + * @param id connection ID + */ +imv_state_t* imv_attestation_state_create(TNC_ConnectionID id); + +#endif /** IMV_ATTESTATION_STATE_H_ @}*/ diff --git a/src/libimcv/tcg/tcg_attr.c b/src/libimcv/tcg/tcg_attr.c new file mode 100644 index 000000000..1ff3b8b3f --- /dev/null +++ b/src/libimcv/tcg/tcg_attr.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "tcg_attr.h" + +ENUM_BEGIN(tcg_attr_names, TCG_PTS_REQ_FUNCT_COMP_EVID, + TCG_PTS_REQ_FUNCT_COMP_EVID, + "Request Functional Component Evidence"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_GEN_ATTEST_EVID, + TCG_PTS_GEN_ATTEST_EVID, + TCG_PTS_REQ_FUNCT_COMP_EVID, + "Generate Attestation Evidence"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_SIMPLE_COMP_EVID, + TCG_PTS_SIMPLE_COMP_EVID, + TCG_PTS_GEN_ATTEST_EVID, + "Simple Component Evidence"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_SIMPLE_EVID_FINAL, + TCG_PTS_SIMPLE_EVID_FINAL, + TCG_PTS_SIMPLE_COMP_EVID, + "Simple Evidence Final"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_VERIFICATION_RESULT, + TCG_PTS_VERIFICATION_RESULT, + TCG_PTS_SIMPLE_EVID_FINAL, + "Verification Result"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_INTEG_REPORT, + TCG_PTS_INTEG_REPORT, + TCG_PTS_VERIFICATION_RESULT, + "Integrity Report"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_FILE_META, + TCG_PTS_REQ_FILE_META, + TCG_PTS_INTEG_REPORT, + "Request File Metadata"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_WIN_FILE_META, + TCG_PTS_WIN_FILE_META, + TCG_PTS_REQ_FILE_META, + "Windows-Style File Metadata"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_UNIX_FILE_META, + TCG_PTS_UNIX_FILE_META, + TCG_PTS_WIN_FILE_META, + "Unix-Style File Metadata"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_REGISTRY_VALUE, + TCG_PTS_REQ_REGISTRY_VALUE, + TCG_PTS_UNIX_FILE_META, + "Request Registry Value"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_REGISTRY_VALUE, + TCG_PTS_REGISTRY_VALUE, + TCG_PTS_REQ_REGISTRY_VALUE, + "Registry Value"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_FILE_MEAS, + TCG_PTS_REQ_FILE_MEAS, + TCG_PTS_REGISTRY_VALUE, + "Request File Measurement"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_FILE_MEAS, + TCG_PTS_FILE_MEAS, + TCG_PTS_REQ_FILE_MEAS, + "File Measurement"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_INTEG_MEAS_LOG, + TCG_PTS_REQ_INTEG_MEAS_LOG, + TCG_PTS_FILE_MEAS, + "Request Integrity Measurement Log"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_INTEG_MEAS_LOG, + TCG_PTS_INTEG_MEAS_LOG, + TCG_PTS_REQ_INTEG_MEAS_LOG, + "Integrity Measurement Log"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_PROTO_CAPS, + TCG_PTS_REQ_PROTO_CAPS, + TCG_PTS_INTEG_MEAS_LOG, + "Request PTS Protocol Capabilities"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_PROTO_CAPS, + TCG_PTS_PROTO_CAPS, + TCG_PTS_REQ_PROTO_CAPS, + "PTS Protocol Capabilities"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_PARAMS_REQ, + TCG_PTS_DH_NONCE_PARAMS_REQ, + TCG_PTS_PROTO_CAPS, + "DH Nonce Parameters Request"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_PARAMS_RESP, + TCG_PTS_DH_NONCE_PARAMS_RESP, + TCG_PTS_DH_NONCE_PARAMS_REQ, + "DH Nonce Parameters Response"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_FINISH, + TCG_PTS_DH_NONCE_FINISH, + TCG_PTS_DH_NONCE_PARAMS_RESP, + "DH Nonce Finish"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_MEAS_ALGO, + TCG_PTS_MEAS_ALGO, + TCG_PTS_DH_NONCE_FINISH, + "PTS Measurement Algorithm Request"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_MEAS_ALGO_SELECTION, + TCG_PTS_MEAS_ALGO_SELECTION, + TCG_PTS_MEAS_ALGO, + "PTS Measurement Algorithm"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_GET_TPM_VERSION_INFO, + TCG_PTS_GET_TPM_VERSION_INFO, + TCG_PTS_MEAS_ALGO_SELECTION, + "Get TPM Version Information"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_TPM_VERSION_INFO, + TCG_PTS_TPM_VERSION_INFO, + TCG_PTS_GET_TPM_VERSION_INFO, + "TPM Version Information"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_TEMPL_REF_MANI_SET_META, + TCG_PTS_REQ_TEMPL_REF_MANI_SET_META, + TCG_PTS_TPM_VERSION_INFO, + "Request Template Reference Manifest Set Metadata"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_TEMPL_REF_MANI_SET_META, + TCG_PTS_TEMPL_REF_MANI_SET_META, + TCG_PTS_REQ_TEMPL_REF_MANI_SET_META, + "Template Reference Manifest Set Metadata"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_UPDATE_TEMPL_REF_MANI, + TCG_PTS_UPDATE_TEMPL_REF_MANI, + TCG_PTS_TEMPL_REF_MANI_SET_META, + "Update Template Reference Manifest"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_GET_AIK, + TCG_PTS_GET_AIK, + TCG_PTS_UPDATE_TEMPL_REF_MANI, + "Get Attestation Identity Key"); +ENUM_NEXT(tcg_attr_names, TCG_PTS_AIK, + TCG_PTS_AIK, + TCG_PTS_GET_AIK, + "Attestation Identity Key"); +ENUM_END(tcg_attr_names, TCG_PTS_AIK); diff --git a/src/libimcv/tcg/tcg_attr.h b/src/libimcv/tcg/tcg_attr.h new file mode 100644 index 000000000..9a5e06b1b --- /dev/null +++ b/src/libimcv/tcg/tcg_attr.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup tcg_attrt tcg_attr + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_ATTR_H_ +#define TCG_ATTR_H_ + +#include + +typedef enum tcg_attr_t tcg_attr_t; + +/** + * TCG PTS IF-M Attributes (section 4 of PTS PROTO: Binding to TNC IF-M) + */ +enum tcg_attr_t { + + /* PTS Protocol Negotiations */ + TCG_PTS_REQ_PROTO_CAPS = 0x01000000, + TCG_PTS_PROTO_CAPS = 0x02000000, + TCG_PTS_DH_NONCE_PARAMS_REQ = 0x03000000, + TCG_PTS_DH_NONCE_PARAMS_RESP = 0x04000000, + TCG_PTS_DH_NONCE_FINISH = 0x05000000, + TCG_PTS_MEAS_ALGO = 0x06000000, + TCG_PTS_MEAS_ALGO_SELECTION = 0x07000000, + TCG_PTS_GET_TPM_VERSION_INFO = 0x08000000, + TCG_PTS_TPM_VERSION_INFO = 0x09000000, + TCG_PTS_REQ_TEMPL_REF_MANI_SET_META = 0x0A000000, + TCG_PTS_TEMPL_REF_MANI_SET_META = 0x0B000000, + TCG_PTS_UPDATE_TEMPL_REF_MANI = 0x0C000000, + TCG_PTS_GET_AIK = 0x0D000000, + TCG_PTS_AIK = 0x0E000000, + + /* PTS-based Attestation Evidence */ + TCG_PTS_REQ_FUNCT_COMP_EVID = 0x00100000, + TCG_PTS_GEN_ATTEST_EVID = 0x00200000, + TCG_PTS_SIMPLE_COMP_EVID = 0x00300000, + TCG_PTS_SIMPLE_EVID_FINAL = 0x00400000, + TCG_PTS_VERIFICATION_RESULT = 0x00500000, + TCG_PTS_INTEG_REPORT = 0x00600000, + TCG_PTS_REQ_FILE_META = 0x00700000, + TCG_PTS_WIN_FILE_META = 0x00800000, + TCG_PTS_UNIX_FILE_META = 0x00900000, + TCG_PTS_REQ_REGISTRY_VALUE = 0x00A00000, + TCG_PTS_REGISTRY_VALUE = 0x00B00000, + TCG_PTS_REQ_FILE_MEAS = 0x00C00000, + TCG_PTS_FILE_MEAS = 0x00D00000, + TCG_PTS_REQ_INTEG_MEAS_LOG = 0x00E00000, + TCG_PTS_INTEG_MEAS_LOG = 0x00F00000, +}; + +/** + * enum name for tcg_attr_t. + */ +extern enum_name_t *tcg_attr_names; + +#endif /** TCG_ATTR_H_ @}*/