OSDN Git Service

cleanup
[openpts/openpts.git] / src / prop.c
1 /*
2  * This file is part of the OpenPTS project.
3  *
4  * The Initial Developer of the Original Code is International
5  * Business Machines Corporation. Portions created by IBM
6  * Corporation are Copyright (C) 2010 International Business
7  * Machines Corporation. All Rights Reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the Common Public License as published by
11  * IBM Corporation; either version 1 of the License, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * Common Public License for more details.
18  *
19  * You should have received a copy of the Common Public License
20  * along with this program; if not, a copy can be viewed at
21  * http://www.opensource.org/licenses/cpl1.0.php.
22  */
23
24 /**
25  * \file src/prop.c
26  * \brief properties
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2010-06-19
29  * cleanup 2012-01-05 SM
30  *
31  * Security Properties
32  *
33  * name - value (Java Properties style)
34  *
35  * SRTM.integrity=valid/invalid/unverified
36  * DRTM.integrity=valid/invalid/unverified
37  * BIOS.integrity=valid/invalid/unverified
38  * IPL.integrity=valid/invalid/unverified
39  * OS.integrity=valid/invalid/unverified
40  *
41  *
42  * TCG did not define any Security Properties.:-(
43  * DMTF?
44  *
45  */
46
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <stdarg.h> /* va_ */
51
52 #include <openpts.h>
53
54 /**
55  * new Property
56  */
57 OPENPTS_PROPERTY * newProperty(char *name, char *value) {
58     OPENPTS_PROPERTY *prop;
59
60     /* check */
61     if (name == NULL) {
62         LOG(LOG_ERR, "null input");
63         return NULL;
64     }
65     if (value == NULL) {
66         LOG(LOG_ERR, "null input");
67         return NULL;
68     }
69
70     prop = (OPENPTS_PROPERTY *) xmalloc(sizeof(OPENPTS_PROPERTY));
71     if (prop == NULL) {
72         LOG(LOG_ERR, "no memory");
73         return NULL;
74     }
75     memset(prop, 0, sizeof(OPENPTS_PROPERTY));
76
77     prop->name = smalloc_assert(name);
78     if (prop->name == NULL) {
79         LOG(LOG_ERR, "no memory");
80         return NULL;
81     }
82     prop->value = smalloc_assert(value);
83     if (prop->value == NULL) {
84         LOG(LOG_ERR, "no memory");
85         return NULL;
86     }
87
88     return prop;
89 }
90
91 /**
92  * Free Property
93  */
94 void freeProperty(OPENPTS_PROPERTY *prop) {
95     /* check */
96     if (prop == NULL) {
97         LOG(LOG_ERR, "null input");
98         return;
99     }
100
101     xfree(prop->name);
102     xfree(prop->value);
103     xfree(prop);
104 }
105
106 /**
107  * Free Property Chain
108  */
109 int freePropertyChain(OPENPTS_PROPERTY *prop) {
110     /* check */
111     if (prop == NULL) {
112         /* end of chain */
113         return PTS_SUCCESS;
114     }
115
116     if (prop->next != NULL) {
117         freePropertyChain(prop->next);
118     }
119
120     /* free one */
121     freeProperty(prop);
122
123     return PTS_SUCCESS;
124 }
125
126
127 /**
128  * get property
129  */
130 OPENPTS_PROPERTY* getProperty(OPENPTS_CONTEXT *ctx, char *name) {
131     OPENPTS_PROPERTY *prop;
132
133     /* check */
134     if (name == NULL) {
135         LOG(LOG_ERR, "null input");
136         return NULL;
137     }
138
139     /* look for the prop with name */
140     prop = ctx->prop_start;
141     while (prop != NULL) {
142         if (prop->name == NULL) {
143             LOG(LOG_ERR, "getProperty(%s) fail, bad property entry exist", name);
144             return NULL;
145         }
146
147         if (!strcmp(name, prop->name)) {
148             // HIT
149             return prop;
150         }
151
152         prop = (OPENPTS_PROPERTY *) prop->next;
153     }
154
155     // MISS
156     return NULL;
157 }
158
159 /**
160  * add new property to chain
161  */
162 int addProperty(OPENPTS_CONTEXT *ctx, char *name, char *value) {
163     OPENPTS_PROPERTY *start;
164     OPENPTS_PROPERTY *end;
165     OPENPTS_PROPERTY *prop;
166
167     /* check */
168     if (ctx == NULL) {
169         LOG(LOG_ERR, "null input");
170         return PTS_FATAL;
171     }
172     if (name == NULL) {
173         LOG(LOG_ERR, "null input");
174         return PTS_FATAL;
175     }
176     if (value == NULL) {
177         LOG(LOG_ERR, "null input");
178         return PTS_FATAL;
179     }
180
181     start = ctx->prop_start;
182     end   = ctx->prop_end;
183
184     /* malloc new prop */
185     prop = newProperty(name, value);
186     if (prop == NULL) {
187         LOG(LOG_ERR, "newProperty() fail");
188         return PTS_FATAL;
189     }
190
191     /* update the chain */
192     if (start == NULL) {
193         /* 1st prop */
194         /* update the link */
195         ctx->prop_start = prop;
196         ctx->prop_end   = prop;
197         prop->next      = NULL;
198         ctx->prop_count = 0;
199     } else {
200         /* update the link */
201         end->next     = prop;
202         ctx->prop_end = prop;
203         prop->next    = NULL;
204     }
205
206     /* inc count  */
207     ctx->prop_count++;
208
209     return PTS_SUCCESS;
210 }
211
212 /**
213  * set/update property
214  */
215 int setProperty(OPENPTS_CONTEXT *ctx, char *name, char *value) {
216     OPENPTS_PROPERTY *hit;
217
218     /* check */
219     if (ctx == NULL) {
220         LOG(LOG_ERR, "null input");
221         return PTS_FATAL;
222     }
223     if (name == NULL) {
224         LOG(LOG_ERR, "null input");
225         return PTS_FATAL;
226     }
227     if (value == NULL) {
228         LOG(LOG_ERR, "null input");
229         return PTS_FATAL;
230     }
231
232     /* check existing prop */
233     hit = getProperty(ctx, name);
234
235     if (hit == NULL) {
236         /* missing name, create new prop */
237         addProperty(ctx, name, value);
238     } else {
239         /* hit, update the value */
240         xfree(hit->value);
241         hit->value = smalloc_assert(value);
242     }
243
244     return PTS_SUCCESS;
245 }
246
247 /**
248  * set Event property
249  */
250 int setEventProperty(OPENPTS_CONTEXT *ctx, char *name, char *value, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
251     int rc = PTS_SUCCESS;
252
253     /* check */
254     if (ctx == NULL) {
255         LOG(LOG_ERR, "null input");
256         return PTS_FATAL;
257     }
258     if (name == NULL) {
259         LOG(LOG_ERR, "null input");
260         return PTS_FATAL;
261     }
262     if (value == NULL) {
263         LOG(LOG_ERR, "null input");
264         return PTS_FATAL;
265     }
266
267     /* X = valid */
268     if (!strcmp(value, "valid")) {
269         setProperty(ctx, name, value);
270         return rc;
271     }
272
273     /* X = digest = base64(digest) */
274     if (!strcmp(value, "digest")) {
275         /* if value = digest, base64 -> set digest as value */
276         char *buf;
277         int buf_len;
278
279         /* check, missing event */
280         if (eventWrapper == NULL) {
281             LOG(LOG_ERR, "setEventProperty() - eventWrapper is NULL\n");
282             return PTS_FATAL;
283         }
284         if (eventWrapper->event == NULL) {
285             LOG(LOG_ERR, "setEventProperty() - event is NULL\n");
286             return PTS_FATAL;
287         }
288         if (eventWrapper->event->rgbPcrValue == NULL) {
289             LOG(LOG_ERR, "setEventProperty() - rgbPcrValue is NULL\n");
290             return PTS_FATAL;
291         }
292
293         buf = encodeBase64(
294             (unsigned char *)eventWrapper->event->rgbPcrValue,
295             SHA1_DIGEST_SIZE,
296             &buf_len);
297         if (buf == NULL) {
298             LOG(LOG_ERR, "encodeBase64 fail");
299             return PTS_FATAL;
300         }
301         rc = setProperty(ctx, name, buf);
302         free(buf);
303
304         if (rc != PTS_SUCCESS) {
305             LOG(LOG_ERR, "setProperty() fail");
306             return PTS_FATAL;
307         }
308         return rc;
309     }
310
311     /* X = eventdata = base64(eventdata) */
312     if (!strcmp(value, "eventdata")) {
313         /* */
314         TSS_PCR_EVENT *event;
315
316
317         /* check, missing event */
318         if (eventWrapper == NULL) {
319             LOG(LOG_ERR, "setEventProperty() - eventWrapper is NULL\n");
320             return PTS_FATAL;
321         }
322         event = eventWrapper->event;
323         if (event == NULL) {
324             LOG(LOG_ERR, "setEventProperty() - event is NULL\n");
325             return PTS_FATAL;
326         }
327         if (event->ulEventLength > 0) {
328             char * str;
329             if (event->rgbEvent == NULL) {
330                 LOG(LOG_ERR, "setEventProperty() - rgbEvent is NULL\n");
331                 return PTS_FATAL;
332             }
333             /* get String */
334
335             str = snmalloc((char*)event->rgbEvent, event->ulEventLength);
336             if (str == NULL) {
337                 LOG(LOG_ERR, "no memory");
338                 return PTS_INTERNAL_ERROR;
339             }
340             xfree(str);
341             rc = setProperty(ctx, name, str);  // TODO 2011-02-03 SM implement
342             if (rc != PTS_SUCCESS) {
343                 LOG(LOG_ERR, "setProperty() fail");
344                 return PTS_FATAL;
345             }
346             return rc;
347         } else {
348             LOG(LOG_ERR, "missing rgbEvent");
349             return PTS_INTERNAL_ERROR;
350         }
351         // NULL
352     }
353     if (!strcmp(value, "notexist")) {
354         rc = setProperty(ctx, name, value);  // TODO
355         if (rc != PTS_SUCCESS) {
356             LOG(LOG_ERR, "setProperty() fail");
357             return PTS_FATAL;
358         }
359         return rc;
360     }
361
362     /* others */
363     rc =  setProperty(ctx, name, value);
364     if (rc != PTS_SUCCESS) {
365         LOG(LOG_ERR, "setProperty() fail");
366         return PTS_FATAL;
367     }
368     return rc;
369 }
370
371 /**
372  * validate property
373  *
374  * if value = base64
375  *   value = digest
376  * else
377  *   name == value
378  *
379  * 
380  * @param update BHV action 
381  */
382
383 int validateProperty(OPENPTS_CONTEXT *ctx, char *name, char *value, char *action) {
384     int rc = OPENPTS_FSM_ERROR;
385     OPENPTS_PROPERTY* prop;
386
387     /* check */
388     if (ctx == NULL) {
389         LOG(LOG_ERR, "null input");
390         return PTS_FATAL;
391     }
392     if (name == NULL) {
393         LOG(LOG_ERR, "null input");
394         return PTS_FATAL;
395     }
396     if (value == NULL) {
397         LOG(LOG_ERR, "null input");
398         return PTS_FATAL;
399     }
400
401     /* trim */
402     // trim(value);
403
404     /* get name */
405     prop = getProperty(ctx, name);
406
407     if (prop == NULL) {
408         /* name miss? */
409         LOG(LOG_ERR, "validateProperty - property %s is missing\n", name);
410         rc = OPENPTS_FSM_ERROR;
411     } else {
412         /* name hit? check the value */
413         if (!strcmp(value, prop->value)) {
414             /* HIT */
415             rc = OPENPTS_FSM_SUCCESS;
416         } else {
417             /* Miss */
418             /* if value = base64 -> BHV model =>  value -> BIN model */
419             if (!strcmp(value, "base64")) {
420                 // DEBUG("Update BIN-FSM %s=%s\n", name, prop->value);
421                 snprintf(action, BUF_SIZE, "validateProperty( %s, %s )", name, prop->value);
422                 rc = OPENPTS_FSM_SUCCESS;
423             } else if (!strcmp(value, "digest")) {
424                 // DEBUG("Update BIN-FSM %s=%s\n", name, prop->value);
425                 snprintf(action, BUF_SIZE, "validateProperty( %s, %s )", name, prop->value);
426                 rc = OPENPTS_FSM_SUCCESS;
427             } else {
428                 // see Reason msg
429                 // INFO("validateProperty() %s != %s, but %s. There is an inconsistency between IR and RM\n",
430                 //    name, value, prop->value);
431                 rc = OPENPTS_FSM_ERROR;
432             }
433         }
434     }
435
436     return rc;
437 }
438
439
440
441 /**
442  * print properties
443  *
444  */
445 void printProperties(OPENPTS_CONTEXT *ctx) {
446     OPENPTS_PROPERTY *prop;
447     int i = 0;
448     prop = ctx->prop_start;
449
450     /* check */
451     if (ctx == NULL) {
452         LOG(LOG_ERR, "null input");
453         return;
454     }
455
456     /* print out */
457     OUTPUT(NLS(MS_OPENPTS, OPENPTS_PRINT_PROPS, "Properties name-value\n"));
458     while (prop != NULL) {
459         OUTPUT("%5d %s=%s\n", i, prop->name, prop->value);
460         prop = prop->next;
461         i++;
462     }
463 }
464
465 /**
466  * save to File (plain text, Java Properties)
467  */
468 int saveProperties(OPENPTS_CONTEXT *ctx, char * filename) {
469     FILE *fp;
470     OPENPTS_PROPERTY *prop;
471     int i = 0;
472
473     /* check */
474     if (ctx == NULL) {
475         LOG(LOG_ERR, "null input");
476         return PTS_FATAL;
477     }
478     if (filename == NULL) {
479         LOG(LOG_ERR, "null input");
480         return PTS_FATAL;
481     }
482
483     /* open */
484     if ((fp = fopen(filename, "w")) == NULL) {
485         LOG(LOG_ERR, "File %s open was failed\n", filename);
486         return PTS_INTERNAL_ERROR;
487     }
488
489     /* get properties chain*/
490     prop = ctx->prop_start;
491     if (prop == NULL) {
492         LOG(LOG_ERR, "properties is NULL\n");
493         fclose(fp);
494         return PTS_INTERNAL_ERROR;
495     }
496
497     fprintf(fp, "# OpenPTS properties, name=value\n");
498     while (prop != NULL) {
499         fprintf(fp, "%s=%s\n", prop->name, prop->value);  // TODO  uninitialised byte(s)
500         prop = prop->next;
501         i++;
502     }
503     fprintf(fp, "# %d props\n", i);
504     fclose(fp);
505
506     return PTS_SUCCESS;
507 }
508
509 int addPropertiesFromConfig(OPENPTS_CONFIG *conf, OPENPTS_CONTEXT *ctx) {
510     /* check */
511     if (conf == NULL) {
512         LOG(LOG_ERR, "null input");
513         return PTS_FATAL;
514     }
515     if (ctx == NULL) {
516         LOG(LOG_ERR, "null input");
517         return PTS_FATAL;
518     }
519
520     /* additional properties from the pts config file */
521     if (conf->iml_maxcount > 0) {
522         char buf[32];
523         snprintf(buf, sizeof(buf), "%d", conf->iml_maxcount);
524         addProperty(ctx, "iml.ipl.maxcount", buf);
525         DEBUG("Added automatic property iml.ipl.maxcount=%d\n", conf->iml_maxcount);
526     }
527     return 0;
528 }