2 * Copyright (C) 2013 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "imc_swid_state.h"
19 #include "swid/swid_tag_id.h"
20 #include "tcg/swid/tcg_swid_attr_req.h"
21 #include "tcg/swid/tcg_swid_attr_tag_id_inv.h"
23 #include <imc/imc_agent.h>
24 #include <imc/imc_msg.h>
26 #include <tncif_pa_subtypes.h>
29 #include <utils/debug.h>
33 static const char imc_name
[] = "SWID";
35 static pen_type_t msg_types
[] = {
36 { PEN_TCG
, PA_SUBTYPE_TCG_SWID
}
39 static imc_agent_t
*imc_swid
;
42 * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
44 TNC_Result
TNC_IMC_Initialize(TNC_IMCID imc_id
,
45 TNC_Version min_version
,
46 TNC_Version max_version
,
47 TNC_Version
*actual_version
)
51 DBG1(DBG_IMC
, "IMC \"%s\" has already been initialized", imc_name
);
52 return TNC_RESULT_ALREADY_INITIALIZED
;
54 imc_swid
= imc_agent_create(imc_name
, msg_types
, countof(msg_types
),
55 imc_id
, actual_version
);
58 return TNC_RESULT_FATAL
;
63 if (min_version
> TNC_IFIMC_VERSION_1
|| max_version
< TNC_IFIMC_VERSION_1
)
65 DBG1(DBG_IMC
, "no common IF-IMC version");
66 return TNC_RESULT_NO_COMMON_VERSION
;
68 return TNC_RESULT_SUCCESS
;
72 * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
74 TNC_Result
TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id
,
75 TNC_ConnectionID connection_id
,
76 TNC_ConnectionState new_state
)
82 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
83 return TNC_RESULT_NOT_INITIALIZED
;
87 case TNC_CONNECTION_STATE_CREATE
:
88 state
= imc_swid_state_create(connection_id
);
89 return imc_swid
->create_state(imc_swid
, state
);
90 case TNC_CONNECTION_STATE_HANDSHAKE
:
91 if (imc_swid
->change_state(imc_swid
, connection_id
, new_state
,
92 &state
) != TNC_RESULT_SUCCESS
)
94 return TNC_RESULT_FATAL
;
96 state
->set_result(state
, imc_id
,
97 TNC_IMV_EVALUATION_RESULT_DONT_KNOW
);
98 return TNC_RESULT_SUCCESS
;
99 case TNC_CONNECTION_STATE_DELETE
:
100 return imc_swid
->delete_state(imc_swid
, connection_id
);
102 return imc_swid
->change_state(imc_swid
, connection_id
,
108 * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
110 TNC_Result
TNC_IMC_BeginHandshake(TNC_IMCID imc_id
,
111 TNC_ConnectionID connection_id
)
117 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
118 return TNC_RESULT_NOT_INITIALIZED
;
120 if (!imc_swid
->get_state(imc_swid
, connection_id
, &state
))
122 return TNC_RESULT_FATAL
;
125 return TNC_RESULT_SUCCESS
;
128 static TNC_Result
receive_message(imc_state_t
*state
, imc_msg_t
*in_msg
)
131 imc_swid_state_t
*swid_state
;
132 enumerator_t
*enumerator
;
136 bool fatal_error
= FALSE
;
138 /* parse received PA-TNC message and handle local and remote errors */
139 result
= in_msg
->receive(in_msg
, &fatal_error
);
140 if (result
!= TNC_RESULT_SUCCESS
)
144 out_msg
= imc_msg_create_as_reply(in_msg
);
145 swid_state
= (imc_swid_state_t
*)state
;
147 /* analyze PA-TNC attributes */
148 enumerator
= in_msg
->create_attribute_enumerator(in_msg
);
149 while (enumerator
->enumerate(enumerator
, &attr
))
151 tcg_swid_attr_req_t
*attr_req
;
152 tcg_swid_attr_tag_id_inv_t
*attr_tag_id_inv
;
153 swid_tag_id_t
*tag_id
;
155 u_int32_t request_id
, eid_epoch
;
157 type
= attr
->get_type(attr
);
159 if (type
.vendor_id
!= PEN_TCG
|| type
.type
!= TCG_SWID_REQUEST
)
164 attr_req
= (tcg_swid_attr_req_t
*)attr
;
165 flags
= attr_req
->get_flags(attr_req
);
166 request_id
= attr_req
->get_request_id(attr_req
);
167 if (flags
& TCG_SWID_ATTR_REQ_FLAG_R
)
169 eid_epoch
= swid_state
->get_eid_epoch(swid_state
);
170 attr
= tcg_swid_attr_tag_id_inv_create(request_id
, eid_epoch
, 1);
171 attr_tag_id_inv
= (tcg_swid_attr_tag_id_inv_t
*)attr
;
172 tag_id
= swid_tag_id_create(
173 chunk_from_str("regid.2004-03.org.strongswan"),
174 chunk_from_str("strongSwan-5-1-0"),
176 attr_tag_id_inv
->add_tag_id(attr_tag_id_inv
, tag_id
);
177 out_msg
->add_attribute(out_msg
, attr
);
180 enumerator
->destroy(enumerator
);
184 result
= TNC_RESULT_FATAL
;
188 result
= out_msg
->send(out_msg
, TRUE
);
190 out_msg
->destroy(out_msg
);
196 * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
199 TNC_Result
TNC_IMC_ReceiveMessage(TNC_IMCID imc_id
,
200 TNC_ConnectionID connection_id
,
201 TNC_BufferReference msg
,
203 TNC_MessageType msg_type
)
211 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
212 return TNC_RESULT_NOT_INITIALIZED
;
214 if (!imc_swid
->get_state(imc_swid
, connection_id
, &state
))
216 return TNC_RESULT_FATAL
;
218 in_msg
= imc_msg_create_from_data(imc_swid
, state
, connection_id
, msg_type
,
219 chunk_create(msg
, msg_len
));
220 result
= receive_message(state
, in_msg
);
221 in_msg
->destroy(in_msg
);
227 * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
229 TNC_Result
TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id
,
230 TNC_ConnectionID connection_id
,
231 TNC_UInt32 msg_flags
,
232 TNC_BufferReference msg
,
234 TNC_VendorID msg_vid
,
235 TNC_MessageSubtype msg_subtype
,
236 TNC_UInt32 src_imv_id
,
237 TNC_UInt32 dst_imc_id
)
245 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
246 return TNC_RESULT_NOT_INITIALIZED
;
248 if (!imc_swid
->get_state(imc_swid
, connection_id
, &state
))
250 return TNC_RESULT_FATAL
;
252 in_msg
= imc_msg_create_from_long_data(imc_swid
, state
, connection_id
,
253 src_imv_id
, dst_imc_id
,msg_vid
, msg_subtype
,
254 chunk_create(msg
, msg_len
));
255 result
=receive_message(state
, in_msg
);
256 in_msg
->destroy(in_msg
);
262 * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
264 TNC_Result
TNC_IMC_BatchEnding(TNC_IMCID imc_id
,
265 TNC_ConnectionID connection_id
)
269 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
270 return TNC_RESULT_NOT_INITIALIZED
;
272 return TNC_RESULT_SUCCESS
;
276 * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
278 TNC_Result
TNC_IMC_Terminate(TNC_IMCID imc_id
)
282 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
283 return TNC_RESULT_NOT_INITIALIZED
;
288 imc_swid
->destroy(imc_swid
);
291 return TNC_RESULT_SUCCESS
;
295 * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
297 TNC_Result
TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id
,
298 TNC_TNCC_BindFunctionPointer bind_function
)
302 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
303 return TNC_RESULT_NOT_INITIALIZED
;
305 return imc_swid
->bind_functions(imc_swid
, bind_function
);