2 * Copyright (C) 2011 Sansar Choinyambuu
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_attestation_state.h"
18 #include <imc/imc_agent.h>
19 #include <pa_tnc/pa_tnc_msg.h>
20 #include <ietf/ietf_attr.h>
21 #include <ietf/ietf_attr_pa_tnc_error.h>
22 #include <tcg/tcg_attr.h>
30 static const char imc_name
[] = "Attestation";
32 #define IMC_VENDOR_ID PEN_ITA
33 #define IMC_SUBTYPE 0x02
35 static imc_agent_t
*imc_attestation
;
38 * see section 3.7.1 of TCG TNC IF-IMC Specification 1.2
40 TNC_Result
TNC_IMC_Initialize(TNC_IMCID imc_id
,
41 TNC_Version min_version
,
42 TNC_Version max_version
,
43 TNC_Version
*actual_version
)
47 DBG1(DBG_IMC
, "IMC \"%s\" has already been initialized", imc_name
);
48 return TNC_RESULT_ALREADY_INITIALIZED
;
50 imc_attestation
= imc_agent_create(imc_name
, IMC_VENDOR_ID
, IMC_SUBTYPE
,
51 imc_id
, actual_version
);
54 return TNC_RESULT_FATAL
;
56 if (min_version
> TNC_IFIMC_VERSION_1
|| max_version
< TNC_IFIMC_VERSION_1
)
58 DBG1(DBG_IMC
, "no common IF-IMC version");
59 return TNC_RESULT_NO_COMMON_VERSION
;
61 return TNC_RESULT_SUCCESS
;
65 * see section 3.7.2 of TCG TNC IF-IMC Specification 1.2
67 TNC_Result
TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id
,
68 TNC_ConnectionID connection_id
,
69 TNC_ConnectionState new_state
)
72 imc_attestation_state_t
*test_state
;
76 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
77 return TNC_RESULT_NOT_INITIALIZED
;
81 case TNC_CONNECTION_STATE_CREATE
:
82 state
= imc_attestation_state_create(connection_id
);
83 return imc_attestation
->create_state(imc_attestation
, state
);
84 case TNC_CONNECTION_STATE_DELETE
:
85 return imc_attestation
->delete_state(imc_attestation
, connection_id
);
86 case TNC_CONNECTION_STATE_ACCESS_ISOLATED
:
87 case TNC_CONNECTION_STATE_ACCESS_NONE
:
89 return imc_attestation
->change_state(imc_attestation
, connection_id
, new_state
);
93 static TNC_Result
send_message(TNC_ConnectionID connection_id
)
98 imc_attestation_state_t
*test_state
;
101 if (!imc_attestation
->get_state(imc_attestation
, connection_id
, &state
))
103 return TNC_RESULT_FATAL
;
105 test_state
= (imc_attestation_state_t
*)state
;
106 msg
= pa_tnc_msg_create();
108 * add TCG PTS attributes
111 result
= imc_attestation
->send_message(imc_attestation
, connection_id
,
112 msg
->get_encoding(msg
));
119 * see section 3.7.3 of TCG TNC IF-IMC Specification 1.2
121 TNC_Result
TNC_IMC_BeginHandshake(TNC_IMCID imc_id
,
122 TNC_ConnectionID connection_id
)
124 if (!imc_attestation
)
126 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
127 return TNC_RESULT_NOT_INITIALIZED
;
129 return send_message(connection_id
);
133 * see section 3.7.4 of TCG TNC IF-IMC Specification 1.2
135 TNC_Result
TNC_IMC_ReceiveMessage(TNC_IMCID imc_id
,
136 TNC_ConnectionID connection_id
,
137 TNC_BufferReference msg
,
139 TNC_MessageType msg_type
)
141 pa_tnc_msg_t
*pa_tnc_msg
;
143 enumerator_t
*enumerator
;
145 bool fatal_error
= FALSE
;
147 if (!imc_attestation
)
149 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
150 return TNC_RESULT_NOT_INITIALIZED
;
153 /* parse received PA-TNC message and automatically handle any errors */
154 result
= imc_attestation
->receive_message(imc_attestation
, connection_id
,
155 chunk_create(msg
, msg_len
), msg_type
,
158 /* no parsed PA-TNC attributes available if an error occurred */
164 /* analyze PA-TNC attributes */
165 enumerator
= pa_tnc_msg
->create_attribute_enumerator(pa_tnc_msg
);
166 while (enumerator
->enumerate(enumerator
, &attr
))
168 if (attr
->get_vendor_id(attr
) == PEN_IETF
&&
169 attr
->get_type(attr
) == IETF_ATTR_PA_TNC_ERROR
)
171 ietf_attr_pa_tnc_error_t
*error_attr
;
172 pa_tnc_error_code_t error_code
;
173 chunk_t msg_info
, attr_info
;
175 error_attr
= (ietf_attr_pa_tnc_error_t
*)attr
;
176 error_code
= error_attr
->get_error_code(error_attr
);
177 msg_info
= error_attr
->get_msg_info(error_attr
);
179 DBG1(DBG_IMC
, "received PA-TNC error '%N' concerning message %#B",
180 pa_tnc_error_code_names
, error_code
, &msg_info
);
183 case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED
:
184 attr_info
= error_attr
->get_attr_info(error_attr
);
185 DBG1(DBG_IMC
, " unsupported attribute %#B", &attr_info
);
192 else if (attr
->get_vendor_id(attr
) == PEN_TCG
)
195 * Handle TCG PTS attributes
199 enumerator
->destroy(enumerator
);
200 pa_tnc_msg
->destroy(pa_tnc_msg
);
202 /* if no error occurred then always return the same response */
203 return fatal_error ? TNC_RESULT_FATAL
: send_message(connection_id
);
207 * see section 3.7.5 of TCG TNC IF-IMC Specification 1.2
209 TNC_Result
TNC_IMC_BatchEnding(TNC_IMCID imc_id
,
210 TNC_ConnectionID connection_id
)
212 if (!imc_attestation
)
214 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
215 return TNC_RESULT_NOT_INITIALIZED
;
217 return TNC_RESULT_SUCCESS
;
221 * see section 3.7.6 of TCG TNC IF-IMC Specification 1.2
223 TNC_Result
TNC_IMC_Terminate(TNC_IMCID imc_id
)
225 if (!imc_attestation
)
227 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
228 return TNC_RESULT_NOT_INITIALIZED
;
230 imc_attestation
->destroy(imc_attestation
);
231 imc_attestation
= NULL
;
233 return TNC_RESULT_SUCCESS
;
237 * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.2
239 TNC_Result
TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id
,
240 TNC_TNCC_BindFunctionPointer bind_function
)
242 if (!imc_attestation
)
244 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
245 return TNC_RESULT_NOT_INITIALIZED
;
247 return imc_attestation
->bind_functions(imc_attestation
, bind_function
);