OSDN Git Service

Update to support Infineon v1.2 TPM
[openpts/openpts.git] / src / ptsc.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) 2011 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/ptsc.c
26  * \brief PTS collector command
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @author Olivier Valentin <olivier.valentin@us.ibm.com>
29  * @author Alexandre Ratchov <alexandre.ratchov@bull.net>
30  * @date 2010-04-04
31  * cleanup 2011-07-06 SM
32  *
33  */
34
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <sys/socketvar.h>
39 #include <errno.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <pwd.h>
44 #include <grp.h>
45 #include <sys/stat.h>  // chmod
46
47 #include <openpts.h>
48
49
50 int verbose = 0; /**< DEBUG */
51 static int terminate = 0;
52
53 #define STDIN 0
54 #define STDOUT 1
55
56 int prop_num = 0;
57 OPENPTS_PROPERTY *start = NULL;
58 OPENPTS_PROPERTY *end = NULL;
59
60 /**
61  * collector daemon
62  *
63  * TODO support single connection.
64  * TODO for multiple conenction, multiple ctxs are required. 
65  * TODO disable remote connection
66  */ 
67 int collector2(OPENPTS_CONFIG *conf) {
68     int rc;
69     OPENPTS_CONTEXT *ctx = NULL;
70     PTS_IF_M_Attribute *read_tlv = NULL;
71     int count = 0;
72     int len;
73
74     /* Init RMs */
75     rc = getRmSetDir(conf);
76     if (rc != PTS_SUCCESS) {
77         ERROR("collector() - getRmSetDir() was failed\n");
78         return PTS_INTERNAL_ERROR;
79     }
80
81     rc = getNewRmSetDir(conf);
82     if (rc != PTS_SUCCESS) {
83         /* don't care */
84         DEBUG("collector() - getNewRmSetDir() was failed - never mind\n");
85     }
86
87     /* syslog message */
88     INFO("start collector (System UUID=%s, RM UUID = %s, timeout=%d)\n",
89         conf->uuid->str, conf->rm_uuid->str, conf->ifm_timeout);
90
91     /* Collector <-> Verifier - handshake loop */
92     do {
93         INFO("open  IF-M PTS connection\n");
94
95         ctx = newPtsContext(conf);
96
97         // TODO new ctx for the new connection
98
99         /* handshake loop */
100         for (;;) {
101             /* V->C request */
102
103             read_tlv = readPtsTlv(STDIN);  // ifm.c, malloc tlv
104             if (read_tlv == NULL) {
105                 INFO("close IF-M PTS connection\n");
106                 /* free current context */
107                 freePtsContext(ctx);
108                 sleep(1);
109                 count++;
110                 if (count >= conf->ifm_timeout) {  // 5sec
111                     terminate = 1;
112                     TODO("collector2 terminate\n");
113                 }
114                 break;
115             }
116
117             /* check bad TLV */
118             if (read_tlv->type == 0)
119                 break;
120
121             if (read_tlv->length > 0 && read_tlv->value == NULL)
122                 break;
123
124             INFO("IF-M read type = 0x%X, len %d\n",
125                 read_tlv->type,
126                 read_tlv->length);
127
128             /* C->V responces */
129             switch (read_tlv->type) {
130             case OPENPTS_CAPABILITIES:
131                 // TODO define CAPABILITIES structure
132                 TODO("IF-M OPENPTS_CAPABILITIES\n");
133                 /* check the UUID */
134                 if (read_tlv->length != sizeof(OPENPTS_IF_M_Capability)) {  // TODO use defined name
135                     ERROR("Bad PTS_CAPABILITIES, len = %d != 32\n", read_tlv->length);
136                 } else {
137                     OPENPTS_IF_M_Capability *cap;
138                     cap = (OPENPTS_IF_M_Capability *) read_tlv->value;
139                     /* get version */
140                     // TODO
141                     /* get verifier's UUID */
142                     ctx->uuid = malloc(sizeof(PTS_UUID));
143                     memcpy(ctx->uuid, &cap->platform_uuid, 16);
144                     ctx->str_uuid = getStringOfUuid(ctx->uuid);
145
146                     /* syslog */
147                     INFO("verifier (UUID=%s)\n", ctx->str_uuid);
148
149                     /* send PTS_CAPABILITIES msg. to verifier (=UUID) */
150                     len = writePtsTlv(ctx, STDOUT, OPENPTS_CAPABILITIES);
151                     if (len < 0) {
152                         ERROR("send OPENPTS_CAPABILITIES was failed\n");
153                     }
154                     TODO("IF-M OPENPTS_CAPABILITIES rc=%d (0x%x)\n", rc, rc);
155                 }
156                 break;
157
158             case DH_NONCE_PARAMETERS_REQUEST:
159                 TODO("IF-M DH_NONCE_PARAMETERS_REQUEST\n");
160                 /* check */
161                 if (read_tlv->length != 4) {
162                     ERROR("Bad DH_NONCE_PARAMETERS_REQUEST, len = %d != 4\n", read_tlv->length);
163                 } else {
164                     /* req -> res */
165                     ctx->nonce->req->reserved      = read_tlv->value[0];
166                     ctx->nonce->req->min_nonce_len = read_tlv->value[1];
167                     // NBO to Host
168                     ctx->nonce->req->dh_group_set  = (read_tlv->value[2]<<8) | read_tlv->value[3];
169
170                     rc = getDhResponce(ctx->nonce);
171
172                     /* send responce */
173                     len = writePtsTlv(
174                             ctx, STDOUT, DH_NONCE_PARAMETORS_RESPONSE);
175                     if (len < 0) {
176                         ERROR("send DH_NONCE_PARAMETORS_RESPONSE was failed\n");
177                     }
178                 }
179                 break;
180             case DH_NONCE_FINISH:
181                 TODO("IF-M DH_NONCE_FINISH\n");
182                 /* check */
183                 if (read_tlv->length != 152) {  // TODO  how to calc this size?
184                     ERROR("Bad DH_NONCE_FINISH, len = %d != 152\n", read_tlv->length);
185                 } else {
186                     /* finish  */
187                     ctx->nonce->fin->reserved            = read_tlv->value[0];
188                     ctx->nonce->fin->nonce_length        = read_tlv->value[1];
189                     // NBO to Host
190                     ctx->nonce->fin->selected_hash_alg   = (read_tlv->value[2]<<8) | read_tlv->value[3];
191
192                     /* public */
193                     ctx->nonce->fin->dh_initiator_public = malloc(ctx->nonce->pubkey_length);
194                     memcpy(
195                         ctx->nonce->fin->dh_initiator_public,
196                         &read_tlv->value[4],
197                         ctx->nonce->pubkey_length);
198
199                     /* nonce */
200                     ctx->nonce->fin->dh_initiator_nonce = malloc(ctx->nonce->fin->nonce_length);
201                     memcpy(
202                         ctx->nonce->fin->dh_initiator_nonce,
203                         &read_tlv->value[4 + ctx->nonce->pubkey_length],
204                         ctx->nonce->fin->nonce_length);
205
206                     rc = calcDhFin(ctx->nonce);
207
208                     /* no responce */
209                 }
210                 break;
211             case REQUEST_RIMM_SET:  // 5
212                 TODO("IF-M REQUEST_RIMM_SET\n");
213                 /* check */
214                 if (read_tlv->length != 0) {
215                     ERROR("Bad REQUEST__RIMM_SET, len = %d != 0\n", read_tlv->length);
216                 } else {
217                     len = writePtsTlv(
218                             ctx, STDOUT, RIMM_SET);
219                     if (len < 0) {
220                         ERROR("send RIMM_SET was failed\n");
221                     }
222                 }
223                 break;
224             case REQUEST_NEW_RIMM_SET:
225                 TODO("IF-M REQUEST_NEW_RIMM_SET\n");
226                 /* check */
227                 if (read_tlv->length != 0) {
228                     ERROR("Bad REQUEST_NEW_RIMM_SET, len = %d != 0\n", read_tlv->length);
229                 } else {
230                     len = writePtsTlv(
231                             ctx, STDOUT, NEW_RIMM_SET);
232                     if (len < 0) {
233                         ERROR("sendNEW_RIMM_SET was failed\n");
234                     }
235                     TODO("IF-M REQUEST_NEW_RIMM_SET, len = %d\n", rc);
236                 }
237                 break;
238             case REQUEST_INTEGRITY_REPORT:
239                 TODO("IF-M REQUEST_INTEGRITY_REPORT\n");
240                 /* check */
241                 if (read_tlv->length != 0) {
242                     ERROR("Bad REQUEST_INTEGRITY_REPORT, len = %d != 0\n", read_tlv->length);
243                 } else {
244                     len = writePtsTlv(ctx, STDOUT, INTEGRITY_REPORT);
245                     if (len < 0) {
246                         ERROR("send INTEGRITY_REPORT was failed\n");
247                     }
248                     TODO("IF-M INTEGRITY_REPORT len=%d (0x%x)\n", rc, rc);
249                 }
250                 break;
251             case VERIFICATION_RESULT:
252                 /* no responce */
253                 INFO("IF-M VERIFICATION_RESULT => terminate\n");
254                 DEBUG_IFM("finish\n");
255                 terminate = 1;  // TODO add TERMINATE MSG
256                 break;
257 #ifdef CONFIG_AIDE
258             case REQUEST_AIDE_DATABASE:
259                 INFO("IF-M REQUEST_AIDE_DATABASE\n");
260                 /* check */
261                 if (read_tlv->length != 0) {
262                     ERROR("Bad REQUEST_AIDE_DATABASE, len = %d != 0\n", read_tlv->length);
263                 } else {
264                     len = writePtsTlv(ctx, STDOUT, AIDE_DATABASE);
265                     if (len < 0) {
266                         ERROR("send AIDE_DATABASE was failed\n");
267                     }
268                 }
269                 break;
270 #endif
271             case REQUEST_TPM_PUBKEY:
272                 /* check */
273                 if (read_tlv->length != 0) {
274                     ERROR("Bad REQUEST_TPM_PUBKEY, len = %d != 0\n", read_tlv->length);
275                 } else {
276                     len = writePtsTlv(ctx, STDOUT, TPM_PUBKEY);  // ifm.c
277                     if (len < 0) {
278                         ERROR("send TPM_PUBKEY was failed\n");
279                     }
280                 }
281                 break;
282             case NONCE:
283                 /* check */
284                 if (read_tlv->length != 20) {
285                     ERROR("Bad NONCE, len = %d != 20\n", read_tlv->length);
286                 } else {
287                     /* set nonce */
288                     ctx->nonce->nonce_length = 20;
289                     if (ctx->nonce->nonce != NULL) {
290                         free(ctx->nonce->nonce);
291                     }
292                     ctx->nonce->nonce = malloc(20);
293                     memcpy(ctx->nonce->nonce, read_tlv->value, 20);
294                     DEBUG_IFM("nonce[%d] : \n", ctx->nonce->nonce_length);
295                 }
296                 break;
297             case OPENPTS_ERROR:
298                 ERROR("verifier returns error, termnate\n");
299                 terminate = 1;
300                 break;
301             default:
302                 ERROR("PTS IF-M type 0x%08x is not supported\n", read_tlv->type);
303                 INFO("send OPENPTS_ERROR msg to verifier, then terminate the conenction");
304                 ctx->ifm_errno = PTS_UNRECOGNIZED_COMMAND;
305                 if (ctx->ifm_strerror != NULL) free(ctx->ifm_strerror);
306                 ctx->ifm_strerror = smalloc("Unknown message type");
307
308                 len = writePtsTlv(ctx, STDOUT, OPENPTS_ERROR);  // ifm.c
309                 if (len < 0) {
310                     ERROR("send OPENPTS_ERROR was failed\n");
311                 }
312                 terminate = 1;
313                 break;
314             }  // switch case
315
316             /* free TLV */
317             if (read_tlv != NULL) {
318                 freePtsTlv(read_tlv);
319             }
320         }  // GET loop
321         /* out */
322         /* free TLV for break out */
323         if (read_tlv != NULL) {
324             freePtsTlv(read_tlv);
325         }
326     } while (terminate == 0);
327
328   // err:
329     return (-1);
330 }
331
332
333 /**
334  * Usage
335  */
336 void usage(void) {
337     fprintf(stderr, NLS(1,  1, "OpenPTS Collector\n\n"));
338     fprintf(stderr, NLS(1,  2, "Usage: ptsc [options] [command]\n\n"));
339     fprintf(stderr, NLS(1,  3, "Commands: (forgrand)\n"));
340     fprintf(stderr, NLS(1,  4, "  -i                    Initialize PTS collector\n"));
341     fprintf(stderr, NLS(1,  5, "  -t                    Self test (attestation)\n"));
342     fprintf(stderr, NLS(1,  6, "  -s                    Startup (selftest + timestamp)\n"));
343     fprintf(stderr, NLS(1,  7, "  -u                    Update the RM\n"));
344 #ifdef CONFIG_AUTO_RM_UPDATE
345     fprintf(stderr, NLS(1,  8, "  -U                    Update the RM (auto)\n"));
346 #endif
347     fprintf(stderr, NLS(1,  9, "  -D                    Display the configuration\n"));
348     fprintf(stderr, NLS(1, 10, "  -m                    IF-M mode\n"));
349     fprintf(stderr, "\n");
350     fprintf(stderr, NLS(1, 11, "Miscellaneous:\n"));
351     fprintf(stderr, NLS(1, 12, "  -h                    Show this help message\n"));
352     fprintf(stderr, NLS(1, 13, "  -v                    Verbose mode. Multiple -v options increase the verbosity.\n"));
353     fprintf(stderr, "\n");
354     fprintf(stderr, NLS(1, 14, "Options:\n"));
355     fprintf(stderr, NLS(1, 15, "  -c configfile         Set configuration file. defalt is %s\n"), PTSC_CONFIG_FILE);
356     // fprintf(stderr, NLS(1, 14, "  -f                    foreground, run in the foreground."));
357     // fprintf(stderr, NLS(1, 15, "                        Logging goes to stderr " "instead of syslog.\n"));
358     fprintf(stderr, NLS(1, 16, "  -P name=value         Set properties.\n"));
359     fprintf(stderr, NLS(1, 17, "  -R                    Remove RMs\n"));
360     fprintf(stderr, NLS(1, 18, "  -z                    Use the SRK secret to all zeros (20 bytes of zeros)"));
361     // fprintf(stderr, "  -d dirname            Debug\n");
362
363     fprintf(stderr, "\n");
364 }
365
366 enum COMMAND {
367     COMMAND_IFM,
368     COMMAND_INIT,
369     COMMAND_STATUS,
370     COMMAND_SELFTEST,
371     COMMAND_UPDATE,
372     COMMAND_STARTUP,
373 #ifdef CONFIG_AUTO_RM_UPDATE
374     COMMAND_AUTO_UPDATE,
375 #endif
376 };
377
378 /**
379  * name=value
380  */
381 OPENPTS_PROPERTY *getPropertyFromArg(char *arg) {
382     char *name;
383     char *value;
384     char * eq;
385     OPENPTS_PROPERTY *prop;
386
387     if ((eq = strstr(arg, "=")) != NULL) {
388         /* remove CR */
389         *eq = 0;
390         name = arg;
391         value = eq + 1;
392
393         prop = newProperty(name, value);
394         return prop;
395     } else {
396         fprintf(stderr, "bad property %s\n", arg);
397         return NULL;
398     }
399 }
400
401
402 static int preparePriv() {
403     int rc = 0;
404     struct group *ptsc_grp;
405
406 #if 0
407     /* check UID */
408     if ((ptscd_pwd = getpwnam(PTSCD_USER_NAME)) == NULL) {
409         ERROR("Looking up for user %s", PTSCD_USER_NAME);
410         return PTS_FATAL;
411     }
412 #endif
413
414     /* check GID */
415     ptsc_grp = getgrnam(PTSC_GROUP_NAME);  // TODO use getgrnam_r
416     if (ptsc_grp == NULL) {
417         ERROR("Looking up for group %s", PTSC_GROUP_NAME);
418         return PTS_FATAL;
419     }
420
421     /* set GID */
422     rc = setgid(ptsc_grp->gr_gid);
423     if (rc < 0) {
424         // TODO do not need for IF-M access (read only)
425         ERROR("Switching group fail. %s\n", strerror(errno));
426         return PTS_FATAL;
427     }
428
429 #if 0
430     if (setuid(ptscd_pwd->pw_uid) == -1) {
431         ERROR("Switching to user %s", PTSCD_USER_NAME);
432         return PTS_FATAL;
433     }
434 #endif
435
436     /*  */
437
438     return PTS_SUCCESS;
439 }
440
441 /**
442  * dir group => PTSC_GROUP_NAME
443  *
444  * flag 0:read, 1:read/write
445  */
446 static int chmodDir(char *dirpath, int flag) {
447     int rc;
448     struct group *ptsc_grp;
449
450     /* check GID */
451     ptsc_grp = getgrnam(PTSC_GROUP_NAME);  // TODO use getgrnam_r
452     if (ptsc_grp == NULL) {
453         ERROR("Looking up for group %s", PTSC_GROUP_NAME);
454         return PTS_FATAL;
455     }
456
457     /* chgep */
458     rc = chown(
459             dirpath,
460             -1,
461             ptsc_grp->gr_gid);
462     if (rc <0) {
463         return PTS_FATAL;
464     }
465
466     if (flag == 0) {
467         rc = chmod(
468                 dirpath,
469                 S_IRUSR | S_IWUSR | S_IXUSR |
470                 S_IRGRP | S_IXGRP);
471         if (rc <0) {
472             return PTS_FATAL;
473         }
474     } else {  // write
475         rc = chmod(
476                 dirpath,
477                 S_IRUSR | S_IWUSR | S_IXUSR |
478                 S_IRGRP | S_IWGRP | S_IXGRP);
479         if (rc <0) {
480             return PTS_FATAL;
481         }
482     }
483     return PTS_SUCCESS;
484 }
485
486
487 /**
488  * Main
489  */
490 int main(int argc, char *argv[]) {
491     int rc;
492     int debug = 0;
493     OPENPTS_CONFIG *conf = NULL;
494     char *config_filename = NULL;
495     int command = COMMAND_STATUS;
496     int c;
497 #ifdef CONFIG_AUTO_RM_UPDATE
498     int remove = 0;
499 #endif
500
501     /* properties by cmdline  */
502     OPENPTS_PROPERTY *prop;
503
504 #ifdef ENABLE_NLS
505 #ifdef HAVE_CATGETS
506     /* catgets */
507     // nl_catd catd;
508     catd = catopen("ptscd", 0);
509 #else
510     /* gettext */
511     setlocale(LC_ALL, "");
512     bindtextdomain(PACKAGE, LOCALEDIR);
513     textdomain(PACKAGE);
514 #endif
515 #endif
516
517
518     // TODO chgrp
519     rc = preparePriv();
520     if (rc != PTS_SUCCESS) {
521         ERROR("preparePriv fail\n");
522     }
523
524
525     conf = newPtsConfig();
526     if (conf == NULL) {
527         ERROR("internal error\n");  // TODO(munetoh)
528         return -1;
529     }
530
531     /* command option */
532     while ((c = getopt(argc, argv, "ic:uUDtsmvP:Rzh")) != EOF) {
533         switch (c) {
534         case 'i':
535             command = COMMAND_INIT;
536             break;
537         case 'u':
538             command = COMMAND_UPDATE;
539             break;
540         case 'U':
541 #ifdef CONFIG_AUTO_RM_UPDATE
542             command = COMMAND_AUTO_UPDATE;
543 #endif
544             break;
545         case 'D':
546             command = COMMAND_STATUS;
547             break;
548         case 't':
549             command = COMMAND_SELFTEST;
550             break;
551         case 's':
552             command = COMMAND_STARTUP;
553             break;
554         case 'm':
555             command = COMMAND_IFM;
556             setenv("OPENPTS_SYSLOG", "1", 1);
557             break;
558         case 'c':
559             config_filename = optarg;
560             break;
561         case 'v':
562             debug++;
563             break;
564         case 'R':
565 #ifdef CONFIG_AUTO_RM_UPDATE
566             remove = 1;
567 #endif
568             break;
569         case 'z':
570             conf->srk_password_mode = 1;
571             break;
572         case 'P':
573             prop = getPropertyFromArg(optarg);
574             if (start == NULL) {
575                 start = prop;
576                 end = prop;
577                 prop->next = NULL;
578             } else {
579                 end->next = prop;
580                 end = prop;
581                 prop->next = NULL;
582             }
583             prop_num++;
584             break;
585         case 'h':
586             /* help */
587         default:
588             usage();
589             return -1;
590             break;
591         }
592     }
593     argc -= optind;
594     argv += optind;
595
596
597     /* DEBUG level, 1,2,3 */
598     if (debug > 2) {
599         verbose = DEBUG_FLAG | DEBUG_FSM_FLAG | DEBUG_IFM_FLAG;
600         INFO("verbose mode 3");
601     } else if (debug > 1) {
602         verbose = DEBUG_FLAG | DEBUG_IFM_FLAG;
603         INFO("verbose mode 2");
604     } else if (debug > 0) {
605         verbose = DEBUG_FLAG;
606         INFO("verbose mode 1");
607     }
608
609     // verbose = DEBUG_FLAG | DEBUG_IFM_FLAG;
610
611     /* load config */
612     if (config_filename == NULL) {
613         DEBUG("config file               : %s\n", PTSC_CONFIG_FILE);
614         rc = readPtsConfig(conf, PTSC_CONFIG_FILE);
615         if (rc != PTS_SUCCESS) {
616             ERROR("read config file, '%s' was failed - abort\n", PTSC_CONFIG_FILE);
617             goto free;
618         }
619     } else {
620         DEBUG("config file               : %s\n", config_filename);
621         rc = readPtsConfig(conf, config_filename);
622         if (rc != PTS_SUCCESS) {
623             ERROR("read config file, '%s' was failed - abort\n", config_filename);
624             goto free;
625         }
626     }
627
628     /* check dir */
629     // TODO root only
630
631     /* check IR dir */
632     if (checkDir(conf->ir_dir) != PTS_SUCCESS) {
633         rc = makeDir(conf->ir_dir);
634         if (rc != PTS_SUCCESS) {
635             ERROR("Can not create the dir to store IR, %s\n", conf->ir_dir);
636             goto free;
637         }
638         rc = chmodDir(conf->ir_dir, 1);
639         if (rc != PTS_SUCCESS) {
640             ERROR("Can not create the dir to store IR, %s\n", conf->ir_dir);
641             goto free;
642         }
643     }
644
645     /* initialize the  collector */
646     if (command == COMMAND_INIT) {
647         DEBUG("Initialize Reference Manifest\n");
648         rc = init(conf, prop_num, start, end);
649         /* Exit */
650         goto free;
651     }
652
653     /* RM UUID */
654     rc = readOpenptsUuidFile(conf->rm_uuid);
655     if (rc != PTS_SUCCESS) {
656         ERROR("read RM UUID file %s was failed, initialize ptscd first\n", conf->rm_uuid->filename);
657         goto free;
658     } else {
659         DEBUG("conf->str_rm_uuid         : %s\n", conf->rm_uuid->str);
660     }
661
662     /* NEWRM UUID */
663     rc = readOpenptsUuidFile(conf->newrm_uuid);
664     if (rc != PTS_SUCCESS) {
665         DEBUG("conf->str_newrm_uuid      : missing (file:%s)\n", conf->newrm_uuid->filename);
666         // goto free;
667     } else {
668         DEBUG("conf->str_newrm_uuid      : %s (for next boot)\n", conf->newrm_uuid->str);
669     }
670
671     /* load RSA PUB key */
672     // TODO single key => multiple keys?
673 #ifdef CONFIG_NO_TSS
674         TODO("CONFIG_NO_TSS, no TPM_PUBKEY\n");
675         conf->pubkey_length = 0;
676         conf->pubkey = NULL;
677 #else
678         /* get PUBKEY */
679         rc = getTssPubKey(
680                 conf->uuid->uuid,
681                 conf->aik_storage_type,  // TSS_PS_TYPE_SYSTEM,
682                 conf->srk_password_mode,
683                 conf->tpm_resetdalock,
684                 conf->aik_storage_filename,  // NULL,
685                 conf->aik_auth_type,
686                 &conf->pubkey_length,
687                 &conf->pubkey);
688         if (rc != TSS_SUCCESS) {
689             ERROR("getTssPubKey() fail rc=0x%x srk password mode=%d, key =%s\n",
690                 rc, conf->srk_password_mode, conf->uuid->str);
691         }
692 #endif
693
694     /* run */
695     switch (command) {
696 #ifdef CONFIG_AUTO_RM_UPDATE
697         case COMMAND_AUTO_UPDATE:
698             /* update by command, but HUP is better */
699             DEBUG("Update Reference Manifest\n");
700             /* update RMs */
701             rc = update(conf, prop_num, start, end, remove);
702             if (rc != PTS_SUCCESS) {
703                 printf("update was fail\n");
704             }
705             break;
706 #endif
707         case COMMAND_STATUS:
708             rc = printCollectorStatus(conf);
709             break;
710         case COMMAND_SELFTEST:
711             rc = selftest(conf, prop_num, start, end);
712             if (rc == OPENPTS_SELFTEST_SUCCESS) {
713                 printf("selftest - OK\n");
714             } else if (rc == OPENPTS_SELFTEST_RENEWED) {
715                 printf("selftest - Renewed\n");
716             } else if (rc == OPENPTS_SELFTEST_FALLBACK) {
717                 printf("selftest -> fallback - TBD\n");
718             } else if (rc == OPENPTS_SELFTEST_FAILED) {
719                 printf("selftest -> fail\n");
720             } else {
721                 printf("TBD\n");
722             }
723             break;
724         case COMMAND_STARTUP:
725             rc = selftest(conf, prop_num, start, end);
726             if (rc == OPENPTS_SELFTEST_SUCCESS) {
727                 INFO("selftest - OK\n");
728                 /* timestamp */
729                 extendEvCollectorStart(conf);  // collector.c
730             } else if (rc == OPENPTS_SELFTEST_RENEWED) {
731                 INFO("selftest - Renewed\n");
732                 /* timestamp */
733                 extendEvCollectorStart(conf);
734             } else if (rc == OPENPTS_SELFTEST_FALLBACK) {
735                 INFO("selftest -> fallback - TBD\n");
736                 /* timestamp */
737                 extendEvCollectorStart(conf);
738             } else if (rc == OPENPTS_SELFTEST_FAILED) {
739                 INFO("selftest -> fail\n");
740                 if (conf->autoupdate == 1) {
741                     TODO("selftest was failed, Try to generate new manifest\n");
742                     /* del RM_UUID */
743                     conf->rm_uuid->status = OPENPTS_UUID_FILENAME_ONLY;
744                     if (conf->rm_uuid->uuid != NULL) freeUuid(conf->rm_uuid->uuid);
745                     if (conf->rm_uuid->str != NULL) free(conf->rm_uuid->str);
746                     if (conf->rm_uuid->time != NULL) free(conf->rm_uuid->time);
747                     conf->rm_uuid->uuid = NULL;
748                     conf->rm_uuid->str = NULL;
749                     conf->rm_uuid->time = NULL;
750
751                     /* gen new RM_UUID and RM */
752                     rc = newrm(conf, prop_num, start, end);
753                     if (rc != PTS_SUCCESS) {
754                         ERROR("newrm() fail\n");
755                         goto free;
756                     }
757                     rc = selftest(conf, prop_num, start, end);
758                     if (rc == OPENPTS_SELFTEST_SUCCESS) {
759                         DEBUG("selftest - OK\n");
760                         INFO("selftest was faild, new manifests has been generated\n");
761                     } else if (rc == OPENPTS_SELFTEST_RENEWED) {
762                         DEBUG("selftest - Renewed\n");
763                     } else {
764                         TODO("TBD\n");
765                     }
766                 } else {
767                     INFO("selftest was faild, but keep existing manifests\n");
768                 }
769             } else {
770                 INFO("TBD\n");
771             }
772             break;
773         case COMMAND_UPDATE:
774             /* del RM_UUID */
775             conf->rm_uuid->status = OPENPTS_UUID_FILENAME_ONLY;
776             if (conf->rm_uuid->uuid != NULL) freeUuid(conf->rm_uuid->uuid);
777             if (conf->rm_uuid->str != NULL) free(conf->rm_uuid->str);
778             if (conf->rm_uuid->time != NULL) free(conf->rm_uuid->time);
779             conf->rm_uuid->uuid = NULL;
780             conf->rm_uuid->str = NULL;
781             conf->rm_uuid->time = NULL;
782
783             /* gen new RM_UUID and RM */
784             rc = newrm(conf, prop_num, start, end);
785             if (rc != PTS_SUCCESS) {
786                 ERROR("newrm() fail\n");
787                 goto free;
788             }
789
790             /* self test */
791             rc = selftest(conf, prop_num, start, end);
792             if (rc == OPENPTS_SELFTEST_SUCCESS) {
793                 INFO("manifest generation - success\n");
794             } else if (rc == OPENPTS_SELFTEST_RENEWED) {
795                 TODO("TBD\n");
796             } else {
797                 TODO("TBD\n");
798             }
799             break;
800         case COMMAND_IFM:
801             /* run colelctor IF-M */
802             rc = collector2(conf);
803             break;
804         default:
805             ERROR("bad command\n");
806             break;
807     }
808
809   free:
810     freePtsConfig(conf);
811
812     return rc;
813 }