Annotation of embedaddon/strongswan/src/libimcv/plugins/imv_attestation/imv_attestation_state.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2011-2012 Sansar Choinyambuu
3: * Copyright (C) 2011-2014 Andreas Steffen
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include "imv_attestation_state.h"
18:
19: #include <imcv.h>
20: #include <imv/imv_lang_string.h>
21: #include "imv/imv_reason_string.h"
22:
23: #include <tncif_policy.h>
24:
25: #include <collections/linked_list.h>
26: #include <utils/debug.h>
27:
28: typedef struct private_imv_attestation_state_t private_imv_attestation_state_t;
29: typedef struct file_meas_request_t file_meas_request_t;
30: typedef struct func_comp_t func_comp_t;
31:
32: /**
33: * Private data of an imv_attestation_state_t object.
34: */
35: struct private_imv_attestation_state_t {
36:
37: /**
38: * Public members of imv_attestation_state_t
39: */
40: imv_attestation_state_t public;
41:
42: /**
43: * TNCCS connection ID
44: */
45: TNC_ConnectionID connection_id;
46:
47: /**
48: * TNCCS connection state
49: */
50: TNC_ConnectionState state;
51:
52: /**
53: * Does the TNCCS connection support long message types?
54: */
55: bool has_long;
56:
57: /**
58: * Does the TNCCS connection support exclusive delivery?
59: */
60: bool has_excl;
61:
62: /**
63: * Maximum PA-TNC message size for this TNCCS connection
64: */
65: uint32_t max_msg_len;
66:
67: /**
68: * Flags set for completed actions
69: */
70: uint32_t action_flags;
71:
72: /**
73: * IMV database session associated with TNCCS connection
74: */
75: imv_session_t *session;
76:
77: /**
78: * PA-TNC attribute segmentation contracts associated with TNCCS connection
79: */
80: seg_contract_manager_t *contracts;
81:
82: /**
83: * IMV Attestation handshake state
84: */
85: imv_attestation_handshake_state_t handshake_state;
86:
87: /**
88: * IMV action recommendation
89: */
90: TNC_IMV_Action_Recommendation rec;
91:
92: /**
93: * IMV evaluation result
94: */
95: TNC_IMV_Evaluation_Result eval;
96:
97: /**
98: * List of Functional Components
99: */
100: linked_list_t *components;
101:
102: /**
103: * PTS object
104: */
105: pts_t *pts;
106:
107: /**
108: * Measurement error flags
109: */
110: uint32_t measurement_error;
111:
112: /**
113: * TNC Reason String
114: */
115: imv_reason_string_t *reason_string;
116:
117: };
118:
119: /**
120: * PTS Functional Component entry
121: */
122: struct func_comp_t {
123: pts_component_t *comp;
124: pts_comp_func_name_t* name;
125: };
126:
127: /**
128: * Frees a func_comp_t object
129: */
130: static void free_func_comp(func_comp_t *this)
131: {
132: this->comp->destroy(this->comp);
133: this->name->destroy(this->name);
134: free(this);
135: }
136:
137: /**
138: * Supported languages
139: */
140: static char* languages[] = { "en", "de", "mn" };
141:
142: /**
143: * Table of reason strings
144: */
145: static imv_lang_string_t reason_file_meas_fail[] = {
146: { "en", "Incorrect file measurement" },
147: { "de", "Falsche Dateimessung" },
148: { "mn", "Буруу байгаа файл" },
149: { NULL, NULL }
150: };
151:
152: static imv_lang_string_t reason_file_meas_pend[] = {
153: { "en", "Pending file measurement" },
154: { "de", "Ausstehende Dateimessung" },
155: { "mn", "Xүлээгдэж байгаа файл" },
156: { NULL, NULL }
157: };
158:
159: static imv_lang_string_t reason_no_trusted_aik[] = {
160: { "en", "No trusted AIK available" },
161: { "de", "Kein vetrauenswürdiger AIK verfügbar" },
162: { NULL, NULL }
163: };
164:
165: static imv_lang_string_t reason_comp_evid_fail[] = {
166: { "en", "Incorrect component evidence" },
167: { "de", "Falsche Komponenten-Evidenz" },
168: { "mn", "Буруу компонент хэмжилт" },
169: { NULL, NULL }
170: };
171:
172: static imv_lang_string_t reason_comp_evid_pend[] = {
173: { "en", "Pending component evidence" },
174: { "de", "Ausstehende Komponenten-Evidenz" },
175: { "mn", "Xүлээгдэж компонент хэмжилт" },
176: { NULL, NULL }
177: };
178:
179: static imv_lang_string_t reason_tpm_quote_fail[] = {
180: { "en", "Invalid TPM Quote signature received" },
181: { "de", "Falsche TPM Quote Signature erhalten" },
182: { "mn", "Буруу TPM Quote гарын үсэг" },
183: { NULL, NULL }
184: };
185:
186: METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
187: private_imv_attestation_state_t *this)
188: {
189: return this->connection_id;
190: }
191:
192: METHOD(imv_state_t, has_long, bool,
193: private_imv_attestation_state_t *this)
194: {
195: return this->has_long;
196: }
197:
198: METHOD(imv_state_t, has_excl, bool,
199: private_imv_attestation_state_t *this)
200: {
201: return this->has_excl;
202: }
203:
204: METHOD(imv_state_t, set_flags, void,
205: private_imv_attestation_state_t *this, bool has_long, bool has_excl)
206: {
207: this->has_long = has_long;
208: this->has_excl = has_excl;
209: }
210:
211: METHOD(imv_state_t, set_max_msg_len, void,
212: private_imv_attestation_state_t *this, uint32_t max_msg_len)
213: {
214: this->max_msg_len = max_msg_len;
215: }
216:
217: METHOD(imv_state_t, get_max_msg_len, uint32_t,
218: private_imv_attestation_state_t *this)
219: {
220: return this->max_msg_len;
221: }
222:
223: METHOD(imv_state_t, set_action_flags, void,
224: private_imv_attestation_state_t *this, uint32_t flags)
225: {
226: this->action_flags |= flags;
227: }
228:
229: METHOD(imv_state_t, get_action_flags, uint32_t,
230: private_imv_attestation_state_t *this)
231: {
232: return this->action_flags;
233: }
234:
235: METHOD(imv_state_t, set_session, void,
236: private_imv_attestation_state_t *this, imv_session_t *session)
237: {
238: this->session = session;
239: }
240:
241: METHOD(imv_state_t, get_session, imv_session_t*,
242: private_imv_attestation_state_t *this)
243: {
244: return this->session;
245: }
246:
247: METHOD(imv_state_t, get_contracts, seg_contract_manager_t*,
248: private_imv_attestation_state_t *this)
249: {
250: return this->contracts;
251: }
252:
253: METHOD(imv_state_t, change_state, TNC_ConnectionState,
254: private_imv_attestation_state_t *this, TNC_ConnectionState new_state)
255: {
256: TNC_ConnectionState old_state;
257:
258: old_state = this->state;
259: this->state = new_state;
260: return old_state;
261: }
262:
263: METHOD(imv_state_t, get_recommendation, void,
264: private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation *rec,
265: TNC_IMV_Evaluation_Result *eval)
266: {
267: *rec = this->rec;
268: *eval = this->eval;
269: }
270:
271: METHOD(imv_state_t, set_recommendation, void,
272: private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation rec,
273: TNC_IMV_Evaluation_Result eval)
274: {
275: this->rec = rec;
276: this->eval = eval;
277: }
278:
279: METHOD(imv_state_t, update_recommendation, void,
280: private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation rec,
281: TNC_IMV_Evaluation_Result eval)
282: {
283: this->rec = tncif_policy_update_recommendation(this->rec, rec);
284: this->eval = tncif_policy_update_evaluation(this->eval, eval);
285: }
286:
287: METHOD(imv_attestation_state_t, add_file_meas_reasons, void,
288: private_imv_attestation_state_t *this, imv_reason_string_t *reason_string)
289: {
290: if (this->measurement_error & IMV_ATTESTATION_ERROR_FILE_MEAS_FAIL)
291: {
292: reason_string->add_reason(reason_string, reason_file_meas_fail);
293: }
294: if (this->measurement_error & IMV_ATTESTATION_ERROR_FILE_MEAS_PEND)
295: {
296: reason_string->add_reason(reason_string, reason_file_meas_pend);
297: }
298: }
299:
300: METHOD(imv_attestation_state_t, add_comp_evid_reasons, void,
301: private_imv_attestation_state_t *this, imv_reason_string_t *reason_string)
302: {
303: if (this->measurement_error & IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK)
304: {
305: reason_string->add_reason(reason_string, reason_no_trusted_aik);
306: }
307: if (this->measurement_error & IMV_ATTESTATION_ERROR_COMP_EVID_FAIL)
308: {
309: reason_string->add_reason(reason_string, reason_comp_evid_fail);
310: }
311: if (this->measurement_error & IMV_ATTESTATION_ERROR_COMP_EVID_PEND)
312: {
313: reason_string->add_reason(reason_string, reason_comp_evid_pend);
314: }
315: if (this->measurement_error & IMV_ATTESTATION_ERROR_TPM_QUOTE_FAIL)
316: {
317: reason_string->add_reason(reason_string, reason_tpm_quote_fail);
318: }
319: }
320:
321: METHOD(imv_state_t, get_reason_string, bool,
322: private_imv_attestation_state_t *this, enumerator_t *language_enumerator,
323: chunk_t *reason_string, char **reason_language)
324: {
325: *reason_language = imv_lang_string_select_lang(language_enumerator,
326: languages, countof(languages));
327:
328: /* Instantiate a TNC Reason String object */
329: DESTROY_IF(this->reason_string);
330: this->reason_string = imv_reason_string_create(*reason_language, "\n");
331: add_file_meas_reasons(this, this->reason_string);
332: add_comp_evid_reasons(this, this->reason_string);
333: *reason_string = this->reason_string->get_encoding(this->reason_string);
334:
335: return TRUE;
336: }
337:
338: METHOD(imv_state_t, get_remediation_instructions, bool,
339: private_imv_attestation_state_t *this, enumerator_t *language_enumerator,
340: chunk_t *string, char **lang_code, char **uri)
341: {
342: return FALSE;
343: }
344:
345: METHOD(imv_state_t, reset, void,
346: private_imv_attestation_state_t *this)
347: {
348: DESTROY_IF(this->reason_string);
349: this->reason_string = NULL;
350: this->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
351: this->eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
352:
353: this->action_flags = 0;
354:
355: this->handshake_state = IMV_ATTESTATION_STATE_INIT;
356: this->measurement_error = 0;
357: this->components->destroy_function(this->components, (void *)free_func_comp);
358: this->components = linked_list_create();
359: this->pts->destroy(this->pts);
360: this->pts = pts_create(FALSE);
361: }
362:
363: METHOD(imv_state_t, destroy, void,
364: private_imv_attestation_state_t *this)
365: {
366: DESTROY_IF(this->session);
367: DESTROY_IF(this->reason_string);
368: this->components->destroy_function(this->components, (void *)free_func_comp);
369: this->pts->destroy(this->pts);
370: this->contracts->destroy(this->contracts);
371: free(this);
372: }
373:
374: METHOD(imv_attestation_state_t, get_handshake_state,
375: imv_attestation_handshake_state_t, private_imv_attestation_state_t *this)
376: {
377: return this->handshake_state;
378: }
379:
380: METHOD(imv_attestation_state_t, set_handshake_state, void,
381: private_imv_attestation_state_t *this,
382: imv_attestation_handshake_state_t new_state)
383: {
384: this->handshake_state = new_state;
385: }
386:
387: METHOD(imv_attestation_state_t, get_pts, pts_t*,
388: private_imv_attestation_state_t *this)
389: {
390: return this->pts;
391: }
392:
393: METHOD(imv_attestation_state_t, create_component, pts_component_t*,
394: private_imv_attestation_state_t *this, pts_comp_func_name_t *name,
395: uint32_t depth, pts_database_t *pts_db)
396: {
397: enumerator_t *enumerator;
398: func_comp_t *entry, *new_entry;
399: pts_component_t *component;
400: bool found = FALSE;
401:
402: enumerator = this->components->create_enumerator(this->components);
403: while (enumerator->enumerate(enumerator, &entry))
404: {
405: if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)))
406: {
407: found = TRUE;
408: break;
409: }
410: }
411: enumerator->destroy(enumerator);
412:
413: if (found)
414: {
415: if (name->equals(name, entry->name))
416: {
417: /* duplicate entry */
418: return NULL;
419: }
420: new_entry = malloc_thing(func_comp_t);
421: new_entry->name = name->clone(name);
422: new_entry->comp = entry->comp->get_ref(entry->comp);
423: this->components->insert_last(this->components, new_entry);
424: return entry->comp;
425: }
426: else
427: {
428: component = imcv_pts_components->create(imcv_pts_components,
429: name, depth, pts_db);
430: if (!component)
431: {
432: /* unsupported component */
433: return NULL;
434: }
435: new_entry = malloc_thing(func_comp_t);
436: new_entry->name = name->clone(name);
437: new_entry->comp = component;
438: this->components->insert_last(this->components, new_entry);
439: return component;
440: }
441: }
442:
443: CALLBACK(entry_filter, bool,
444: void *null, enumerator_t *orig, va_list args)
445: {
446: func_comp_t *entry;
447: pts_comp_func_name_t **comp_name;
448: uint32_t *depth;
449: uint8_t *flags;
450:
451: VA_ARGS_VGET(args, flags, depth, comp_name);
452:
453: if (orig->enumerate(orig, &entry))
454: {
455: *flags = entry->comp->get_evidence_flags(entry->comp);
456: *depth = entry->comp->get_depth(entry->comp);
457: *comp_name = entry->name;
458: return TRUE;
459: }
460: return FALSE;
461: }
462:
463: METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*,
464: private_imv_attestation_state_t *this)
465: {
466: return enumerator_create_filter(
467: this->components->create_enumerator(this->components),
468: entry_filter, NULL, NULL);
469: }
470:
471: METHOD(imv_attestation_state_t, get_component, pts_component_t*,
472: private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
473: {
474: enumerator_t *enumerator;
475: func_comp_t *entry;
476: pts_component_t *found = NULL;
477:
478: enumerator = this->components->create_enumerator(this->components);
479: while (enumerator->enumerate(enumerator, &entry))
480: {
481: if (name->equals(name, entry->name))
482: {
483: found = entry->comp;
484: break;
485: }
486: }
487: enumerator->destroy(enumerator);
488: return found;
489: }
490:
491: METHOD(imv_attestation_state_t, get_measurement_error, uint32_t,
492: private_imv_attestation_state_t *this)
493: {
494: return this->measurement_error;
495: }
496:
497: METHOD(imv_attestation_state_t, set_measurement_error, void,
498: private_imv_attestation_state_t *this, uint32_t error)
499: {
500: this->measurement_error |= error;
501: }
502:
503: METHOD(imv_attestation_state_t, finalize_components, void,
504: private_imv_attestation_state_t *this, bio_writer_t *result)
505: {
506: func_comp_t *entry;
507: bool first = TRUE;
508:
509: while (this->components->remove_last(this->components,
510: (void**)&entry) == SUCCESS)
511: {
512: if (first)
513: {
514: first = FALSE;
515: }
516: else
517: {
518: result->write_data(result, chunk_from_str("; "));
519: }
520: if (!entry->comp->finalize(entry->comp,
521: entry->name->get_qualifier(entry->name),
522: result))
523: {
524: set_measurement_error(this, IMV_ATTESTATION_ERROR_COMP_EVID_PEND);
525: }
526: free_func_comp(entry);
527: }
528: }
529:
530: /**
531: * Described in header.
532: */
533: imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
534: {
535: private_imv_attestation_state_t *this;
536:
537: INIT(this,
538: .public = {
539: .interface = {
540: .get_connection_id = _get_connection_id,
541: .has_long = _has_long,
542: .has_excl = _has_excl,
543: .set_flags = _set_flags,
544: .set_max_msg_len = _set_max_msg_len,
545: .get_max_msg_len = _get_max_msg_len,
546: .set_action_flags = _set_action_flags,
547: .get_action_flags = _get_action_flags,
548: .set_session = _set_session,
549: .get_session = _get_session,
550: .get_contracts = _get_contracts,
551: .change_state = _change_state,
552: .get_recommendation = _get_recommendation,
553: .set_recommendation = _set_recommendation,
554: .update_recommendation = _update_recommendation,
555: .get_reason_string = _get_reason_string,
556: .get_remediation_instructions = _get_remediation_instructions,
557: .reset = _reset,
558: .destroy = _destroy,
559: },
560: .get_handshake_state = _get_handshake_state,
561: .set_handshake_state = _set_handshake_state,
562: .get_pts = _get_pts,
563: .create_component = _create_component,
564: .create_component_enumerator = _create_component_enumerator,
565: .get_component = _get_component,
566: .finalize_components = _finalize_components,
567: .get_measurement_error = _get_measurement_error,
568: .set_measurement_error = _set_measurement_error,
569: .add_file_meas_reasons = _add_file_meas_reasons,
570: .add_comp_evid_reasons = _add_comp_evid_reasons,
571: },
572: .connection_id = connection_id,
573: .state = TNC_CONNECTION_STATE_CREATE,
574: .handshake_state = IMV_ATTESTATION_STATE_INIT,
575: .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
576: .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
577: .contracts = seg_contract_manager_create(),
578: .components = linked_list_create(),
579: .pts = pts_create(FALSE),
580: );
581:
582: return &this->public.interface;
583: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>