shortened some type names and enforced encoding rules
[strongswan.git] / src / libimcv / tcg / tcg_pts_attr_simple_evid_final.c
1 /*
2 * Copyright (C) 2011 Sansar Choinyambuu
3 * HSR Hochschule fuer Technik Rapperswil
4 *
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>.
9 *
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
13 * for more details.
14 */
15
16 #include "tcg_pts_attr_simple_evid_final.h"
17
18 #include <pa_tnc/pa_tnc_msg.h>
19 #include <bio/bio_writer.h>
20 #include <bio/bio_reader.h>
21 #include <debug.h>
22
23 typedef struct private_tcg_pts_attr_simple_evid_final_t private_tcg_pts_attr_simple_evid_final_t;
24
25 /**
26 * Simple Evidence Final
27 * see section 3.15.2 of PTS Protocol: Binding to TNC IF-M Specification
28 *
29 * 1 2 3
30 * 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
31 *
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 * | Flags | Reserved | Optional Composite Hash Alg |
34 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 * | Optional TPM PCR Composite Length |
36 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 * ~ Optional TPM PCR Composite (Variable Length) ~
38 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 * | Optional TPM Quote Signature Length |
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * ~ Optional TPM Quote Signature (Variable Length) ~
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * ~ Optional Evidence Signature (Variable Length) ~
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 */
46
47 #define PTS_SIMPLE_EVID_FINAL_SIZE 4
48 #define PTS_SIMPLE_EVID_FINAL_RESERVED 0x00
49
50 /**
51 * Private data of an tcg_pts_attr_simple_evid_final_t object.
52 */
53 struct private_tcg_pts_attr_simple_evid_final_t {
54
55 /**
56 * Public members of tcg_pts_attr_simple_evid_final_t
57 */
58 tcg_pts_attr_simple_evid_final_t public;
59
60 /**
61 * Attribute vendor ID
62 */
63 pen_t vendor_id;
64
65 /**
66 * Attribute type
67 */
68 u_int32_t type;
69
70 /**
71 * Attribute value
72 */
73 chunk_t value;
74
75 /**
76 * Noskip flag
77 */
78 bool noskip_flag;
79
80 /**
81 * Set of flags for Simple Evidence Final
82 */
83 pts_simple_evid_final_flag_t flags;
84
85 /**
86 * Optional Composite Hash Algorithm
87 */
88 pts_meas_algorithms_t comp_hash_algorithm;
89
90 /**
91 * Optional TPM PCR Composite
92 */
93 chunk_t pcr_comp;
94
95 /**
96 * Optional TPM Quote Signature
97 */
98 chunk_t tpm_quote_sign;
99
100 /**
101 * Optional Evidence Signature
102 */
103 chunk_t evid_sign;
104
105 };
106
107 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
108 private_tcg_pts_attr_simple_evid_final_t *this)
109 {
110 return this->vendor_id;
111 }
112
113 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
114 private_tcg_pts_attr_simple_evid_final_t *this)
115 {
116 return this->type;
117 }
118
119 METHOD(pa_tnc_attr_t, get_value, chunk_t,
120 private_tcg_pts_attr_simple_evid_final_t *this)
121 {
122 return this->value;
123 }
124
125 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
126 private_tcg_pts_attr_simple_evid_final_t *this)
127 {
128 return this->noskip_flag;
129 }
130
131 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
132 private_tcg_pts_attr_simple_evid_final_t *this, bool noskip)
133 {
134 this->noskip_flag = noskip;
135 }
136
137 METHOD(pa_tnc_attr_t, build, void,
138 private_tcg_pts_attr_simple_evid_final_t *this)
139 {
140 bio_writer_t *writer;
141 u_int8_t flags = 0;
142 u_int16_t algorithm = 0;
143
144 writer = bio_writer_create(PTS_SIMPLE_EVID_FINAL_SIZE);
145
146 /* Determine the flags to set*/
147 if (this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO)
148 {
149 flags += 64;
150 }
151 else if (this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2)
152 {
153 flags += 128;
154 }
155 else if (this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER)
156 {
157 flags += 192;
158 }
159 if (this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID)
160 {
161 flags += 32;
162 }
163 writer->write_uint8(writer, flags);
164 writer->write_uint8(writer, PTS_SIMPLE_EVID_FINAL_RESERVED);
165
166 /* Determine the hash algorithm to set*/
167 if (this->comp_hash_algorithm & PTS_MEAS_ALGO_SHA384)
168 {
169 algorithm = 8192;
170 }
171 else if (this->comp_hash_algorithm & PTS_MEAS_ALGO_SHA256)
172 {
173 algorithm = 16384;
174 }
175 else if (this->comp_hash_algorithm & PTS_MEAS_ALGO_SHA1)
176 {
177 algorithm = 32768;
178 }
179 writer->write_uint16(writer, algorithm);
180
181 /* Optional fields */
182 if (this->pcr_comp.ptr && this->pcr_comp.len > 0)
183 {
184 writer->write_uint32 (writer, this->pcr_comp.len);
185 writer->write_data (writer, this->pcr_comp);
186 }
187 if (this->tpm_quote_sign.ptr && this->tpm_quote_sign.len > 0)
188 {
189 writer->write_uint32 (writer, this->tpm_quote_sign.len);
190 writer->write_data (writer, this->tpm_quote_sign);
191 }
192 if (this->evid_sign.ptr && this->evid_sign.len > 0)
193 {
194 writer->write_data (writer, this->evid_sign);
195 }
196
197 this->value = chunk_clone(writer->get_buf(writer));
198 writer->destroy(writer);
199 }
200
201 METHOD(pa_tnc_attr_t, process, status_t,
202 private_tcg_pts_attr_simple_evid_final_t *this, u_int32_t *offset)
203 {
204 bio_reader_t *reader;
205 u_int8_t flags;
206 u_int8_t reserved;
207 u_int16_t algorithm;
208
209 if (this->value.len < PTS_SIMPLE_EVID_FINAL_SIZE)
210 {
211 DBG1(DBG_TNC, "insufficient data for Simple Evidence Final");
212 *offset = 0;
213 return FAILED;
214 }
215 reader = bio_reader_create(this->value);
216
217 reader->read_uint8(reader, &flags);
218
219 /* Determine the flags to set*/
220 if (!((flags >> 7) & 1) && !((flags >> 6) & 1))
221 {
222 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_NO;
223 }
224 else if (!((flags >> 7) & 1) && ((flags >> 6) & 1))
225 {
226 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
227 }
228 else if (((flags >> 7) & 1) && !((flags >> 6) & 1))
229 {
230 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2;
231 }
232 else if (((flags >> 7) & 1) && ((flags >> 6) & 1))
233 {
234 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER;
235 }
236 if ((flags >> 5) & 1)
237 {
238 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_EVID;
239 }
240
241 reader->read_uint8(reader, &reserved);
242 reader->read_uint16(reader, &algorithm);
243
244 if ((algorithm >> 13) & 1)
245 {
246 this->comp_hash_algorithm = PTS_MEAS_ALGO_SHA384;
247 }
248 else if ((algorithm >> 14) & 1)
249 {
250 this->comp_hash_algorithm = PTS_MEAS_ALGO_SHA256;
251 }
252 else if ((algorithm >> 15) & 1)
253 {
254 this->comp_hash_algorithm = PTS_MEAS_ALGO_SHA1;
255 }
256
257 /* Optional TPM PCR Composite field is included */
258 if (!(this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_NO))
259 {
260 u_int32_t pcr_comp_len;
261 u_int32_t tpm_quote_sign_len;
262 reader->read_uint32(reader, &pcr_comp_len);
263 reader->read_data(reader, pcr_comp_len, &this->pcr_comp);
264 reader->read_uint32(reader, &tpm_quote_sign_len);
265 reader->read_data(reader, tpm_quote_sign_len, &this->tpm_quote_sign);
266 }
267
268 /* Optional Evidence Signature field is included */
269 if (this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID)
270 {
271 u_int32_t evid_sign_len = reader->remaining(reader);
272 reader->read_data(reader, evid_sign_len, &this->evid_sign);
273 }
274
275 reader->destroy(reader);
276 return SUCCESS;
277 }
278
279 METHOD(pa_tnc_attr_t, destroy, void,
280 private_tcg_pts_attr_simple_evid_final_t *this)
281 {
282 free(this->value.ptr);
283 free(this->pcr_comp.ptr);
284 free(this->tpm_quote_sign.ptr);
285 free(this->evid_sign.ptr);
286 free(this);
287 }
288
289 METHOD(tcg_pts_attr_simple_evid_final_t, get_flags, pts_simple_evid_final_flag_t,
290 private_tcg_pts_attr_simple_evid_final_t *this)
291 {
292 return this->flags;
293 }
294
295 METHOD(tcg_pts_attr_simple_evid_final_t, set_flags, void,
296 private_tcg_pts_attr_simple_evid_final_t *this, pts_simple_evid_final_flag_t flags)
297 {
298 this->flags = flags;
299 }
300
301 METHOD(tcg_pts_attr_simple_evid_final_t, get_comp_hash_algorithm, pts_meas_algorithms_t,
302 private_tcg_pts_attr_simple_evid_final_t *this)
303 {
304 return this->comp_hash_algorithm;
305 }
306
307 METHOD(tcg_pts_attr_simple_evid_final_t, set_comp_hash_algorithm, void,
308 private_tcg_pts_attr_simple_evid_final_t *this, pts_meas_algorithms_t comp_hash_algorithm)
309 {
310 this->comp_hash_algorithm = comp_hash_algorithm;
311 }
312
313 METHOD(tcg_pts_attr_simple_evid_final_t, get_comp_pcr_len, u_int32_t,
314 private_tcg_pts_attr_simple_evid_final_t *this)
315 {
316 if (this->pcr_comp.ptr && this->pcr_comp.len > 0)
317 {
318 return this->pcr_comp.len;
319 }
320 return 0;
321 }
322
323 METHOD(tcg_pts_attr_simple_evid_final_t, get_pcr_comp, chunk_t,
324 private_tcg_pts_attr_simple_evid_final_t *this)
325 {
326 return this->pcr_comp;
327 }
328
329 METHOD(tcg_pts_attr_simple_evid_final_t, set_pcr_comp, void,
330 private_tcg_pts_attr_simple_evid_final_t *this, chunk_t pcr_comp)
331 {
332 this->pcr_comp = pcr_comp;
333 }
334
335 METHOD(tcg_pts_attr_simple_evid_final_t, get_tpm_quote_sign_len, u_int32_t,
336 private_tcg_pts_attr_simple_evid_final_t *this)
337 {
338 if (this->tpm_quote_sign.ptr && this->tpm_quote_sign.len > 0)
339 {
340 return this->tpm_quote_sign.len;
341 }
342 return 0;
343 }
344
345 METHOD(tcg_pts_attr_simple_evid_final_t, get_tpm_quote_sign, chunk_t,
346 private_tcg_pts_attr_simple_evid_final_t *this)
347 {
348 return this->tpm_quote_sign;
349 }
350
351 METHOD(tcg_pts_attr_simple_evid_final_t, set_tpm_quote_sign, void,
352 private_tcg_pts_attr_simple_evid_final_t *this, chunk_t tpm_quote_sign)
353 {
354 this->tpm_quote_sign = tpm_quote_sign;
355 }
356
357 METHOD(tcg_pts_attr_simple_evid_final_t, get_evid_sign, chunk_t,
358 private_tcg_pts_attr_simple_evid_final_t *this)
359 {
360 return this->evid_sign;
361 }
362
363 METHOD(tcg_pts_attr_simple_evid_final_t, set_evid_sign, void,
364 private_tcg_pts_attr_simple_evid_final_t *this, chunk_t evid_sign)
365 {
366 this->evid_sign = evid_sign;
367 }
368
369 /**
370 * Described in header.
371 */
372 pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(
373 pts_simple_evid_final_flag_t flags,
374 pts_meas_algorithms_t comp_hash_algorithm,
375 chunk_t pcr_comp,
376 chunk_t tpm_quote_sign,
377 chunk_t evid_sign)
378 {
379 private_tcg_pts_attr_simple_evid_final_t *this;
380
381 INIT(this,
382 .public = {
383 .pa_tnc_attribute = {
384 .get_vendor_id = _get_vendor_id,
385 .get_type = _get_type,
386 .get_value = _get_value,
387 .get_noskip_flag = _get_noskip_flag,
388 .set_noskip_flag = _set_noskip_flag,
389 .build = _build,
390 .process = _process,
391 .destroy = _destroy,
392 },
393 .get_flags= _get_flags,
394 .set_flags= _set_flags,
395 .get_comp_hash_algorithm = _get_comp_hash_algorithm,
396 .set_comp_hash_algorithm = _set_comp_hash_algorithm,
397 .get_comp_pcr_len = _get_comp_pcr_len,
398 .get_pcr_comp = _get_pcr_comp,
399 .set_pcr_comp = _set_pcr_comp,
400 .get_tpm_quote_sign_len = _get_tpm_quote_sign_len,
401 .get_tpm_quote_sign = _get_tpm_quote_sign,
402 .set_tpm_quote_sign = _set_tpm_quote_sign,
403 .get_evid_sign = _get_evid_sign,
404 .set_evid_sign = _set_evid_sign,
405 },
406 .vendor_id = PEN_TCG,
407 .type = TCG_PTS_SIMPLE_EVID_FINAL,
408 .flags = flags,
409 .comp_hash_algorithm = comp_hash_algorithm,
410 .pcr_comp = pcr_comp,
411 .tpm_quote_sign = tpm_quote_sign,
412 .evid_sign = evid_sign,
413 );
414
415 return &this->public.pa_tnc_attribute;
416 }
417
418
419 /**
420 * Described in header.
421 */
422 pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data)
423 {
424 private_tcg_pts_attr_simple_evid_final_t *this;
425
426 INIT(this,
427 .public = {
428 .pa_tnc_attribute = {
429 .get_vendor_id = _get_vendor_id,
430 .get_type = _get_type,
431 .get_value = _get_value,
432 .get_noskip_flag = _get_noskip_flag,
433 .set_noskip_flag = _set_noskip_flag,
434 .build = _build,
435 .process = _process,
436 .destroy = _destroy,
437 },
438 .get_flags= _get_flags,
439 .set_flags= _set_flags,
440 .get_comp_hash_algorithm = _get_comp_hash_algorithm,
441 .set_comp_hash_algorithm = _set_comp_hash_algorithm,
442 .get_comp_pcr_len = _get_comp_pcr_len,
443 .get_pcr_comp = _get_pcr_comp,
444 .set_pcr_comp = _set_pcr_comp,
445 .get_tpm_quote_sign_len = _get_tpm_quote_sign_len,
446 .get_tpm_quote_sign = _get_tpm_quote_sign,
447 .set_tpm_quote_sign = _set_tpm_quote_sign,
448 .get_evid_sign = _get_evid_sign,
449 .set_evid_sign = _set_evid_sign,
450 },
451 .vendor_id = PEN_TCG,
452 .type = TCG_PTS_SIMPLE_EVID_FINAL,
453 .value = chunk_clone(data),
454 );
455
456 return &this->public.pa_tnc_attribute;
457 }