diff --git a/configure.ac b/configure.ac index 7111922c5..f92168a26 100644 --- a/configure.ac +++ b/configure.ac @@ -188,6 +188,8 @@ ARG_ENABL_SET([imc-os], [enable IMC operating system module.]) ARG_ENABL_SET([imv-os], [enable IMV operating system module.]) ARG_ENABL_SET([imc-attestation],[enable IMC attestation module.]) ARG_ENABL_SET([imv-attestation],[enable IMV attestation module.]) +ARG_ENABL_SET([imc-swid], [enable IMC swid module.]) +ARG_ENABL_SET([imv-swid], [enable IMV swid module.]) 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.]) @@ -339,11 +341,11 @@ if test x$tnc_imc = xtrue -o x$tnc_imv = xtrue -o x$tnccs_11 = xtrue -o x$tnccs_ tnc_tnccs=true; fi -if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue -o x$imc_os = xtrue -o x$imv_os = xtrue -o x$imc_attestation = xtrue -o x$imv_attestation = 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_os = xtrue -o x$imv_os = xtrue -o x$imc_attestation = xtrue -o x$imv_attestation = xtrue -o x$imc_swid = xtrue -o x$imv_swid = xtrue; then imcv=true; fi -if test x$imc_attestation = xtrue -o x$imv_attestation = xtrue; then +if test x$imc_attestation = xtrue -o x$imv_attestation = xtrue -o x$imc_swid = xtrue -o x$imv_swid = xtrue; then pts=true; fi @@ -1225,6 +1227,8 @@ AM_CONDITIONAL(USE_IMC_OS, test x$imc_os = xtrue) AM_CONDITIONAL(USE_IMV_OS, test x$imv_os = xtrue) AM_CONDITIONAL(USE_IMC_ATTESTATION, test x$imc_attestation = xtrue) AM_CONDITIONAL(USE_IMV_ATTESTATION, test x$imv_attestation = xtrue) +AM_CONDITIONAL(USE_IMC_SWID, test x$imc_swid = xtrue) +AM_CONDITIONAL(USE_IMV_SWID, test x$imv_swid = xtrue) AM_CONDITIONAL(USE_SOCKET_DEFAULT, test x$socket_default = xtrue) AM_CONDITIONAL(USE_SOCKET_DYNAMIC, test x$socket_dynamic = xtrue) AM_CONDITIONAL(USE_FARP, test x$farp = xtrue) @@ -1386,6 +1390,8 @@ AC_CONFIG_FILES([ src/libpts/Makefile src/libpts/plugins/imc_attestation/Makefile src/libpts/plugins/imv_attestation/Makefile + src/libpts/plugins/imc_swid/Makefile + src/libpts/plugins/imv_swid/Makefile src/libimcv/Makefile src/libimcv/plugins/imc_test/Makefile src/libimcv/plugins/imv_test/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 1a025ad24..8ed45acc9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,7 +33,7 @@ if USE_LIBTNCCS endif if USE_LIBPTTLS - SUBDIRS += libpttls pt-tls-client + SUBDIRS += libpttls endif if USE_IMCV @@ -108,6 +108,10 @@ if USE_CMD SUBDIRS += charon-cmd endif +if USE_LIBPTTLS + SUBDIRS += pt-tls-client +endif + EXTRA_DIST = strongswan.conf install-exec-local : diff --git a/src/libimcv/imv/imv_workitem.c b/src/libimcv/imv/imv_workitem.c index a61a826bc..dbff3a340 100644 --- a/src/libimcv/imv/imv_workitem.c +++ b/src/libimcv/imv/imv_workitem.c @@ -20,7 +20,7 @@ typedef struct private_imv_workitem_t private_imv_workitem_t; -ENUM(imv_workitem_type_names, IMV_WORKITEM_PACKAGES, IMV_WORKITEM_UDP_PORT_BLOCK, +ENUM(imv_workitem_type_names, IMV_WORKITEM_PACKAGES, IMV_WORKITEM_SWID_TAGS, "PCKGS", "UNSRC", "FWDEN", @@ -34,7 +34,8 @@ ENUM(imv_workitem_type_names, IMV_WORKITEM_PACKAGES, IMV_WORKITEM_UDP_PORT_BLOCK "TCPOP", "TCPBL", "UDPOP", - "UDPBL" + "UDPBL", + "SWIDT" ); /** diff --git a/src/libimcv/imv/imv_workitem.h b/src/libimcv/imv/imv_workitem.h index f6ca3ea68..868997797 100644 --- a/src/libimcv/imv/imv_workitem.h +++ b/src/libimcv/imv/imv_workitem.h @@ -43,7 +43,8 @@ enum imv_workitem_type_t { IMV_WORKITEM_TCP_PORT_OPEN = 11, IMV_WORKITEM_TCP_PORT_BLOCK = 12, IMV_WORKITEM_UDP_PORT_OPEN = 13, - IMV_WORKITEM_UDP_PORT_BLOCK = 14 + IMV_WORKITEM_UDP_PORT_BLOCK = 14, + IMV_WORKITEM_SWID_TAGS = 15 }; extern enum_name_t *imv_workitem_type_names; diff --git a/src/libpts/Makefile.am b/src/libpts/Makefile.am index 162af5d0d..06246f392 100644 --- a/src/libpts/Makefile.am +++ b/src/libpts/Makefile.am @@ -35,24 +35,27 @@ libpts_la_SOURCES = \ pts/components/ita/ita_comp_tboot.h pts/components/ita/ita_comp_tboot.c \ pts/components/ita/ita_comp_tgrub.h pts/components/ita/ita_comp_tgrub.c \ pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \ + swid/swid_tag_id.h swid/swid_tag_id.c \ tcg/tcg_attr.h tcg/tcg_attr.c \ - tcg/tcg_pts_attr_proto_caps.h tcg/tcg_pts_attr_proto_caps.c \ - tcg/tcg_pts_attr_dh_nonce_params_req.h tcg/tcg_pts_attr_dh_nonce_params_req.c \ - tcg/tcg_pts_attr_dh_nonce_params_resp.h tcg/tcg_pts_attr_dh_nonce_params_resp.c \ - tcg/tcg_pts_attr_dh_nonce_finish.h tcg/tcg_pts_attr_dh_nonce_finish.c \ - tcg/tcg_pts_attr_meas_algo.h tcg/tcg_pts_attr_meas_algo.c \ - tcg/tcg_pts_attr_get_tpm_version_info.h tcg/tcg_pts_attr_get_tpm_version_info.c \ - tcg/tcg_pts_attr_tpm_version_info.h tcg/tcg_pts_attr_tpm_version_info.c \ - tcg/tcg_pts_attr_get_aik.h tcg/tcg_pts_attr_get_aik.c \ - tcg/tcg_pts_attr_aik.h tcg/tcg_pts_attr_aik.c \ - tcg/tcg_pts_attr_req_func_comp_evid.h tcg/tcg_pts_attr_req_func_comp_evid.c \ - tcg/tcg_pts_attr_gen_attest_evid.h tcg/tcg_pts_attr_gen_attest_evid.c \ - tcg/tcg_pts_attr_simple_comp_evid.h tcg/tcg_pts_attr_simple_comp_evid.c \ - tcg/tcg_pts_attr_simple_evid_final.h tcg/tcg_pts_attr_simple_evid_final.c \ - tcg/tcg_pts_attr_req_file_meas.h tcg/tcg_pts_attr_req_file_meas.c \ - tcg/tcg_pts_attr_file_meas.h tcg/tcg_pts_attr_file_meas.c \ - tcg/tcg_pts_attr_req_file_meta.h tcg/tcg_pts_attr_req_file_meta.c \ - tcg/tcg_pts_attr_unix_file_meta.h tcg/tcg_pts_attr_unix_file_meta.c + tcg/pts/tcg_pts_attr_proto_caps.h tcg/pts/tcg_pts_attr_proto_caps.c \ + tcg/pts/tcg_pts_attr_dh_nonce_params_req.h tcg/pts/tcg_pts_attr_dh_nonce_params_req.c \ + tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c \ + tcg/pts/tcg_pts_attr_dh_nonce_finish.h tcg/pts/tcg_pts_attr_dh_nonce_finish.c \ + tcg/pts/tcg_pts_attr_meas_algo.h tcg/pts/tcg_pts_attr_meas_algo.c \ + tcg/pts/tcg_pts_attr_get_tpm_version_info.h tcg/pts/tcg_pts_attr_get_tpm_version_info.c \ + tcg/pts/tcg_pts_attr_tpm_version_info.h tcg/pts/tcg_pts_attr_tpm_version_info.c \ + tcg/pts/tcg_pts_attr_get_aik.h tcg/pts/tcg_pts_attr_get_aik.c \ + tcg/pts/tcg_pts_attr_aik.h tcg/pts/tcg_pts_attr_aik.c \ + tcg/pts/tcg_pts_attr_req_func_comp_evid.h tcg/pts/tcg_pts_attr_req_func_comp_evid.c \ + tcg/pts/tcg_pts_attr_gen_attest_evid.h tcg/pts/tcg_pts_attr_gen_attest_evid.c \ + tcg/pts/tcg_pts_attr_simple_comp_evid.h tcg/pts/tcg_pts_attr_simple_comp_evid.c \ + tcg/pts/tcg_pts_attr_simple_evid_final.h tcg/pts/tcg_pts_attr_simple_evid_final.c \ + tcg/pts/tcg_pts_attr_req_file_meas.h tcg/pts/tcg_pts_attr_req_file_meas.c \ + tcg/pts/tcg_pts_attr_file_meas.h tcg/pts/tcg_pts_attr_file_meas.c \ + tcg/pts/tcg_pts_attr_req_file_meta.h tcg/pts/tcg_pts_attr_req_file_meta.c \ + tcg/pts/tcg_pts_attr_unix_file_meta.h tcg/pts/tcg_pts_attr_unix_file_meta.c \ + tcg/swid/tcg_swid_attr_req.h tcg/swid/tcg_swid_attr_req.c \ + tcg/swid/tcg_swid_attr_tag_id_inv.h tcg/swid/tcg_swid_attr_tag_id_inv.c SUBDIRS = . @@ -63,3 +66,11 @@ endif if USE_IMV_ATTESTATION SUBDIRS += plugins/imv_attestation endif + +if USE_IMC_SWID + SUBDIRS += plugins/imc_swid +endif + +if USE_IMV_SWID + SUBDIRS += plugins/imv_swid +endif diff --git a/src/libpts/plugins/imc_attestation/imc_attestation.c b/src/libpts/plugins/imc_attestation/imc_attestation.c index bb327e936..e783b8f29 100644 --- a/src/libpts/plugins/imc_attestation/imc_attestation.c +++ b/src/libpts/plugins/imc_attestation/imc_attestation.c @@ -29,8 +29,8 @@ #include -#include -#include +#include +#include #include diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_process.c b/src/libpts/plugins/imc_attestation/imc_attestation_process.c index 88d24dd88..92e2e3abe 100644 --- a/src/libpts/plugins/imc_attestation/imc_attestation_process.c +++ b/src/libpts/plugins/imc_attestation/imc_attestation_process.c @@ -25,23 +25,23 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/libpts/plugins/imc_swid/Makefile.am b/src/libpts/plugins/imc_swid/Makefile.am new file mode 100644 index 000000000..8c4410562 --- /dev/null +++ b/src/libpts/plugins/imc_swid/Makefile.am @@ -0,0 +1,19 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libimcv \ + -I$(top_srcdir)/src/libpts + +AM_CFLAGS = \ + -rdynamic + +imcv_LTLIBRARIES = imc-swid.la + +imc_swid_la_LIBADD = \ + $(top_builddir)/src/libimcv/libimcv.la \ + $(top_builddir)/src/libpts/libpts.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la + +imc_swid_la_SOURCES = imc_swid.c imc_swid_state.h imc_swid_state.c + +imc_swid_la_LDFLAGS = -module -avoid-version diff --git a/src/libpts/plugins/imc_swid/imc_swid.c b/src/libpts/plugins/imc_swid/imc_swid.c new file mode 100644 index 000000000..f83ced16c --- /dev/null +++ b/src/libpts/plugins/imc_swid/imc_swid.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2013 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 "imc_swid_state.h" + +#include "libpts.h" +#include "swid/swid_tag_id.h" +#include "tcg/swid/tcg_swid_attr_req.h" +#include "tcg/swid/tcg_swid_attr_tag_id_inv.h" + +#include +#include + +#include + +#include +#include + +/* IMC definitions */ + +static const char imc_name[] = "SWID"; + +static pen_type_t msg_types[] = { + { PEN_TCG, PA_SUBTYPE_TCG_SWID } +}; + +static imc_agent_t *imc_swid; + +/** + * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3 + */ +TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id, + TNC_Version min_version, + TNC_Version max_version, + TNC_Version *actual_version) +{ + if (imc_swid) + { + DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name); + return TNC_RESULT_ALREADY_INITIALIZED; + } + imc_swid = imc_agent_create(imc_name, msg_types, countof(msg_types), + imc_id, actual_version); + if (!imc_swid) + { + return TNC_RESULT_FATAL; + } + + libpts_init(); + + 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.8.2 of TCG TNC IF-IMC Specification 1.3 + */ +TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_ConnectionState new_state) +{ + imc_state_t *state; + + if (!imc_swid) + { + 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_swid_state_create(connection_id); + return imc_swid->create_state(imc_swid, state); + case TNC_CONNECTION_STATE_HANDSHAKE: + if (imc_swid->change_state(imc_swid, connection_id, new_state, + &state) != TNC_RESULT_SUCCESS) + { + return TNC_RESULT_FATAL; + } + state->set_result(state, imc_id, + TNC_IMV_EVALUATION_RESULT_DONT_KNOW); + return TNC_RESULT_SUCCESS; + case TNC_CONNECTION_STATE_DELETE: + return imc_swid->delete_state(imc_swid, connection_id); + default: + return imc_swid->change_state(imc_swid, connection_id, + new_state, NULL); + } +} + +/** + * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3 + */ +TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id, + TNC_ConnectionID connection_id) +{ + imc_state_t *state; + + if (!imc_swid) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + if (!imc_swid->get_state(imc_swid, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + + return TNC_RESULT_SUCCESS; +} + +static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg) +{ + imc_msg_t *out_msg; + imc_swid_state_t *swid_state; + enumerator_t *enumerator; + pa_tnc_attr_t *attr; + pen_type_t type; + TNC_Result result; + bool fatal_error = FALSE; + + /* parse received PA-TNC message and handle local and remote errors */ + result = in_msg->receive(in_msg, &fatal_error); + if (result != TNC_RESULT_SUCCESS) + { + return result; + } + out_msg = imc_msg_create_as_reply(in_msg); + swid_state = (imc_swid_state_t*)state; + + /* analyze PA-TNC attributes */ + enumerator = in_msg->create_attribute_enumerator(in_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + tcg_swid_attr_req_t *attr_req; + tcg_swid_attr_tag_id_inv_t *attr_tag_id_inv; + swid_tag_id_t *tag_id; + u_int8_t flags; + u_int32_t request_id, eid_epoch; + + type = attr->get_type(attr); + + if (type.vendor_id != PEN_TCG || type.type != TCG_SWID_REQUEST) + { + continue; + } + + attr_req = (tcg_swid_attr_req_t*)attr; + flags = attr_req->get_flags(attr_req); + request_id = attr_req->get_request_id(attr_req); + if (flags & TCG_SWID_ATTR_REQ_FLAG_R) + { + eid_epoch = swid_state->get_eid_epoch(swid_state); + attr = tcg_swid_attr_tag_id_inv_create(request_id, eid_epoch, 1); + attr_tag_id_inv = (tcg_swid_attr_tag_id_inv_t*)attr; + tag_id = swid_tag_id_create( + chunk_from_str("regid.2004-03.org.strongswan"), + chunk_from_str("strongSwan-5-1-0"), + chunk_empty); + attr_tag_id_inv->add_tag_id(attr_tag_id_inv, tag_id); + out_msg->add_attribute(out_msg, attr); + } + } + enumerator->destroy(enumerator); + + if (fatal_error) + { + result = TNC_RESULT_FATAL; + } + else + { + result = out_msg->send(out_msg, TRUE); + } + out_msg->destroy(out_msg); + + return result; +} + +/** + * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3 + + */ +TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_MessageType msg_type) +{ + imc_state_t *state; + imc_msg_t *in_msg; + TNC_Result result; + + if (!imc_swid) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + if (!imc_swid->get_state(imc_swid, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + in_msg = imc_msg_create_from_data(imc_swid, state, connection_id, msg_type, + chunk_create(msg, msg_len)); + result = receive_message(state, in_msg); + in_msg->destroy(in_msg); + + return result; +} + +/** + * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3 + */ +TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_UInt32 msg_flags, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype, + TNC_UInt32 src_imv_id, + TNC_UInt32 dst_imc_id) +{ + imc_state_t *state; + imc_msg_t *in_msg; + TNC_Result result; + + if (!imc_swid) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + if (!imc_swid->get_state(imc_swid, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + in_msg = imc_msg_create_from_long_data(imc_swid, state, connection_id, + src_imv_id, dst_imc_id,msg_vid, msg_subtype, + chunk_create(msg, msg_len)); + result =receive_message(state, in_msg); + in_msg->destroy(in_msg); + + return result; +} + +/** + * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3 + */ +TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id, + TNC_ConnectionID connection_id) +{ + if (!imc_swid) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3 + */ +TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id) +{ + if (!imc_swid) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + + libpts_deinit(); + + imc_swid->destroy(imc_swid); + imc_swid = NULL; + + return TNC_RESULT_SUCCESS; +} + +/** + * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3 + */ +TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id, + TNC_TNCC_BindFunctionPointer bind_function) +{ + if (!imc_swid) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imc_swid->bind_functions(imc_swid, bind_function); +} diff --git a/src/libpts/plugins/imc_swid/imc_swid_state.c b/src/libpts/plugins/imc_swid/imc_swid_state.c new file mode 100644 index 000000000..11f467303 --- /dev/null +++ b/src/libpts/plugins/imc_swid/imc_swid_state.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2013 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 "imc_swid_state.h" + +#include + +#include + +typedef struct private_imc_swid_state_t private_imc_swid_state_t; + +/** + * Private data of an imc_swid_state_t object. + */ +struct private_imc_swid_state_t { + + /** + * Public members of imc_swid_state_t + */ + imc_swid_state_t public; + + /** + * TNCCS connection ID + */ + TNC_ConnectionID connection_id; + + /** + * TNCCS connection state + */ + TNC_ConnectionState state; + + /** + * Assessment/Evaluation Result + */ + TNC_IMV_Evaluation_Result result; + + /** + * Does the TNCCS connection support long message types? + */ + bool has_long; + + /** + * Does the TNCCS connection support exclusive delivery? + */ + bool has_excl; + + /** + * Maximum PA-TNC message size for this TNCCS connection + */ + u_int32_t max_msg_len; + + /** + * Event ID Epoch + */ + u_int32_t eid_epoch; +}; + +METHOD(imc_state_t, get_connection_id, TNC_ConnectionID, + private_imc_swid_state_t *this) +{ + return this->connection_id; +} + +METHOD(imc_state_t, has_long, bool, + private_imc_swid_state_t *this) +{ + return this->has_long; +} + +METHOD(imc_state_t, has_excl, bool, + private_imc_swid_state_t *this) +{ + return this->has_excl; +} + +METHOD(imc_state_t, set_flags, void, + private_imc_swid_state_t *this, bool has_long, bool has_excl) +{ + this->has_long = has_long; + this->has_excl = has_excl; +} + +METHOD(imc_state_t, set_max_msg_len, void, + private_imc_swid_state_t *this, u_int32_t max_msg_len) +{ + this->max_msg_len = max_msg_len; +} + +METHOD(imc_state_t, get_max_msg_len, u_int32_t, + private_imc_swid_state_t *this) +{ + return this->max_msg_len; +} + +METHOD(imc_state_t, change_state, void, + private_imc_swid_state_t *this, TNC_ConnectionState new_state) +{ + this->state = new_state; +} + +METHOD(imc_state_t, set_result, void, + private_imc_swid_state_t *this, TNC_IMCID id, + TNC_IMV_Evaluation_Result result) +{ + this->result = result; +} + +METHOD(imc_state_t, get_result, bool, + private_imc_swid_state_t *this, TNC_IMCID id, + TNC_IMV_Evaluation_Result *result) +{ + if (result) + { + *result = this->result; + } + return this->result != TNC_IMV_EVALUATION_RESULT_DONT_KNOW; +} + +METHOD(imc_state_t, destroy, void, + private_imc_swid_state_t *this) +{ + free(this); +} + +METHOD(imc_swid_state_t, get_eid_epoch, u_int32_t, + private_imc_swid_state_t *this) +{ + return this->eid_epoch; +} + +/** + * Described in header. + */ +imc_state_t *imc_swid_state_create(TNC_ConnectionID connection_id) +{ + private_imc_swid_state_t *this; + u_int32_t eid_epoch; + nonce_gen_t *ng; + + ng = lib->crypto->create_nonce_gen(lib->crypto); + if (!ng || !ng->get_nonce(ng, 4, (u_int8_t*)&eid_epoch)) + { + DBG1(DBG_TNC, "failed to generate random EID epoch value"); + DESTROY_IF(ng); + return NULL; + } + ng->destroy(ng); + + DBG1(DBG_IMC, "creating random EID epoch 0x%08x", eid_epoch); + + INIT(this, + .public = { + .interface = { + .get_connection_id = _get_connection_id, + .has_long = _has_long, + .has_excl = _has_excl, + .set_flags = _set_flags, + .set_max_msg_len = _set_max_msg_len, + .get_max_msg_len = _get_max_msg_len, + .change_state = _change_state, + .set_result = _set_result, + .get_result = _get_result, + .destroy = _destroy, + }, + .get_eid_epoch = _get_eid_epoch, + }, + .state = TNC_CONNECTION_STATE_CREATE, + .result = TNC_IMV_EVALUATION_RESULT_DONT_KNOW, + .connection_id = connection_id, + .eid_epoch = eid_epoch, + ); + + + return &this->public.interface; +} + + diff --git a/src/libpts/plugins/imc_swid/imc_swid_state.h b/src/libpts/plugins/imc_swid/imc_swid_state.h new file mode 100644 index 000000000..cb3ac4589 --- /dev/null +++ b/src/libpts/plugins/imc_swid/imc_swid_state.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 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_swid imc_swid + * @ingroup libimcv_plugins + * + * @defgroup imc_swid_state_t imc_swid_state + * @{ @ingroup imc_swid + */ + +#ifndef IMC_SWID_STATE_H_ +#define IMC_SWID_STATE_H_ + +#include +#include + +typedef struct imc_swid_state_t imc_swid_state_t; + +/** + * Internal state of an imc_swid_t connection instance + */ +struct imc_swid_state_t { + + /** + * imc_state_t interface + */ + imc_state_t interface; + + /** + * Get Event ID Epoch + * + * @return Event ID Epoch + */ + u_int32_t (*get_eid_epoch)(imc_swid_state_t *this); + +}; + +/** + * Create an imc_swid_state_t instance + * + * @param id connection ID + */ +imc_state_t* imc_swid_state_create(TNC_ConnectionID id); + +#endif /** IMC_SWID_STATE_H_ @}*/ diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c index fb934127e..9da9ae0b0 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c @@ -35,8 +35,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.c b/src/libpts/plugins/imv_attestation/imv_attestation_build.c index 3e09f7204..2d3ff8360 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_build.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_build.c @@ -16,14 +16,14 @@ #include "imv_attestation_build.h" #include "imv_attestation_state.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.c b/src/libpts/plugins/imv_attestation/imv_attestation_process.c index d422ebcda..7319c0b6b 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_process.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.c @@ -20,15 +20,15 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/libpts/plugins/imv_swid/Makefile.am b/src/libpts/plugins/imv_swid/Makefile.am new file mode 100644 index 000000000..874fa150b --- /dev/null +++ b/src/libpts/plugins/imv_swid/Makefile.am @@ -0,0 +1,21 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libimcv \ + -I$(top_srcdir)/src/libpts + +AM_CFLAGS = \ + -rdynamic + +imcv_LTLIBRARIES = imv-swid.la + +imv_swid_la_LIBADD = \ + $(top_builddir)/src/libimcv/libimcv.la \ + $(top_builddir)/src/libpts/libpts.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la + +imv_swid_la_SOURCES = \ + imv_swid.c imv_swid_state.h imv_swid_state.c \ + imv_swid_agent.h imv_swid_agent.c + +imv_swid_la_LDFLAGS = -module -avoid-version diff --git a/src/libpts/plugins/imv_swid/imv_swid.c b/src/libpts/plugins/imv_swid/imv_swid.c new file mode 100644 index 000000000..cab011580 --- /dev/null +++ b/src/libpts/plugins/imv_swid/imv_swid.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 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 "imv_swid_agent.h" + +static const char imv_name[] = "SWID"; +static const imv_agent_create_t imv_agent_create = imv_swid_agent_create; + +/* include generic TGC TNC IF-IMV API code below */ + +#include + diff --git a/src/libpts/plugins/imv_swid/imv_swid_agent.c b/src/libpts/plugins/imv_swid/imv_swid_agent.c new file mode 100644 index 000000000..eb477a907 --- /dev/null +++ b/src/libpts/plugins/imv_swid/imv_swid_agent.c @@ -0,0 +1,425 @@ +/* + * Copyright (C) 2013 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 "imv_swid_agent.h" +#include "imv_swid_state.h" + +#include "libpts.h" +#include "tcg/swid/tcg_swid_attr_req.h" +#include "tcg/swid/tcg_swid_attr_tag_id_inv.h" + +#include +#include +#include + +#include +#include + +#include +#include + +typedef struct private_imv_swid_agent_t private_imv_swid_agent_t; + +/* Subscribed PA-TNC message subtypes */ +static pen_type_t msg_types[] = { + { PEN_TCG, PA_SUBTYPE_TCG_SWID } +}; + +/** + * Private data of an imv_swid_agent_t object. + */ +struct private_imv_swid_agent_t { + + /** + * Public members of imv_swid_agent_t + */ + imv_agent_if_t public; + + /** + * IMV agent responsible for generic functions + */ + imv_agent_t *agent; + +}; + +METHOD(imv_agent_if_t, bind_functions, TNC_Result, + private_imv_swid_agent_t *this, TNC_TNCS_BindFunctionPointer bind_function) +{ + return this->agent->bind_functions(this->agent, bind_function); +} + +METHOD(imv_agent_if_t, notify_connection_change, TNC_Result, + private_imv_swid_agent_t *this, TNC_ConnectionID id, + TNC_ConnectionState new_state) +{ + imv_state_t *state; + + switch (new_state) + { + case TNC_CONNECTION_STATE_CREATE: + state = imv_swid_state_create(id); + return this->agent->create_state(this->agent, state); + case TNC_CONNECTION_STATE_DELETE: + return this->agent->delete_state(this->agent, id); + default: + return this->agent->change_state(this->agent, id, new_state, NULL); + } +} + +/** + * Process a received message + */ +static TNC_Result receive_msg(private_imv_swid_agent_t *this, + imv_state_t *state, imv_msg_t *in_msg) +{ + imv_msg_t *out_msg; + imv_session_t *session; + imv_workitem_t *workitem, *found = NULL; + enumerator_t *enumerator; + pa_tnc_attr_t *attr; + pen_type_t type; + TNC_IMV_Evaluation_Result eval; + TNC_IMV_Action_Recommendation rec; + TNC_Result result; + char *result_str; + bool fatal_error = FALSE; + + /* parse received PA-TNC message and handle local and remote errors */ + result = in_msg->receive(in_msg, &fatal_error); + if (result != TNC_RESULT_SUCCESS) + { + return result; + } + + session = state->get_session(state); + + /* analyze PA-TNC attributes */ + enumerator = in_msg->create_attribute_enumerator(in_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + type = attr->get_type(attr); + + if (type.vendor_id != PEN_TCG) + { + continue; + } + switch (type.type) + { + case TCG_SWID_TAG_ID_INVENTORY: + { + tcg_swid_attr_tag_id_inv_t *attr_cast; + u_int32_t request_id; + swid_tag_id_t *tag_id; + chunk_t tag_creator, unique_sw_id; + enumerator_t *et, *ew; + + attr_cast = (tcg_swid_attr_tag_id_inv_t*)attr; + request_id = attr_cast->get_request_id(attr_cast); + + DBG2(DBG_IMV, "received SWID tag ID inventory for request %d", + request_id); + et = attr_cast->create_tag_id_enumerator(attr_cast); + while (et->enumerate(et, &tag_id)) + { + tag_creator = tag_id->get_tag_creator(tag_id); + unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL); + DBG3(DBG_IMV, " %.*s_%.*s.swidtag", + tag_creator.len, tag_creator.ptr, + unique_sw_id.len, unique_sw_id.ptr); + } + et->destroy(et); + + if (request_id == 0) + { + /* TODO handle subscribed messages */ + break; + } + + ew = session->create_workitem_enumerator(session); + while (ew->enumerate(ew, &workitem)) + { + if (workitem->get_id(workitem) == request_id) + { + found = workitem; + break; + } + } + + if (!found) + { + DBG1(DBG_IMV, "no workitem found for SWID tag ID inventory " + "with request ID %d", request_id); + ew->destroy(ew); + break; + } + + eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT; + result_str = "received SWID tag ID inventory"; + session->remove_workitem(session, ew); + ew->destroy(ew); + rec = found->set_result(found, result_str, eval); + state->update_recommendation(state, rec, eval); + imcv_db->finalize_workitem(imcv_db, found); + found->destroy(found); + break; + } + case TCG_SWID_TAG_INVENTORY: + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + if (fatal_error) + { + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, + TNC_IMV_EVALUATION_RESULT_ERROR); + out_msg = imv_msg_create_as_reply(in_msg); + result = out_msg->send_assessment(out_msg); + out_msg->destroy(out_msg); + if (result != TNC_RESULT_SUCCESS) + { + return result; + } + return this->agent->provide_recommendation(this->agent, state); + } + + return TNC_RESULT_SUCCESS; +} + +METHOD(imv_agent_if_t, receive_message, TNC_Result, + private_imv_swid_agent_t *this, TNC_ConnectionID id, + TNC_MessageType msg_type, chunk_t msg) +{ + imv_state_t *state; + imv_msg_t *in_msg; + TNC_Result result; + + if (!this->agent->get_state(this->agent, id, &state)) + { + return TNC_RESULT_FATAL; + } + in_msg = imv_msg_create_from_data(this->agent, state, id, msg_type, msg); + result = receive_msg(this, state, in_msg); + in_msg->destroy(in_msg); + + return result; +} + +METHOD(imv_agent_if_t, receive_message_long, TNC_Result, + private_imv_swid_agent_t *this, TNC_ConnectionID id, + TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id, + TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype, chunk_t msg) +{ + imv_state_t *state; + imv_msg_t *in_msg; + TNC_Result result; + + if (!this->agent->get_state(this->agent, id, &state)) + { + return TNC_RESULT_FATAL; + } + in_msg = imv_msg_create_from_long_data(this->agent, state, id, + src_imc_id, dst_imv_id, msg_vid, msg_subtype, msg); + result = receive_msg(this, state, in_msg); + in_msg->destroy(in_msg); + + return result; + +} + +METHOD(imv_agent_if_t, batch_ending, TNC_Result, + private_imv_swid_agent_t *this, TNC_ConnectionID id) +{ + imv_msg_t *out_msg; + imv_state_t *state; + imv_session_t *session; + imv_workitem_t *workitem; + imv_swid_state_t *swid_state; + imv_swid_handshake_state_t handshake_state; + pa_tnc_attr_t *attr; + TNC_IMVID imv_id; + TNC_Result result = TNC_RESULT_SUCCESS; + bool no_workitems = TRUE; + u_int32_t request_id; + u_int8_t flags; + enumerator_t *enumerator; + + if (!this->agent->get_state(this->agent, id, &state)) + { + return TNC_RESULT_FATAL; + } + swid_state = (imv_swid_state_t*)state; + handshake_state = swid_state->get_handshake_state(swid_state); + session = state->get_session(state); + imv_id = this->agent->get_id(this->agent); + + if (handshake_state == IMV_SWID_STATE_END) + { + return TNC_RESULT_SUCCESS; + } + + /* create an empty out message - we might need it */ + out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY, + msg_types[0]); + + if (!session) + { + DBG2(DBG_IMV, "no workitems available - no evaluation possible"); + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_ALLOW, + TNC_IMV_EVALUATION_RESULT_DONT_KNOW); + result = out_msg->send_assessment(out_msg); + out_msg->destroy(out_msg); + swid_state->set_handshake_state(swid_state, IMV_SWID_STATE_END); + + if (result != TNC_RESULT_SUCCESS) + { + return result; + } + return this->agent->provide_recommendation(this->agent, state); + } + + if (handshake_state == IMV_SWID_STATE_INIT) + { + enumerator = session->create_workitem_enumerator(session); + if (enumerator) + { + while (enumerator->enumerate(enumerator, &workitem)) + { + if (workitem->get_imv_id(workitem) != TNC_IMVID_ANY || + workitem->get_type(workitem) != IMV_WORKITEM_SWID_TAGS) + { + continue; + } + + flags = TCG_SWID_ATTR_REQ_FLAG_NONE; + if (strchr(workitem->get_arg_str(workitem), 'R')) + { + flags |= TCG_SWID_ATTR_REQ_FLAG_R; + } + if (strchr(workitem->get_arg_str(workitem), 'S')) + { + flags |= TCG_SWID_ATTR_REQ_FLAG_S; + } + if (strchr(workitem->get_arg_str(workitem), 'C')) + { + flags |= TCG_SWID_ATTR_REQ_FLAG_C; + } + request_id = workitem->get_id(workitem); + + DBG2(DBG_IMV, "IMV %d issues SWID tag request %d", + imv_id, request_id); + attr = tcg_swid_attr_req_create(flags, request_id, 0); + out_msg->add_attribute(out_msg, attr); + workitem->set_imv_id(workitem, imv_id); + no_workitems = FALSE; + } + enumerator->destroy(enumerator); + + if (no_workitems) + { + DBG2(DBG_IMV, "IMV %d has no workitems - " + "no evaluation requested", imv_id); + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_ALLOW, + TNC_IMV_EVALUATION_RESULT_DONT_KNOW); + } + handshake_state = IMV_SWID_STATE_WORKITEMS; + swid_state->set_handshake_state(swid_state, handshake_state); + } + } + + /* finalized all workitems ? */ + if (handshake_state == IMV_SWID_STATE_WORKITEMS && + session->get_workitem_count(session, imv_id) == 0) + { + result = out_msg->send_assessment(out_msg); + out_msg->destroy(out_msg); + swid_state->set_handshake_state(swid_state, IMV_SWID_STATE_END); + + if (result != TNC_RESULT_SUCCESS) + { + return result; + } + return this->agent->provide_recommendation(this->agent, state); + } + + /* send non-empty PA-TNC message with excl flag not set */ + if (out_msg->get_attribute_count(out_msg)) + { + result = out_msg->send(out_msg, FALSE); + } + out_msg->destroy(out_msg); + + return result; +} + +METHOD(imv_agent_if_t, solicit_recommendation, TNC_Result, + private_imv_swid_agent_t *this, TNC_ConnectionID id) +{ + imv_state_t *state; + + if (!this->agent->get_state(this->agent, id, &state)) + { + return TNC_RESULT_FATAL; + } + return this->agent->provide_recommendation(this->agent, state); +} + +METHOD(imv_agent_if_t, destroy, void, + private_imv_swid_agent_t *this) +{ + this->agent->destroy(this->agent); + free(this); + libpts_deinit(); +} + +/** + * Described in header. + */ +imv_agent_if_t *imv_swid_agent_create(const char *name, TNC_IMVID id, + TNC_Version *actual_version) +{ + private_imv_swid_agent_t *this; + imv_agent_t *agent; + + agent = imv_agent_create(name, msg_types, countof(msg_types), id, + actual_version); + if (!agent) + { + return NULL; + } + + INIT(this, + .public = { + .bind_functions = _bind_functions, + .notify_connection_change = _notify_connection_change, + .receive_message = _receive_message, + .receive_message_long = _receive_message_long, + .batch_ending = _batch_ending, + .solicit_recommendation = _solicit_recommendation, + .destroy = _destroy, + }, + .agent = agent, + ); + + libpts_init(); + + return &this->public; +} + diff --git a/src/libpts/plugins/imv_swid/imv_swid_agent.h b/src/libpts/plugins/imv_swid/imv_swid_agent.h new file mode 100644 index 000000000..4218040bc --- /dev/null +++ b/src/libpts/plugins/imv_swid/imv_swid_agent.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013 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 imv_swid_agent_t imv_swid_agent + * @{ @ingroup imv_swid + */ + +#ifndef IMV_SWID_AGENT_H_ +#define IMV_SWID_AGENT_H_ + +#include + +/** + * Creates an SWID IMV agent + * + * @param name Name of the IMV + * @param id ID of the IMV + * @param actual_version TNC IF-IMV version + */ +imv_agent_if_t* imv_swid_agent_create(const char* name, TNC_IMVID id, + TNC_Version *actual_version); + +#endif /** IMV_SWID_AGENT_H_ @}*/ diff --git a/src/libpts/plugins/imv_swid/imv_swid_state.c b/src/libpts/plugins/imv_swid/imv_swid_state.c new file mode 100644 index 000000000..5be8c0254 --- /dev/null +++ b/src/libpts/plugins/imv_swid/imv_swid_state.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2013 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 "imv_swid_state.h" +#include "imv/imv_lang_string.h" +#include "imv/imv_reason_string.h" +#include "imv/imv_remediation_string.h" + +#include + +#include +#include + +typedef struct private_imv_swid_state_t private_imv_swid_state_t; + +/** + * Private data of an imv_swid_state_t object. + */ +struct private_imv_swid_state_t { + + /** + * Public members of imv_swid_state_t + */ + imv_swid_state_t public; + + /** + * TNCCS connection ID + */ + TNC_ConnectionID connection_id; + + /** + * TNCCS connection state + */ + TNC_ConnectionState state; + + /** + * Does the TNCCS connection support long message types? + */ + bool has_long; + + /** + * Does the TNCCS connection support exclusive delivery? + */ + bool has_excl; + + /** + * Maximum PA-TNC message size for this TNCCS connection + */ + u_int32_t max_msg_len; + + /** + * Flags set for completed actions + */ + u_int32_t action_flags; + + /** + * Access Requestor ID Type + */ + u_int32_t ar_id_type; + + /** + * Access Requestor ID Value + */ + chunk_t ar_id_value; + + /** + * IMV database session associatied with TNCCS connection + */ + imv_session_t *session; + + /** + * IMV action recommendation + */ + TNC_IMV_Action_Recommendation rec; + + /** + * IMV evaluation result + */ + TNC_IMV_Evaluation_Result eval; + + /** + * IMV Scanner handshake state + */ + imv_swid_handshake_state_t handshake_state; + + /** + * TNC Reason String + */ + imv_reason_string_t *reason_string; + + /** + * IETF Remediation Instructions String + */ + imv_remediation_string_t *remediation_string; + +}; + +METHOD(imv_state_t, get_connection_id, TNC_ConnectionID, + private_imv_swid_state_t *this) +{ + return this->connection_id; +} + +METHOD(imv_state_t, has_long, bool, + private_imv_swid_state_t *this) +{ + return this->has_long; +} + +METHOD(imv_state_t, has_excl, bool, + private_imv_swid_state_t *this) +{ + return this->has_excl; +} + +METHOD(imv_state_t, set_flags, void, + private_imv_swid_state_t *this, bool has_long, bool has_excl) +{ + this->has_long = has_long; + this->has_excl = has_excl; +} + +METHOD(imv_state_t, set_max_msg_len, void, + private_imv_swid_state_t *this, u_int32_t max_msg_len) +{ + this->max_msg_len = max_msg_len; +} + +METHOD(imv_state_t, get_max_msg_len, u_int32_t, + private_imv_swid_state_t *this) +{ + return this->max_msg_len; +} + +METHOD(imv_state_t, set_action_flags, void, + private_imv_swid_state_t *this, u_int32_t flags) +{ + this->action_flags |= flags; +} + +METHOD(imv_state_t, get_action_flags, u_int32_t, + private_imv_swid_state_t *this) +{ + return this->action_flags; +} + +METHOD(imv_state_t, set_ar_id, void, + private_imv_swid_state_t *this, u_int32_t id_type, chunk_t id_value) +{ + this->ar_id_type = id_type; + this->ar_id_value = chunk_clone(id_value); +} + +METHOD(imv_state_t, get_ar_id, chunk_t, + private_imv_swid_state_t *this, u_int32_t *id_type) +{ + if (id_type) + { + *id_type = this->ar_id_type; + } + return this->ar_id_value; +} + +METHOD(imv_state_t, set_session, void, + private_imv_swid_state_t *this, imv_session_t *session) +{ + this->session = session; +} + +METHOD(imv_state_t, get_session, imv_session_t*, + private_imv_swid_state_t *this) +{ + return this->session; +} + +METHOD(imv_state_t, change_state, void, + private_imv_swid_state_t *this, TNC_ConnectionState new_state) +{ + this->state = new_state; +} + +METHOD(imv_state_t, get_recommendation, void, + private_imv_swid_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_swid_state_t *this, TNC_IMV_Action_Recommendation rec, + TNC_IMV_Evaluation_Result eval) +{ + this->rec = rec; + this->eval = eval; +} + +METHOD(imv_state_t, update_recommendation, void, + private_imv_swid_state_t *this, TNC_IMV_Action_Recommendation rec, + TNC_IMV_Evaluation_Result eval) +{ + this->rec = tncif_policy_update_recommendation(this->rec, rec); + this->eval = tncif_policy_update_evaluation(this->eval, eval); +} + +METHOD(imv_state_t, get_reason_string, bool, + private_imv_swid_state_t *this, enumerator_t *language_enumerator, + chunk_t *reason_string, char **reason_language) +{ + return FALSE; +} + +METHOD(imv_state_t, get_remediation_instructions, bool, + private_imv_swid_state_t *this, enumerator_t *language_enumerator, + chunk_t *string, char **lang_code, char **uri) +{ + return FALSE; +} + +METHOD(imv_state_t, destroy, void, + private_imv_swid_state_t *this) +{ + DESTROY_IF(this->session); + DESTROY_IF(this->reason_string); + DESTROY_IF(this->remediation_string); + free(this->ar_id_value.ptr); + free(this); +} + +METHOD(imv_swid_state_t, set_handshake_state, void, + private_imv_swid_state_t *this, imv_swid_handshake_state_t new_state) +{ + this->handshake_state = new_state; +} + +METHOD(imv_swid_state_t, get_handshake_state, imv_swid_handshake_state_t, + private_imv_swid_state_t *this) +{ + return this->handshake_state; +} + +/** + * Described in header. + */ +imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id) +{ + private_imv_swid_state_t *this; + + INIT(this, + .public = { + .interface = { + .get_connection_id = _get_connection_id, + .has_long = _has_long, + .has_excl = _has_excl, + .set_flags = _set_flags, + .set_max_msg_len = _set_max_msg_len, + .get_max_msg_len = _get_max_msg_len, + .set_action_flags = _set_action_flags, + .get_action_flags = _get_action_flags, + .set_ar_id = _set_ar_id, + .get_ar_id = _get_ar_id, + .set_session = _set_session, + .get_session= _get_session, + .change_state = _change_state, + .get_recommendation = _get_recommendation, + .set_recommendation = _set_recommendation, + .update_recommendation = _update_recommendation, + .get_reason_string = _get_reason_string, + .get_remediation_instructions = _get_remediation_instructions, + .destroy = _destroy, + }, + .set_handshake_state = _set_handshake_state, + .get_handshake_state = _get_handshake_state, + }, + .state = TNC_CONNECTION_STATE_CREATE, + .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, + .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW, + .connection_id = connection_id, + ); + + return &this->public.interface; +} + + diff --git a/src/libpts/plugins/imv_swid/imv_swid_state.h b/src/libpts/plugins/imv_swid/imv_swid_state.h new file mode 100644 index 000000000..d6e5840df --- /dev/null +++ b/src/libpts/plugins/imv_swid/imv_swid_state.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2013 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 imv_swid imv_swid + * @ingroup libimcv_plugins + * + * @defgroup imv_swid_state_t imv_swid_state + * @{ @ingroup imv_swid + */ + +#ifndef IMV_SWID_STATE_H_ +#define IMV_SWID_STATE_H_ + +#include +#include + +typedef struct imv_swid_state_t imv_swid_state_t; +typedef enum imv_swid_handshake_state_t imv_swid_handshake_state_t; + +/** + * IMV OS Handshake States (state machine) + */ +enum imv_swid_handshake_state_t { + IMV_SWID_STATE_INIT, + IMV_SWID_STATE_WORKITEMS, + IMV_SWID_STATE_END +}; + +/** + * Internal state of an imv_swid_t connection instance + */ +struct imv_swid_state_t { + + /** + * imv_state_t interface + */ + imv_state_t interface; + + /** + * Set state of the handshake + * + * @param new_state the handshake state of IMV + */ + void (*set_handshake_state)(imv_swid_state_t *this, + imv_swid_handshake_state_t new_state); + + /** + * Get state of the handshake + * + * @return the handshake state of IMV + */ + imv_swid_handshake_state_t (*get_handshake_state)(imv_swid_state_t *this); + +}; + +/** + * Create an imv_swid_state_t instance + * + * @param id connection ID + */ +imv_state_t* imv_swid_state_create(TNC_ConnectionID id); + +#endif /** IMV_SWID_STATE_H_ @}*/ diff --git a/src/libpts/swid/swid_tag_id.c b/src/libpts/swid/swid_tag_id.c new file mode 100644 index 000000000..7ad486d4b --- /dev/null +++ b/src/libpts/swid/swid_tag_id.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2013 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 "swid_tag_id.h" + +typedef struct private_swid_tag_id_t private_swid_tag_id_t; + +/** + * Private data of a swid_tag_id_t object. + * + */ +struct private_swid_tag_id_t { + + /** + * Public swid_tag_id_t interface. + */ + swid_tag_id_t public; + + /** + * Tag Creator + */ + chunk_t tag_creator; + + /** + * Unique Software ID + */ + chunk_t unique_sw_id; + + /** + * Optional Unique Sequence ID + */ + chunk_t unique_seq_id; + +}; + +METHOD(swid_tag_id_t, get_tag_creator, chunk_t, + private_swid_tag_id_t *this) +{ + return this->tag_creator; +} + +METHOD(swid_tag_id_t, get_unique_sw_id, chunk_t, + private_swid_tag_id_t *this, chunk_t *unique_seq_id) +{ + if (unique_seq_id) + { + *unique_seq_id = this->unique_seq_id; + } + return this->unique_sw_id; +} + +METHOD(swid_tag_id_t, destroy, void, + private_swid_tag_id_t *this) +{ + free(this->tag_creator.ptr); + free(this->unique_sw_id.ptr); + free(this->unique_seq_id.ptr); + free(this); +} + +/** + * See header + */ +swid_tag_id_t *swid_tag_id_create(chunk_t tag_creator, chunk_t unique_sw_id, + chunk_t unique_seq_id) +{ + private_swid_tag_id_t *this; + + INIT(this, + .public = { + .get_tag_creator = _get_tag_creator, + .get_unique_sw_id = _get_unique_sw_id, + .destroy = _destroy, + }, + .tag_creator = chunk_clone(tag_creator), + .unique_sw_id = chunk_clone(unique_sw_id), + ); + + if (unique_seq_id.len > 0) + { + this->unique_seq_id = chunk_clone(unique_seq_id); + } + + return &this->public; +} + diff --git a/src/libpts/swid/swid_tag_id.h b/src/libpts/swid/swid_tag_id.h new file mode 100644 index 000000000..d4715967d --- /dev/null +++ b/src/libpts/swid/swid_tag_id.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 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 swid_tag_id swid_tag_id + * @{ @ingroup swid + */ + +#ifndef SWID_TAG_ID_H_ +#define SWID_TAG_ID_H_ + +#include + +typedef struct swid_tag_id_t swid_tag_id_t; + + +/** + * Class storing a SWID Tag ID + */ +struct swid_tag_id_t { + + /** + * Get the Tag Creator + * + * @return Tag Creator + */ + chunk_t (*get_tag_creator)(swid_tag_id_t *this); + + /** + * Get the Unique Software ID and optional Unique Sequence ID + * + * @param Optional Unique Sequence ID + * @return Unique Software ID + */ + chunk_t (*get_unique_sw_id)(swid_tag_id_t *this, chunk_t *unique_seq_id); + + /** + * Destroys a swid_tag_id_t object. + */ + void (*destroy)(swid_tag_id_t *this); + +}; + +/** + * Creates a swid_tag_id_t object + * + * @param tag_creator Tag Creator + * @param unique_sw_id Unique Software ID + * @param unique_seq_id Unique Sequence ID or empty chunk + */ +swid_tag_id_t* swid_tag_id_create(chunk_t tag_creator, chunk_t unique_sw_id, + chunk_t unique_seq_id); + +#endif /** SWID_TAG_ID_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_aik.c b/src/libpts/tcg/pts/tcg_pts_attr_aik.c new file mode 100644 index 000000000..17a8db5d6 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_aik.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_aik.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_aik_t private_tcg_pts_attr_aik_t; + +/** + * Attestation Identity Key + * see section 3.13 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | Attestation Identity Key (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attestation Identity Key (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PTS_AIK_SIZE 4 +#define PTS_AIK_FLAGS_NONE 0 +#define PTS_AIK_FLAGS_NAKED_KEY (1<<7) +/** + * Private data of an tcg_pts_attr_aik_t object. + */ +struct private_tcg_pts_attr_aik_t { + + /** + * Public members of tcg_pts_attr_aik_t + */ + tcg_pts_attr_aik_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * AIK Certificate or Public Key + */ + certificate_t *aik; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_aik_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_aik_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_aik_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_aik_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_aik_t *this) +{ + bio_writer_t *writer; + u_int8_t flags = PTS_AIK_FLAGS_NONE; + cred_encoding_type_t encoding_type = CERT_ASN1_DER; + chunk_t aik_blob; + + if (this->value.ptr) + { + return; + } + if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY) + { + flags |= PTS_AIK_FLAGS_NAKED_KEY; + encoding_type = PUBKEY_SPKI_ASN1_DER; + } + if (!this->aik->get_encoding(this->aik, encoding_type, &aik_blob)) + { + DBG1(DBG_TNC, "encoding of Attestation Identity Key failed"); + aik_blob = chunk_empty; + } + writer = bio_writer_create(PTS_AIK_SIZE); + writer->write_uint8(writer, flags); + writer->write_data (writer, aik_blob); + this->value = writer->extract_buf(writer); + writer->destroy(writer); + free(aik_blob.ptr); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_aik_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t flags; + certificate_type_t type; + chunk_t aik_blob; + + if (this->value.len < PTS_AIK_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Attestation Identity Key"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint8(reader, &flags); + reader->read_data (reader, reader->remaining(reader), &aik_blob); + + type = (flags & PTS_AIK_FLAGS_NAKED_KEY) ? CERT_TRUSTED_PUBKEY : CERT_X509; + + this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE, type, + BUILD_BLOB_PEM, aik_blob, BUILD_END); + reader->destroy(reader); + + if (!this->aik) + { + DBG1(DBG_TNC, "parsing of Attestation Identity Key failed"); + *offset = 0; + return FAILED; + } + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_aik_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_aik_t *this) +{ + if (ref_put(&this->ref)) + { + DESTROY_IF(this->aik); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_aik_t, get_aik, certificate_t*, + private_tcg_pts_attr_aik_t *this) +{ + return this->aik; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik) +{ + private_tcg_pts_attr_aik_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_aik = _get_aik, + }, + .type = { PEN_TCG, TCG_PTS_AIK }, + .aik = aik->get_ref(aik), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_aik_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_aik = _get_aik, + }, + .type = { PEN_TCG, TCG_PTS_AIK }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_aik.h b/src/libpts/tcg/pts/tcg_pts_attr_aik.h new file mode 100644 index 000000000..0962432e9 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_aik.h @@ -0,0 +1,65 @@ +/* + * 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 tcg_pts_attr_aik tcg_pts_attr_aik + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_AIK_H_ +#define TCG_PTS_ATTR_AIK_H_ + +typedef struct tcg_pts_attr_aik_t tcg_pts_attr_aik_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +#include + +/** + * Class implementing the TCG PTS Attestation Identity Key attribute + * + */ +struct tcg_pts_attr_aik_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get AIK + * + * @return AIK Certificate or Public Key + */ + certificate_t* (*get_aik)(tcg_pts_attr_aik_t *this); + +}; + +/** + * Creates an tcg_pts_attr_aik_t object + * + * @param aik Attestation Identity Key + */ +pa_tnc_attr_t* tcg_pts_attr_aik_create(certificate_t *aik); + +/** + * Creates an tcg_pts_attr_aik_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_aik_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_AIK_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_finish.c b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_finish.c new file mode 100644 index 000000000..6119b4973 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_finish.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_dh_nonce_finish.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_dh_nonce_finish_t + private_tcg_pts_attr_dh_nonce_finish_t; + +/** + * PTS DH Nonce Finish + * see section 3.8.3 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Nonce Len | Selected Hash Algorithm | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | D-H Initiator Public Value ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | D-H Initiator Nonce ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_DH_NONCE_FINISH_SIZE 12 +#define PTS_DH_NONCE_FINISH_RESERVED 0x00 + +/** + * Private data of an tcg_pts_attr_dh_nonce_finish_t object. + */ +struct private_tcg_pts_attr_dh_nonce_finish_t { + + /** + * Public members of tcg_pts_attr_dh_nonce_finish_t + */ + tcg_pts_attr_dh_nonce_finish_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Selected Hashing Algorithm + */ + pts_meas_algorithms_t hash_algo; + + /** + * DH Initiator Public Value + */ + chunk_t initiator_value; + + /** + * DH Initiator Nonce + */ + chunk_t initiator_nonce; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_dh_nonce_finish_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_DH_NONCE_FINISH_SIZE); + writer->write_uint8 (writer, PTS_DH_NONCE_FINISH_RESERVED); + writer->write_uint8 (writer, this->initiator_nonce.len); + writer->write_uint16(writer, this->hash_algo); + writer->write_data (writer, this->initiator_value); + writer->write_data (writer, this->initiator_nonce); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_dh_nonce_finish_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t reserved, nonce_len; + u_int16_t hash_algo; + + if (this->value.len < PTS_DH_NONCE_FINISH_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Finish"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &reserved); + reader->read_uint8 (reader, &nonce_len); + reader->read_uint16(reader, &hash_algo); + reader->read_data(reader, reader->remaining(reader) - nonce_len, + &this->initiator_value); + reader->read_data(reader, nonce_len, &this->initiator_nonce); + this->hash_algo = hash_algo; + this->initiator_value = chunk_clone(this->initiator_value); + this->initiator_nonce = chunk_clone(this->initiator_nonce); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->initiator_value.ptr); + free(this->initiator_nonce.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_dh_nonce_finish_t, get_hash_algo, pts_meas_algorithms_t, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + return this->hash_algo; +} + +METHOD(tcg_pts_attr_dh_nonce_finish_t, get_initiator_value, chunk_t, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + return this->initiator_value; +} + +METHOD(tcg_pts_attr_dh_nonce_finish_t, get_initiator_nonce, chunk_t, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + return this->initiator_nonce; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create( + pts_meas_algorithms_t hash_algo, + chunk_t initiator_value, + chunk_t initiator_nonce) +{ + private_tcg_pts_attr_dh_nonce_finish_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_hash_algo = _get_hash_algo, + .get_initiator_nonce = _get_initiator_nonce, + .get_initiator_value = _get_initiator_value, + }, + .type = { PEN_TCG, TCG_PTS_DH_NONCE_FINISH }, + .hash_algo = hash_algo, + .initiator_value = initiator_value, + .initiator_nonce = chunk_clone(initiator_nonce), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value) +{ + private_tcg_pts_attr_dh_nonce_finish_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_hash_algo = _get_hash_algo, + .get_initiator_nonce = _get_initiator_nonce, + .get_initiator_value = _get_initiator_value, + }, + .type = { PEN_TCG, TCG_PTS_DH_NONCE_FINISH }, + .value = chunk_clone(value), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_finish.h b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_finish.h new file mode 100644 index 000000000..efe6fd153 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_finish.h @@ -0,0 +1,89 @@ +/* + * 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 tcg_pts_attr_dh_nonce_finish tcg_pts_attr_dh_nonce_finish + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_DH_NONCE_FINISH_H_ +#define TCG_PTS_ATTR_DH_NONCE_FINISH_H_ + +typedef struct tcg_pts_attr_dh_nonce_finish_t tcg_pts_attr_dh_nonce_finish_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "pts/pts_meas_algo.h" + +/** + * Class implementing the TCG PTS DH Nonce Finish Attribute + */ +struct tcg_pts_attr_dh_nonce_finish_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get nonce length + * + * @return Length of nonce + */ + u_int8_t (*get_nonce_len)(tcg_pts_attr_dh_nonce_finish_t *this); + + /** + * Get selected hash algorithm + * + * @return Selected hash algorithm + */ + pts_meas_algorithms_t (*get_hash_algo)(tcg_pts_attr_dh_nonce_finish_t *this); + + /** + * Get DH Initiator Public Value + * + * @return DH Initiator Public Value + */ + chunk_t (*get_initiator_value)(tcg_pts_attr_dh_nonce_finish_t *this); + + /** + * Get DH Initiator Nonce + * + * @return DH Initiator Nonce + */ + chunk_t (*get_initiator_nonce)(tcg_pts_attr_dh_nonce_finish_t *this); + +}; + +/** + * Creates an tcg_pts_attr_dh_nonce_finish_t object + * + * @param hash_algo Selected hash algorithm + * @param initiator_value DH Initiator Public Value + * @param initiator_nonce DH Initiator Nonce + */ +pa_tnc_attr_t* tcg_pts_attr_dh_nonce_finish_create( + pts_meas_algorithms_t hash_algo, + chunk_t initiator_value, + chunk_t initiator_nonce); + +/** + * Creates an tcg_pts_attr_dh_nonce_finish_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_DH_NONCE_FINISH_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_req.c b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_req.c new file mode 100644 index 000000000..7761b977d --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_req.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_dh_nonce_params_req.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_dh_nonce_params_req_t + private_tcg_pts_attr_dh_nonce_params_req_t; + +/** + * PTS DH Nonce Parameters Request + * see section 3.8.1 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Min. Nonce Len | D-H Group Set | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_DH_NONCE_PARAMS_REQ_SIZE 4 +#define PTS_DH_NONCE_PARAMS_REQ_RESERVED 0x00 + +/** + * Private data of an tcg_pts_attr_dh_nonce_params_req_t object. + */ +struct private_tcg_pts_attr_dh_nonce_params_req_t { + + /** + * Public members of tcg_pts_attr_dh_nonce_params_req_t + */ + tcg_pts_attr_dh_nonce_params_req_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Minimum acceptable length of nonce + */ + u_int8_t min_nonce_len; + + /** + * Diffie Hellman group set + */ + pts_dh_group_t dh_groups; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_dh_nonce_params_req_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_DH_NONCE_PARAMS_REQ_SIZE); + writer->write_uint8 (writer, PTS_DH_NONCE_PARAMS_REQ_RESERVED); + writer->write_uint8 (writer, this->min_nonce_len); + writer->write_uint16(writer, this->dh_groups); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_dh_nonce_params_req_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t reserved; + u_int16_t dh_groups; + + if (this->value.len < PTS_DH_NONCE_PARAMS_REQ_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Parameters Request"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint8(reader, &reserved); + reader->read_uint8(reader, &this->min_nonce_len); + reader->read_uint16(reader, &dh_groups); + this->dh_groups = dh_groups; + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_dh_nonce_params_req_t, get_min_nonce_len, u_int8_t, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + return this->min_nonce_len; +} + +METHOD(tcg_pts_attr_dh_nonce_params_req_t, get_dh_groups, pts_dh_group_t, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + return this->dh_groups; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len, + pts_dh_group_t dh_groups) +{ + private_tcg_pts_attr_dh_nonce_params_req_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_min_nonce_len = _get_min_nonce_len, + .get_dh_groups = _get_dh_groups, + }, + .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_REQ }, + .min_nonce_len = min_nonce_len, + .dh_groups = dh_groups, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value) +{ + private_tcg_pts_attr_dh_nonce_params_req_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_min_nonce_len = _get_min_nonce_len, + .get_dh_groups = _get_dh_groups, + }, + .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_REQ }, + .value = chunk_clone(value), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_req.h b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_req.h new file mode 100644 index 000000000..024648abb --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_req.h @@ -0,0 +1,72 @@ +/* + * 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 tcg_pts_attr_dh_nonce_params_req tcg_pts_attr_dh_nonce_params_req + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_ +#define TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_ + +typedef struct tcg_pts_attr_dh_nonce_params_req_t + tcg_pts_attr_dh_nonce_params_req_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "pts/pts_dh_group.h" + +/** + * Class implementing the TCG PTS DH Nonce Parameters Request Attribute + */ +struct tcg_pts_attr_dh_nonce_params_req_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get Minimum nonce length + * + * @return Minimum acceptable length of nonce + */ + u_int8_t (*get_min_nonce_len)(tcg_pts_attr_dh_nonce_params_req_t *this); + + /** + * Get supported Diffie Hellman Groups + * + * @return Supported Diffie Hellman Groups + */ + pts_dh_group_t (*get_dh_groups)(tcg_pts_attr_dh_nonce_params_req_t *this); +}; + +/** + * Creates an tcg_pts_attr_dh_nonce_params_req_t object + * + * @param min_nonce_len Minimum acceptable length of nonce + * @param dh_groups Initiator's supported DH groups + */ +pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len, + pts_dh_group_t dh_groups); + +/** + * Creates an tcg_pts_attr_dh_nonce_params_req_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c new file mode 100644 index 000000000..eb0d0e533 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_dh_nonce_params_resp.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_dh_nonce_params_resp_t + private_tcg_pts_attr_dh_nonce_params_resp_t; + +/** + * PTS DH Nonce Parameters Response + * see section 3.8.2 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Nonce Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Selected D-H Group | Hash Algorithm Set | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | D-H Responder Nonce ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | D-H Responder Public Value ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_DH_NONCE_PARAMS_RESP_SIZE 16 +#define PTS_DH_NONCE_PARAMS_RESP_RESERVED 0x0000 + +/** + * Private data of an tcg_pts_attr_dh_nonce_params_resp_t object. + */ +struct private_tcg_pts_attr_dh_nonce_params_resp_t { + + /** + * Public members of tcg_pts_attr_dh_nonce_params_resp_t + */ + tcg_pts_attr_dh_nonce_params_resp_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Selected Diffie Hellman group + */ + pts_dh_group_t dh_group; + + /** + * Supported Hashing Algorithms + */ + pts_meas_algorithms_t hash_algo_set; + + /** + * DH Responder Nonce + */ + chunk_t responder_nonce; + + /** + * DH Responder Public Value + */ + chunk_t responder_value; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_dh_nonce_params_resp_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_DH_NONCE_PARAMS_RESP_SIZE); + writer->write_uint24(writer, PTS_DH_NONCE_PARAMS_RESP_RESERVED); + writer->write_uint8 (writer, this->responder_nonce.len); + writer->write_uint16(writer, this->dh_group); + writer->write_uint16(writer, this->hash_algo_set); + writer->write_data (writer, this->responder_nonce); + writer->write_data (writer, this->responder_value); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_dh_nonce_params_resp_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t reserved; + u_int8_t nonce_len; + u_int16_t dh_group, hash_algo_set; + + if (this->value.len < PTS_DH_NONCE_PARAMS_RESP_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Parameters Response"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint24(reader, &reserved); + reader->read_uint8 (reader, &nonce_len); + reader->read_uint16(reader, &dh_group); + reader->read_uint16(reader, &hash_algo_set); + reader->read_data(reader, nonce_len, &this->responder_nonce); + reader->read_data(reader, reader->remaining(reader), &this->responder_value); + this->dh_group = dh_group; + this->hash_algo_set = hash_algo_set; + this->responder_nonce = chunk_clone(this->responder_nonce); + this->responder_value = chunk_clone(this->responder_value); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->responder_nonce.ptr); + free(this->responder_value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_dh_group, pts_dh_group_t, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + return this->dh_group; +} + +METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_hash_algo_set, + pts_meas_algorithms_t, private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + return this->hash_algo_set; +} + +METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_responder_nonce, chunk_t, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + return this->responder_nonce; +} + +METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_responder_value, chunk_t, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + return this->responder_value; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group, + pts_meas_algorithms_t hash_algo_set, + chunk_t responder_nonce, + chunk_t responder_value) +{ + private_tcg_pts_attr_dh_nonce_params_resp_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_dh_group = _get_dh_group, + .get_hash_algo_set = _get_hash_algo_set, + .get_responder_nonce = _get_responder_nonce, + .get_responder_value = _get_responder_value, + }, + .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_RESP }, + .dh_group = dh_group, + .hash_algo_set = hash_algo_set, + .responder_nonce = chunk_clone(responder_nonce), + .responder_value = responder_value, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value) +{ + private_tcg_pts_attr_dh_nonce_params_resp_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_dh_group = _get_dh_group, + .get_hash_algo_set = _get_hash_algo_set, + .get_responder_nonce = _get_responder_nonce, + .get_responder_value = _get_responder_value, + }, + .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_RESP }, + .value = chunk_clone(value), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h new file mode 100644 index 000000000..72046d2ed --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h @@ -0,0 +1,93 @@ +/* + * 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 tcg_pts_attr_dh_nonce_params_resp tcg_pts_attr_dh_nonce_params_resp + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_ +#define TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_ + +typedef struct tcg_pts_attr_dh_nonce_params_resp_t + tcg_pts_attr_dh_nonce_params_resp_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "pts/pts_dh_group.h" +#include "pts/pts_meas_algo.h" + +/** + * Class implementing the TCG PTS DH Nonce Parameters Response Attribute + */ +struct tcg_pts_attr_dh_nonce_params_resp_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get selected Diffie Hellman Group + * + * @return Selected Diffie Hellman Group + */ + pts_dh_group_t (*get_dh_group)(tcg_pts_attr_dh_nonce_params_resp_t *this); + + /** + * Get supported hash algorithms + * + * @return Hash algorithm set + */ + pts_meas_algorithms_t (*get_hash_algo_set)( + tcg_pts_attr_dh_nonce_params_resp_t *this); + + /** + * Get DH Responder Nonce + * + * @return DH Responder Nonce + */ + chunk_t (*get_responder_nonce)(tcg_pts_attr_dh_nonce_params_resp_t *this); + + /** + * Get DH Responder Public Value + * + * @return DH Responder Public Value + */ + chunk_t (*get_responder_value)(tcg_pts_attr_dh_nonce_params_resp_t *this); + +}; + +/** + * Creates an tcg_pts_attr_dh_nonce_params_resp_t object + * + * @param dh_group Selected DH group + * @param hash_algo_set Set of supported hash algorithms + * @param responder_nonce DH Responder Nonce + * @param responder_value DH Responder Public value + */ +pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group, + pts_meas_algorithms_t hash_algo_set, + chunk_t responder_nonce, + chunk_t responder_value); + +/** + * Creates an tcg_pts_attr_dh_nonce_params_resp_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_file_meas.c b/src/libpts/tcg/pts/tcg_pts_attr_file_meas.c new file mode 100644 index 000000000..b9095f5be --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_file_meas.c @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_file_meas.h" + +#include +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_file_meas_t private_tcg_pts_attr_file_meas_t; + +/** + * File Measurement + * see section 3.19.2 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Number of Files included | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Number of Files included | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Request ID | Measurement Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measurement #1 (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Filename Length | Filename (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Filename (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measurement #2 (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Filename Length | Filename (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Filename (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ........................... + */ + +#define PTS_FILE_MEAS_SIZE 12 + +/** + * Private data of an tcg_pts_attr_file_meas_t object. + */ +struct private_tcg_pts_attr_file_meas_t { + + /** + * Public members of tcg_pts_attr_file_meas_t + */ + tcg_pts_attr_file_meas_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * PTS File Measurements + */ + pts_file_meas_t *measurements; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_file_meas_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_file_meas_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_file_meas_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_file_meas_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_file_meas_t *this) +{ + bio_writer_t *writer; + enumerator_t *enumerator; + u_int64_t number_of_files; + u_int16_t request_id; + char *filename; + chunk_t measurement; + bool first = TRUE; + + if (this->value.ptr) + { + return; + } + number_of_files = this->measurements->get_file_count(this->measurements); + request_id = this->measurements->get_request_id(this->measurements); + + writer = bio_writer_create(PTS_FILE_MEAS_SIZE); + writer->write_uint64(writer, number_of_files); + writer->write_uint16(writer, request_id); + + enumerator = this->measurements->create_enumerator(this->measurements); + while (enumerator->enumerate(enumerator, &filename, &measurement)) + { + if (first) + { + writer->write_uint16(writer, measurement.len); + first = FALSE; + } + writer->write_data (writer, measurement); + writer->write_data16(writer, chunk_create(filename, strlen(filename))); + } + enumerator->destroy(enumerator); + + if (first) + { + /* no attached measurements */ + writer->write_uint16(writer, 0); + } + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_file_meas_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int64_t number_of_files; + u_int16_t request_id, meas_len; + chunk_t measurement, filename; + size_t len; + char buf[BUF_LEN]; + status_t status = FAILED; + + if (this->value.len < PTS_FILE_MEAS_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PTS file measurement header"); + *offset = 0; + return FAILED; + } + + reader = bio_reader_create(this->value); + reader->read_uint64(reader, &number_of_files); + reader->read_uint16(reader, &request_id); + reader->read_uint16(reader, &meas_len); + *offset = PTS_FILE_MEAS_SIZE; + + this->measurements = pts_file_meas_create(request_id); + + while (number_of_files--) + { + if (!reader->read_data(reader, meas_len, &measurement)) + { + DBG1(DBG_TNC, "insufficient data for PTS file measurement"); + goto end; + } + *offset += meas_len; + + if (!reader->read_data16(reader, &filename)) + { + DBG1(DBG_TNC, "insufficient data for filename"); + goto end; + } + *offset += 2 + filename.len; + + len = min(filename.len, BUF_LEN-1); + memcpy(buf, filename.ptr, len); + buf[len] = '\0'; + this->measurements->add(this->measurements, buf, measurement); + } + status = SUCCESS; + +end: + reader->destroy(reader); + return status; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_file_meas_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_file_meas_t *this) +{ + if (ref_put(&this->ref)) + { + DESTROY_IF(this->measurements); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_file_meas_t, get_measurements, pts_file_meas_t*, + private_tcg_pts_attr_file_meas_t *this) +{ + return this->measurements; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements) +{ + private_tcg_pts_attr_file_meas_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_measurements = _get_measurements, + }, + .type = { PEN_TCG, TCG_PTS_FILE_MEAS }, + .measurements = measurements, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_file_meas_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_measurements = _get_measurements, + }, + .type = { PEN_TCG, TCG_PTS_FILE_MEAS }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_file_meas.h b/src/libpts/tcg/pts/tcg_pts_attr_file_meas.h new file mode 100644 index 000000000..4f155f05b --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_file_meas.h @@ -0,0 +1,65 @@ +/* + * 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 tcg_pts_attr_file_meas tcg_pts_attr_file_meas + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_FILE_MEAS_H_ +#define TCG_PTS_ATTR_FILE_MEAS_H_ + +typedef struct tcg_pts_attr_file_meas_t tcg_pts_attr_file_meas_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "pts/pts.h" +#include "pts/pts_file_meas.h" + +/** + * Class implementing the TCG PTS File Measurement attribute + * + */ +struct tcg_pts_attr_file_meas_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get PTS File Measurements + * + * @return PTS File Measurements + */ + pts_file_meas_t* (*get_measurements)(tcg_pts_attr_file_meas_t *this); + +}; + +/** + * Creates an tcg_pts_attr_file_meas_t object + * + * @param measurements PTS File Measurements + */ +pa_tnc_attr_t* tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements); + +/** + * Creates an tcg_pts_attr_file_meas_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_file_meas_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_FILE_MEAS_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_gen_attest_evid.c b/src/libpts/tcg/pts/tcg_pts_attr_gen_attest_evid.c new file mode 100644 index 000000000..f263747a3 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_gen_attest_evid.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_gen_attest_evid.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_gen_attest_evid_t + private_tcg_pts_attr_gen_attest_evid_t; + +/** + * Generate Attestation Evidence + * see section 3.14.2 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_GEN_ATTEST_EVID_SIZE 4 +#define PTS_GEN_ATTEST_EVID_RESERVED 0x00 + +/** + * Private data of an tcg_pts_attr_gen_attest_evid_t object. + */ +struct private_tcg_pts_attr_gen_attest_evid_t { + + /** + * Public members of tcg_pts_attr_gen_attest_evid_t + */ + tcg_pts_attr_gen_attest_evid_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_gen_attest_evid_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_gen_attest_evid_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_gen_attest_evid_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_gen_attest_evid_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_gen_attest_evid_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_GEN_ATTEST_EVID_SIZE); + writer->write_uint32 (writer, PTS_GEN_ATTEST_EVID_RESERVED); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_gen_attest_evid_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t reserved; + + if (this->value.len < PTS_GEN_ATTEST_EVID_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Generate Attestation Evidence"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint32 (reader, &reserved); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_gen_attest_evid_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_gen_attest_evid_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create() +{ + private_tcg_pts_attr_gen_attest_evid_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .type = { PEN_TCG, TCG_PTS_GEN_ATTEST_EVID }, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_gen_attest_evid_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .type = { PEN_TCG, TCG_PTS_GEN_ATTEST_EVID }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_gen_attest_evid.h b/src/libpts/tcg/pts/tcg_pts_attr_gen_attest_evid.h new file mode 100644 index 000000000..38909b025 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_gen_attest_evid.h @@ -0,0 +1,53 @@ +/* + * 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 tcg_pts_attr_gen_attest_evid tcg_pts_attr_gen_attest_evid + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_GEN_ATTEST_EVID_H_ +#define TCG_PTS_ATTR_GEN_ATTEST_EVID_H_ + +typedef struct tcg_pts_attr_gen_attest_evid_t tcg_pts_attr_gen_attest_evid_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Generate Attestation Evidence Attribute + * + */ +struct tcg_pts_attr_gen_attest_evid_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; +}; + +/** + * Creates an tcg_pts_attr_gen_attest_evid_t object + */ +pa_tnc_attr_t* tcg_pts_attr_gen_attest_evid_create(); + +/** + * Creates an tcg_pts_attr_gen_attest_evid_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_gen_attest_evid_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_GEN_ATTEST_EVID_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_get_aik.c b/src/libpts/tcg/pts/tcg_pts_attr_get_aik.c new file mode 100644 index 000000000..cf944d2a9 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_get_aik.c @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_get_aik.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_get_aik_t private_tcg_pts_attr_get_aik_t; + +/** + * Get Attestation Identity Key + * see section 3.12 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PTS_GET_AIK_SIZE 4 +#define PTS_GET_AIK_RESERVED 0x00000000 + +/** + * Private data of an tcg_pts_attr_get_aik_t object. + */ +struct private_tcg_pts_attr_get_aik_t { + + /** + * Public members of tcg_pts_attr_get_aik_t + */ + tcg_pts_attr_get_aik_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_get_aik_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_get_aik_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_get_aik_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_get_aik_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_get_aik_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_GET_AIK_SIZE); + writer->write_uint32 (writer, PTS_GET_AIK_RESERVED); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_get_aik_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t reserved; + + if (this->value.len < PTS_GET_AIK_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Get AIK"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint32 (reader, &reserved); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_get_aik_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_get_aik_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_get_aik_create() +{ + private_tcg_pts_attr_get_aik_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .type = { PEN_TCG, TCG_PTS_GET_AIK }, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_get_aik_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_get_aik_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .type = { PEN_TCG, TCG_PTS_GET_AIK }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_get_aik.h b/src/libpts/tcg/pts/tcg_pts_attr_get_aik.h new file mode 100644 index 000000000..120100e59 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_get_aik.h @@ -0,0 +1,53 @@ +/* + * 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 tcg_pts_attr_get_aik tcg_pts_attr_get_aik + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_GET_AIK_H_ +#define TCG_PTS_ATTR_GET_AIK_H_ + +typedef struct tcg_pts_attr_get_aik_t tcg_pts_attr_get_aik_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Get Attestation Identity Key Attribute + * + */ +struct tcg_pts_attr_get_aik_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; +}; + +/** + * Creates an tcg_pts_attr_get_aik_t object + */ +pa_tnc_attr_t* tcg_pts_attr_get_aik_create(); + +/** + * Creates an tcg_pts_attr_get_aik_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_get_aik_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_GET_AIK_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_get_tpm_version_info.c b/src/libpts/tcg/pts/tcg_pts_attr_get_tpm_version_info.c new file mode 100644 index 000000000..647c426ed --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_get_tpm_version_info.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_get_tpm_version_info.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_get_tpm_version_info_t + private_tcg_pts_attr_get_tpm_version_info_t; + +/** + * Get TPM Version Information + * see section 3.10 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_GET_TPM_VER_INFO_SIZE 4 +#define PTS_GET_TPM_VER_INFO_RESERVED 0x00 + +/** + * Private data of an tcg_pts_attr_get_tpm_version_info_t object. + */ +struct private_tcg_pts_attr_get_tpm_version_info_t { + + /** + * Public members of tcg_pts_attr_get_tpm_version_info_t + */ + tcg_pts_attr_get_tpm_version_info_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_get_tpm_version_info_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_get_tpm_version_info_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_get_tpm_version_info_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_get_tpm_version_info_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_get_tpm_version_info_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_GET_TPM_VER_INFO_SIZE); + writer->write_uint32 (writer, PTS_GET_TPM_VER_INFO_RESERVED); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_get_tpm_version_info_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t reserved; + + if (this->value.len < PTS_GET_TPM_VER_INFO_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Get TPM Version Information"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint32 (reader, &reserved); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_get_tpm_version_info_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_get_tpm_version_info_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create() +{ + private_tcg_pts_attr_get_tpm_version_info_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .type = { PEN_TCG, TCG_PTS_GET_TPM_VERSION_INFO }, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_get_tpm_version_info_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .type = { PEN_TCG, TCG_PTS_GET_TPM_VERSION_INFO }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_get_tpm_version_info.h b/src/libpts/tcg/pts/tcg_pts_attr_get_tpm_version_info.h new file mode 100644 index 000000000..711a1d50c --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_get_tpm_version_info.h @@ -0,0 +1,54 @@ +/* + * 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 tcg_pts_attr_get_tpm_version_info tcg_pts_attr_get_tpm_version_info + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_ +#define TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_ + +typedef struct tcg_pts_attr_get_tpm_version_info_t + tcg_pts_attr_get_tpm_version_info_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Get TPM Version Info Attribute + * + */ +struct tcg_pts_attr_get_tpm_version_info_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; +}; + +/** + * Creates an tcg_pts_attr_get_tpm_version_info_t object + */ +pa_tnc_attr_t* tcg_pts_attr_get_tpm_version_info_create(); + +/** + * Creates an tcg_pts_attr_get_tpm_version_info_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_get_tpm_version_info_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_meas_algo.c b/src/libpts/tcg/pts/tcg_pts_attr_meas_algo.c new file mode 100644 index 000000000..a4dac9070 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_meas_algo.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_meas_algo.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_meas_algo_t private_tcg_pts_attr_meas_algo_t; + +/** + * PTS Measurement Algorithm + * see section 3.9.1 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Hash Algorithm Set | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_MEAS_ALGO_SIZE 4 +#define PTS_MEAS_ALGO_RESERVED 0x0000 + +/** + * Private data of an tcg_pts_attr_meas_algo_t object. + */ +struct private_tcg_pts_attr_meas_algo_t { + + /** + * Public members of tcg_pts_attr_meas_algo_t + */ + tcg_pts_attr_meas_algo_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Set of algorithms + */ + pts_meas_algorithms_t algorithms; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_meas_algo_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_meas_algo_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_meas_algo_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_meas_algo_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_meas_algo_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_MEAS_ALGO_SIZE); + writer->write_uint16(writer, PTS_MEAS_ALGO_RESERVED); + writer->write_uint16(writer, this->algorithms); + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_meas_algo_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int16_t reserved, algorithms; + + if (this->value.len < PTS_MEAS_ALGO_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PTS Measurement Algorithm"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint16(reader, &reserved); + reader->read_uint16(reader, &algorithms); + this->algorithms = algorithms; + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_meas_algo_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_meas_algo_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(tcg_pts_attr_meas_algo_t, get_algorithms, pts_meas_algorithms_t, + private_tcg_pts_attr_meas_algo_t *this) +{ + return this->algorithms; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms, + bool selection) +{ + private_tcg_pts_attr_meas_algo_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_algorithms = _get_algorithms, + }, + .type = { PEN_TCG, + selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO }, + .algorithms = algorithms, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_meas_algo_create_from_data(chunk_t data, + bool selection) +{ + private_tcg_pts_attr_meas_algo_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_algorithms = _get_algorithms, + }, + .type = { PEN_TCG, + selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_meas_algo.h b/src/libpts/tcg/pts/tcg_pts_attr_meas_algo.h new file mode 100644 index 000000000..88d1be0aa --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_meas_algo.h @@ -0,0 +1,68 @@ +/* + * 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 tcg_pts_attr_meas_algo tcg_pts_attr_meas_algo + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_MEAS_ALGO_H_ +#define TCG_PTS_ATTR_MEAS_ALGO_H_ + +typedef struct tcg_pts_attr_meas_algo_t tcg_pts_attr_meas_algo_t; + +#include "tcg/tcg_attr.h" +#include "pts/pts_meas_algo.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG Measurement Algorithm Attribute + * + */ +struct tcg_pts_attr_meas_algo_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get PTS Measurement Algorithm Set + * + * @return set of algorithms + */ + pts_meas_algorithms_t (*get_algorithms)(tcg_pts_attr_meas_algo_t *this); + +}; + +/** + * Creates an tcg_pts_attr_meas_algo_t object + * + * @param algorithms set of algorithms + * @param selection TRUE if a selection + */ +pa_tnc_attr_t* tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms, + bool selection); + +/** + * Creates an tcg_pts_attr_meas_algo_t object from received data + * + * @param value unparsed attribute value + * @param selection TRUE if a selection + */ +pa_tnc_attr_t* tcg_pts_attr_meas_algo_create_from_data(chunk_t value, + bool selection); + +#endif /** TCG_PTS_ATTR_MEAS_ALGO_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_proto_caps.c b/src/libpts/tcg/pts/tcg_pts_attr_proto_caps.c new file mode 100644 index 000000000..6473ea808 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_proto_caps.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_proto_caps.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_proto_caps_t private_tcg_pts_attr_proto_caps_t; + +/** + * PTS Protocol Capabilities + * see section 3.7 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved |C|V|D|T|X| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_PROTO_CAPS_SIZE 4 +#define PTS_PROTO_CAPS_RESERVED 0x0000 + +/** + * Private data of an tcg_pts_attr_proto_caps_t object. + */ +struct private_tcg_pts_attr_proto_caps_t { + + /** + * Public members of tcg_pts_attr_proto_caps_t + */ + tcg_pts_attr_proto_caps_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Set of flags + */ + pts_proto_caps_flag_t flags; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_proto_caps_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_proto_caps_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_proto_caps_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_proto_caps_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_proto_caps_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_PROTO_CAPS_SIZE); + writer->write_uint16(writer, PTS_PROTO_CAPS_RESERVED); + writer->write_uint16(writer, this->flags); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_proto_caps_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int16_t reserved, flags; + + if (this->value.len < PTS_PROTO_CAPS_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PTS Protocol Capabilities"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint16(reader, &reserved); + reader->read_uint16(reader, &flags); + this->flags = flags; + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_proto_caps_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_proto_caps_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(tcg_pts_attr_proto_caps_t, get_flags, pts_proto_caps_flag_t, + private_tcg_pts_attr_proto_caps_t *this) +{ + return this->flags; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags, + bool request) +{ + private_tcg_pts_attr_proto_caps_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_flags = _get_flags, + }, + .type = { PEN_TCG, + request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS }, + .flags = flags, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_proto_caps_create_from_data(chunk_t data, + bool request) +{ + private_tcg_pts_attr_proto_caps_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_flags = _get_flags, + }, + .type = { PEN_TCG, + request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_proto_caps.h b/src/libpts/tcg/pts/tcg_pts_attr_proto_caps.h new file mode 100644 index 000000000..c2478da0b --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_proto_caps.h @@ -0,0 +1,67 @@ +/* + * 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 tcg_pts_attr_proto_caps tcg_pts_attr_proto_caps + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_PROTO_CAPS_H_ +#define TCG_PTS_ATTR_PROTO_CAPS_H_ + +typedef struct tcg_pts_attr_proto_caps_t tcg_pts_attr_proto_caps_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "pts/pts_proto_caps.h" + +/** + * Class implementing the TCG PTS Protocol Capabilities Attribute + */ +struct tcg_pts_attr_proto_caps_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get PTS procol capabilities flags + * + * @return set of flags + */ + pts_proto_caps_flag_t (*get_flags)(tcg_pts_attr_proto_caps_t *this); + +}; + +/** + * Creates an tcg_pts_attr_proto_caps_t object + * + * @param flags set of flags + * @param request TRUE for a PTS protocol capabilities request + */ +pa_tnc_attr_t* tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags, + bool request); + +/** + * Creates an tcg_pts_attr_proto_caps_t object from received data + * + * @param value unparsed attribute value + * @param request TRUE for a PTS protocol capabilities request + */ +pa_tnc_attr_t* tcg_pts_attr_proto_caps_create_from_data(chunk_t value, + bool request); + +#endif /** TCG_PTS_ATTR_PROTO_CAPS_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.c b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.c new file mode 100644 index 000000000..f0bc7cf60 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_req_file_meas.h" + +#include +#include +#include +#include + +#include + +typedef struct private_tcg_pts_attr_req_file_meas_t private_tcg_pts_attr_req_file_meas_t; + +/** + * Request File Measurement + * see section 3.19.1 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | Reserved | Request ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Delimiter | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Fully Qualified File Pathname (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PTS_REQ_FILE_MEAS_SIZE 8 +#define PTS_REQ_FILE_MEAS_RESERVED 0x00 +#define PTS_REQ_FILE_MEAS_NO_FLAGS 0x00 + +#define DIRECTORY_CONTENTS_FLAG (1<<7) + +/** + * Private data of an tcg_pts_attr_req_file_meas_t object. + */ +struct private_tcg_pts_attr_req_file_meas_t { + + /** + * Public members of tcg_pts_attr_req_file_meas_t + */ + tcg_pts_attr_req_file_meas_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Directory Contents flag + */ + bool directory_flag; + + /** + * Request ID + */ + u_int16_t request_id; + + /** + * UTF8 Encoding of Delimiter Character + */ + u_int32_t delimiter; + + /** + * Fully Qualified File Pathname + */ + char *pathname; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_req_file_meas_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_req_file_meas_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_req_file_meas_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_req_file_meas_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_req_file_meas_t *this) +{ + u_int8_t flags = PTS_REQ_FILE_MEAS_NO_FLAGS; + chunk_t pathname; + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + if (this->directory_flag) + { + flags |= DIRECTORY_CONTENTS_FLAG; + } + pathname = chunk_create(this->pathname, strlen(this->pathname)); + + writer = bio_writer_create(PTS_REQ_FILE_MEAS_SIZE); + writer->write_uint8 (writer, flags); + writer->write_uint8 (writer, PTS_REQ_FILE_MEAS_RESERVED); + writer->write_uint16(writer, this->request_id); + writer->write_uint32(writer, this->delimiter); + writer->write_data (writer, pathname); + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_req_file_meas_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t flags; + u_int8_t reserved; + chunk_t pathname; + + if (this->value.len < PTS_REQ_FILE_MEAS_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Request File Measurement"); + *offset = 0; + return FAILED; + } + + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &flags); + reader->read_uint8 (reader, &reserved); + reader->read_uint16(reader, &this->request_id); + reader->read_uint32(reader, &this->delimiter); + reader->read_data (reader, reader->remaining(reader), &pathname); + + this->directory_flag = (flags & DIRECTORY_CONTENTS_FLAG) != + PTS_REQ_FILE_MEAS_NO_FLAGS; + this->pathname = strndup(pathname.ptr, pathname.len); + + reader->destroy(reader); + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_req_file_meas_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_req_file_meas_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->pathname); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_req_file_meas_t, get_directory_flag, bool, + private_tcg_pts_attr_req_file_meas_t *this) +{ + return this->directory_flag; +} + +METHOD(tcg_pts_attr_req_file_meas_t, get_request_id, u_int16_t, + private_tcg_pts_attr_req_file_meas_t *this) +{ + return this->request_id; +} + +METHOD(tcg_pts_attr_req_file_meas_t, get_delimiter, u_int32_t, + private_tcg_pts_attr_req_file_meas_t *this) +{ + return this->delimiter; +} + +METHOD(tcg_pts_attr_req_file_meas_t, get_pathname, char*, + private_tcg_pts_attr_req_file_meas_t *this) +{ + return this->pathname; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag, + u_int16_t request_id, + u_int32_t delimiter, + char *pathname) +{ + private_tcg_pts_attr_req_file_meas_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_directory_flag = _get_directory_flag, + .get_request_id = _get_request_id, + .get_delimiter = _get_delimiter, + .get_pathname = _get_pathname, + }, + .type = { PEN_TCG, TCG_PTS_REQ_FILE_MEAS }, + .directory_flag = directory_flag, + .request_id = request_id, + .delimiter = delimiter, + .pathname = strdup(pathname), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_req_file_meas_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_directory_flag = _get_directory_flag, + .get_request_id = _get_request_id, + .get_delimiter = _get_delimiter, + .get_pathname = _get_pathname, + }, + .type = { PEN_TCG, TCG_PTS_REQ_FILE_MEAS }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.h b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.h new file mode 100644 index 000000000..135c088bf --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.h @@ -0,0 +1,90 @@ +/* + * 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 tcg_pts_attr_req_file_meas tcg_pts_attr_req_file_meas + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_REQ_FILE_MEAS_H_ +#define TCG_PTS_ATTR_REQ_FILE_MEAS_H_ + +typedef struct tcg_pts_attr_req_file_meas_t tcg_pts_attr_req_file_meas_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Request File Measurement attribute + * + */ +struct tcg_pts_attr_req_file_meas_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get flag for PTS Request File Measurement + * + * @return Directory Contents flag + */ + bool (*get_directory_flag)(tcg_pts_attr_req_file_meas_t *this); + + /** + * Get Request ID + * + * @return Request ID + */ + u_int16_t (*get_request_id)(tcg_pts_attr_req_file_meas_t *this); + + /** + * Get Delimiter + * + * @return UTF-8 encoding of a Delimiter Character + */ + u_int32_t (*get_delimiter)(tcg_pts_attr_req_file_meas_t *this); + + /** + * Get Fully Qualified File Pathname + * + * @return Pathname + */ + char* (*get_pathname)(tcg_pts_attr_req_file_meas_t *this); + +}; + +/** + * Creates an tcg_pts_attr_req_file_meas_t object + * + * @param directory_flag Directory Contents Flag + * @param request_id Request ID + * @param delimiter Delimiter Character + * @param pathname File Pathname + */ +pa_tnc_attr_t* tcg_pts_attr_req_file_meas_create(bool directory_flag, + u_int16_t request_id, + u_int32_t delimiter, + char *pathname); + +/** + * Creates an tcg_pts_attr_req_file_meas_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_req_file_meas_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_REQ_FILE_MEAS_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.c b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.c new file mode 100644 index 000000000..e475cd35b --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_req_file_meta.h" + +#include +#include +#include +#include + +#include + +typedef struct private_tcg_pts_attr_req_file_meta_t private_tcg_pts_attr_req_file_meta_t; + +/** + * Request File Metadata + * see section 3.17.1 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | Delimiter | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Fully Qualified File Pathname (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PTS_REQ_FILE_META_SIZE 4 +#define PTS_REQ_FILE_META_RESERVED 0x00 +#define PTS_REQ_FILE_META_NO_FLAGS 0x00 + +#define DIRECTORY_CONTENTS_FLAG (1<<7) + +/** + * Private data of an tcg_pts_attr_req_file_meta_t object. + */ +struct private_tcg_pts_attr_req_file_meta_t { + + /** + * Public members of tcg_pts_attr_req_file_meta_t + */ + tcg_pts_attr_req_file_meta_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Directory Contents flag + */ + bool directory_flag; + + /** + * UTF8 Encoding of Delimiter Character + */ + u_int8_t delimiter; + + /** + * Fully Qualified File Pathname + */ + char *pathname; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_req_file_meta_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_req_file_meta_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_req_file_meta_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_req_file_meta_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_req_file_meta_t *this) +{ + u_int8_t flags = PTS_REQ_FILE_META_NO_FLAGS; + chunk_t pathname; + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + if (this->directory_flag) + { + flags |= DIRECTORY_CONTENTS_FLAG; + } + pathname = chunk_create(this->pathname, strlen(this->pathname)); + + writer = bio_writer_create(PTS_REQ_FILE_META_SIZE); + writer->write_uint8 (writer, flags); + writer->write_uint8 (writer, this->delimiter); + writer->write_uint16(writer, PTS_REQ_FILE_META_RESERVED); + + writer->write_data (writer, pathname); + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_req_file_meta_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t flags; + u_int16_t reserved; + chunk_t pathname; + + if (this->value.len < PTS_REQ_FILE_META_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Request File Metadata"); + *offset = 0; + return FAILED; + } + + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &flags); + reader->read_uint8 (reader, &this->delimiter); + reader->read_uint16(reader, &reserved); + + reader->read_data (reader, reader->remaining(reader), &pathname); + + this->directory_flag = (flags & DIRECTORY_CONTENTS_FLAG) != + PTS_REQ_FILE_META_NO_FLAGS; + this->pathname = strndup(pathname.ptr, pathname.len); + + reader->destroy(reader); + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_req_file_meta_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->pathname); + free(this->value.ptr); + free(this); + } +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_req_file_meta_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(tcg_pts_attr_req_file_meta_t, get_directory_flag, bool, + private_tcg_pts_attr_req_file_meta_t *this) +{ + return this->directory_flag; +} + +METHOD(tcg_pts_attr_req_file_meta_t, get_delimiter, u_int8_t, + private_tcg_pts_attr_req_file_meta_t *this) +{ + return this->delimiter; +} + +METHOD(tcg_pts_attr_req_file_meta_t, get_pathname, char*, + private_tcg_pts_attr_req_file_meta_t *this) +{ + return this->pathname; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create(bool directory_flag, + u_int8_t delimiter, + char *pathname) +{ + private_tcg_pts_attr_req_file_meta_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_directory_flag = _get_directory_flag, + .get_delimiter = _get_delimiter, + .get_pathname = _get_pathname, + }, + .type = { PEN_TCG, TCG_PTS_REQ_FILE_META }, + .directory_flag = directory_flag, + .delimiter = delimiter, + .pathname = strdup(pathname), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_req_file_meta_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_directory_flag = _get_directory_flag, + .get_delimiter = _get_delimiter, + .get_pathname = _get_pathname, + }, + .type = { PEN_TCG, TCG_PTS_REQ_FILE_META }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.h b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.h new file mode 100644 index 000000000..9aa1b93d6 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.h @@ -0,0 +1,81 @@ +/* + * 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 tcg_pts_attr_req_file_meta tcg_pts_attr_req_file_meta + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_REQ_FILE_META_H_ +#define TCG_PTS_ATTR_REQ_FILE_META_H_ + +typedef struct tcg_pts_attr_req_file_meta_t tcg_pts_attr_req_file_meta_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Request File Metadata attribute + * + */ +struct tcg_pts_attr_req_file_meta_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get directory flag for PTS Request File Metadata + * + * @return Directory Contents flag + */ + bool (*get_directory_flag)(tcg_pts_attr_req_file_meta_t *this); + + /** + * Get Delimiter + * + * @return UTF-8 encoding of a Delimiter Character + */ + u_int8_t (*get_delimiter)(tcg_pts_attr_req_file_meta_t *this); + + /** + * Get Fully Qualified File Pathname + * + * @return Pathname + */ + char* (*get_pathname)(tcg_pts_attr_req_file_meta_t *this); + +}; + +/** + * Creates an tcg_pts_attr_req_file_meta_t object + * + * @param directory_flag Directory Contents Flag + * @param delimiter Delimiter Character + * @param pathname File Pathname + */ +pa_tnc_attr_t* tcg_pts_attr_req_file_meta_create(bool directory_flag, + u_int8_t delimiter, + char *pathname); + +/** + * Creates an tcg_pts_attr_req_file_meta_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_req_file_meta_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_REQ_FILE_META_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c b/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c new file mode 100644 index 000000000..5249fa2ad --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c @@ -0,0 +1,367 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_req_func_comp_evid.h" + +#include +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_req_func_comp_evid_t private_tcg_pts_attr_req_func_comp_evid_t; + +/** + * Request Functional Component Evidence + * see section 3.14.1 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | Sub-component Depth (for Component #1) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name #1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name #1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ........ | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | Sub-component Depth (for Component #N) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name #N | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name #N | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/** + * Component Functional Name Structure + * (see section 5.1 of PTS Protocol: Binding to TNC IF-M Specification) + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name Vendor ID |Fam| Qualifier | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PTS_REQ_FUNC_COMP_EVID_SIZE 12 +#define PTS_REQ_FUNC_COMP_FAMILY_MASK 0xC0 + +/** + * Private data of an tcg_pts_attr_req_func_comp_evid_t object. + */ +struct private_tcg_pts_attr_req_func_comp_evid_t { + + /** + * Public members of tcg_pts_attr_req_func_comp_evid_t + */ + tcg_pts_attr_req_func_comp_evid_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * List of Functional Components + */ + linked_list_t *list; + + /** + * Reference count + */ + refcount_t ref; +}; + +typedef struct entry_t entry_t; + +/** + * Functional component entry + */ +struct entry_t { + u_int8_t flags; + u_int32_t depth; + pts_comp_func_name_t *name; +}; + +/** + * Enumerate functional component entries + */ +static bool entry_filter(void *null, entry_t **entry, u_int8_t *flags, + void *i2, u_int32_t *depth, void *i3, + pts_comp_func_name_t **name) +{ + *flags = (*entry)->flags; + *depth = (*entry)->depth; + *name = (*entry)->name; + + return TRUE; +} + +/** + * Free an entry_t object + */ +static void free_entry(entry_t *this) +{ + if (this) + { + this->name->destroy(this->name); + free(this); + } +} + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_req_func_comp_evid_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + bio_writer_t *writer; + enumerator_t *enumerator; + entry_t *entry; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_REQ_FUNC_COMP_EVID_SIZE); + + enumerator = this->list->create_enumerator(this->list); + while (enumerator->enumerate(enumerator, &entry)) + { + writer->write_uint8 (writer, entry->flags); + writer->write_uint24(writer, entry->depth); + writer->write_uint24(writer, entry->name->get_vendor_id(entry->name)); + writer->write_uint8 (writer, entry->name->get_qualifier(entry->name)); + writer->write_uint32(writer, entry->name->get_name(entry->name)); + } + enumerator->destroy(enumerator); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_req_func_comp_evid_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t depth, vendor_id, name; + u_int8_t flags, fam_and_qualifier, qualifier; + status_t status = FAILED; + entry_t *entry = NULL; + + if (this->value.len < PTS_REQ_FUNC_COMP_EVID_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Request Functional " + "Component Evidence"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + + while (reader->remaining(reader)) + { + if (!reader->read_uint8(reader, &flags)) + { + DBG1(DBG_TNC, "insufficient data for PTS Request Functional " + "Component Evidence Flags"); + goto end; + } + if (!reader->read_uint24(reader, &depth)) + { + DBG1(DBG_TNC, "insufficient data for PTS Request Functional " + "Component Evidence Sub Component Depth"); + goto end; + } + if (!reader->read_uint24(reader, &vendor_id)) + { + DBG1(DBG_TNC, "insufficient data for PTS Request Functional " + "Component Evidence Component Name Vendor ID"); + goto end; + } + if (!reader->read_uint8(reader, &fam_and_qualifier)) + { + DBG1(DBG_TNC, "insufficient data for PTS Request Functional " + "Component Evidence Family and Qualifier"); + goto end; + } + if (fam_and_qualifier & PTS_REQ_FUNC_COMP_FAMILY_MASK) + { + DBG1(DBG_TNC, "the Functional Name Encoding Family " + "is not Binary Enumeration"); + goto end; + } + if (!reader->read_uint32(reader, &name)) + { + DBG1(DBG_TNC, "insufficient data for PTS Request Functional " + "Component Evidence Component Functional Name"); + goto end; + } + qualifier = fam_and_qualifier & ~PTS_REQ_FUNC_COMP_FAMILY_MASK; + + entry = malloc_thing(entry_t); + entry->flags = flags; + entry->depth = depth; + entry->name = pts_comp_func_name_create(vendor_id, name, qualifier); + + this->list->insert_last(this->list, entry); + } + status = SUCCESS; + +end: + reader->destroy(reader); + return status; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + if (ref_put(&this->ref)) + { + this->list->destroy_function(this->list, (void *)free_entry); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_req_func_comp_evid_t, add_component, void, + private_tcg_pts_attr_req_func_comp_evid_t *this, u_int8_t flags, + u_int32_t depth, pts_comp_func_name_t *name) +{ + entry_t *entry; + + entry = malloc_thing(entry_t); + entry->flags = flags; + entry->depth = depth; + entry->name = name; + this->list->insert_last(this->list, entry); +} + +METHOD(tcg_pts_attr_req_func_comp_evid_t, get_count, int, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + return this->list->get_count(this->list); +} + +METHOD(tcg_pts_attr_req_func_comp_evid_t, create_enumerator, enumerator_t*, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + return enumerator_create_filter(this->list->create_enumerator(this->list), + (void*)entry_filter, NULL, NULL); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void) +{ + private_tcg_pts_attr_req_func_comp_evid_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .add_component = _add_component, + .get_count = _get_count, + .create_enumerator = _create_enumerator, + }, + .type = { PEN_TCG, TCG_PTS_REQ_FUNC_COMP_EVID }, + .list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_req_func_comp_evid_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .add_component = _add_component, + .get_count = _get_count, + .create_enumerator = _create_enumerator, + }, + .type = { PEN_TCG, TCG_PTS_REQ_FUNC_COMP_EVID }, + .list = linked_list_create(), + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.h b/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.h new file mode 100644 index 000000000..2c0b8a974 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.h @@ -0,0 +1,80 @@ +/* + * 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 tcg_pts_attr_req_func_comp_evid tcg_pts_attr_req_func_comp_evid + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_ +#define TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_ + +typedef struct tcg_pts_attr_req_func_comp_evid_t tcg_pts_attr_req_func_comp_evid_t; + +#include "tcg/tcg_attr.h" +#include "pts/components/pts_comp_func_name.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Request Functional Component Evidence attribute + * + */ +struct tcg_pts_attr_req_func_comp_evid_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Add a component to the Functional Component Evidence Request + * + * @param flags Component Evidence Request Flags + * @param depth Sub-component Depth + * @param name Functional Component Name + */ + void (*add_component)(tcg_pts_attr_req_func_comp_evid_t *this, + u_int8_t flags, u_int32_t depth, + pts_comp_func_name_t *name); + + /** + * Returns the number of Functional Component entries + * + * @return Number of entries + */ + int (*get_count)(tcg_pts_attr_req_func_comp_evid_t *this); + + /** + * Enumerator over Functional Component entries + * + * @return Entry enumerator + */ + enumerator_t* (*create_enumerator)(tcg_pts_attr_req_func_comp_evid_t *this); + +}; + +/** + * Creates a tcg_pts_attr_req_func_comp_evid_t object + */ +pa_tnc_attr_t* tcg_pts_attr_req_func_comp_evid_create(void); + +/** + * Creates a tcg_pts_attr_req_func_comp_evid_t object from received data + * + * @param value Unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_simple_comp_evid.c b/src/libpts/tcg/pts/tcg_pts_attr_simple_comp_evid.c new file mode 100644 index 000000000..40f380ab4 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_simple_comp_evid.c @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_simple_comp_evid.h" + +#include +#include +#include +#include + +#include + +typedef struct private_tcg_pts_attr_simple_comp_evid_t private_tcg_pts_attr_simple_comp_evid_t; + +/** + * Simple Component Evidence + * see section 3.15.1 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | Sub-Component Depth | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Specific Functional Component | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Specific Functional Component | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measure. Type | Extended into PCR | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Hash Algorithm | PCR Transform | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measurement Date/Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measurement Date/Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measurement Date/Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measurement Date/Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Measurement Date/Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Optional Policy URI Length | Opt. Verification Policy URI ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Optional Verification Policy URI ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Optional PCR Length | Optional PCR Before Value ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Optional PCR Before Value (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Optional PCR After Value (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Component Measurement (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/** + * Specific Functional Component -> Component Functional Name Structure + * see section 5.1 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name Vendor ID |Fam| Qualifier | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Component Functional Name | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define PTS_SIMPLE_COMP_EVID_SIZE 40 +#define PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE 20 +#define PTS_SIMPLE_COMP_EVID_RESERVED 0x00 +#define PTS_SIMPLE_COMP_EVID_FAMILY_MASK 0xC0 +#define PTS_SIMPLE_COMP_EVID_VALIDATION_MASK 0x60 +#define PTS_SIMPLE_COMP_EVID_MEAS_TYPE (1<<7) +#define PTS_SIMPLE_COMP_EVID_FLAG_PCR (1<<7) + +static char *utc_undefined_time_str = "0000-00-00T00:00:00Z"; + +/** + * Private data of an tcg_pts_attr_simple_comp_evid_t object. + */ +struct private_tcg_pts_attr_simple_comp_evid_t { + + /** + * Public members of tcg_pts_attr_simple_comp_evid_t + */ + tcg_pts_attr_simple_comp_evid_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * PTS Component Evidence + */ + pts_comp_evidence_t *evidence; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_simple_comp_evid_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +/** + * Convert time_t to Simple Component Evidence UTS string format + */ +void measurement_time_to_utc(time_t measurement_time, chunk_t *utc_time) +{ + struct tm t; + + if (measurement_time == UNDEFINED_TIME) + { + utc_time->ptr = utc_undefined_time_str; + } + else + { + gmtime_r(&measurement_time, &t); + sprintf(utc_time->ptr, "%04d-%02d-%02dT%02d:%02d:%02dZ", + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, + t.tm_hour, t.tm_min, t.tm_sec); + } +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + bio_writer_t *writer; + bool has_pcr_info; + char utc_time_buf[25], *policy_uri; + u_int8_t flags; + u_int16_t len; + u_int32_t depth, extended_pcr; + pts_comp_func_name_t *name; + pts_meas_algorithms_t hash_algorithm; + pts_pcr_transform_t transform; + pts_comp_evid_validation_t validation; + time_t measurement_time; + chunk_t measurement, utc_time, pcr_before, pcr_after; + + if (this->value.ptr) + { + return; + } + + /* Extract parameters from comp_evidence_t object */ + name = this->evidence->get_comp_func_name(this->evidence, + &depth); + measurement = this->evidence->get_measurement(this->evidence, + &extended_pcr, &hash_algorithm, &transform, + &measurement_time); + has_pcr_info = this->evidence->get_pcr_info(this->evidence, + &pcr_before, &pcr_after); + validation = this->evidence->get_validation(this->evidence, + &policy_uri); + + /* Determine the flags to set*/ + flags = validation; + if (has_pcr_info) + { + flags |= PTS_SIMPLE_COMP_EVID_FLAG_PCR; + } + + utc_time = chunk_create(utc_time_buf, PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE); + measurement_time_to_utc(measurement_time, &utc_time); + + writer = bio_writer_create(PTS_SIMPLE_COMP_EVID_SIZE); + + writer->write_uint8 (writer, flags); + writer->write_uint24(writer, depth); + writer->write_uint24(writer, name->get_vendor_id(name)); + writer->write_uint8 (writer, name->get_qualifier(name)); + writer->write_uint32(writer, name->get_name(name)); + writer->write_uint8 (writer, PTS_SIMPLE_COMP_EVID_MEAS_TYPE); + writer->write_uint24(writer, extended_pcr); + writer->write_uint16(writer, hash_algorithm); + writer->write_uint8 (writer, transform); + writer->write_uint8 (writer, PTS_SIMPLE_COMP_EVID_RESERVED); + writer->write_data (writer, utc_time); + + /* Optional fields */ + if (validation == PTS_COMP_EVID_VALIDATION_FAILED || + validation == PTS_COMP_EVID_VALIDATION_PASSED) + { + len = strlen(policy_uri); + writer->write_uint16(writer, len); + writer->write_data (writer, chunk_create(policy_uri, len)); + } + if (has_pcr_info) + { + writer->write_uint16(writer, pcr_before.len); + writer->write_data (writer, pcr_before); + writer->write_data (writer, pcr_after); + } + + writer->write_data(writer, measurement); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; +static const int tm_leap_1970 = 477; + +/** + * Convert Simple Component Evidence UTS string format to time_t + */ +bool measurement_time_from_utc(time_t *measurement_time, chunk_t utc_time) +{ + int tm_year, tm_mon, tm_day, tm_days, tm_hour, tm_min, tm_sec, tm_secs; + int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap; + + if (memeq(utc_undefined_time_str, utc_time.ptr, utc_time.len)) + { + *measurement_time = 0; + return TRUE; + } + if (sscanf(utc_time.ptr, "%4d-%2d-%2dT%2d:%2d:%2dZ", + &tm_year, &tm_mon, &tm_day, &tm_hour, &tm_min, &tm_sec) != 6) + { + return FALSE; + } + + /* representation of months as 0..11 */ + tm_mon--; + + /* representation of days as 0..30 */ + tm_day--; + + /* number of leap years between last year and 1970? */ + tm_leap_4 = (tm_year - 1) / 4; + tm_leap_100 = tm_leap_4 / 25; + tm_leap_400 = tm_leap_100 / 4; + tm_leap = tm_leap_4 - tm_leap_100 + tm_leap_400 - tm_leap_1970; + + /* if date later then February, is the current year a leap year? */ + if (tm_mon > 1 && (tm_year % 4 == 0) && + (tm_year % 100 != 0 || tm_year % 400 == 0)) + { + tm_leap++; + } + tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap; + tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec; + + *measurement_time = tm_secs; + return TRUE; +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_simple_comp_evid_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + pts_comp_func_name_t *name; + u_int8_t flags, fam_and_qualifier, qualifier, reserved; + u_int8_t measurement_type, transform, validation; + u_int16_t hash_algorithm, len; + u_int32_t depth, vendor_id, comp_name, extended_pcr; + chunk_t measurement, utc_time, policy_uri, pcr_before, pcr_after; + time_t measurement_time; + bool has_pcr_info = FALSE, has_validation = FALSE; + status_t status = FAILED; + + if (this->value.len < PTS_SIMPLE_COMP_EVID_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Simple Component Evidence"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + + reader->read_uint8 (reader, &flags); + reader->read_uint24(reader, &depth); + reader->read_uint24(reader, &vendor_id); + reader->read_uint8 (reader, &fam_and_qualifier); + reader->read_uint32(reader, &comp_name); + reader->read_uint8 (reader, &measurement_type); + reader->read_uint24(reader, &extended_pcr); + reader->read_uint16(reader, &hash_algorithm); + reader->read_uint8 (reader, &transform); + reader->read_uint8 (reader, &reserved); + reader->read_data (reader, PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE, &utc_time); + + if (measurement_type != PTS_SIMPLE_COMP_EVID_MEAS_TYPE) + { + DBG1(DBG_TNC, "unsupported Measurement Type in " + "Simple Component Evidence"); + *offset = 12; + reader->destroy(reader); + return FAILED; + } + if (!measurement_time_from_utc(&measurement_time, utc_time)) + { + DBG1(DBG_TNC, "invalid Measurement Time field in " + "Simple Component Evidence"); + *offset = 20; + reader->destroy(reader); + return FAILED; + } + validation = flags & PTS_SIMPLE_COMP_EVID_VALIDATION_MASK; + qualifier = fam_and_qualifier & ~PTS_SIMPLE_COMP_EVID_FAMILY_MASK; + + /* Is optional Policy URI field included? */ + if (validation == PTS_COMP_EVID_VALIDATION_FAILED || + validation == PTS_COMP_EVID_VALIDATION_PASSED) + { + if (!reader->read_uint16(reader, &len)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence " + "Verification Policy URI Length"); + goto end; + } + if (!reader->read_data(reader, len, &policy_uri)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence " + "Verification Policy URI"); + goto end; + } + has_validation = TRUE; + } + + /* Are optional PCR value fields included? */ + if (flags & PTS_SIMPLE_COMP_EVID_FLAG_PCR) + { + if (!reader->read_uint16(reader, &len)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence " + "PCR Value length"); + goto end; + } + if (!reader->read_data(reader, len, &pcr_before)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence " + "PCR Before Value"); + goto end; + } + if (!reader->read_data(reader, len, &pcr_after)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence " + "PCR After Value"); + goto end; + } + has_pcr_info = TRUE; + } + + /* Measurement field comes at the very end */ + reader->read_data(reader,reader->remaining(reader), &measurement); + reader->destroy(reader); + + /* Create Component Functional Name object */ + name = pts_comp_func_name_create(vendor_id, comp_name, qualifier); + + /* Create Component Evidence object */ + measurement = chunk_clone(measurement); + this->evidence = pts_comp_evidence_create(name, depth, extended_pcr, + hash_algorithm, transform, + measurement_time, measurement); + + /* Add options */ + if (has_validation) + { + char buf[BUF_LEN]; + size_t len; + + len = min(policy_uri.len, BUF_LEN-1); + memcpy(buf, policy_uri.ptr, len); + buf[len] = '\0'; + this->evidence->set_validation(this->evidence, validation, buf); + } + if (has_pcr_info) + { + pcr_before = chunk_clone(pcr_before); + pcr_after = chunk_clone(pcr_after); + this->evidence->set_pcr_info(this->evidence, pcr_before, pcr_after); + } + + return SUCCESS; + +end: + reader->destroy(reader); + return status; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + if (ref_put(&this->ref)) + { + DESTROY_IF(this->evidence); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_simple_comp_evid_t, get_comp_evidence, pts_comp_evidence_t*, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + return this->evidence; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid) +{ + private_tcg_pts_attr_simple_comp_evid_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_comp_evidence = _get_comp_evidence, + }, + .type = { PEN_TCG, TCG_PTS_SIMPLE_COMP_EVID }, + .evidence = evid, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_simple_comp_evid_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_comp_evidence = _get_comp_evidence, + }, + .type = { PEN_TCG, TCG_PTS_SIMPLE_COMP_EVID }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_simple_comp_evid.h b/src/libpts/tcg/pts/tcg_pts_attr_simple_comp_evid.h new file mode 100644 index 000000000..628fad621 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_simple_comp_evid.h @@ -0,0 +1,64 @@ +/* + * 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 tcg_pts_attr_simple_comp_evid tcg_pts_attr_simple_comp_evid + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_ +#define TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_ + +typedef struct tcg_pts_attr_simple_comp_evid_t tcg_pts_attr_simple_comp_evid_t; + +#include "tcg/tcg_attr.h" +#include "pts/components/pts_comp_evidence.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Simple Component Evidence attribute + * + */ +struct tcg_pts_attr_simple_comp_evid_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get Component Evidence + * + * @return Component Evidence + */ + pts_comp_evidence_t* (*get_comp_evidence)(tcg_pts_attr_simple_comp_evid_t *this); + +}; + +/** + * Creates an tcg_pts_attr_simple_comp_evid_t object + * + * @param evid Component Evidence + */ +pa_tnc_attr_t* tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid); + +/** + * Creates an tcg_pts_attr_simple_comp_evid_t object from received data + * + * @param value Unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_simple_evid_final.c b/src/libpts/tcg/pts/tcg_pts_attr_simple_evid_final.c new file mode 100644 index 000000000..baadd943f --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_simple_evid_final.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_simple_evid_final.h" +#include "pts/pts_simple_evid_final.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_simple_evid_final_t private_tcg_pts_attr_simple_evid_final_t; + +/** + * Simple Evidence Final + * see section 3.15.2 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | Reserved | Optional Composite Hash Alg | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Optional TPM PCR Composite Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Optional TPM PCR Composite (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Optional TPM Quote Signature Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Optional TPM Quote Signature (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Optional Evidence Signature (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PTS_SIMPLE_EVID_FINAL_SIZE 2 +#define PTS_SIMPLE_EVID_FINAL_RESERVED 0x00 +#define PTS_SIMPLE_EVID_FINAL_FLAG_MASK 0xC0 +/** + * Private data of an tcg_pts_attr_simple_evid_final_t object. + */ +struct private_tcg_pts_attr_simple_evid_final_t { + + /** + * Public members of tcg_pts_attr_simple_evid_final_t + */ + tcg_pts_attr_simple_evid_final_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Set of flags for Simple Evidence Final + */ + u_int8_t flags; + + /** + * Optional Composite Hash Algorithm + */ + pts_meas_algorithms_t comp_hash_algorithm; + + /** + * Optional TPM PCR Composite + */ + chunk_t pcr_comp; + + /** + * Optional TPM Quote Signature + */ + chunk_t tpm_quote_sig; + + /** + * Is Evidence Signature included? + */ + bool has_evid_sig; + + /** + * Optional Evidence Signature + */ + chunk_t evid_sig; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_simple_evid_final_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_simple_evid_final_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_simple_evid_final_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_simple_evid_final_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_simple_evid_final_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_simple_evid_final_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->pcr_comp.ptr); + free(this->tpm_quote_sig.ptr); + free(this->evid_sig.ptr); + free(this); + } +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_simple_evid_final_t *this) +{ + bio_writer_t *writer; + u_int8_t flags; + + if (this->value.ptr) + { + return; + } + flags = this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK; + + if (this->has_evid_sig) + { + flags |= PTS_SIMPLE_EVID_FINAL_EVID_SIG; + } + + writer = bio_writer_create(PTS_SIMPLE_EVID_FINAL_SIZE); + writer->write_uint8 (writer, flags); + writer->write_uint8 (writer, PTS_SIMPLE_EVID_FINAL_RESERVED); + + /** Optional Composite Hash Algorithm field is always present + * Field has value of all zeroes if not used. + * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011 + */ + writer->write_uint16(writer, this->comp_hash_algorithm); + + /* Optional fields */ + if (this->flags != PTS_SIMPLE_EVID_FINAL_NO) + { + writer->write_uint32 (writer, this->pcr_comp.len); + writer->write_data (writer, this->pcr_comp); + + writer->write_uint32 (writer, this->tpm_quote_sig.len); + writer->write_data (writer, this->tpm_quote_sig); + } + + if (this->has_evid_sig) + { + writer->write_data (writer, this->evid_sig); + } + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_simple_evid_final_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t flags, reserved; + u_int16_t algorithm; + u_int32_t pcr_comp_len, tpm_quote_sig_len, evid_sig_len; + status_t status = FAILED; + + if (this->value.len < PTS_SIMPLE_EVID_FINAL_SIZE) + { + DBG1(DBG_TNC, "insufficient data for Simple Evidence Final"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + + reader->read_uint8(reader, &flags); + reader->read_uint8(reader, &reserved); + + this->flags = flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK; + + this->has_evid_sig = (flags & PTS_SIMPLE_EVID_FINAL_EVID_SIG) != 0; + + /** Optional Composite Hash Algorithm field is always present + * Field has value of all zeroes if not used. + * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011 + */ + + reader->read_uint16(reader, &algorithm); + this->comp_hash_algorithm = algorithm; + + /* Optional Composite Hash Algorithm and TPM PCR Composite fields */ + if (this->flags != PTS_SIMPLE_EVID_FINAL_NO) + { + if (!reader->read_uint32(reader, &pcr_comp_len)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final " + "PCR Composite Length"); + goto end; + } + if (!reader->read_data(reader, pcr_comp_len, &this->pcr_comp)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final " + "PCR Composite"); + goto end; + } + this->pcr_comp = chunk_clone(this->pcr_comp); + + if (!reader->read_uint32(reader, &tpm_quote_sig_len)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final " + "TPM Quote Singature Length"); + goto end; + } + if (!reader->read_data(reader, tpm_quote_sig_len, &this->tpm_quote_sig)) + { + DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final " + "TPM Quote Singature"); + goto end; + } + this->tpm_quote_sig = chunk_clone(this->tpm_quote_sig); + } + + /* Optional Evidence Signature field */ + if (this->has_evid_sig) + { + evid_sig_len = reader->remaining(reader); + reader->read_data(reader, evid_sig_len, &this->evid_sig); + this->evid_sig = chunk_clone(this->evid_sig); + } + + reader->destroy(reader); + return SUCCESS; + +end: + reader->destroy(reader); + return status; +} + +METHOD(tcg_pts_attr_simple_evid_final_t, get_quote_info, u_int8_t, + private_tcg_pts_attr_simple_evid_final_t *this, + pts_meas_algorithms_t *comp_hash_algo, chunk_t *pcr_comp, chunk_t *tpm_quote_sig) +{ + if (comp_hash_algo) + { + *comp_hash_algo = this->comp_hash_algorithm; + } + if (pcr_comp) + { + *pcr_comp = this->pcr_comp; + } + if (tpm_quote_sig) + { + *tpm_quote_sig = this->tpm_quote_sig; + } + return this->flags; +} + +METHOD(tcg_pts_attr_simple_evid_final_t, get_evid_sig, bool, + private_tcg_pts_attr_simple_evid_final_t *this, chunk_t *evid_sig) +{ + if (evid_sig) + { + *evid_sig = this->evid_sig; + } + return this->has_evid_sig; +} + +METHOD(tcg_pts_attr_simple_evid_final_t, set_evid_sig, void, + private_tcg_pts_attr_simple_evid_final_t *this, chunk_t evid_sig) +{ + this->evid_sig = evid_sig; + this->has_evid_sig = TRUE; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(u_int8_t flags, + pts_meas_algorithms_t comp_hash_algorithm, + chunk_t pcr_comp, chunk_t tpm_quote_sig) +{ + private_tcg_pts_attr_simple_evid_final_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_quote_info = _get_quote_info, + .get_evid_sig = _get_evid_sig, + .set_evid_sig = _set_evid_sig, + }, + .type = { PEN_TCG, TCG_PTS_SIMPLE_EVID_FINAL }, + .flags = flags, + .comp_hash_algorithm = comp_hash_algorithm, + .pcr_comp = pcr_comp, + .tpm_quote_sig = tpm_quote_sig, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_simple_evid_final_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_quote_info = _get_quote_info, + .get_evid_sig = _get_evid_sig, + .set_evid_sig = _set_evid_sig, + }, + .type = { PEN_TCG, TCG_PTS_SIMPLE_EVID_FINAL }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_simple_evid_final.h b/src/libpts/tcg/pts/tcg_pts_attr_simple_evid_final.h new file mode 100644 index 000000000..1fac2e1ce --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_simple_evid_final.h @@ -0,0 +1,93 @@ +/* + * 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 tcg_pts_attr_simple_evid_final tcg_pts_attr_simple_evid_final + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_ +#define TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_ + +typedef struct tcg_pts_attr_simple_evid_final_t tcg_pts_attr_simple_evid_final_t; + +#include "tcg/tcg_attr.h" +#include "tcg_pts_attr_meas_algo.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS Simple Evidence Final attribute + * + */ +struct tcg_pts_attr_simple_evid_final_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get Optional PCR Composite and TPM Quote Signature + * + * @param comp_hash_algo Optional Composite Hash Algorithm + * @param pcr_comp Optional PCR Composite + * @param tpm_quote sig Optional TPM Quote Signature + * @return PTS_SIMPLE_EVID_FINAL flags + */ + u_int8_t (*get_quote_info)(tcg_pts_attr_simple_evid_final_t *this, + pts_meas_algorithms_t *comp_hash_algo, + chunk_t *pcr_comp, chunk_t *tpm_quote_sig); + + /** + * Get Optional Evidence Signature + * + * @param evid_sig Optional Evidence Signature + * @return TRUE if Evidence Signature is available + */ + bool (*get_evid_sig)(tcg_pts_attr_simple_evid_final_t *this, + chunk_t *evid_sig); + + /** + * Set Optional Evidence Signature + * + * @param vid_sig Optional Evidence Signature + */ + void (*set_evid_sig)(tcg_pts_attr_simple_evid_final_t *this, + chunk_t evid_sig); + +}; + +/** + * Creates an tcg_pts_attr_simple_evid_final_t object + * + * @param flags Set of flags + * @param comp_hash_algorithm Composite Hash Algorithm + * @param pcr_comp Optional TPM PCR Composite + * @param tpm_quote_sign Optional TPM Quote Signature + */ +pa_tnc_attr_t* tcg_pts_attr_simple_evid_final_create( + u_int8_t flags, + pts_meas_algorithms_t comp_hash_algorithm, + chunk_t pcr_comp, + chunk_t tpm_quote_sign); + +/** + * Creates an tcg_pts_attr_simple_evid_final_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_simple_evid_final_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_tpm_version_info.c b/src/libpts/tcg/pts/tcg_pts_attr_tpm_version_info.c new file mode 100644 index 000000000..b776cb662 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_tpm_version_info.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_tpm_version_info.h" + +#include +#include +#include +#include + +typedef struct private_tcg_pts_attr_tpm_version_info_t private_tcg_pts_attr_tpm_version_info_t; + +/** + * TPM Version Information + * see section 3.11 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TPM Version Information (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * see TPM Structure Specification Part 2, section 21.6: TPM_CAP_VERSION_INFO + */ + +#define PTS_TPM_VER_INFO_SIZE 4 + +/** + * Private data of an tcg_pts_attr_tpm_version_info_t object. + */ +struct private_tcg_pts_attr_tpm_version_info_t { + + /** + * Public members of tcg_pts_attr_tpm_version_info_t + */ + tcg_pts_attr_tpm_version_info_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * TPM Version Information + */ + chunk_t tpm_version_info; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_tpm_version_info_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(PTS_TPM_VER_INFO_SIZE); + writer->write_data(writer, this->tpm_version_info); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_tpm_version_info_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + + if (this->value.len < PTS_TPM_VER_INFO_SIZE) + { + DBG1(DBG_TNC, "insufficient data for TPM Version Information"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_data (reader, this->value.len, &this->tpm_version_info); + this->tpm_version_info = chunk_clone(this->tpm_version_info); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->tpm_version_info.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_tpm_version_info_t, get_tpm_version_info, chunk_t, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + return this->tpm_version_info; +} + +METHOD(tcg_pts_attr_tpm_version_info_t, set_tpm_version_info, void, + private_tcg_pts_attr_tpm_version_info_t *this, + chunk_t tpm_version_info) +{ + this->tpm_version_info = tpm_version_info; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info) +{ + private_tcg_pts_attr_tpm_version_info_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_tpm_version_info = _get_tpm_version_info, + .set_tpm_version_info = _set_tpm_version_info, + }, + .type = { PEN_TCG, TCG_PTS_TPM_VERSION_INFO }, + .tpm_version_info = chunk_clone(tpm_version_info), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_tpm_version_info_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_tpm_version_info = _get_tpm_version_info, + .set_tpm_version_info = _set_tpm_version_info, + }, + .type = { PEN_TCG, TCG_PTS_TPM_VERSION_INFO }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_tpm_version_info.h b/src/libpts/tcg/pts/tcg_pts_attr_tpm_version_info.h new file mode 100644 index 000000000..e03b57f79 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_tpm_version_info.h @@ -0,0 +1,70 @@ +/* + * 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 tcg_pts_attr_tpm_version_info tcg_pts_attr_tpm_version_info + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_TPM_VERSION_INFO_H_ +#define TCG_PTS_ATTR_TPM_VERSION_INFO_H_ + +typedef struct tcg_pts_attr_tpm_version_info_t tcg_pts_attr_tpm_version_info_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG PTS TPM Version Info Attribute + * + */ +struct tcg_pts_attr_tpm_version_info_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get TPM Version Info + * + * @return TPM version info + */ + chunk_t (*get_tpm_version_info)(tcg_pts_attr_tpm_version_info_t *this); + + /** + * Set TPM Version Info + * + * @param tpm_version_info TPM version info + */ + void (*set_tpm_version_info)(tcg_pts_attr_tpm_version_info_t *this, + chunk_t tpm_version_info); +}; + +/** + * Creates an tcg_pts_attr_tpm_version_info_t object + * + * @param tpm_version_info TPM version info + */ +pa_tnc_attr_t* tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info); + +/** + * Creates an tcg_pts_attr_tpm_version_info_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_tpm_version_info_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_TPM_VERSION_INFO_H_ @}*/ diff --git a/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.c b/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.c new file mode 100644 index 000000000..f96371b8b --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.c @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2011-2012 Sansar Choinyambuu, 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_pts_attr_unix_file_meta.h" + +#include +#include +#include +#include +#include + +#include + +typedef struct private_tcg_pts_attr_file_meta_t private_tcg_pts_attr_file_meta_t; + +/** + * Unix-Style File Metadata + * see section 3.17.3 of PTS Protocol: Binding to TNC IF-M Specification + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Number of Files included | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Number of Files included | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File metadata Length | Type | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Create Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Create Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Modify Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Modify Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Access Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Access Time | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Owner ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Owner ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Group ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | File Group ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ~ Filename (Variable Length) ~ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ........................... + */ + +#define PTS_FILE_META_SIZE 8 +#define PTS_FILE_MEAS_RESERVED 0x00 +#define PTS_FILE_METADATA_SIZE 52 + +/** + * Private data of an tcg_pts_attr_file_meta_t object. + */ +struct private_tcg_pts_attr_file_meta_t { + + /** + * Public members of tcg_pts_attr_file_meta_t + */ + tcg_pts_attr_file_meta_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * PTS File Metadata + */ + pts_file_meta_t *metadata; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_pts_attr_file_meta_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_pts_attr_file_meta_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_pts_attr_file_meta_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_pts_attr_file_meta_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_pts_attr_file_meta_t *this) +{ + bio_writer_t *writer; + enumerator_t *enumerator; + pts_file_metadata_t *entry; + u_int64_t number_of_files; + + if (this->value.ptr) + { + return; + } + number_of_files = this->metadata->get_file_count(this->metadata); + writer = bio_writer_create(PTS_FILE_META_SIZE); + + writer->write_uint64(writer, number_of_files); + + enumerator = this->metadata->create_enumerator(this->metadata); + while (enumerator->enumerate(enumerator, &entry)) + { + writer->write_uint16(writer, PTS_FILE_METADATA_SIZE + + strlen(entry->filename)); + writer->write_uint8 (writer, entry->type); + writer->write_uint8 (writer, PTS_FILE_MEAS_RESERVED); + writer->write_uint64(writer, entry->filesize); + writer->write_uint64(writer, entry->created); + writer->write_uint64(writer, entry->modified); + writer->write_uint64(writer, entry->accessed); + writer->write_uint64(writer, entry->owner); + writer->write_uint64(writer, entry->group); + writer->write_data (writer, chunk_create(entry->filename, + strlen(entry->filename))); + } + enumerator->destroy(enumerator); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_pts_attr_file_meta_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + pts_file_metadata_t *entry; + u_int8_t type, reserved; + u_int16_t len; + u_int64_t number_of_files, filesize, created, modified, accessed; + u_int64_t owner, group; + chunk_t filename; + status_t status = FAILED; + + if (this->value.len < PTS_FILE_META_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PTS Unix-Style file metadata header"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint64(reader, &number_of_files); + + this->metadata = pts_file_meta_create(); + + while (number_of_files--) + { + if (!reader->read_uint16(reader, &len)) + { + DBG1(DBG_TNC, "insufficient data for PTS file metadata length"); + goto end; + } + if (!reader->read_uint8(reader, &type)) + { + DBG1(DBG_TNC, "insufficient data for file type"); + goto end; + } + if (!reader->read_uint8(reader, &reserved)) + { + DBG1(DBG_TNC, "insufficient data for reserved field"); + goto end; + } + if (!reader->read_uint64(reader, &filesize)) + { + DBG1(DBG_TNC, "insufficient data for file size"); + goto end; + } + if (!reader->read_uint64(reader, &created)) + { + DBG1(DBG_TNC, "insufficient data for file create time"); + goto end; + } + if (!reader->read_uint64(reader, &modified)) + { + DBG1(DBG_TNC, "insufficient data for last modify time"); + goto end; + } + if (!reader->read_uint64(reader, &accessed)) + { + DBG1(DBG_TNC, "insufficient data for last access time"); + goto end; + } + if (!reader->read_uint64(reader, &owner)) + { + DBG1(DBG_TNC, "insufficient data for owner id"); + goto end; + } + if (!reader->read_uint64(reader, &group)) + { + DBG1(DBG_TNC, "insufficient data for group id"); + goto end; + } + if (!reader->read_data(reader, len - PTS_FILE_METADATA_SIZE, &filename)) + { + DBG1(DBG_TNC, "insufficient data for filename"); + goto end; + } + + entry = malloc_thing(pts_file_metadata_t); + entry->type = type; + entry->filesize = filesize; + entry->created = created; + entry->modified = modified; + entry->accessed = accessed; + entry->owner = owner; + entry->group = group; + entry->filename = strndup(filename.ptr, filename.len); + + this->metadata->add(this->metadata, entry); + } + status = SUCCESS; + +end: + reader->destroy(reader); + return status; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_file_meta_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_pts_attr_file_meta_t *this) +{ + if (ref_put(&this->ref)) + { + DESTROY_IF(this->metadata); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_pts_attr_file_meta_t, get_metadata, pts_file_meta_t*, + private_tcg_pts_attr_file_meta_t *this) +{ + return this->metadata; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata) +{ + private_tcg_pts_attr_file_meta_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_metadata = _get_metadata, + }, + .type = { PEN_TCG, TCG_PTS_UNIX_FILE_META }, + .metadata = metadata, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(chunk_t data) +{ + private_tcg_pts_attr_file_meta_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_metadata = _get_metadata, + }, + .type = { PEN_TCG, TCG_PTS_UNIX_FILE_META }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.h b/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.h new file mode 100644 index 000000000..2118d3920 --- /dev/null +++ b/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.h @@ -0,0 +1,65 @@ +/* + * 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 tcg_pts_attr_unix_file_meta tcg_pts_attr_unix_file_meta + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_PTS_ATTR_UNIX_FILE_META_H_ +#define TCG_PTS_ATTR_UNIX_FILE_META_H_ + +typedef struct tcg_pts_attr_file_meta_t tcg_pts_attr_file_meta_t; + +#include "tcg/tcg_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "pts/pts.h" +#include "pts/pts_file_meta.h" + +/** + * Class implementing the TCG PTS File Measurement attribute + * + */ +struct tcg_pts_attr_file_meta_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get PTS File Metadata + * + * @return PTS File Metadata + */ + pts_file_meta_t* (*get_metadata)(tcg_pts_attr_file_meta_t *this); + +}; + +/** + * Creates an tcg_pts_attr_file_meta_t object + * + * @param metadata PTS File Metadata + */ +pa_tnc_attr_t* tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata); + +/** + * Creates an tcg_pts_attr_file_meta_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_pts_attr_unix_file_meta_create_from_data(chunk_t value); + +#endif /** TCG_PTS_ATTR_UNIX_FILE_META_H_ @}*/ diff --git a/src/libpts/tcg/swid/tcg_swid_attr_req.c b/src/libpts/tcg/swid/tcg_swid_attr_req.c new file mode 100644 index 000000000..48f1d1040 --- /dev/null +++ b/src/libpts/tcg/swid/tcg_swid_attr_req.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2013 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_swid_attr_req.h" + +#include "swid/swid_tag_id.h" + +#include +#include +#include +#include +#include + +typedef struct private_tcg_swid_attr_req_t private_tcg_swid_attr_req_t; + +/** + * SWID Request + * see section 4.7 of TCG TNC SWID Message and Attributes for IF-M + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Reserved |C|S|R| Tag ID Count | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Request ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Earliest EID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Tag Creator Length | Tag Creator (variable length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Unique Software ID Length |Unique Software ID (var length)| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define SWID_REQ_SIZE 12 +#define SWID_REQ_RESERVED_MASK 0x03 + +/** + * Private data of an tcg_swid_attr_req_t object. + */ +struct private_tcg_swid_attr_req_t { + + /** + * Public members of tcg_swid_attr_req_t + */ + tcg_swid_attr_req_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * SWID request flags + */ + u_int8_t flags; + + /** + * Request ID + */ + u_int32_t request_id; + + /** + * Earliest EID + */ + u_int32_t earliest_eid; + + /** + * List of Tag Identifiers + */ + linked_list_t *tag_id_list; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_swid_attr_req_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_swid_attr_req_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_swid_attr_req_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_swid_attr_req_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_swid_attr_req_t *this) +{ + bio_writer_t *writer; + chunk_t tag_creator, unique_sw_id; + swid_tag_id_t *tag_id; + enumerator_t *enumerator; + + if (this->value.ptr) + { + return; + } + + writer = bio_writer_create(SWID_REQ_SIZE); + writer->write_uint8 (writer, this->flags); + writer->write_uint24(writer, this->tag_id_list->get_count(this->tag_id_list)); + writer->write_uint32(writer, this->request_id); + writer->write_uint32(writer, this->earliest_eid); + + enumerator = this->tag_id_list->create_enumerator(this->tag_id_list); + while (enumerator->enumerate(enumerator, &tag_id)) + { + tag_creator = tag_id->get_tag_creator(tag_id); + unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL); + writer->write_data16(writer, tag_creator); + writer->write_data16(writer, unique_sw_id); + } + enumerator->destroy(enumerator); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_swid_attr_req_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t tag_id_count; + chunk_t tag_creator, unique_sw_id; + swid_tag_id_t *tag_id; + + if (this->value.len < SWID_REQ_SIZE) + { + DBG1(DBG_TNC, "insufficient data for SWID Request"); + *offset = 0; + return FAILED; + } + + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &this->flags); + reader->read_uint24(reader, &tag_id_count); + reader->read_uint32(reader, &this->request_id); + reader->read_uint32(reader, &this->earliest_eid); + *offset = SWID_REQ_SIZE; + + this->flags &= SWID_REQ_RESERVED_MASK; + + while (tag_id_count--) + { + if (!reader->read_data16(reader, &tag_creator)) + { + DBG1(DBG_TNC, "insufficient data for Tag Creator field"); + return FAILED; + } + *offset += 2 + tag_creator.len; + + if (!reader->read_data16(reader, &unique_sw_id)) + { + DBG1(DBG_TNC, "insufficient data for Unique Software ID"); + return FAILED; + } + *offset += 2 + unique_sw_id.len; + + tag_id = swid_tag_id_create(tag_creator, unique_sw_id, chunk_empty); + this->tag_id_list->insert_last(this->tag_id_list, tag_id); + } + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_swid_attr_req_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_swid_attr_req_t *this) +{ + if (ref_put(&this->ref)) + { + this->tag_id_list->destroy_offset(this->tag_id_list, + offsetof(swid_tag_id_t, destroy)); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_swid_attr_req_t, get_flags, u_int8_t, + private_tcg_swid_attr_req_t *this) +{ + return this->flags; +} + +METHOD(tcg_swid_attr_req_t, get_request_id, u_int32_t, + private_tcg_swid_attr_req_t *this) +{ + return this->request_id; +} + +METHOD(tcg_swid_attr_req_t, get_earliest_eid, u_int32_t, + private_tcg_swid_attr_req_t *this) +{ + return this->earliest_eid; +} + +METHOD(tcg_swid_attr_req_t, add_tag_id, void, + private_tcg_swid_attr_req_t *this, swid_tag_id_t *tag_id) +{ + this->tag_id_list->insert_last(this->tag_id_list, tag_id); +} + +METHOD(tcg_swid_attr_req_t, create_tag_id_enumerator, enumerator_t*, + private_tcg_swid_attr_req_t *this) +{ + return this->tag_id_list->create_enumerator(this->tag_id_list); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_swid_attr_req_create(u_int8_t flags, u_int32_t request_id, + u_int32_t eid) +{ + private_tcg_swid_attr_req_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_flags = _get_flags, + .get_request_id = _get_request_id, + .get_earliest_eid = _get_earliest_eid, + .add_tag_id = _add_tag_id, + .create_tag_id_enumerator = _create_tag_id_enumerator, + }, + .type = { PEN_TCG, TCG_SWID_REQUEST }, + .flags = flags & SWID_REQ_RESERVED_MASK, + .request_id = request_id, + .earliest_eid = eid, + .tag_id_list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_swid_attr_req_create_from_data(chunk_t data) +{ + private_tcg_swid_attr_req_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_flags = _get_flags, + .get_request_id = _get_request_id, + .get_earliest_eid = _get_earliest_eid, + .add_tag_id = _add_tag_id, + .create_tag_id_enumerator = _create_tag_id_enumerator, + }, + .type = { PEN_TCG, TCG_SWID_REQUEST }, + .value = chunk_clone(data), + .tag_id_list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/swid/tcg_swid_attr_req.h b/src/libpts/tcg/swid/tcg_swid_attr_req.h new file mode 100644 index 000000000..40503df93 --- /dev/null +++ b/src/libpts/tcg/swid/tcg_swid_attr_req.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 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_swid_attr_req tcg_swid_attr_req + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_SWID_ATTR_REQ_H_ +#define TCG_SWID_ATTR_REQ_H_ + +typedef struct tcg_swid_attr_req_t tcg_swid_attr_req_t; +typedef enum tcg_swid_attr_req_flag_t tcg_swid_attr_req_flag_t; + +enum tcg_swid_attr_req_flag_t { + TCG_SWID_ATTR_REQ_FLAG_NONE = 0, + TCG_SWID_ATTR_REQ_FLAG_R = (1 << 0), + TCG_SWID_ATTR_REQ_FLAG_S = (1 << 1), + TCG_SWID_ATTR_REQ_FLAG_C = (1 << 2) +}; + +#include "tcg/tcg_attr.h" +#include "swid/swid_tag_id.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the TCG SWID Request attribute + */ +struct tcg_swid_attr_req_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get SWID request flags + * + * @return Flags + */ + u_int8_t (*get_flags)(tcg_swid_attr_req_t *this); + + /** + * Get Request ID + * + * @return Request ID + */ + u_int32_t (*get_request_id)(tcg_swid_attr_req_t *this); + + /** + * Get Earliest EID + * + * @return Event ID + */ + u_int32_t (*get_earliest_eid)(tcg_swid_attr_req_t *this); + + /** + * Add Tag ID + * + * @param tag_id SWID Tag ID (is not cloned by constructor!) + */ + void (*add_tag_id)(tcg_swid_attr_req_t *this, swid_tag_id_t *tag_id); + + /** + * Create Tag ID enumerator + * + * @return Tag ID enumerator + */ + enumerator_t* (*create_tag_id_enumerator)(tcg_swid_attr_req_t *this); + +}; + +/** + * Creates an tcg_swid_attr_req_t object + * + * @param flags Sets the C|S|R flags + * @param request_id Request ID + * @param eid Earliest Event ID + */ +pa_tnc_attr_t* tcg_swid_attr_req_create(u_int8_t flags, u_int32_t request_id, + u_int32_t eid); + +/** + * Creates an tcg_swid_attr_req_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_swid_attr_req_create_from_data(chunk_t value); + +#endif /** TCG_SWID_ATTR_REQ_H_ @}*/ diff --git a/src/libpts/tcg/swid/tcg_swid_attr_tag_id_inv.c b/src/libpts/tcg/swid/tcg_swid_attr_tag_id_inv.c new file mode 100644 index 000000000..bdb2e6ad5 --- /dev/null +++ b/src/libpts/tcg/swid/tcg_swid_attr_tag_id_inv.c @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2013 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_swid_attr_tag_id_inv.h" + +#include +#include +#include +#include + + +typedef struct private_tcg_swid_attr_tag_id_inv_t private_tcg_swid_attr_tag_id_inv_t; + +/** + * SWID Tag Identifier Inventory + * see section 4.8 of TCG TNC SWID Message and Attributes for IF-M + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Tag ID Count | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Request ID Copy | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | EID Epoch | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last EID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Tag Creator Length | Tag Creator (variable length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Unique Software ID Length |Unique Software ID (var length)| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Unique Sequence ID Length |Unique Sequence ID (var length)| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define SWID_TAG_ID_INV_SIZE 16 +#define SWID_TAG_ID_INV_RESERVED 0x00 + +/** + * Private data of an tcg_swid_attr_tag_id_inv_t object. + */ +struct private_tcg_swid_attr_tag_id_inv_t { + + /** + * Public members of tcg_swid_attr_tag_id_inv_t + */ + tcg_swid_attr_tag_id_inv_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Request ID + */ + u_int32_t request_id; + + /** + * Event ID Epoch + */ + u_int32_t eid_epoch; + + /** + * Last Event ID + */ + u_int32_t last_eid; + + /** + * List of Tag Identifiers + */ + linked_list_t *tag_id_list; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_swid_attr_tag_id_inv_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + bio_writer_t *writer; + swid_tag_id_t *tag_id; + chunk_t tag_creator, unique_sw_id, unique_seq_id; + enumerator_t *enumerator; + + if (this->value.ptr) + { + return; + } + + writer = bio_writer_create(SWID_TAG_ID_INV_SIZE); + writer->write_uint8 (writer, SWID_TAG_ID_INV_RESERVED); + writer->write_uint24(writer, this->tag_id_list->get_count(this->tag_id_list)); + writer->write_uint32(writer, this->request_id); + writer->write_uint32(writer, this->eid_epoch); + writer->write_uint32(writer, this->last_eid); + + enumerator = this->tag_id_list->create_enumerator(this->tag_id_list); + while (enumerator->enumerate(enumerator, &tag_id)) + { + tag_creator = tag_id->get_tag_creator(tag_id); + unique_sw_id = tag_id->get_unique_sw_id(tag_id, &unique_seq_id); + writer->write_data16(writer, tag_creator); + writer->write_data16(writer, unique_sw_id); + writer->write_data16(writer, unique_seq_id); + } + enumerator->destroy(enumerator); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_swid_attr_tag_id_inv_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t tag_id_count; + u_int8_t reserved; + chunk_t tag_creator, unique_sw_id, unique_seq_id; + swid_tag_id_t *tag_id; + + if (this->value.len < SWID_TAG_ID_INV_SIZE) + { + DBG1(DBG_TNC, "insufficient data for SWID Tag Identifier Inventory"); + *offset = 0; + return FAILED; + } + + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &reserved); + reader->read_uint24(reader, &tag_id_count); + reader->read_uint32(reader, &this->request_id); + reader->read_uint32(reader, &this->eid_epoch); + reader->read_uint32(reader, &this->last_eid); + *offset = SWID_TAG_ID_INV_SIZE; + + while (tag_id_count--) + { + if (!reader->read_data16(reader, &tag_creator)) + { + DBG1(DBG_TNC, "insufficient data for Tag Creator field"); + return FAILED; + } + *offset += 2 + tag_creator.len; + + if (!reader->read_data16(reader, &unique_sw_id)) + { + DBG1(DBG_TNC, "insufficient data for Unique Software ID"); + return FAILED; + } + *offset += 2 + unique_sw_id.len; + + if (!reader->read_data16(reader, &unique_seq_id)) + { + DBG1(DBG_TNC, "insufficient data for Unique Sequence ID"); + return FAILED; + } + *offset += 2 + unique_seq_id.len; + + tag_id = swid_tag_id_create(tag_creator, unique_sw_id, unique_seq_id); + this->tag_id_list->insert_last(this->tag_id_list, tag_id); + } + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + if (ref_put(&this->ref)) + { + this->tag_id_list->destroy_offset(this->tag_id_list, + offsetof(swid_tag_id_t, destroy)); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_swid_attr_tag_id_inv_t, get_request_id, u_int32_t, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + return this->request_id; +} + +METHOD(tcg_swid_attr_tag_id_inv_t, get_last_eid, u_int32_t, + private_tcg_swid_attr_tag_id_inv_t *this, u_int32_t *eid_epoch) +{ + if (eid_epoch) + { + *eid_epoch = this->eid_epoch; + } + return this->last_eid; +} + +METHOD(tcg_swid_attr_tag_id_inv_t, add_tag_id, void, + private_tcg_swid_attr_tag_id_inv_t *this, swid_tag_id_t *tag_id) +{ + this->tag_id_list->insert_last(this->tag_id_list, tag_id); +} + +METHOD(tcg_swid_attr_tag_id_inv_t, create_tag_id_enumerator, enumerator_t*, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + return this->tag_id_list->create_enumerator(this->tag_id_list); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create(u_int32_t request_id, + u_int32_t eid_epoch, + u_int32_t eid) +{ + private_tcg_swid_attr_tag_id_inv_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_request_id = _get_request_id, + .get_last_eid = _get_last_eid, + .add_tag_id = _add_tag_id, + .create_tag_id_enumerator = _create_tag_id_enumerator, + }, + .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY }, + .request_id = request_id, + .eid_epoch = eid_epoch, + .last_eid = eid, + .tag_id_list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create_from_data(chunk_t data) +{ + private_tcg_swid_attr_tag_id_inv_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_request_id = _get_request_id, + .get_last_eid = _get_last_eid, + .add_tag_id = _add_tag_id, + .create_tag_id_enumerator = _create_tag_id_enumerator, + }, + .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY }, + .value = chunk_clone(data), + .tag_id_list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/swid/tcg_swid_attr_tag_id_inv.h b/src/libpts/tcg/swid/tcg_swid_attr_tag_id_inv.h new file mode 100644 index 000000000..9719587e2 --- /dev/null +++ b/src/libpts/tcg/swid/tcg_swid_attr_tag_id_inv.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013 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_swid_attr_tag_id_inv tcg_swid_attr_tag_id_inv + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_SWID_ATTR_TAG_ID_INV_H_ +#define TCG_SWID_ATTR_TAG_ID_INV_H_ + +typedef struct tcg_swid_attr_tag_id_inv_t tcg_swid_attr_tag_id_inv_t; + +#include "tcg/tcg_attr.h" +#include "swid/swid_tag_id.h" + +#include + +/** + * Class implementing the TCG SWID Tag Identifier Inventory attribute + * + */ +struct tcg_swid_attr_tag_id_inv_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get Request ID + * + * @return Request ID + */ + u_int32_t (*get_request_id)(tcg_swid_attr_tag_id_inv_t *this); + + /** + * Get Last Event ID + * + * @param eid_epoch Event ID Epoch + * @return Last Event ID + */ + u_int32_t (*get_last_eid)(tcg_swid_attr_tag_id_inv_t *this, + u_int32_t *eid_epoch); + + /** + * Add Tag ID + * + * @param tag_id SWID Tag ID (is not cloned by constructor!) + */ + void (*add_tag_id)(tcg_swid_attr_tag_id_inv_t *this, swid_tag_id_t *tag_id); + + /** + * Create Tag ID enumerator + * + * @return Tag ID enumerator + */ + enumerator_t* (*create_tag_id_enumerator)(tcg_swid_attr_tag_id_inv_t *this); + +}; + +/** + * Creates an tcg_swid_attr_tag_id_inv_t object + * + * @param request_id Copy of the Request ID + * @param eid_epoch Event ID Epoch + * @param eid Last Event ID + */ +pa_tnc_attr_t* tcg_swid_attr_tag_id_inv_create(u_int32_t request_id, + u_int32_t eid_epoch, + u_int32_t eid); + +/** + * Creates an tcg_swid_attr_tag_id_inv_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_swid_attr_tag_id_inv_create_from_data(chunk_t value); + +#endif /** TCG_SWID_ATTR_TAG_ID_INV_H_ @}*/ diff --git a/src/libpts/tcg/tcg_attr.c b/src/libpts/tcg/tcg_attr.c index 2ce235e50..d55ce9367 100644 --- a/src/libpts/tcg/tcg_attr.c +++ b/src/libpts/tcg/tcg_attr.c @@ -13,23 +13,25 @@ */ #include "tcg_attr.h" -#include "tcg/tcg_pts_attr_proto_caps.h" -#include "tcg/tcg_pts_attr_dh_nonce_params_req.h" -#include "tcg/tcg_pts_attr_dh_nonce_params_resp.h" -#include "tcg/tcg_pts_attr_dh_nonce_finish.h" -#include "tcg/tcg_pts_attr_meas_algo.h" -#include "tcg/tcg_pts_attr_get_tpm_version_info.h" -#include "tcg/tcg_pts_attr_tpm_version_info.h" -#include "tcg/tcg_pts_attr_get_aik.h" -#include "tcg/tcg_pts_attr_aik.h" -#include "tcg/tcg_pts_attr_req_func_comp_evid.h" -#include "tcg/tcg_pts_attr_gen_attest_evid.h" -#include "tcg/tcg_pts_attr_simple_comp_evid.h" -#include "tcg/tcg_pts_attr_simple_evid_final.h" -#include "tcg/tcg_pts_attr_req_file_meas.h" -#include "tcg/tcg_pts_attr_file_meas.h" -#include "tcg/tcg_pts_attr_req_file_meta.h" -#include "tcg/tcg_pts_attr_unix_file_meta.h" +#include "tcg/pts/tcg_pts_attr_proto_caps.h" +#include "tcg/pts/tcg_pts_attr_dh_nonce_params_req.h" +#include "tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h" +#include "tcg/pts/tcg_pts_attr_dh_nonce_finish.h" +#include "tcg/pts/tcg_pts_attr_meas_algo.h" +#include "tcg/pts/tcg_pts_attr_get_tpm_version_info.h" +#include "tcg/pts/tcg_pts_attr_tpm_version_info.h" +#include "tcg/pts/tcg_pts_attr_get_aik.h" +#include "tcg/pts/tcg_pts_attr_aik.h" +#include "tcg/pts/tcg_pts_attr_req_func_comp_evid.h" +#include "tcg/pts/tcg_pts_attr_gen_attest_evid.h" +#include "tcg/pts/tcg_pts_attr_simple_comp_evid.h" +#include "tcg/pts/tcg_pts_attr_simple_evid_final.h" +#include "tcg/pts/tcg_pts_attr_req_file_meas.h" +#include "tcg/pts/tcg_pts_attr_file_meas.h" +#include "tcg/pts/tcg_pts_attr_req_file_meta.h" +#include "tcg/pts/tcg_pts_attr_unix_file_meta.h" +#include "tcg/swid/tcg_swid_attr_req.h" +#include "tcg/swid/tcg_swid_attr_tag_id_inv.h" ENUM_BEGIN(tcg_attr_names, TCG_SCAP_REFERENCES, TCG_SCAP_SUMMARY_RESULTS, @@ -172,6 +174,10 @@ pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, chunk_t value) { switch (type) { + case TCG_SWID_REQUEST: + return tcg_swid_attr_req_create_from_data(value); + case TCG_SWID_TAG_ID_INVENTORY: + return tcg_swid_attr_tag_id_inv_create_from_data(value); case TCG_PTS_REQ_PROTO_CAPS: return tcg_pts_attr_proto_caps_create_from_data(value, TRUE); case TCG_PTS_PROTO_CAPS: @@ -210,6 +216,9 @@ pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, chunk_t value) return tcg_pts_attr_req_file_meta_create_from_data(value); case TCG_PTS_UNIX_FILE_META: return tcg_pts_attr_unix_file_meta_create_from_data(value); + case TCG_SWID_TAG_ID_EVENTS: + case TCG_SWID_TAG_INVENTORY: + case TCG_SWID_TAG_EVENTS: case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META: case TCG_PTS_TEMPL_REF_MANI_SET_META: case TCG_PTS_UPDATE_TEMPL_REF_MANI: diff --git a/testing/scripts/recipes/013_strongswan.mk b/testing/scripts/recipes/013_strongswan.mk index 6240d4228..efa4a77e3 100644 --- a/testing/scripts/recipes/013_strongswan.mk +++ b/testing/scripts/recipes/013_strongswan.mk @@ -43,6 +43,8 @@ CONFIG_OPTS = \ --enable-imv-os \ --enable-imc-attestation \ --enable-imv-attestation \ + --enable-imc-swid \ + --enable-imv-swid \ --enable-sql \ --enable-sqlite \ --enable-attr-sql \