Corrected typo
[strongswan.git] / src / libimcv / tcg / tcg_pts_attr_file_meas.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_file_meas.h"
17
18 #include <pa_tnc/pa_tnc_msg.h>
19 #include <bio/bio_writer.h>
20 #include <bio/bio_reader.h>
21 #include <utils/linked_list.h>
22 /* For pow function */
23 #include <math.h>
24 #include <debug.h>
25
26 typedef struct private_tcg_pts_attr_file_meas_t private_tcg_pts_attr_file_meas_t;
27 typedef struct file_meas_entry_t file_meas_entry_t;
28
29 /**
30 * File Measurement entry
31 */
32 struct file_meas_entry_t {
33 chunk_t measurement;
34 u_int16_t file_name_len;
35 chunk_t file_name;
36 };
37
38 /**
39 * File Measurement (see section 3.19.2 of PTS Protocol: Binding to TNC IF-M Specification)
40 *
41 * 1 2 3
42 * 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
43 *
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | Number of Files included |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 * | Number of Files included |
48 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 * | Request ID | Measurement Length |
50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 * | Measurement #1 (Variable Length) |
52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 * | Filename Length | Filename (Variable Length) ~
54 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 * ~ Filename (Variable Length) ~
56 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 * | Measurement #2 (Variable Length) |
58 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 * | Filename Length | Filename (Variable Length) ~
60 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 * ~ Filename (Variable Length) ~
62 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 * ...........................
64 */
65
66 #define PTS_FILE_MEAS_SIZE 12
67
68 /**
69 * Private data of an tcg_pts_attr_file_meas_t object.
70 */
71 struct private_tcg_pts_attr_file_meas_t {
72
73 /**
74 * Public members of tcg_pts_attr_file_meas_t
75 */
76 tcg_pts_attr_file_meas_t public;
77
78 /**
79 * Attribute vendor ID
80 */
81 pen_t vendor_id;
82
83 /**
84 * Attribute type
85 */
86 u_int32_t type;
87
88 /**
89 * Attribute value
90 */
91 chunk_t value;
92
93 /**
94 * Noskip flag
95 */
96 bool noskip_flag;
97
98 /**
99 * Number of files included
100 */
101 u_int64_t number_of_files;
102
103 /**
104 * Request ID
105 */
106 u_int16_t request_id;
107
108 /**
109 * Measurement Length
110 */
111 u_int16_t meas_len;
112
113 /**
114 * List of File Measurement entries
115 */
116 linked_list_t *measurements;
117
118 };
119
120 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
121 private_tcg_pts_attr_file_meas_t *this)
122 {
123 return this->vendor_id;
124 }
125
126 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
127 private_tcg_pts_attr_file_meas_t *this)
128 {
129 return this->type;
130 }
131
132 METHOD(pa_tnc_attr_t, get_value, chunk_t,
133 private_tcg_pts_attr_file_meas_t *this)
134 {
135 return this->value;
136 }
137
138 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
139 private_tcg_pts_attr_file_meas_t *this)
140 {
141 return this->noskip_flag;
142 }
143
144 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
145 private_tcg_pts_attr_file_meas_t *this, bool noskip)
146 {
147 this->noskip_flag = noskip;
148 }
149
150 METHOD(pa_tnc_attr_t, build, void,
151 private_tcg_pts_attr_file_meas_t *this)
152 {
153 bio_writer_t *writer;
154 enumerator_t *enumerator;
155 file_meas_entry_t *entry;
156
157 writer = bio_writer_create(PTS_FILE_MEAS_SIZE);
158
159 /* Write the 64 bit integer as 2 parts, first 32 bit and second */
160 writer->write_uint32 (writer, (this->number_of_files >> 32));
161 writer->write_uint32 (writer, (this->number_of_files & (int)(pow(2,32) - 1)));
162 writer->write_uint16(writer, this->request_id);
163 writer->write_uint16(writer, this->meas_len);
164
165 enumerator = this->measurements->create_enumerator(this->measurements);
166 while (enumerator->enumerate(enumerator, &entry))
167 {
168 writer->write_data (writer, entry->measurement);
169 writer->write_uint16 (writer, entry->file_name_len);
170 writer->write_data(writer, entry->file_name);
171 }
172 enumerator->destroy(enumerator);
173
174 this->value = chunk_clone(writer->get_buf(writer));
175 writer->destroy(writer);
176 }
177
178 METHOD(pa_tnc_attr_t, process, status_t,
179 private_tcg_pts_attr_file_meas_t *this, u_int32_t *offset)
180 {
181 bio_reader_t *reader;
182 u_int32_t number_of_files;
183 u_int64_t number_of_files_64;
184 file_meas_entry_t *entry;
185
186 if (this->value.len < PTS_FILE_MEAS_SIZE)
187 {
188 DBG1(DBG_TNC, "insufficient data for File Measurement");
189 *offset = 0;
190 return FAILED;
191 }
192 reader = bio_reader_create(this->value);
193
194 reader->read_uint32(reader, &number_of_files);
195 number_of_files_64 = number_of_files;
196 this->number_of_files = (number_of_files_64 << 32);
197 reader->read_uint32(reader, &number_of_files);
198 this->number_of_files += number_of_files;
199
200 reader->read_uint16(reader, &this->request_id);
201 reader->read_uint16(reader, &this->meas_len);
202
203 while (reader->remaining(reader))
204 {
205 entry = malloc_thing(file_meas_entry_t);
206 reader->read_data (reader, this->meas_len, &entry->measurement);
207 reader->read_uint16 (reader, &entry->file_name_len);
208 reader->read_data(reader, entry->file_name_len, &entry->file_name);
209 this->measurements->insert_last(this->measurements, entry);
210 }
211
212 reader->destroy(reader);
213 return SUCCESS;
214 }
215
216 METHOD(pa_tnc_attr_t, destroy, void,
217 private_tcg_pts_attr_file_meas_t *this)
218 {
219 free(this->value.ptr);
220 this->measurements->destroy_function(this->measurements, free);
221 free(this);
222 }
223
224 METHOD(tcg_pts_attr_file_meas_t, get_number_of_files, u_int64_t,
225 private_tcg_pts_attr_file_meas_t *this)
226 {
227 return this->number_of_files;
228 }
229
230 METHOD(tcg_pts_attr_file_meas_t, set_number_of_files, void,
231 private_tcg_pts_attr_file_meas_t *this, u_int64_t number_of_files)
232 {
233 this->number_of_files = number_of_files;
234 }
235
236 METHOD(tcg_pts_attr_file_meas_t, get_request_id, u_int16_t,
237 private_tcg_pts_attr_file_meas_t *this)
238 {
239 return this->request_id;
240 }
241
242 METHOD(tcg_pts_attr_file_meas_t, set_request_id, void,
243 private_tcg_pts_attr_file_meas_t *this, u_int16_t request_id)
244 {
245 this->request_id = request_id;
246 }
247
248 METHOD(tcg_pts_attr_file_meas_t, get_meas_len, u_int16_t,
249 private_tcg_pts_attr_file_meas_t *this)
250 {
251 return this->meas_len;
252 }
253
254 METHOD(tcg_pts_attr_file_meas_t, set_meas_len, void,
255 private_tcg_pts_attr_file_meas_t *this, u_int16_t meas_len)
256 {
257 this->meas_len = meas_len;
258 }
259
260 METHOD(tcg_pts_attr_file_meas_t, add_file_meas, void,
261 private_tcg_pts_attr_file_meas_t *this, chunk_t measurement,
262 chunk_t file_name)
263 {
264 file_meas_entry_t *entry;
265
266 entry = malloc_thing(file_meas_entry_t);
267 entry->measurement = measurement;
268 entry->file_name_len = file_name.len;
269 entry->file_name = file_name;
270 this->measurements->insert_last(this->measurements, entry);
271 }
272
273 /**
274 * Enumerate file measurement entries
275 */
276 static bool measurement_filter(void *null, file_meas_entry_t **entry, chunk_t *measurement,
277 void *i2, u_int16_t *file_name_len,
278 void *i3, chunk_t *file_name)
279 {
280 *measurement = (*entry)->measurement;
281 *file_name_len = (*entry)->file_name_len;
282 *file_name = (*entry)->file_name;
283 return TRUE;
284 }
285
286 METHOD(tcg_pts_attr_file_meas_t, create_file_meas_enumerator, enumerator_t*,
287 private_tcg_pts_attr_file_meas_t *this)
288 {
289 return enumerator_create_filter(this->measurements->create_enumerator(this->measurements),
290 (void*)measurement_filter, NULL, NULL);
291 }
292
293 /**
294 * Described in header.
295 */
296 pa_tnc_attr_t *tcg_pts_attr_file_meas_create(
297 u_int64_t number_of_files,
298 u_int16_t request_id,
299 u_int16_t meas_len)
300 {
301 private_tcg_pts_attr_file_meas_t *this;
302
303 INIT(this,
304 .public = {
305 .pa_tnc_attribute = {
306 .get_vendor_id = _get_vendor_id,
307 .get_type = _get_type,
308 .get_value = _get_value,
309 .get_noskip_flag = _get_noskip_flag,
310 .set_noskip_flag = _set_noskip_flag,
311 .build = _build,
312 .process = _process,
313 .destroy = _destroy,
314 },
315 .get_number_of_files= _get_number_of_files,
316 .set_number_of_files= _set_number_of_files,
317 .get_request_id = _get_request_id,
318 .set_request_id = _set_request_id,
319 .get_meas_len = _get_meas_len,
320 .set_meas_len = _set_meas_len,
321 .add_file_meas = _add_file_meas,
322 .create_file_meas_enumerator = _create_file_meas_enumerator,
323 },
324 .vendor_id = PEN_TCG,
325 .type = TCG_PTS_FILE_MEAS,
326 .number_of_files = number_of_files,
327 .request_id = request_id,
328 .meas_len = meas_len,
329 .measurements = linked_list_create(),
330 );
331
332 return &this->public.pa_tnc_attribute;
333 }
334
335
336 /**
337 * Described in header.
338 */
339 pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data)
340 {
341 private_tcg_pts_attr_file_meas_t *this;
342
343 INIT(this,
344 .public = {
345 .pa_tnc_attribute = {
346 .get_vendor_id = _get_vendor_id,
347 .get_type = _get_type,
348 .get_value = _get_value,
349 .get_noskip_flag = _get_noskip_flag,
350 .set_noskip_flag = _set_noskip_flag,
351 .build = _build,
352 .process = _process,
353 .destroy = _destroy,
354 },
355 .get_number_of_files= _get_number_of_files,
356 .set_number_of_files= _set_number_of_files,
357 .get_request_id = _get_request_id,
358 .set_request_id = _set_request_id,
359 .get_meas_len = _get_meas_len,
360 .set_meas_len = _set_meas_len,
361 .add_file_meas = _add_file_meas,
362 .create_file_meas_enumerator = _create_file_meas_enumerator,
363 },
364 .vendor_id = PEN_TCG,
365 .type = TCG_PTS_FILE_MEAS,
366 .value = chunk_clone(data),
367 .measurements = linked_list_create(),
368 );
369
370 return &this->public.pa_tnc_attribute;
371 }