Implemented matching of Optional PCR Composite field value when Hashing was done...
[strongswan.git] / src / libpts / 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 * | Flags | Reserved | Optional Composite Hash Alg |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Optional TPM PCR Composite Length |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * ~ Optional TPM PCR Composite (Variable Length) ~
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | Optional TPM Quote Signature Length |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * ~ Optional TPM Quote Signature (Variable Length) ~
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * ~ Optional Evidence Signature (Variable Length) ~
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 */
45
46 #define PTS_SIMPLE_EVID_FINAL_SIZE 2
47 #define PTS_SIMPLE_EVID_FINAL_RESERVED 0x00
48
49 /**
50 * Private data of an tcg_pts_attr_simple_evid_final_t object.
51 */
52 struct private_tcg_pts_attr_simple_evid_final_t {
53
54 /**
55 * Public members of tcg_pts_attr_simple_evid_final_t
56 */
57 tcg_pts_attr_simple_evid_final_t public;
58
59 /**
60 * Attribute vendor ID
61 */
62 pen_t vendor_id;
63
64 /**
65 * Attribute type
66 */
67 u_int32_t type;
68
69 /**
70 * Attribute value
71 */
72 chunk_t value;
73
74 /**
75 * Noskip flag
76 */
77 bool noskip_flag;
78
79 /**
80 * Is Evidence Signature included
81 */
82 bool evid_sign_included;
83
84 /**
85 * Set of flags for Simple Evidence Final
86 */
87 pts_simple_evid_final_flag_t flags;
88
89 /**
90 * Optional Composite Hash Algorithm
91 */
92 pts_meas_algorithms_t comp_hash_algorithm;
93
94 /**
95 * Optional TPM PCR Composite
96 */
97 chunk_t pcr_comp;
98
99 /**
100 * Optional TPM Quote Signature
101 */
102 chunk_t tpm_quote_sign;
103
104 /**
105 * Optional Evidence Signature
106 */
107 chunk_t evid_sign;
108
109 };
110
111 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
112 private_tcg_pts_attr_simple_evid_final_t *this)
113 {
114 return this->vendor_id;
115 }
116
117 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
118 private_tcg_pts_attr_simple_evid_final_t *this)
119 {
120 return this->type;
121 }
122
123 METHOD(pa_tnc_attr_t, get_value, chunk_t,
124 private_tcg_pts_attr_simple_evid_final_t *this)
125 {
126 return this->value;
127 }
128
129 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
130 private_tcg_pts_attr_simple_evid_final_t *this)
131 {
132 return this->noskip_flag;
133 }
134
135 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
136 private_tcg_pts_attr_simple_evid_final_t *this, bool noskip)
137 {
138 this->noskip_flag = noskip;
139 }
140
141 METHOD(pa_tnc_attr_t, build, void,
142 private_tcg_pts_attr_simple_evid_final_t *this)
143 {
144 bio_writer_t *writer;
145 u_int8_t flags = 0;
146
147 writer = bio_writer_create(PTS_SIMPLE_EVID_FINAL_SIZE);
148
149 /* Determine the flags to set*/
150 if (this->flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO)
151 {
152 flags += 64;
153 }
154 else if (this->flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2)
155 {
156 flags += 128;
157 }
158 else if (this->flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER)
159 {
160 flags += 192;
161 }
162 if (this->evid_sign_included)
163 {
164 flags += 32;
165 }
166
167 writer->write_uint8 (writer, flags);
168 writer->write_uint8 (writer, PTS_SIMPLE_EVID_FINAL_RESERVED);
169
170 /** Optional Composite Hash Algorithm field is always present
171 * Field has value of all zeroes if not used.
172 * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
173 */
174 writer->write_uint16(writer, this->comp_hash_algorithm);
175
176 /* Optional fields */
177 if (this->pcr_comp.ptr && this->pcr_comp.len > 0)
178 {
179 writer->write_uint32 (writer, this->pcr_comp.len);
180 writer->write_data (writer, this->pcr_comp);
181 }
182 if (this->tpm_quote_sign.ptr && this->tpm_quote_sign.len > 0)
183 {
184 writer->write_uint32 (writer, this->tpm_quote_sign.len);
185 writer->write_data (writer, this->tpm_quote_sign);
186 }
187 if (this->evid_sign.ptr && this->evid_sign.len > 0)
188 {
189 writer->write_data (writer, this->evid_sign);
190 }
191
192 this->value = chunk_clone(writer->get_buf(writer));
193 writer->destroy(writer);
194 }
195
196 METHOD(pa_tnc_attr_t, process, status_t,
197 private_tcg_pts_attr_simple_evid_final_t *this, u_int32_t *offset)
198 {
199 bio_reader_t *reader;
200 u_int8_t flags;
201 u_int8_t reserved;
202 u_int16_t algorithm;
203
204 if (this->value.len < PTS_SIMPLE_EVID_FINAL_SIZE)
205 {
206 DBG1(DBG_TNC, "insufficient data for Simple Evidence Final");
207 *offset = 0;
208 return FAILED;
209 }
210 reader = bio_reader_create(this->value);
211
212 reader->read_uint8(reader, &flags);
213
214 /* Determine the flags to set*/
215 if (!((flags >> 7) & 1) && !((flags >> 6) & 1))
216 {
217 this->flags = PTS_SIMPLE_EVID_FINAL_FLAG_NO;
218 }
219 else if (!((flags >> 7) & 1) && ((flags >> 6) & 1))
220 {
221 this->flags = PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
222 }
223 else if (((flags >> 7) & 1) && !((flags >> 6) & 1))
224 {
225 this->flags = PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2;
226 }
227 else if (((flags >> 7) & 1) && ((flags >> 6) & 1))
228 {
229 this->flags = PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER;
230 }
231 if ((flags >> 5) & 1)
232 {
233 this->evid_sign_included = TRUE;
234 }
235
236 reader->read_uint8(reader, &reserved);
237
238 /** Optional Composite Hash Algorithm field is always present
239 * Field has value of all zeroes if not used.
240 * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
241 */
242
243 reader->read_uint16(reader, &algorithm);
244 this->comp_hash_algorithm = algorithm;
245
246 /* Optional Composite Hash Algorithm and TPM PCR Composite field is included */
247 if (this->flags != PTS_SIMPLE_EVID_FINAL_FLAG_NO)
248 {
249 u_int32_t pcr_comp_len, tpm_quote_sign_len;
250
251 reader->read_uint32(reader, &pcr_comp_len);
252 reader->read_data(reader, pcr_comp_len, &this->pcr_comp);
253 this->pcr_comp = chunk_clone(this->pcr_comp);
254
255 this->pcr_comp = chunk_empty;
256 reader->read_uint32(reader, &tpm_quote_sign_len);
257 reader->read_data(reader, tpm_quote_sign_len, &this->tpm_quote_sign);
258 this->tpm_quote_sign = chunk_clone(this->tpm_quote_sign);
259 }
260
261 /* Optional Evidence Signature field is included */
262 if (this->evid_sign_included)
263 {
264 u_int32_t evid_sign_len = reader->remaining(reader);
265 reader->read_data(reader, evid_sign_len, &this->evid_sign);
266 this->evid_sign = chunk_clone(this->evid_sign);
267 }
268
269 reader->destroy(reader);
270 return SUCCESS;
271 }
272
273 METHOD(pa_tnc_attr_t, destroy, void,
274 private_tcg_pts_attr_simple_evid_final_t *this)
275 {
276 free(this->value.ptr);
277 free(this->pcr_comp.ptr);
278 free(this->tpm_quote_sign.ptr);
279 free(this->evid_sign.ptr);
280 free(this);
281 }
282
283 METHOD(tcg_pts_attr_simple_evid_final_t, is_evid_sign_included, bool,
284 private_tcg_pts_attr_simple_evid_final_t *this)
285 {
286 return this->evid_sign_included;
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, get_comp_hash_algorithm, pts_meas_algorithms_t,
296 private_tcg_pts_attr_simple_evid_final_t *this)
297 {
298 return this->comp_hash_algorithm;
299 }
300
301 METHOD(tcg_pts_attr_simple_evid_final_t, get_pcr_comp, chunk_t,
302 private_tcg_pts_attr_simple_evid_final_t *this)
303 {
304 return this->pcr_comp;
305 }
306
307 METHOD(tcg_pts_attr_simple_evid_final_t, get_tpm_quote_sign, chunk_t,
308 private_tcg_pts_attr_simple_evid_final_t *this)
309 {
310 return this->tpm_quote_sign;
311 }
312
313 METHOD(tcg_pts_attr_simple_evid_final_t, get_evid_sign, chunk_t,
314 private_tcg_pts_attr_simple_evid_final_t *this)
315 {
316 return this->evid_sign;
317 }
318
319 /**
320 * Described in header.
321 */
322 pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(
323 bool evid_sign_included,
324 pts_simple_evid_final_flag_t flags,
325 pts_meas_algorithms_t comp_hash_algorithm,
326 chunk_t pcr_comp,
327 chunk_t tpm_quote_sign,
328 chunk_t evid_sign)
329 {
330 private_tcg_pts_attr_simple_evid_final_t *this;
331
332 INIT(this,
333 .public = {
334 .pa_tnc_attribute = {
335 .get_vendor_id = _get_vendor_id,
336 .get_type = _get_type,
337 .get_value = _get_value,
338 .get_noskip_flag = _get_noskip_flag,
339 .set_noskip_flag = _set_noskip_flag,
340 .build = _build,
341 .process = _process,
342 .destroy = _destroy,
343 },
344 .is_evid_sign_included = _is_evid_sign_included,
345 .get_flags = _get_flags,
346 .get_comp_hash_algorithm = _get_comp_hash_algorithm,
347 .get_pcr_comp = _get_pcr_comp,
348 .get_tpm_quote_sign = _get_tpm_quote_sign,
349 .get_evid_sign = _get_evid_sign,
350 },
351 .vendor_id = PEN_TCG,
352 .type = TCG_PTS_SIMPLE_EVID_FINAL,
353 .evid_sign_included = evid_sign_included,
354 .flags = flags,
355 .comp_hash_algorithm = comp_hash_algorithm,
356 .pcr_comp = chunk_clone(pcr_comp),
357 .tpm_quote_sign = chunk_clone(tpm_quote_sign),
358 .evid_sign = chunk_clone(evid_sign),
359 );
360
361 return &this->public.pa_tnc_attribute;
362 }
363
364
365 /**
366 * Described in header.
367 */
368 pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data)
369 {
370 private_tcg_pts_attr_simple_evid_final_t *this;
371
372 INIT(this,
373 .public = {
374 .pa_tnc_attribute = {
375 .get_vendor_id = _get_vendor_id,
376 .get_type = _get_type,
377 .get_value = _get_value,
378 .get_noskip_flag = _get_noskip_flag,
379 .set_noskip_flag = _set_noskip_flag,
380 .build = _build,
381 .process = _process,
382 .destroy = _destroy,
383 },
384 .is_evid_sign_included = _is_evid_sign_included,
385 .get_flags= _get_flags,
386 .get_comp_hash_algorithm = _get_comp_hash_algorithm,
387 .get_pcr_comp = _get_pcr_comp,
388 .get_tpm_quote_sign = _get_tpm_quote_sign,
389 .get_evid_sign = _get_evid_sign,
390 },
391 .vendor_id = PEN_TCG,
392 .type = TCG_PTS_SIMPLE_EVID_FINAL,
393 .value = chunk_clone(data),
394 );
395
396 return &this->public.pa_tnc_attribute;
397 }