bound functional component measurements to AIK
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 27 Nov 2011 18:10:29 +0000 (19:10 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 28 Nov 2011 20:24:00 +0000 (21:24 +0100)
14 files changed:
src/libpts/plugins/imv_attestation/attest.c
src/libpts/plugins/imv_attestation/attest_db.c
src/libpts/plugins/imv_attestation/attest_db.h
src/libpts/plugins/imv_attestation/attest_usage.c
src/libpts/plugins/imv_attestation/data.sql
src/libpts/plugins/imv_attestation/imv_attestation_build.c
src/libpts/plugins/imv_attestation/imv_attestation_process.c
src/libpts/plugins/imv_attestation/tables.sql
src/libpts/pts/components/ita/ita_comp_ima.c
src/libpts/pts/components/ita/ita_comp_tboot.c
src/libpts/pts/pts.c
src/libpts/pts/pts.h
src/libpts/pts/pts_database.c
src/libpts/pts/pts_database.h

index ca9efab..ac91b5a 100644 (file)
@@ -97,10 +97,12 @@ static void do_args(int argc, char *argv[])
        enum {
                OP_UNDEF,
                OP_USAGE,
-               OP_FILES,
+               OP_KEYS,
                OP_COMPONENTS,
-               OP_PRODUCTS,
+               OP_FILES,
                OP_HASHES,
+               OP_MEASUREMENTS,
+               OP_PRODUCTS,
                OP_ADD,
                OP_DEL,
        } op = OP_UNDEF;
@@ -116,8 +118,10 @@ static void do_args(int argc, char *argv[])
                        { "help", no_argument, NULL, 'h' },
                        { "components", no_argument, NULL, 'c' },
                        { "files", no_argument, NULL, 'f' },
+                       { "keys", no_argument, NULL, 'k' },
                        { "products", no_argument, NULL, 'p' },
                        { "hashes", no_argument, NULL, 'H' },
+                       { "measurements", no_argument, NULL, 'M' },
                        { "add", no_argument, NULL, 'a' },
                        { "delete", no_argument, NULL, 'd' },
                        { "del", no_argument, NULL, 'd' },
@@ -129,6 +133,8 @@ static void do_args(int argc, char *argv[])
                        { "directory", required_argument, NULL, 'D' },
                        { "dir", required_argument, NULL, 'D' },
                        { "file", required_argument, NULL, 'F' },
+                       { "key", required_argument, NULL, 'K' },
+                       { "owner", required_argument, NULL, 'O' },
                        { "product", required_argument, NULL, 'P' },
                        { "sha1", no_argument, NULL, '1' },
                        { "sha256", no_argument, NULL, '2' },
@@ -137,6 +143,7 @@ static void do_args(int argc, char *argv[])
                        { "fid", required_argument, NULL, '5' },
                        { "pid", required_argument, NULL, '6' },
                        { "cid", required_argument, NULL, '7' },
+                       { "kid", required_argument, NULL, '8' },
                        { 0,0,0,0 }
                };
 
@@ -154,12 +161,18 @@ static void do_args(int argc, char *argv[])
                        case 'f':
                                op = OP_FILES;
                                continue;
+                       case 'k':
+                               op = OP_KEYS;
+                               continue;
                        case 'p':
                                op = OP_PRODUCTS;
                                continue;
                        case 'H':
                                op = OP_HASHES;
                                continue;
+                       case 'M':
+                               op = OP_MEASUREMENTS;
+                               continue;
                        case 'a':
                                op = OP_ADD;
                                continue;
@@ -199,6 +212,15 @@ static void do_args(int argc, char *argv[])
                                        exit(EXIT_FAILURE);
                                }
                                continue;
+                       case 'K':
+                               if (!attest->set_key(attest, optarg, op == OP_ADD))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
+                               continue;
+                       case 'O':
+                               attest->set_owner(attest, optarg);
+                               continue;
                        case 'P':
                                if (!attest->set_product(attest, optarg, op == OP_ADD))
                                {
@@ -238,6 +260,12 @@ static void do_args(int argc, char *argv[])
                                        exit(EXIT_FAILURE);
                                }
                                continue;
+                       case '8':
+                               if (!attest->set_kid(attest, atoi(optarg)))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
+                               continue;
                }
                break;
        }
@@ -250,6 +278,9 @@ static void do_args(int argc, char *argv[])
                case OP_PRODUCTS:
                        attest->list_products(attest);
                        break;
+               case OP_KEYS:
+                       attest->list_keys(attest);
+                       break;
                case OP_COMPONENTS:
                        attest->list_components(attest);
                        break;
@@ -259,6 +290,9 @@ static void do_args(int argc, char *argv[])
                case OP_HASHES:
                        attest->list_hashes(attest);
                        break;
+               case OP_MEASUREMENTS:
+                       attest->list_measurements(attest);
+                       break;
                case OP_ADD:
                        attest->add(attest);
                        break;
index a9f1f71..10c719b 100644 (file)
@@ -31,19 +31,34 @@ struct private_attest_db_t {
        attest_db_t public;
 
        /**
-        * Software product to be queried
+        * Component Functional Name to be queried
         */
-       char *product;
+       pts_comp_func_name_t *cfn;
 
        /**
-        * Primary key of software product to be queried
+        * Primary key of the Component Functional Name to be queried
         */
-       int pid;
+       int cid;
 
        /**
-        * TRUE if product has been set
+        * TRUE if Component Functional Name has been set
         */
-       bool product_set;
+       bool comp_set;
+
+       /**
+        * Directory containing the Measurement file to be queried
+        */
+       char *dir;
+
+       /**
+        * Primary key of the directory to be queried
+        */
+       int did;
+
+       /**
+        * TRUE if directory has been set
+        */
+       bool dir_set;
 
        /**
         * Measurement file to be queried
@@ -61,34 +76,34 @@ struct private_attest_db_t {
        bool file_set;
 
        /**
-        * Directory containing the Measurement file to be queried
+        *  AIK to be queried
         */
-       char *dir;
+       chunk_t key;
 
        /**
-        * Primary key of the directory to be queried
+        * Primary key of the AIK to be queried
         */
-       int did;
+       int kid;
 
        /**
-        * TRUE if directory has been set
+        * TRUE if AIK has been set
         */
-       bool dir_set;
+       bool key_set;
 
        /**
-        * Component Functional Name to be queried
+        * Software product to be queried
         */
-       pts_comp_func_name_t *cfn;
+       char *product;
 
        /**
-        * Primary key of the Component Functional Name to be queried
+        * Primary key of software product to be queried
         */
-       int cid;
+       int pid;
 
        /**
-        * TRUE if Component Functional Name has been set
+        * TRUE if product has been set
         */
-       bool comp_set;
+       bool product_set;
 
        /**
         * File measurement hash algorithm
@@ -96,6 +111,11 @@ struct private_attest_db_t {
        pts_meas_algorithms_t algo;
 
        /**
+        * Optional owner (user/host name)
+        */
+       char *owner;
+
+       /**
         * Attestation database
         */
        database_t *db;
@@ -125,79 +145,185 @@ char* print_cfn(pts_comp_func_name_t *cfn)
        return buf;
 }
 
-METHOD(attest_db_t, set_product, bool,
-       private_attest_db_t *this, char *product, bool create)
+METHOD(attest_db_t, set_component, bool,
+       private_attest_db_t *this, char *comp, bool create)
 {
        enumerator_t *e;
+       char *pos1, *pos2;
+       int vid, name, qualifier;
+       pts_comp_func_name_t *cfn;
 
-       if (this->product_set)
+       if (this->comp_set)
        {
-               printf("product has already been set\n");
+               printf("component has already been set\n");
                return FALSE;
        }
-       this->product = strdup(product);
 
-       e = this->db->query(this->db, "SELECT id FROM products WHERE name = ?",
-                                               DB_TEXT, product, DB_INT);
+       /* parse component string */
+       pos1 = strchr(comp, '/');
+       pos2 = strchr(comp, '-');
+       if (!pos1 || !pos2)
+       {
+               printf("component string must have the form \"vendor_id/name-qualifier\"\n");
+               return FALSE;
+       }
+       vid       = atoi(comp);
+       name      = atoi(pos1 + 1);
+       qualifier = atoi(pos2 + 1);
+       cfn = pts_comp_func_name_create(vid, name, qualifier);
+
+       e = this->db->query(this->db,
+                                          "SELECT id FROM components "
+                                          "WHERE vendor_id = ? AND name = ? AND qualifier = ?",
+                                               DB_INT, vid, DB_INT, name, DB_INT, qualifier, DB_INT);
        if (e)
        {
-               if (e->enumerate(e, &this->pid))
+               if (e->enumerate(e, &this->cid))
                {
-                       this->product_set = TRUE;
+                       this->comp_set = TRUE;
+                       this->cfn = cfn;
                }
                e->destroy(e);
        }
-       if (this->product_set)
+       if (this->comp_set)
        {
                return TRUE;
        }
 
        if (!create)
        {
-               printf("product '%s' not found in database\n", product);
+               printf("component '%s' not found in database\n", print_cfn(cfn));
+               cfn->destroy(cfn);
                return FALSE;
        }
 
        /* Add a new database entry */
-       this->product_set = this->db->execute(this->db, &this->pid,
-                                                                       "INSERT INTO products (name) VALUES (?)",
-                                                                       DB_TEXT, product) == 1;
+       this->comp_set = this->db->execute(this->db, &this->cid,
+                                               "INSERT INTO components (vendor_id, name, qualifier) "
+                                               "VALUES (?, ?, ?)",
+                                               DB_INT, vid, DB_INT, name, DB_INT, qualifier) == 1;
 
-       printf("product '%s' %sinserted into database\n", product,
-                  this->product_set ? "" : "could not be ");
+       printf("component '%s' %sinserted into database\n", print_cfn(cfn),
+                  this->comp_set ? "" : "could not be ");
+       if (this->comp_set)
+       {
+               this->cfn = cfn;
+       }
+       else
+       {
+               cfn->destroy(cfn);
+       }
+       return this->comp_set;
+}
 
-       return this->product_set;
+METHOD(attest_db_t, set_cid, bool,
+       private_attest_db_t *this, int cid)
+{
+       enumerator_t *e;
+       int vid, name, qualifier;
+
+       if (this->comp_set)
+       {
+               printf("component has already been set\n");
+               return FALSE;
+       }
+       this->cid = cid;
+
+       e = this->db->query(this->db, "SELECT vendor_id, name, qualifier "
+                                                                 "FROM components WHERE id = ?",
+                                               DB_INT, cid, DB_INT, DB_INT, DB_INT);
+       if (e)
+       {
+               if (e->enumerate(e, &vid, &name, &qualifier))
+               {
+                       this->cfn = pts_comp_func_name_create(vid, name, qualifier);
+                       this->comp_set = TRUE;
+               }
+               else
+               {
+                       printf("no component found with cid %d\n", cid);
+               }
+               e->destroy(e);
+       }
+       return this->comp_set;
 }
 
-METHOD(attest_db_t, set_pid, bool,
-       private_attest_db_t *this, int pid)
+METHOD(attest_db_t, set_directory, bool,
+       private_attest_db_t *this, char *dir, bool create)
 {
        enumerator_t *e;
-       char *product;
 
-       if (this->product_set)
+       if (this->dir_set)
        {
-               printf("product has already been set\n");
+               printf("directory has already been set\n");
                return FALSE;
        }
-       this->pid = pid;
+       free(this->dir);
+       this->dir = strdup(dir);
 
-       e = this->db->query(this->db, "SELECT name FROM products WHERE id = ?",
-                                               DB_INT, pid, DB_TEXT);
+       e = this->db->query(this->db,
+                                               "SELECT id FROM files WHERE type = 1 AND path = ?",
+                                               DB_TEXT, dir, DB_INT);
        if (e)
        {
-               if (e->enumerate(e, &product))
+               if (e->enumerate(e, &this->did))
                {
-                       this->product = strdup(product);
-                       this->product_set = TRUE;
+                       this->dir_set = TRUE;
+               }
+               e->destroy(e);
+       }
+       if (this->dir_set)
+       {
+               return TRUE;
+       }
+
+       if (!create)
+       {
+               printf("directory '%s' not found in database\n", dir);
+               return FALSE;
+       }
+
+       /* Add a new database entry */
+       this->dir_set = this->db->execute(this->db, &this->did,
+                                                               "INSERT INTO files (type, path) VALUES (1, ?)",
+                                                               DB_TEXT, dir) == 1;
+
+       printf("directory '%s' %sinserted into database\n", dir,
+                  this->dir_set ? "" : "could not be ");
+
+       return this->dir_set;
+}
+
+METHOD(attest_db_t, set_did, bool,
+       private_attest_db_t *this, int did)
+{
+       enumerator_t *e;
+       char *dir;
+
+       if (this->dir_set)
+       {
+               printf("directory has already been set\n");
+               return FALSE;
+       }
+       this->did = did;
+
+       e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
+                                               DB_INT, did, DB_TEXT);
+       if (e)
+       {
+               if (e->enumerate(e, &dir))
+               {
+                       free(this->dir);
+                       this->dir = strdup(dir);
+                       this->dir_set = TRUE;
                }
                else
                {
-                       printf("no product found with pid %d in database\n", pid);
+                       printf("no directory found with did %d\n", did);
                }
                e->destroy(e);
        }
-       return this->product_set;
+       return this->dir_set;
 }
 
 METHOD(attest_db_t, set_file, bool,
@@ -275,185 +401,164 @@ METHOD(attest_db_t, set_fid, bool,
        return this->file_set;
 }
 
-METHOD(attest_db_t, set_directory, bool,
-       private_attest_db_t *this, char *dir, bool create)
+METHOD(attest_db_t, set_key, bool,
+       private_attest_db_t *this, char *key, bool create)
 {
        enumerator_t *e;
+       char *owner;
 
-       if (this->dir_set)
+       if (this->key_set)
        {
-               printf("directory has already been set\n");
+               printf("key has already been set\n");
                return FALSE;
        }
-       free(this->dir);
-       this->dir = strdup(dir);
+       this->key = chunk_from_hex(chunk_create(key, strlen(key)), NULL);
 
-       e = this->db->query(this->db,
-                                               "SELECT id FROM files WHERE type = 1 AND path = ?",
-                                               DB_TEXT, dir, DB_INT);
+       e = this->db->query(this->db, "SELECT id, owner FROM keys WHERE keyid= ?",
+                                               DB_BLOB, this->key, DB_INT, DB_TEXT);
        if (e)
        {
-               if (e->enumerate(e, &this->did))
+               if (e->enumerate(e, &this->kid, &owner))
                {
-                       this->dir_set = TRUE;
+                       this->owner = strdup(owner);
+                       this->key_set = TRUE;
                }
                e->destroy(e);
        }
-       if (this->dir_set)
+       if (this->key_set)
        {
                return TRUE;
        }
 
        if (!create)
        {
-               printf("directory '%s' not found in database\n", dir);
+               printf("key '%#B' not found in database\n", &this->key);
                return FALSE;
        }
 
        /* Add a new database entry */
-       this->dir_set = this->db->execute(this->db, &this->did,
-                                                               "INSERT INTO files (type, path) VALUES (1, ?)",
-                                                               DB_TEXT, dir) == 1;
+       if (!this->owner)
+       {
+               this->owner = strdup("");
+       }
+       this->key_set = this->db->execute(this->db, &this->kid,
+                                                               "INSERT INTO keys (keyid, owner) VALUES (?, ?)",
+                                                               DB_BLOB, this->key, DB_TEXT, this->owner) == 1;
 
-       printf("directory '%s' %sinserted into database\n", dir,
-                  this->dir_set ? "" : "could not be ");
+       printf("key '%#B' %sinserted into database\n", &this->key,
+                  this->key_set ? "" : "could not be ");
 
-       return this->dir_set;
-}
+       return this->key_set;
 
-METHOD(attest_db_t, set_did, bool,
-       private_attest_db_t *this, int did)
+};
+
+METHOD(attest_db_t, set_kid, bool,
+       private_attest_db_t *this, int kid)
 {
        enumerator_t *e;
-       char *dir;
+       chunk_t key;
+       char *owner;
 
-       if (this->dir_set)
+       if (this->key_set)
        {
-               printf("directory has already been set\n");
+               printf("key has already been set\n");
                return FALSE;
        }
-       this->did = did;
+       this->kid = kid;
 
-       e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
-                                               DB_INT, did, DB_TEXT);
+       e = this->db->query(this->db, "SELECT keyid, owner FROM keys WHERE id = ?",
+                                               DB_INT, kid, DB_BLOB, DB_TEXT);
        if (e)
        {
-               if (e->enumerate(e, &dir))
+               if (e->enumerate(e, &key, &owner))
                {
-                       free(this->dir);
-                       this->dir = strdup(dir);
-                       this->dir_set = TRUE;
+                       this->owner = strdup(owner);
+                       this->key = chunk_clone(key);
+                       this->key_set = TRUE;
                }
                else
                {
-                       printf("no directory found with did %d\n", did);
+                       printf("no key found with kid %d\n", kid);
                }
                e->destroy(e);
        }
-       return this->dir_set;
-}
+       return this->key_set;
 
-METHOD(attest_db_t, set_component, bool,
-       private_attest_db_t *this, char *comp, bool create)
+};
+
+METHOD(attest_db_t, set_product, bool,
+       private_attest_db_t *this, char *product, bool create)
 {
        enumerator_t *e;
-       char *pos1, *pos2;
-       int vid, name, qualifier;
-       pts_comp_func_name_t *cfn;
-
-       if (this->comp_set)
-       {
-               printf("component has already been set\n");
-               return FALSE;
-       }
 
-       /* parse component string */
-       pos1 = strchr(comp, '/');
-       pos2 = strchr(comp, '-');
-       if (!pos1 || !pos2)
+       if (this->product_set)
        {
-               printf("component string must have the form \"vendor_id/name-qualifier\"\n");
+               printf("product has already been set\n");
                return FALSE;
        }
-       vid       = atoi(comp);
-       name      = atoi(pos1 + 1);
-       qualifier = atoi(pos2 + 1);
-       cfn = pts_comp_func_name_create(vid, name, qualifier);
+       this->product = strdup(product);
 
-       e = this->db->query(this->db,
-                                          "SELECT id FROM components "
-                                          "WHERE vendor_id = ? AND name = ? AND qualifier = ?",
-                                               DB_INT, vid, DB_INT, name, DB_INT, qualifier, DB_INT);
+       e = this->db->query(this->db, "SELECT id FROM products WHERE name = ?",
+                                               DB_TEXT, product, DB_INT);
        if (e)
        {
-               if (e->enumerate(e, &this->cid))
+               if (e->enumerate(e, &this->pid))
                {
-                       this->comp_set = TRUE;
-                       this->cfn = cfn;
+                       this->product_set = TRUE;
                }
                e->destroy(e);
        }
-       if (this->comp_set)
+       if (this->product_set)
        {
                return TRUE;
        }
 
        if (!create)
        {
-               printf("component '%s' not found in database\n", print_cfn(cfn));
-               cfn->destroy(cfn);
+               printf("product '%s' not found in database\n", product);
                return FALSE;
        }
 
        /* Add a new database entry */
-       this->comp_set = this->db->execute(this->db, &this->cid,
-                                               "INSERT INTO components (vendor_id, name, qualifier) "
-                                               "VALUES (?, ?, ?)",
-                                               DB_INT, vid, DB_INT, name, DB_INT, qualifier) == 1;
+       this->product_set = this->db->execute(this->db, &this->pid,
+                                                                       "INSERT INTO products (name) VALUES (?)",
+                                                                       DB_TEXT, product) == 1;
 
-       printf("component '%s' %sinserted into database\n", print_cfn(cfn),
-                  this->comp_set ? "" : "could not be ");
-       if (this->comp_set)
-       {
-               this->cfn = cfn;
-       }
-       else
-       {
-               cfn->destroy(cfn);
-       }
-       return this->comp_set;
+       printf("product '%s' %sinserted into database\n", product,
+                  this->product_set ? "" : "could not be ");
+
+       return this->product_set;
 }
 
-METHOD(attest_db_t, set_cid, bool,
-       private_attest_db_t *this, int cid)
+METHOD(attest_db_t, set_pid, bool,
+       private_attest_db_t *this, int pid)
 {
        enumerator_t *e;
-       int vid, name, qualifier;
+       char *product;
 
-       if (this->comp_set)
+       if (this->product_set)
        {
-               printf("component has already been set\n");
+               printf("product has already been set\n");
                return FALSE;
        }
-       this->cid = cid;
+       this->pid = pid;
 
-       e = this->db->query(this->db, "SELECT vendor_id, name, qualifier "
-                                                                 "FROM components WHERE id = ?",
-                                               DB_INT, cid, DB_INT, DB_INT, DB_INT);
+       e = this->db->query(this->db, "SELECT name FROM products WHERE id = ?",
+                                               DB_INT, pid, DB_TEXT);
        if (e)
        {
-               if (e->enumerate(e, &vid, &name, &qualifier))
+               if (e->enumerate(e, &product))
                {
-                       this->cfn = pts_comp_func_name_create(vid, name, qualifier);
-                       this->comp_set = TRUE;
+                       this->product = strdup(product);
+                       this->product_set = TRUE;
                }
                else
                {
-                       printf("no component found with cid %d\n", cid);
+                       printf("no product found with pid %d in database\n", pid);
                }
                e->destroy(e);
        }
-       return this->comp_set;
+       return this->product_set;
 }
 
 METHOD(attest_db_t, set_algo, void,
@@ -462,6 +567,13 @@ METHOD(attest_db_t, set_algo, void,
        this->algo = algo;
 }
 
+METHOD(attest_db_t, set_owner, void,
+       private_attest_db_t *this, char *owner)
+{
+       free(this->owner);
+       this->owner = strdup(owner);
+}
+
 METHOD(attest_db_t, list_components, void,
        private_attest_db_t *this)
 {
@@ -469,14 +581,14 @@ METHOD(attest_db_t, list_components, void,
        pts_comp_func_name_t *cfn;
        int cid, vid, name, qualifier, count = 0;
 
-       if (this->pid)
+       if (this->kid)
        {
                e = this->db->query(this->db,
                                "SELECT c.id, c.vendor_id, c.name, c.qualifier "
                                "FROM components AS c "
-                               "JOIN product_component AS pc ON c.id = pc.component "
-                               "WHERE pc.product = ? ORDER BY c.vendor_id, c.name, c.qualifier",
-                               DB_INT, this->pid, DB_INT, DB_INT, DB_INT, DB_INT);
+                               "JOIN key_component AS kc ON c.id = kc.component "
+                               "WHERE kc.key = ? ORDER BY c.vendor_id, c.name, c.qualifier",
+                               DB_INT, this->kid, DB_INT, DB_INT, DB_INT, DB_INT);
        }
        else
        {
@@ -497,14 +609,63 @@ METHOD(attest_db_t, list_components, void,
                e->destroy(e);
 
                printf("%d component%s found", count, (count == 1) ? "" : "s");
-               if (this->product_set)
+               if (this->key_set)
                {
-                       printf(" for product '%s'", this->product);
+                       printf(" for key %#B", &this->key);
                }
                printf("\n");
        }
 }
 
+METHOD(attest_db_t, list_keys, void,
+       private_attest_db_t *this)
+{
+       enumerator_t *e;
+       chunk_t keyid;
+       char *owner;
+       int kid, count = 0;
+
+       if (this->cid)
+       {
+               e = this->db->query(this->db,
+                               "SELECT k.id, k.keyid, k.owner FROM keys AS k "
+                               "JOIN key_component AS kc ON k.id = kc.key "
+                               "WHERE kc.component = ? ORDER BY k.keyid",
+                               DB_INT, this->cid, DB_INT, DB_BLOB, DB_TEXT);
+               if (e)
+               {
+                       while (e->enumerate(e, &kid, &keyid, &owner))
+                       {
+                               printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+                               count++;
+                       }
+                       e->destroy(e);
+               }
+       }
+       else
+       {
+               e = this->db->query(this->db, "SELECT id, keyid, owner FROM keys "
+                               "ORDER BY keyid",
+                               DB_INT, DB_BLOB, DB_TEXT);
+               if (e)
+               {
+                       while (e->enumerate(e, &kid, &keyid, &owner))
+                       {
+                               printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+                               count++;
+                       }
+                       e->destroy(e);
+               }
+       }
+
+       printf("%d key%s found", count, (count == 1) ? "" : "s");
+       if (this->comp_set)
+       {
+               printf(" for component '%s'", print_cfn(this->cfn));
+       }
+       printf("\n");
+}
+
 METHOD(attest_db_t, list_files, void,
        private_attest_db_t *this)
 {
@@ -584,23 +745,6 @@ METHOD(attest_db_t, list_products, void,
                        e->destroy(e);
                }
        }
-       else if (this->cid)
-       {
-               e = this->db->query(this->db,
-                               "SELECT p.id, p.name FROM products AS p "
-                               "JOIN product_component AS pc ON p.id = pc.product "
-                               "WHERE pc.component = ? ORDER BY p.name",
-                               DB_INT, this->cid, DB_INT, DB_TEXT);
-               if (e)
-               {
-                       while (e->enumerate(e, &pid, &product, &meas, &meta))
-                       {
-                               printf("%3d: %s\n", pid, product);
-                               count++;
-                       }
-                       e->destroy(e);
-               }
-       }
        else
        {
                e = this->db->query(this->db, "SELECT id, name FROM products "
@@ -622,10 +766,6 @@ METHOD(attest_db_t, list_products, void,
        {
                printf(" for file '%s'", this->file);
        }
-       else if (this->comp_set)
-       {
-               printf(" for component '%s'", print_cfn(this->cfn));
-       }
        printf("\n");
 }
 
@@ -672,34 +812,7 @@ METHOD(attest_db_t, list_hashes, void,
 
        dir = strdup("");
 
-       if (this->pid && this->fid && this->cid)
-       {
-               e = this->db->query(this->db,
-                               "SELECT hash FROM file_hashes "
-                               "WHERE algo = ? AND file = ? AND component = ? AND product = ?",
-                               DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->cid,
-                               DB_INT, this->pid, DB_BLOB);
-               if (e)
-               {
-                       while (e->enumerate(e, &hash))
-                       {
-                               if (this->fid != fid_old)
-                               {
-                                       printf("%3d: %s%s%s\n", this->fid, this->dir,
-                                                  slash(this->dir, this->file) ? "/" : "", this->file);
-                                       fid_old = this->fid;
-                               }
-                               printf("     %#B '%s'\n", &hash, this->product);
-                               count++;
-                       }
-                       e->destroy(e);
-
-                       printf("%d %N value%s found for component '%s'\n", count,
-                                  hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
-                                  (count == 1) ? "" : "s", print_cfn(this->cfn));
-               }
-       }
-       else if (this->pid && this->fid)
+       if (this->pid && this->fid)
        {
                e = this->db->query(this->db,
                                "SELECT hash FROM file_hashes "
@@ -824,6 +937,110 @@ METHOD(attest_db_t, list_hashes, void,
        free(dir);
 }
 
+METHOD(attest_db_t, list_measurements, void,
+       private_attest_db_t *this)
+{
+       enumerator_t *e;
+       chunk_t hash, keyid;
+       pts_comp_func_name_t *cfn;
+       char *owner;
+       int seq_no, pcr, vid, name, qualifier;
+       int cid, cid_old = 0, kid, kid_old = 0, count = 0;
+
+       if (this->kid && this->cid)
+       {
+               e = this->db->query(this->db,
+                               "SELECT ch.seq_no, ch.pcr, ch.hash, k.owner "
+                               "FROM component_hashes AS ch "
+                               "JOIN keys AS k ON k.id = ch.key "
+                               "WHERE ch.algo = ? AND ch.key = ? AND ch.component = ? "
+                               "ORDER BY seq_no",
+                               DB_INT, this->algo, DB_INT, this->kid, DB_INT, this->cid,
+                               DB_INT, DB_INT, DB_BLOB, DB_TEXT);
+               if (e)
+               {
+                       while (e->enumerate(e, &seq_no, &pcr, &hash, &owner))
+                       {
+                               if (this->kid != kid_old)
+                               {
+                                       printf("%3d: %#B '%s'\n", this->kid, &this->key, owner);
+                                       kid_old = this->kid;
+                               }
+                               printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+                               count++;
+                       }
+                       e->destroy(e);
+
+                       printf("%d %N value%s found for component '%s'\n", count,
+                                  hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+                                  (count == 1) ? "" : "s", print_cfn(this->cfn));
+               }
+       }
+       else if (this->cid)
+       {
+               e = this->db->query(this->db,
+                               "SELECT ch.seq_no, ch.pcr, ch.hash, k.id, k.keyid, k.owner "
+                               "FROM component_hashes AS ch "
+                               "JOIN keys AS k ON k.id = ch.key "
+                               "WHERE ch.algo = ? AND ch.component = ? "
+                               "ORDER BY keyid, seq_no",
+                               DB_INT, this->algo, DB_INT, this->cid,
+                               DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB, DB_TEXT);
+               if (e)
+               {
+                       while (e->enumerate(e, &seq_no, &pcr, &hash, &kid, &keyid, &owner))
+                       {
+                               if (kid != kid_old)
+                               {
+                                       printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+                                       kid_old = kid;
+                               }
+                               printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+                               count++;
+                       }
+                       e->destroy(e);
+
+                       printf("%d %N value%s found for component '%s'\n", count,
+                                  hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+                                  (count == 1) ? "" : "s", print_cfn(this->cfn));
+               }
+
+       }
+       else if (this->kid)
+       {
+               e = this->db->query(this->db,
+                               "SELECT ch.seq_no, ch.pcr, ch.hash, "
+                               "c.id, c.vendor_id, c.name, c.qualifier "
+                               "FROM component_hashes AS ch "
+                               "JOIN components AS c ON c.id = ch.component "
+                               "WHERE ch.algo = ? AND ch.key = ? "
+                               "ORDER BY vendor_id, name, qualifier, seq_no",
+                               DB_INT, this->algo, DB_INT, this->kid, DB_INT, DB_INT, DB_BLOB,
+                               DB_TEXT, DB_INT, DB_INT, DB_INT, DB_INT);
+               if (e)
+               {
+                       while (e->enumerate(e, &seq_no, &pcr, &hash, &cid, &vid, &name,
+                                                                  &qualifier))
+                       {
+                               if (cid != cid_old)
+                               {
+                                       cfn = pts_comp_func_name_create(vid, name, qualifier);
+                                       printf("%3d: %s\n", cid, print_cfn(cfn));
+                                       cfn->destroy(cfn);
+                                       cid_old = cid;
+                               }
+                               printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+                               count++;
+                       }
+                       e->destroy(e);
+
+                       printf("%d %N value%s found for key %#B '%s'\n", count,
+                                  hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+                                  (count == 1) ? "" : "s", &this->key, this->owner);
+               }
+       }
+}
+
 METHOD(attest_db_t, add, bool,
        private_attest_db_t *this)
 {
@@ -841,13 +1058,30 @@ METHOD(attest_db_t, delete, bool,
                return FALSE;
        }
 
-       if (this->pid)
+       if (this->kid && this->did)
+       {
+               printf("deletion of key/component entries not supported yet\n");
+               return FALSE;
+       }
+
+       if (this->cid)
        {
                success = this->db->execute(this->db, NULL,
-                                                               "DELETE FROM products WHERE id = ?",
-                                                               DB_UINT, this->pid) > 0;
+                                                               "DELETE FROM components WHERE id = ?",
+                                                               DB_UINT, this->cid) > 0;
 
-               printf("product '%s' %sdeleted from database\n", this->product,
+               printf("component '%s' %sdeleted from database\n", print_cfn(this->cfn),
+                          success ? "" : "could not be ");
+               return success;
+       }
+
+       if (this->did)
+       {
+               success = this->db->execute(this->db, NULL,
+                                                               "DELETE FROM files WHERE type = 1 AND id = ?",
+                                                               DB_UINT, this->did) > 0;
+
+               printf("directory '%s' %sdeleted from database\n", this->dir,
                           success ? "" : "could not be ");
                return success;
        }
@@ -863,24 +1097,23 @@ METHOD(attest_db_t, delete, bool,
                return success;
        }
 
-       if (this->did)
+       if (this->kid)
        {
                success = this->db->execute(this->db, NULL,
-                                                               "DELETE FROM files WHERE type = 1 AND id = ?",
-                                                               DB_UINT, this->did) > 0;
+                                                               "DELETE FROM keys WHERE id = ?",
+                                                               DB_UINT, this->kid) > 0;
 
-               printf("directory '%s' %sdeleted from database\n", this->dir,
+               printf("key %#B %sdeleted from database\n", &this->key,
                           success ? "" : "could not be ");
                return success;
        }
-
-       if (this->cid)
+       if (this->pid)
        {
                success = this->db->execute(this->db, NULL,
-                                                               "DELETE FROM components WHERE id = ?",
-                                                               DB_UINT, this->cid) > 0;
+                                                               "DELETE FROM products WHERE id = ?",
+                                                               DB_UINT, this->pid) > 0;
 
-               printf("component '%s' %sdeleted from database\n", print_cfn(this->cfn),
+               printf("product '%s' %sdeleted from database\n", this->product,
                           success ? "" : "could not be ");
                return success;
        }
@@ -897,6 +1130,8 @@ METHOD(attest_db_t, destroy, void,
        free(this->product);
        free(this->file);
        free(this->dir);
+       free(this->owner);
+       free(this->key.ptr);
        free(this);
 }
 
@@ -909,19 +1144,24 @@ attest_db_t *attest_db_create(char *uri)
 
        INIT(this,
                .public = {
-                       .set_product = _set_product,
-                       .set_pid = _set_pid,
-                       .set_file = _set_file,
-                       .set_fid = _set_fid,
-                       .set_directory = _set_directory,
-                       .set_did = _set_did,
                        .set_component = _set_component,
                        .set_cid = _set_cid,
+                       .set_directory = _set_directory,
+                       .set_did = _set_did,
+                       .set_file = _set_file,
+                       .set_fid = _set_fid,
+                       .set_key = _set_key,
+                       .set_kid = _set_kid,
+                       .set_product = _set_product,
+                       .set_pid = _set_pid,
                        .set_algo = _set_algo,
+                       .set_owner = _set_owner,
                        .list_products = _list_products,
                        .list_files = _list_files,
                        .list_components = _list_components,
+                       .list_keys = _list_keys,
                        .list_hashes = _list_hashes,
+                       .list_measurements = _list_measurements,
                        .add = _add,
                        .delete = _delete,
                        .destroy = _destroy,
index 6669a76..80a8f4c 100644 (file)
@@ -34,21 +34,38 @@ typedef struct attest_db_t attest_db_t;
 struct attest_db_t {
 
        /**
-        * Set software product to be queried
+        * Set functional component to be queried
         *
-        * @param product               software product
+        * @param comp                  functional component
         * @param create                if TRUE create database entry if it doesn't exist
         * @return                              TRUE if successful
         */
-       bool (*set_product)(attest_db_t *this, char *product, bool create);
+       bool (*set_component)(attest_db_t *this, char *comp, bool create);
 
        /**
-        * Set primary key of the software product to be queried
+        * Set primary key of the functional component to be queried
         *
-        * @param pid                   primary key of software product
+        * @param fid                   primary key of functional component
         * @return                              TRUE if successful
         */
-       bool (*set_pid)(attest_db_t *this, int pid);
+       bool (*set_cid)(attest_db_t *this, int fid);
+
+       /**
+        * Set directory to be queried
+        *
+        * @param dir                   directory
+        * @param create                if TRUE create database entry if it doesn't exist
+        * @return                              TRUE if successful
+        */
+       bool (*set_directory)(attest_db_t *this, char *dir, bool create);
+
+       /**
+        * Set primary key of the directory to be queried
+        *
+        * @param did                   primary key of directory
+        * @return                              TRUE if successful
+        */
+       bool (*set_did)(attest_db_t *this, int did);
 
        /**
         * Set measurement file to be queried
@@ -70,36 +87,36 @@ struct attest_db_t {
        /**
         * Set functional component to be queried
         *
-        * @param comp                  functional component
+        * @param key                   AIK
         * @param create                if TRUE create database entry if it doesn't exist
         * @return                              TRUE if successful
         */
-       bool (*set_component)(attest_db_t *this, char *comp, bool create);
+       bool (*set_key)(attest_db_t *this, char *key, bool create);
 
        /**
-        * Set primary key of the functional component to be queried
+        * Set primary key of the AIK to be queried
         *
-        * @param fid                   primary key of functional component
+        * @param kid                   primary key of AIK
         * @return                              TRUE if successful
         */
-       bool (*set_cid)(attest_db_t *this, int fid);
+       bool (*set_kid)(attest_db_t *this, int kid);
 
        /**
-        * Set directory to be queried
+        * Set software product to be queried
         *
-        * @param dir                   directory
+        * @param product               software product
         * @param create                if TRUE create database entry if it doesn't exist
         * @return                              TRUE if successful
         */
-       bool (*set_directory)(attest_db_t *this, char *dir, bool create);
+       bool (*set_product)(attest_db_t *this, char *product, bool create);
 
        /**
-        * Set primary key of the directory to be queried
+        * Set primary key of the software product to be queried
         *
-        * @param did                   primary key of directory
+        * @param pid                   primary key of software product
         * @return                              TRUE if successful
         */
-       bool (*set_did)(attest_db_t *this, int did);
+       bool (*set_pid)(attest_db_t *this, int pid);
 
        /**
         * Set measurement hash algorithm
@@ -109,6 +126,14 @@ struct attest_db_t {
        void (*set_algo)(attest_db_t *this, pts_meas_algorithms_t algo);
 
        /**
+        * Set owner [user/host] of an AIK
+        *
+        * @param owner                 user/host name
+        * @return                              TRUE if successful
+        */
+       void (*set_owner)(attest_db_t *this, char *owner);
+
+       /**
         * List all products stored in the database
         */
        void (*list_products)(attest_db_t *this);
@@ -124,11 +149,21 @@ struct attest_db_t {
        void (*list_components)(attest_db_t *this);
 
        /**
+        * List all AIKs stored in the database
+        */
+       void (*list_keys)(attest_db_t *this);
+
+       /**
         * List selected measurement hashes stored in the database
         */
        void (*list_hashes)(attest_db_t *this);
 
        /**
+        * List selected component measurement stored in the database
+        */
+       void (*list_measurements)(attest_db_t *this);
+
+       /**
         * Add an entry to the database
         */
        bool (*add)(attest_db_t *this);
index 964e100..952b88b 100644 (file)
@@ -24,16 +24,14 @@ void usage(void)
 {
        printf("\
 Usage:\n\
-  ipsec attest --files|--components|--products|--hashes|--add|--del [options]\n\
+  ipsec attest --files|--products|--keys|--hashes [options]\n\
+  \n\
+  ipsec attest --components|-keys|--measurements|--add|--del [options]\n\
   \n\
   ipsec attest --files [--product <name>|--pid <id>]\n\
     Show a list of files with a software product name or\n\
     its primary key as an optional selector.\n\
   \n\
-  ipsec attest --components [--product <name>|--pid <id>]\n\
-    Show a list of components with a software product name or\n\
-    its primary key as an optional selector.\n\
-  \n\
   ipsec attest --products [--file <path>|--fid <id>]\n\
     Show a list of supported software products with a file path or\n\
     its primary key as an optional selector.\n\
@@ -46,15 +44,37 @@ Usage:\n\
     Show a list of measurement hashes for a given file or\n\
     its primary key as an optional selector.\n\
   \n\
+  ipsec attest --components [--key <digest>|--kid <id>]\n\
+    Show a list of components with an AIK digest or\n\
+    its primary key as an optional selector.\n\
+  \n\
+  ipsec attest --keys [--components <cfn>|--cid <id>]\n\
+    Show a list of AIK key digests with a component or\n\
+    its primary key as an optional selector.\n\
+  \n\
+  ipsec attest --measurements [--sha1|--sha256|--sha384] [--component <cfn>|--cid <id>]\n\
+    Show a list of component measurements for a given component or\n\
+    its primary key as an optional selector.\n\
+  \n\
+  ipsec attest --measurements [--sha1|--sha256|--sha384] [--key <digest>|--kid <id>]\n\
+    Show a list of component measurements for a given AIK or\n\
+    its primary key as an optional selector.\n\
+  \n\
   ipsec attest --add --file <path>|--dir <path>|--product <name>|--component <cfn>\n\
     Add a file, directory, product or component entry\n\
     Component <cfn> entries must be of the form <vendor_id>/<name>-<qualifier>\n\
   \n\
+  ipsec attest --add [--owner <name>] --key <digest>\n\
+    Add an AIK public key digest entry preceded by an optional owner name\n\
+  \n\
   ipsec attest --del --file <path>|--fid <id>|--dir <path>|--did <id>\n\
-    Delete a file or directoryentry referenced either by value or primary key\n\
+    Delete a file or directory entry referenced either by value or primary key\n\
   \n\
   ipsec attest --del --product <name>|--pid <id>|--component <cfn>|--cid <id>\n\
     Delete a product or component entry referenced either by value or primary key\n\
+  \n\
+  ipsec attest --del --key <digest>|--kid <id>\n\
+    Delete an AIK entry referenced either by value or primary key\n\
   \n");
 }
 
index cc580bc..20a8e40 100644 (file)
@@ -176,26 +176,6 @@ INSERT INTO files (
   0, '/etc/tnc_config'
 );
 
-/* Components */
-
-INSERT INTO components (
-  vendor_id, name, qualifier
-) VALUES (
-  36906, 1, 33  /* ITA TGRUB */
-);
-
-INSERT INTO components (
-  vendor_id, name, qualifier
-) VALUES (
-  36906, 2, 33  /* ITA TBOOT */
-);
-
-INSERT INTO components (
-  vendor_id, name, qualifier
-) VALUES (
-  36906, 3, 33  /* ITA IMA */
-);
-
 /* Product-File */
 
 INSERT INTO product_file (
@@ -408,26 +388,6 @@ INSERT INTO product_file (
   7, 22, 1
 );
 
-/* Product Component */
-
-INSERT INTO product_component (
-  product, component, depth, seq_no
-) VALUES (
-  4, 2, 0, 1
-);
-
-INSERT INTO product_component (
-  product, component, depth, seq_no
-) VALUES (
-  7, 3, 0, 1
-);
-
-INSERT INTO product_component (
-  product, component, depth, seq_no
-) VALUES (
-  7, 2, 0, 2
-);
-
 /* File Hashes */
 
 INSERT INTO file_hashes (
@@ -1295,789 +1255,837 @@ INSERT INTO file_hashes (
   20, 7, 7, 8192, X'84200bd318bb022915150842ddf4002e061ef593604ad0d07021dc662cc40bfa749cce084ddf25d0e5137f6380f613d8'
 );
 
+/* AIKs */
+
+INSERT INTO keys (
+  keyid, owner
+) VALUES (
+  X'b772a6730776b9f028e5adfccd40b55c320a13b6', 'Andreas, merthyr (Fujitsu Siemens Lifebook S6420)'
+);
+
+/* Components */
+
+INSERT INTO components (
+  vendor_id, name, qualifier
+) VALUES (
+  36906, 1, 33  /* ITA TGRUB */
+);
+
+INSERT INTO components (
+  vendor_id, name, qualifier
+) VALUES (
+  36906, 2, 33  /* ITA TBOOT */
+);
+
+INSERT INTO components (
+  vendor_id, name, qualifier
+) VALUES (
+  36906, 3, 33  /* ITA IMA */
+);
+
+/* AIK Component */
+
+INSERT INTO key_component (
+  key, component, depth, seq_no
+) VALUES (
+  2, 2, 0, 1
+);
+
+INSERT INTO key_component (
+  key, component, depth, seq_no
+) VALUES (
+  1, 3, 0, 1
+);
+
+INSERT INTO key_component (
+  key, component, depth, seq_no
+) VALUES (
+  1, 2, 0, 2
+);
+
 /* Component Hashes */
 
 /* ITA TBOOT Functional Component */
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  2, 4, 1, 17, 32768, X'9704353630674bfe21b86b64a7b0f99c297cf902'
+  2, 2, 1, 17, 32768, X'9704353630674bfe21b86b64a7b0f99c297cf902'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  2, 4, 2, 18, 32768, X'8397d8048ee36d7955e38da16fc33e86ef61d6b0'
+  2, 2, 2, 18, 32768, X'8397d8048ee36d7955e38da16fc33e86ef61d6b0'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  2, 7, 1, 17, 32768, X'd537d437f058136eb3d7be517dbe7647b623c619'
+  2, 1, 1, 17, 32768, X'd537d437f058136eb3d7be517dbe7647b623c619'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  2, 7, 2, 18, 32768, X'160d2b04d11eb225fb148615b699081869e15b6c'
+  2, 1, 2, 18, 32768, X'160d2b04d11eb225fb148615b699081869e15b6c'
 );
 
 /* ITA IMA Functional Component */
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  1, 0, 32768, X'4d894eef0ae7cb124740df4f6c5c35aa0fe7dae8'
+  3, 1,  1, 0, 32768, X'4d894eef0ae7cb124740df4f6c5c35aa0fe7dae8'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  2, 0, 32768, X'f2c846e7f335f7b9e9dd0a44f48c48e1986750c7'
+  3, 1,  2, 0, 32768, X'f2c846e7f335f7b9e9dd0a44f48c48e1986750c7'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  3, 0, 32768, X'db0b68f3ad06b5c0c35deb56af22b8f0bc23ea50'
+  3, 1,  3, 0, 32768, X'db0b68f3ad06b5c0c35deb56af22b8f0bc23ea50'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  4, 0, 32768, X'a662680c8564f92cf20c5857d781ed3f0806da5d'
+  3, 1,  4, 0, 32768, X'a662680c8564f92cf20c5857d781ed3f0806da5d'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  5, 0, 32768, X'10bfa817da3a9e5760fbe78f216502e8ca4f94ef'
+  3, 1,  5, 0, 32768, X'10bfa817da3a9e5760fbe78f216502e8ca4f94ef'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  6, 0, 32768, X'd0e1af1be845f570e44612613c4ddf3f08996151'
+  3, 1,  6, 0, 32768, X'd0e1af1be845f570e44612613c4ddf3f08996151'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  7, 0, 32768, X'f05553c39e8130c7bb5db6cd6a6bf627311a9b01'
+  3, 1,  7, 0, 32768, X'f05553c39e8130c7bb5db6cd6a6bf627311a9b01'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  8, 0, 32768, X'96ef1ad4efc5be2b894a12e5bffddcd496044a08'
+  3, 1,  8, 0, 32768, X'96ef1ad4efc5be2b894a12e5bffddcd496044a08'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7,  9, 0, 32768, X'e9055f2050b99b9127b6feef3164cb8ead8eb2eb'
+  3, 1,  9, 0, 32768, X'e9055f2050b99b9127b6feef3164cb8ead8eb2eb'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 10, 0, 32768, X'6f8150aa3423544ea59ea10025993e660568cc08'
+  3, 1, 10, 0, 32768, X'6f8150aa3423544ea59ea10025993e660568cc08'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 11, 0, 32768, X'f843e55c9061fec89f2aeb369a74b73fe8eb09e4'
+  3, 1, 11, 0, 32768, X'f843e55c9061fec89f2aeb369a74b73fe8eb09e4'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 12, 0, 32768, X'1d1efd1cb89be96f8fdf20ee0b67a89670659208'
+  3, 1, 12, 0, 32768, X'1d1efd1cb89be96f8fdf20ee0b67a89670659208'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 13, 0, 32768, X'f907598ec6fcc5779ff9091ba0925c1d58500352'
+  3, 1, 13, 0, 32768, X'f907598ec6fcc5779ff9091ba0925c1d58500352'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 14, 0, 32768, X'42f32d6fba099b0eea2e9a480dc8d4482e20412e'
+  3, 1, 14, 0, 32768, X'42f32d6fba099b0eea2e9a480dc8d4482e20412e'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 15, 0, 32768, X'e8a7cd52522ebacf4637a2b875494cda1c26bd8c'
+  3, 1, 15, 0, 32768, X'e8a7cd52522ebacf4637a2b875494cda1c26bd8c'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 16, 0, 32768, X'd62d2c550fd06cae76f3e9c4d63f5fc22e34d4fe'
+  3, 1, 16, 0, 32768, X'd62d2c550fd06cae76f3e9c4d63f5fc22e34d4fe'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 17, 0, 32768, X'dc1293a87cab43024a4eaeb684a0186e33dacfe3'
+  3, 1, 17, 0, 32768, X'dc1293a87cab43024a4eaeb684a0186e33dacfe3'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 18, 0, 32768, X'03df488f642a9614ed718bf149fb7289d124189a'
+  3, 1, 18, 0, 32768, X'03df488f642a9614ed718bf149fb7289d124189a'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 19, 0, 32768, X'46f1426433c57ee44b5593584308f8b7ac414e17'
+  3, 1, 19, 0, 32768, X'46f1426433c57ee44b5593584308f8b7ac414e17'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 20, 0, 32768, X'1a837850cff01cd311948abd611174fa5699804b'
+  3, 1, 20, 0, 32768, X'1a837850cff01cd311948abd611174fa5699804b'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 21, 0, 32768, X'1c15052b28ac97e6e1cd0b4671fe75607c07de02'
+  3, 1, 21, 0, 32768, X'1c15052b28ac97e6e1cd0b4671fe75607c07de02'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 22, 0, 32768, X'1839bc8b6cd9351565a6bacb57f0e35562962cba'
+  3, 1, 22, 0, 32768, X'1839bc8b6cd9351565a6bacb57f0e35562962cba'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 23, 0, 32768, X'f428189580a77b142b3de6cd3c183cb0a24dba6f'
+  3, 1, 23, 0, 32768, X'f428189580a77b142b3de6cd3c183cb0a24dba6f'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 24, 0, 32768, X'f9b7302c9212a5398057ddea9c7506b265c3276f'
+  3, 1, 24, 0, 32768, X'f9b7302c9212a5398057ddea9c7506b265c3276f'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 25, 0, 32768, X'3af5d2929b9606b94b404a45deed9a9d673f49b7'
+  3, 1, 25, 0, 32768, X'3af5d2929b9606b94b404a45deed9a9d673f49b7'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 26, 0, 32768, X'51a7df78bd7a23399b2824ec053f2abe5e4ee049'
+  3, 1, 26, 0, 32768, X'51a7df78bd7a23399b2824ec053f2abe5e4ee049'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 27, 0, 32768, X'2a3675f5efce9151670e9d4ec41e2edf4708d336'
+  3, 1, 27, 0, 32768, X'2a3675f5efce9151670e9d4ec41e2edf4708d336'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 28, 0, 32768, X'a0cc14b4fde29d7251673af434b2ab246e5acf5a'
+  3, 1, 28, 0, 32768, X'a0cc14b4fde29d7251673af434b2ab246e5acf5a'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 29, 0, 32768, X'5932b35ba45894e65d6aa1afbe2101f677e17000'
+  3, 1, 29, 0, 32768, X'5932b35ba45894e65d6aa1afbe2101f677e17000'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 30, 0, 32768, X'ee12ad673d19d8f436ea7832e64935a0ddf9930e'
+  3, 1, 30, 0, 32768, X'ee12ad673d19d8f436ea7832e64935a0ddf9930e'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 31, 0, 32768, X'7bd9b4947ae9b600e6a2d61ead80104d878bb9d2'
+  3, 1, 31, 0, 32768, X'7bd9b4947ae9b600e6a2d61ead80104d878bb9d2'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 32, 0, 32768, X'849c60fc7b366717aea2295a37b341e40626dd28'
+  3, 1, 32, 0, 32768, X'849c60fc7b366717aea2295a37b341e40626dd28'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 33, 0, 32768, X'cdd448834760041cc30edd09f41ae36cbf9459ef'
+  3, 1, 33, 0, 32768, X'cdd448834760041cc30edd09f41ae36cbf9459ef'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 34, 0, 32768, X'9471225809633ae61f2693711cd878ba2ac59ef9'
+  3, 1, 34, 0, 32768, X'9471225809633ae61f2693711cd878ba2ac59ef9'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 35, 0, 32768, X'4aaa26a4d1389b2400138269d3415bb492cc4312'
+  3, 1, 35, 0, 32768, X'4aaa26a4d1389b2400138269d3415bb492cc4312'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 36, 0, 32768, X'a08b0c957c8f741e273e8aa9a88d87b32b860228'
+  3, 1, 36, 0, 32768, X'a08b0c957c8f741e273e8aa9a88d87b32b860228'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 37, 0, 32768, X'7ecbc26a2272256969e4c626998570c7e013be9c'
+  3, 1, 37, 0, 32768, X'7ecbc26a2272256969e4c626998570c7e013be9c'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 38, 0, 32768, X'12dcf52c5a92b64dd5113031379f27b9f42d5c49'
+  3, 1, 38, 0, 32768, X'12dcf52c5a92b64dd5113031379f27b9f42d5c49'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 39, 0, 32768, X'ca1b8cc8e8ee8b209fc7b55656c3f6ac0b8f86fd'
+  3, 1, 39, 0, 32768, X'ca1b8cc8e8ee8b209fc7b55656c3f6ac0b8f86fd'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 40, 0, 32768, X'8566865ae43d19574e85f9f3b6376715ffb3c707'
+  3, 1, 40, 0, 32768, X'8566865ae43d19574e85f9f3b6376715ffb3c707'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 41, 0, 32768, X'39c9fda07d57fc185b37bac70ba1068d6e7c41d3'
+  3, 1, 41, 0, 32768, X'39c9fda07d57fc185b37bac70ba1068d6e7c41d3'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 42, 0, 32768, X'96a2c8b6caf11da5a37b41706217d4e94bb627c0'
+  3, 1, 42, 0, 32768, X'96a2c8b6caf11da5a37b41706217d4e94bb627c0'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 43, 0, 32768, X'6ee8c5a500af82a1fdf42e5122196fad4f2bbc06'
+  3, 1, 43, 0, 32768, X'6ee8c5a500af82a1fdf42e5122196fad4f2bbc06'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 44, 0, 32768, X'd2f71dff59d0ab86d0ada6ea288227602d6cf371'
+  3, 1, 44, 0, 32768, X'd2f71dff59d0ab86d0ada6ea288227602d6cf371'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 45, 0, 32768, X'095c8df0b106947e2c62a4458b13f38c6fc4f982'
+  3, 1, 45, 0, 32768, X'095c8df0b106947e2c62a4458b13f38c6fc4f982'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 46, 0, 32768, X'706071d37157e1030900df60e6efaf897fbab1ec'
+  3, 1, 46, 0, 32768, X'706071d37157e1030900df60e6efaf897fbab1ec'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 47, 0, 32768, X'97f093c5ab5e2baf9b6f1473b631d3db2595fe99'
+  3, 1, 47, 0, 32768, X'97f093c5ab5e2baf9b6f1473b631d3db2595fe99'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 48, 0, 32768, X'c12dd08ffbb4c09e3c282dd7f94cdcc9148ab866'
+  3, 1, 48, 0, 32768, X'c12dd08ffbb4c09e3c282dd7f94cdcc9148ab866'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 49, 0, 32768, X'fb3df3be6d847db26e07eb61312bdc533bda53d2'
+  3, 1, 49, 0, 32768, X'fb3df3be6d847db26e07eb61312bdc533bda53d2'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 50, 0, 32768, X'88195da5656b80c68bd3e131fb673b197281c2b0'
+  3, 1, 50, 0, 32768, X'88195da5656b80c68bd3e131fb673b197281c2b0'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 51, 0, 32768, X'28353744f0fab757b1a870de007b6c8821d4723e'
+  3, 1, 51, 0, 32768, X'28353744f0fab757b1a870de007b6c8821d4723e'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 52, 0, 32768, X'9338b619160d4fb1a844acc95b0556b3d6109a77'
+  3, 1, 52, 0, 32768, X'9338b619160d4fb1a844acc95b0556b3d6109a77'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 53, 0, 32768, X'cd7f42895c6e4f9752f8b34184059d7ad4e5e6ce'
+  3, 1, 53, 0, 32768, X'cd7f42895c6e4f9752f8b34184059d7ad4e5e6ce'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 54, 0, 32768, X'da5611278bf6855a44e5b1b5d62c76822a81674d'
+  3, 1, 54, 0, 32768, X'da5611278bf6855a44e5b1b5d62c76822a81674d'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 55, 0, 32768, X'eb4148c57806114b755416ba96b282fcc99ac2d1'
+  3, 1, 55, 0, 32768, X'eb4148c57806114b755416ba96b282fcc99ac2d1'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 56, 0, 32768, X'5e05f61508a391480dc83f741920a5de059546bc'
+  3, 1, 56, 0, 32768, X'5e05f61508a391480dc83f741920a5de059546bc'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 57, 0, 32768, X'a23b279883915b0dc3313081924366ea5e75bdc1'
+  3, 1, 57, 0, 32768, X'a23b279883915b0dc3313081924366ea5e75bdc1'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 58, 2, 32768, X'ef7511b5248557ae637f46b552f8af59020f2b00'
+  3, 1, 58, 2, 32768, X'ef7511b5248557ae637f46b552f8af59020f2b00'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 59, 2, 32768, X'6240c588a2d7740f5c2c9523bff7d98334998d77'
+  3, 1, 59, 2, 32768, X'6240c588a2d7740f5c2c9523bff7d98334998d77'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 60, 2, 32768, X'808ce28868d844d547e0c2cc4271c14be2a568b6'
+  3, 1, 60, 2, 32768, X'808ce28868d844d547e0c2cc4271c14be2a568b6'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 61, 2, 32768, X'd736a206033ecbefc09e909f0d2d72c38d49d50b'
+  3, 1, 61, 2, 32768, X'd736a206033ecbefc09e909f0d2d72c38d49d50b'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 62, 2, 32768, X'387a7087c3159f7d0a6388d722c200a599b4703b'
+  3, 1, 62, 2, 32768, X'387a7087c3159f7d0a6388d722c200a599b4703b'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 63, 2, 32768, X'b6a679dda488042eee3cf9a525a9ae88b9514229'
+  3, 1, 63, 2, 32768, X'b6a679dda488042eee3cf9a525a9ae88b9514229'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 64, 2, 32768, X'693b89dc96682f85b389208ec052f4853fd971eb'
+  3, 1, 64, 2, 32768, X'693b89dc96682f85b389208ec052f4853fd971eb'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 65, 2, 32768, X'e4b83a6888c69eeb1c65c7ff50ee39897ca51008'
+  3, 1, 65, 2, 32768, X'e4b83a6888c69eeb1c65c7ff50ee39897ca51008'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 66, 2, 32768, X'9e0735ad94f4d10faa43f75d02c4edb9b7eb91d4'
+  3, 1, 66, 2, 32768, X'9e0735ad94f4d10faa43f75d02c4edb9b7eb91d4'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 67, 2, 32768, X'881dd3cb2f1f0e3323bf8c5586dfaba2ffcb1a55'
+  3, 1, 67, 2, 32768, X'881dd3cb2f1f0e3323bf8c5586dfaba2ffcb1a55'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 68, 2, 32768, X'6461d3771999c3a4b3c15bf4e38da30b91bc1b17'
+  3, 1, 68, 2, 32768, X'6461d3771999c3a4b3c15bf4e38da30b91bc1b17'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 69, 6, 32768, X'fcad787f7771637d659638d92b5eee9385b3d7b9'
+  3, 1, 69, 6, 32768, X'fcad787f7771637d659638d92b5eee9385b3d7b9'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 70, 0, 32768, X'4b90d9178efc5cf9a9ddf4f8bcc49008785d76ec'
+  3, 1, 70, 0, 32768, X'4b90d9178efc5cf9a9ddf4f8bcc49008785d76ec'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 71, 2, 32768, X'e79e468b1921b2293a80c5917efa6a45c379e810'
+  3, 1, 71, 2, 32768, X'e79e468b1921b2293a80c5917efa6a45c379e810'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 72, 2, 32768, X'be1bdec0aa74b4dcb079943e70528096cca985f8'
+  3, 1, 72, 2, 32768, X'be1bdec0aa74b4dcb079943e70528096cca985f8'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 73, 2, 32768, X'bc3a1d50aaffa207d2e6645228bb4f1cd40c88e0'
+  3, 1, 73, 2, 32768, X'bc3a1d50aaffa207d2e6645228bb4f1cd40c88e0'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 74, 2, 32768, X'96ea8b0ccfb43fa6da4e98d8f51609cf8eabd91e'
+  3, 1, 74, 2, 32768, X'96ea8b0ccfb43fa6da4e98d8f51609cf8eabd91e'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 75, 2, 32768, X'd05ef7250cc103540601fb8956c89c3ba1f47a4e'
+  3, 1, 75, 2, 32768, X'd05ef7250cc103540601fb8956c89c3ba1f47a4e'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 76, 2, 32768, X'd5c28da6b58a66fba125e99c6b6d0e36a1b18315'
+  3, 1, 76, 2, 32768, X'd5c28da6b58a66fba125e99c6b6d0e36a1b18315'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 77, 2, 32768, X'0ba611dd45de9acbe3d0da0d2e478e4aa77ff515'
+  3, 1, 77, 2, 32768, X'0ba611dd45de9acbe3d0da0d2e478e4aa77ff515'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 78, 4, 32768, X'9b4d80cfefc7d5576c4d9f224872505896ef2798'
+  3, 1, 78, 4, 32768, X'9b4d80cfefc7d5576c4d9f224872505896ef2798'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 79, 2, 32768, X'e79e468b1921b2293a80c5917efa6a45c379e810'
+  3, 1, 79, 2, 32768, X'e79e468b1921b2293a80c5917efa6a45c379e810'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 80, 2, 32768, X'be1bdec0aa74b4dcb079943e70528096cca985f8'
+  3, 1, 80, 2, 32768, X'be1bdec0aa74b4dcb079943e70528096cca985f8'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 81, 2, 32768, X'e79e468b1921b2293a80c5917efa6a45c379e810'
+  3, 1, 81, 2, 32768, X'e79e468b1921b2293a80c5917efa6a45c379e810'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 82, 2, 32768, X'be1bdec0aa74b4dcb079943e70528096cca985f8'
+  3, 1, 82, 2, 32768, X'be1bdec0aa74b4dcb079943e70528096cca985f8'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 83, 1, 32768, X'230b3bf13c752834decf47f5a86a75582abee51c'
+  3, 1, 83, 1, 32768, X'230b3bf13c752834decf47f5a86a75582abee51c'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 84, 1, 32768, X'61f59f7782bb39610dbb6b1f57033c161810a267'
+  3, 1, 84, 1, 32768, X'61f59f7782bb39610dbb6b1f57033c161810a267'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 85, 1, 32768, X'c744cac6af7621524fc3a2b0a9a135a32b33c81b'
+  3, 1, 85, 1, 32768, X'c744cac6af7621524fc3a2b0a9a135a32b33c81b'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 86, 1, 32768, X'8a7532af1862f9f61ed08d2b92b82a2ecc99c54f'
+  3, 1, 86, 1, 32768, X'8a7532af1862f9f61ed08d2b92b82a2ecc99c54f'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 87, 1, 32768, X'ba8fa710d303b3b2a594cba1cb73797c970ffa0b'
+  3, 1, 87, 1, 32768, X'ba8fa710d303b3b2a594cba1cb73797c970ffa0b'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 88, 1, 32768, X'a46c5c8b58e67fbe9d3203bae335c0e39f68eff9'
+  3, 1, 88, 1, 32768, X'a46c5c8b58e67fbe9d3203bae335c0e39f68eff9'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 89, 1, 32768, X'67476198f63603b84afa235970611cd614560cf2'
+  3, 1, 89, 1, 32768, X'67476198f63603b84afa235970611cd614560cf2'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 90, 2, 32768, X'cdf4d79ac0a10d46a1d9d7ec9642883c71f77fc7'
+  3, 1, 90, 2, 32768, X'cdf4d79ac0a10d46a1d9d7ec9642883c71f77fc7'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 91, 2, 32768, X'436067385bf6cd43e2f65f8d70d264af8fca876d'
+  3, 1, 91, 2, 32768, X'436067385bf6cd43e2f65f8d70d264af8fca876d'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 92, 2, 32768, X'4916c4e9f1e91b34bd8acef1f827f0b444bdb858'
+  3, 1, 92, 2, 32768, X'4916c4e9f1e91b34bd8acef1f827f0b444bdb858'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 93, 2, 32768, X'c66007c47ea62816006d220bbb8fc9d5681c4cc6'
+  3, 1, 93, 2, 32768, X'c66007c47ea62816006d220bbb8fc9d5681c4cc6'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 94, 2, 32768, X'85782c59534d3915298da3da35101891a84be99e'
+  3, 1, 94, 2, 32768, X'85782c59534d3915298da3da35101891a84be99e'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 95, 2, 32768, X'335f1897c44fef511bed7eb4394375bc2a36dbc3'
+  3, 1, 95, 2, 32768, X'335f1897c44fef511bed7eb4394375bc2a36dbc3'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 96, 2, 32768, X'82ca255a4c2655eca1516b4249dcdd1edb892eef'
+  3, 1, 96, 2, 32768, X'82ca255a4c2655eca1516b4249dcdd1edb892eef'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 97, 2, 32768, X'1086445009abbad955b9e915be04ac9afc74567d'
+  3, 1, 97, 2, 32768, X'1086445009abbad955b9e915be04ac9afc74567d'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 98, 2, 32768, X'18fe7ae42869e2b3b11bf67215ef4f1c2e260251'
+  3, 1, 98, 2, 32768, X'18fe7ae42869e2b3b11bf67215ef4f1c2e260251'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 99, 2, 32768, X'061efe921cad309990e63ed35a7b833e2eabfd2f'
+  3, 1, 99, 2, 32768, X'061efe921cad309990e63ed35a7b833e2eabfd2f'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 100, 2, 32768, X'aab5803005883807e91538fdc71968edf81f367c'
+  3, 1, 100, 2, 32768, X'aab5803005883807e91538fdc71968edf81f367c'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 101, 2, 32768, X'aab5803005883807e91538fdc71968edf81f367c'
+  3, 1, 101, 2, 32768, X'aab5803005883807e91538fdc71968edf81f367c'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 102, 2, 32768, X'0ba199b3cd6991a884fe30f40e89d3d603aa5cbd'
+  3, 1, 102, 2, 32768, X'0ba199b3cd6991a884fe30f40e89d3d603aa5cbd'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 103, 2, 32768, X'0ba199b3cd6991a884fe30f40e89d3d603aa5cbd'
+  3, 1, 103, 2, 32768, X'0ba199b3cd6991a884fe30f40e89d3d603aa5cbd'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 104, 2, 32768, X'2a5aa44e77a223d701a53b0f9af6d13cf8443b2a'
+  3, 1, 104, 2, 32768, X'2a5aa44e77a223d701a53b0f9af6d13cf8443b2a'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 105, 2, 32768, X'2a5aa44e77a223d701a53b0f9af6d13cf8443b2a'
+  3, 1, 105, 2, 32768, X'2a5aa44e77a223d701a53b0f9af6d13cf8443b2a'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 106, 2, 32768, X'c32ab71e81421207255b2665316a9049ddff3653'
+  3, 1, 106, 2, 32768, X'c32ab71e81421207255b2665316a9049ddff3653'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 107, 2, 32768, X'c32ab71e81421207255b2665316a9049ddff3653'
+  3, 1, 107, 2, 32768, X'c32ab71e81421207255b2665316a9049ddff3653'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 108, 2, 32768, X'cafaeff88886bf0d07b0a6527341da22c08b609d'
+  3, 1, 108, 2, 32768, X'cafaeff88886bf0d07b0a6527341da22c08b609d'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 109, 2, 32768, X'cafaeff88886bf0d07b0a6527341da22c08b609d'
+  3, 1, 109, 2, 32768, X'cafaeff88886bf0d07b0a6527341da22c08b609d'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 110, 2, 32768, X'68d74b6eacdc3360615744c6aaddb357df9bdbec'
+  3, 1, 110, 2, 32768, X'68d74b6eacdc3360615744c6aaddb357df9bdbec'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 111, 2, 32768, X'68d74b6eacdc3360615744c6aaddb357df9bdbec'
+  3, 1, 111, 2, 32768, X'68d74b6eacdc3360615744c6aaddb357df9bdbec'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 112, 2, 32768, X'ac254b04f277ca7e887a4141bf5ed0cf62600d10'
+  3, 1, 112, 2, 32768, X'ac254b04f277ca7e887a4141bf5ed0cf62600d10'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 113, 2, 32768, X'ac254b04f277ca7e887a4141bf5ed0cf62600d10'
+  3, 1, 113, 2, 32768, X'ac254b04f277ca7e887a4141bf5ed0cf62600d10'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 114, 1, 32768, X'4f135c9ee49ca7fbfea079e5d6714802f0405407'
+  3, 1, 114, 1, 32768, X'4f135c9ee49ca7fbfea079e5d6714802f0405407'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 115, 0, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 115, 0, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 116, 1, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 116, 1, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 117, 2, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 117, 2, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 118, 3, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 118, 3, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 119, 4, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 119, 4, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 120, 5, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 120, 5, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 121, 6, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 121, 6, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 122, 7, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
+  3, 1, 122, 7, 32768, X'9069ca78e7450a285173431b3e52c5c25299e473'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 123, 4, 32768, X'c1e25c3f6b0dc78d57296aa2870ca6f782ccf80f'
+  3, 1, 123, 4, 32768, X'c1e25c3f6b0dc78d57296aa2870ca6f782ccf80f'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 124, 4, 32768, X'67a0a98bc4d6321142895a4d938b342f6959c1a9'
+  3, 1, 124, 4, 32768, X'67a0a98bc4d6321142895a4d938b342f6959c1a9'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 125, 4, 32768, X'06d60b3a0dee9bb9beb2f0b04aff2e75bd1d2860'
+  3, 1, 125, 4, 32768, X'06d60b3a0dee9bb9beb2f0b04aff2e75bd1d2860'
 );
 
 INSERT INTO component_hashes (
-  component, product, seq_no, pcr, algo, hash
+  component, key, seq_no, pcr, algo, hash
 ) VALUES (
-  3, 7, 126, 5, 32768, X'1b87003b6c7d90483713c90100cca3e62392b9bc'
+  3, 1, 126, 5, 32768, X'1b87003b6c7d90483713c90100cca3e62392b9bc'
 );
 
index fb04ee0..c2447cd 100644 (file)
@@ -210,9 +210,9 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                {
                        tcg_pts_attr_req_func_comp_evid_t *attr_cast;
                        enumerator_t *enumerator;
-                       char *platform_info;
                        pts_component_t *comp;
                        pts_comp_func_name_t *comp_name;
+                       chunk_t keyid;
                        int vid, name, qualifier;
                        u_int8_t flags;
                        u_int32_t depth;
@@ -221,18 +221,17 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_END);
 
-                       /* Get Platform and OS of the PTS-IMC */
-                       platform_info = pts->get_platform_info(pts);
-                       if (!pts_db || !platform_info)
+                       if (!pts->get_aik_keyid(pts, &keyid))
                        {
-                               DBG1(DBG_IMV, "%s%s%s not available",
-                                       (pts_db) ? "" : "pts database",
-                                       (!pts_db && !platform_info) ? "and" : "",
-                                       (platform_info) ? "" : "platform info");
+                               break;
+                       }
+                       if (!pts_db)
+                       {
+                               DBG1(DBG_PTS, "pts database not available");
                                break;
                        }
                        
-                       enumerator = pts_db->create_comp_evid_enumerator(pts_db, platform_info);
+                       enumerator = pts_db->create_comp_evid_enumerator(pts_db, keyid);
                        if (!enumerator)
                        {
                                break;
index 5fa7612..a50810b 100644 (file)
@@ -146,6 +146,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                {
                        tcg_pts_attr_aik_t *attr_cast;
                        certificate_t *aik, *issuer;
+                       public_key_t *public;
+                       chunk_t keyid;
                        enumerator_t *e;
                        bool trusted = FALSE;
 
@@ -158,7 +160,11 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        }
                        if (aik->get_type(aik) == CERT_X509)
                        {
-                               DBG1(DBG_IMV, "verifying AIK certificate");
+                               public = aik->get_public_key(aik);
+                               public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid);
+                               DBG1(DBG_IMV, "verifying AIK certificate with keyid %#B", &keyid);
+                               public->destroy(public);
+
                                e = pts_credmgr->create_trusted_enumerator(pts_credmgr,
                                                        KEY_ANY, aik->get_issuer(aik), FALSE);
                                while (e->enumerate(e, &issuer))
@@ -285,8 +291,10 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                default:
                                case FAILED:
                                        attestation_state->set_measurement_error(attestation_state);
-                                       /* fall through to next case */
+                                       comp->destroy(comp);
+                                       break;
                                case SUCCESS:
+                                       name->log(name, "  successfully measured ");
                                        comp->destroy(comp);
                                        break;
                                case NEED_MORE:
index 564914e..703557a 100644 (file)
@@ -7,14 +7,6 @@ CREATE TABLE files (
   path TEXT NOT NULL
 );
 
-DROP TABLE IF EXISTS components;
-CREATE TABLE components (
-  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-  vendor_id INTEGER NOT NULL,
-  name INTEGER NOT NULL,
-  qualifier INTEGER DEFAULT 0
-);
-
 DROP TABLE IF EXISTS products;
 CREATE TABLE products (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
@@ -34,15 +26,6 @@ CREATE TABLE product_file (
   PRIMARY KEY (product, file)
 );
 
-DROP TABLE IF EXISTS product_component;
-CREATE TABLE product_component (
-  product INTEGER NOT NULL,
-  component INTEGER NOT NULL,
-  depth INTEGER DEFAULT 0,
-  seq_no INTEGER DEFAULT 0,
-  PRIMARY KEY (product, component)
-);
-
 DROP TABLE IF EXISTS file_hashes;
 CREATE TABLE file_hashes (
   file INTEGER NOT NULL,
@@ -53,13 +36,47 @@ CREATE TABLE file_hashes (
   PRIMARY KEY(file, directory, product, algo)
 );
 
+DROP TABLE IF EXISTS keys;
+CREATE TABLE keys (
+  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  keyid BLOB NOT NULL,
+  owner TEXT NOT NULL
+);
+DROP INDEX IF EXISTS keys_keyid;
+CREATE INDEX keys_keyid ON keys (
+  keyid
+);
+DROP INDEX IF EXISTS keys_owner;
+CREATE INDEX keys_owner ON keys (
+  owner
+);
+
+DROP TABLE IF EXISTS components;
+CREATE TABLE components (
+  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  vendor_id INTEGER NOT NULL,
+  name INTEGER NOT NULL,
+  qualifier INTEGER DEFAULT 0
+);
+
+
+DROP TABLE IF EXISTS key_component;
+CREATE TABLE key_component (
+  key INTEGER NOT NULL,
+  component INTEGER NOT NULL,
+  depth INTEGER DEFAULT 0,
+  seq_no INTEGER DEFAULT 0,
+  PRIMARY KEY (key, component)
+);
+
+
 DROP TABLE IF EXISTS component_hashes;
 CREATE TABLE component_hashes (
   component INTEGER NOT NULL,
-  product INTEGER NOT NULL,
+  key INTEGER NOT NULL,
   seq_no INTEGER NOT NULL,
   pcr INTEGER NOT NULL,
   algo INTEGER NOT NULL,
   hash BLOB NOT NULL,
-  PRIMARY KEY(component, product, seq_no, algo)
+  PRIMARY KEY(component, key, seq_no, algo)
 );
index a05dc7e..808a595 100644 (file)
@@ -17,6 +17,7 @@
 #include "ita_comp_ima.h"
 #include "ita_comp_func_name.h"
 
+#include "libpts.h"
 #include "pts/components/pts_component.h"
 
 #include <debug.h>
@@ -31,7 +32,6 @@
 #define IMA_SECURITY_DIR                       "/sys/kernel/security/tpm0/"
 #define IMA_BIOS_MEASUREMENT_PATH      IMA_SECURITY_DIR "binary_bios_measurements"
 #define IMA_PCR_MAX                                    8
-#define IMA_SEQUENCE                           126
 
 typedef struct pts_ita_comp_ima_t pts_ita_comp_ima_t;
 
@@ -57,6 +57,11 @@ struct pts_ita_comp_ima_t {
        u_int32_t depth;
 
        /**
+        * AIK keyid
+        */
+       chunk_t keyid;
+
+       /**
      * IMA BIOS measurement time
         */
        time_t bios_measurement_time;
@@ -67,6 +72,11 @@ struct pts_ita_comp_ima_t {
        linked_list_t *list;
 
        /**
+        * Expected measurement count
+        */
+       int count;
+
+       /**
         * Measurement sequence number
         */
        int seq_no;
@@ -247,27 +257,50 @@ METHOD(pts_component_t, verify, status_t,
        pts_comp_evidence_t *evidence)
 {
        bool has_pcr_info;
-       char *platform_info;
-       u_int32_t extended_pcr;
+       u_int32_t extended_pcr, vid, name;
+       enum_name_t *names;
        pts_meas_algorithms_t algo;
        pts_pcr_transform_t transform;
        time_t measurement_time;
        chunk_t measurement, pcr_before, pcr_after;
 
-       platform_info = pts->get_platform_info(pts);
-       if (!pts_db || !platform_info)
-       {
-               DBG1(DBG_PTS, "%s%s%s not available",
-                                         (pts_db) ? "" : "pts database",
-                                         (!pts_db && !platform_info) ? "and" : "",
-                                         (platform_info) ? "" : "platform info");
-               return FAILED;
-       }
        measurement = evidence->get_measurement(evidence, &extended_pcr,
                                                                        &algo, &transform, &measurement_time);
 
+       if (!this->keyid.ptr)
+       {
+               if (!pts->get_aik_keyid(pts, &this->keyid))
+               {
+                       return FAILED;
+               }
+               this->keyid = chunk_clone(this->keyid);
+
+               if (!pts_db)
+               {
+                       DBG1(DBG_PTS, "pts database not available");
+                       return FAILED;
+               }
+               if (!pts_db->get_comp_measurement_count(pts_db, this->name, this->keyid,
+                                                                                               algo, &this->count))
+               {
+                       return FAILED;
+               }
+               vid = this->name->get_vendor_id(this->name);
+               name = this->name->get_name(this->name);
+               names = pts_components->get_comp_func_names(pts_components, vid);
+
+               if (this->count == 0)
+               {
+                       DBG1(DBG_PTS, "no %N '%N' functional component evidence measurements "
+                                                 "available", pen_names, vid, names, name);
+                       return FAILED;
+               }
+               DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence measurements",
+                                         this->count, pen_names, vid, names, name);
+               }
+
        if (pts_db->check_comp_measurement(pts_db, measurement, this->name,
-                       platform_info, ++this->seq_no, extended_pcr, algo) != SUCCESS)
+                               this->keyid, ++this->seq_no, extended_pcr, algo) != SUCCESS)
        {
                return FAILED;
        }
@@ -281,7 +314,7 @@ METHOD(pts_component_t, verify, status_t,
                }
        }
 
-       return (this->seq_no < IMA_SEQUENCE) ? NEED_MORE : SUCCESS;
+       return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
 }
 
 METHOD(pts_component_t, destroy, void,
@@ -295,6 +328,7 @@ METHOD(pts_component_t, destroy, void,
        }
        this->list->destroy_function(this->list, (void *)free_entry);
        this->name->destroy(this->name);
+       free(this->keyid.ptr);
        free(this);
 }
 
index 572828a..67ad2d4 100644 (file)
 #include "ita_comp_tboot.h"
 #include "ita_comp_func_name.h"
 
+#include "libpts.h"
 #include "pts/components/pts_component.h"
-#include "pts/components/pts_comp_evidence.h"
 
 #include <debug.h>
 #include <pen/pen.h>
 
-#define TBOOT_SEQUENCE         2
-
 typedef struct pts_ita_comp_tboot_t pts_ita_comp_tboot_t;
 
 /**
@@ -49,11 +47,21 @@ struct pts_ita_comp_tboot_t {
        u_int32_t depth;
 
        /**
+        * AIK keyid
+        */
+       chunk_t keyid;
+
+       /**
         * Time of TBOOT measurement
         */
        time_t measurement_time;
 
        /**
+        * Expected measurement count
+        */
+       int count;
+
+       /**
         * Measurement sequence number
         */
        int seq_no;
@@ -144,7 +152,7 @@ METHOD(pts_component_t, measure, status_t,
                                                                this->measurement_time, measurement);
        evid->set_pcr_info(evid, pcr_before, pcr_after);
 
-       return (this->seq_no < TBOOT_SEQUENCE) ? NEED_MORE : SUCCESS;
+       return (this->seq_no < 2) ? NEED_MORE : SUCCESS;
 }
 
 METHOD(pts_component_t, verify, status_t,
@@ -152,27 +160,50 @@ METHOD(pts_component_t, verify, status_t,
        pts_comp_evidence_t *evidence)
 {
        bool has_pcr_info;
-       char *platform_info;
-       u_int32_t extended_pcr;
+       u_int32_t extended_pcr, vid, name;
+       enum_name_t *names;
        pts_meas_algorithms_t algo;
        pts_pcr_transform_t transform;
        time_t measurement_time;
-       chunk_t measurement, pcr_before, pcr_after, hash;
+       chunk_t measurement, pcr_before, pcr_after;
 
-       platform_info = pts->get_platform_info(pts);
-       if (!pts_db || !platform_info)
-       {
-               DBG1(DBG_PTS, "%s%s%s not available",
-                                         (pts_db) ? "" : "pts database",
-                                         (!pts_db && !platform_info) ? "and" : "",
-                                         (platform_info) ? "" : "platform info");
-               return FAILED;
-       }
        measurement = evidence->get_measurement(evidence, &extended_pcr,
                                                                &algo, &transform, &measurement_time);
 
+       if (!this->keyid.ptr)
+       {
+               if (!pts->get_aik_keyid(pts, &this->keyid))
+               {
+                       return FAILED;
+               }
+               this->keyid = chunk_clone(this->keyid);
+
+               if (!pts_db)
+               {
+                       DBG1(DBG_PTS, "pts database not available");
+                       return FAILED;
+               }
+               if (!pts_db->get_comp_measurement_count(pts_db, this->name, this->keyid,
+                                                                                               algo, &this->count))
+               {
+                       return FAILED;
+               }
+               vid = this->name->get_vendor_id(this->name);
+               name = this->name->get_name(this->name);
+               names = pts_components->get_comp_func_names(pts_components, vid);
+
+               if (this->count == 0)
+               {
+                       DBG1(DBG_PTS, "no %N '%N' functional component evidence measurements "
+                                                 "available", pen_names, vid, names, name);
+                       return FAILED;
+               }
+               DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence measurements",
+                                         this->count, pen_names, vid, names, name);
+               }
+
        if (pts_db->check_comp_measurement(pts_db, measurement, this->name,
-                       platform_info,  ++this->seq_no, extended_pcr, algo) != SUCCESS)
+                       this->keyid, ++this->seq_no, extended_pcr, algo) != SUCCESS)
        {
                return FAILED;
        }
@@ -186,13 +217,14 @@ METHOD(pts_component_t, verify, status_t,
                }
        }
 
-       return (this->seq_no < TBOOT_SEQUENCE) ? NEED_MORE : SUCCESS;
+       return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
 }
 
 METHOD(pts_component_t, destroy, void,
           pts_ita_comp_tboot_t *this)
 {
        this->name->destroy(this->name);
+       free(this->keyid.ptr);
        free(this);
 }
 
index bf5c2bc..c30a557 100644 (file)
@@ -459,6 +459,33 @@ METHOD(pts_t, set_aik, void,
        this->aik = aik->get_ref(aik);
 }
 
+METHOD(pts_t, get_aik_keyid, bool,
+       private_pts_t *this, chunk_t *keyid)
+{
+       public_key_t *public;
+       bool success;
+
+       if (!this->aik)
+       {
+               DBG1(DBG_PTS, "no AIK certificate available");
+               return FALSE;
+       }
+       public = this->aik->get_public_key(this->aik);
+       if (!public)
+       {
+               DBG1(DBG_PTS, "no AIK public key available");
+               return FALSE;
+       }
+       success = public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, keyid);
+       if (!success)
+       {
+               DBG1(DBG_PTS, "no SHA-1 AIK public key info ID available");
+       }
+       public->destroy(public);
+
+       return success;
+}
+
 METHOD(pts_t, hash_file, bool,
        private_pts_t *this, hasher_t *hasher, char *pathname, u_char *hash)
 {
@@ -932,7 +959,6 @@ METHOD(pts_t, quote_tpm, bool,
                }               
                if (this->pcr_select[i] & f)
                {
-                       DBG2(DBG_TNC, "PCR %02d selected for TPM Quote", pcr);
                        result = use_quote2 ?
                                        Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcr,
                                                                                                TSS_PCRS_DIRECTION_RELEASE) :
@@ -1510,6 +1536,7 @@ pts_t *pts_create(bool is_imc)
                        .get_pcr_len = _get_pcr_len,
                        .get_aik = _get_aik,
                        .set_aik = _set_aik,
+                       .get_aik_keyid = _get_aik_keyid,
                        .is_path_valid = _is_path_valid,
                        .hash_file = _hash_file,
                        .do_measurements = _do_measurements,
index 3a40c1e..327b1a1 100644 (file)
@@ -246,6 +246,14 @@ struct pts_t {
        void (*set_aik)(pts_t *this, certificate_t *aik);
 
        /**
+        * Get SHA-1 Attestation Identity Public Key Info ID
+        *
+        * @param keyid                         AIK ID
+        * @return                                      TRUE if AIK ID exists
+        */
+       bool (*get_aik_keyid)(pts_t *this, chunk_t *keyid);
+
+       /**
         * Check whether path is valid file/directory on filesystem
         *
         * @param path                          Absolute path
index cb2d104..d91a408 100644 (file)
@@ -69,23 +69,6 @@ METHOD(pts_database_t, create_file_meta_enumerator, enumerator_t*,
        return e;
 }
 
-METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*,
-       private_pts_database_t *this, char *product)
-{
-       enumerator_t *e;
-
-       /* look for all entries belonging to a product in the components table */
-       e = this->db->query(this->db,
-                               "SELECT c.vendor_id, c.name, c.qualifier, pc.depth "
-                               "FROM components AS c "
-                               "JOIN product_component AS pc ON c.id = pc.component "
-                               "JOIN products AS p ON p.id = pc.product "
-                               "WHERE p.name = ? ORDER BY pc.seq_no",
-                               DB_TEXT, product, DB_INT, DB_INT, DB_INT, DB_INT);
-       return e;
-}
-
-
 METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
        private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
        int id, bool is_dir)
@@ -114,9 +97,25 @@ METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
        return e;
 }
 
+METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*,
+       private_pts_database_t *this, chunk_t keyid)
+{
+       enumerator_t *e;
+
+       /* look for all entries belonging to a product in the components table */
+       e = this->db->query(this->db,
+                               "SELECT c.vendor_id, c.name, c.qualifier, kc.depth "
+                               "FROM components AS c "
+                               "JOIN key_component AS kc ON c.id = kc.component "
+                               "JOIN keys AS k ON k.id = kc.key "
+                               "WHERE k.keyid = ? ORDER BY kc.seq_no",
+                               DB_BLOB, keyid, DB_INT, DB_INT, DB_INT, DB_INT);
+       return e;
+}
+
 METHOD(pts_database_t, check_comp_measurement, status_t,
        private_pts_database_t *this, chunk_t measurement,
-       pts_comp_func_name_t *comp_name,  char *product,
+       pts_comp_func_name_t *comp_name, chunk_t keyid,
        int seq_no, int pcr, pts_meas_algorithms_t algo)
 {
        enumerator_t *e;
@@ -125,14 +124,14 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
        
        e = this->db->query(this->db,
                        "SELECT ch.hash FROM component_hashes AS ch "
-                       "JOIN products AS p ON ch.product = p.id "
+                       "JOIN keys AS k ON ch.key = k.id "
                        "JOIN components AS c ON ch.component = c.id "
                        "WHERE c.vendor_id = ?  AND c.name = ? AND c.qualifier = ? "
-                       "AND p.name = ? AND ch.seq_no = ? AND ch.pcr = ? AND ch.algo = ? ",
+                       "AND k.keyid = ? AND ch.seq_no = ? AND ch.pcr = ? AND ch.algo = ? ",
                        DB_INT, comp_name->get_vendor_id(comp_name),
                        DB_INT, comp_name->get_name(comp_name),
                        DB_INT, comp_name->get_qualifier(comp_name),
-                       DB_TEXT, product, DB_INT, seq_no, DB_INT, pcr, DB_INT, algo,
+                       DB_BLOB, keyid, DB_INT, seq_no, DB_INT, pcr, DB_INT, algo,
                        DB_BLOB);
        if (!e)
        {
@@ -144,8 +143,6 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
        {
                if (chunk_equals(hash, measurement))
                {
-                       DBG2(DBG_PTS, "PCR %2d matching component measurement #%d "
-                                                 "found in database", pcr, seq_no);
                        status = SUCCESS;
                        break;
                }
@@ -170,6 +167,58 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
        return status;
 }
 
+METHOD(pts_database_t, get_comp_measurement_count, bool,
+       private_pts_database_t *this, pts_comp_func_name_t *comp_name,
+       chunk_t keyid, pts_meas_algorithms_t algo, int *count)
+{
+       enumerator_t *e;
+       int kid;
+       bool success = TRUE;
+
+       /* Initialize count */
+       *count = 0;
+
+       /* Is the AIK registered? */
+       e = this->db->query(this->db,
+                       "SELECT id FROM keys WHERE keyid = ?", DB_BLOB, keyid, DB_INT);
+       if (!e)
+       {
+               DBG1(DBG_PTS, "no database query enumerator returned");
+               return FALSE;
+       }
+       if (!e->enumerate(e, &kid))
+       {
+               DBG1(DBG_PTS, "AIK %#B is not registered in database", &keyid);
+               e->destroy(e);
+               return FALSE;
+       }
+       e->destroy(e);
+
+       /* Get the number of stored measurements for a given AIK and component */
+       e = this->db->query(this->db,
+                       "SELECT COUNT(*) FROM component_hashes AS ch "
+                       "JOIN components AS c ON ch.component = c.id "
+                       "WHERE c.vendor_id = ?  AND c.name = ? AND c.qualifier = ? "
+                       "AND ch.key = ? AND ch.algo = ? ",
+                       DB_INT, comp_name->get_vendor_id(comp_name),
+                       DB_INT, comp_name->get_name(comp_name),
+                       DB_INT, comp_name->get_qualifier(comp_name),
+                       DB_INT, kid, DB_INT, algo, DB_INT);
+       if (!e)
+       {
+               DBG1(DBG_PTS, "no database query enumerator returned");
+               return FALSE;
+       }
+       if (!e->enumerate(e, count))
+       {
+               DBG1(DBG_PTS, "no component measurement count returned from database");
+               success = FALSE;
+       }
+       e->destroy(e);
+
+       return success;
+}
+
 METHOD(pts_database_t, destroy, void,
        private_pts_database_t *this)
 {
@@ -191,6 +240,7 @@ pts_database_t *pts_database_create(char *uri)
                        .create_comp_evid_enumerator = _create_comp_evid_enumerator,
                        .create_file_hash_enumerator = _create_file_hash_enumerator,
                        .check_comp_measurement = _check_comp_measurement,
+                       .get_comp_measurement_count = _get_comp_measurement_count,
                        .destroy = _destroy,
                },
                .db = lib->db->create(lib->db, uri),
index 3ed0b5b..61c00a1 100644 (file)
@@ -52,15 +52,6 @@ struct pts_database_t {
                                                                                                 char *product);
 
        /**
-       * Get functional components to request evidence of
-       *
-       * @param product                Software product (os, vpn client, etc.)
-       * @return                               Enumerator over all matching components
-       */
-       enumerator_t* (*create_comp_evid_enumerator)(pts_database_t *this,
-                                                                                                char *product);
-
-       /**
        * Get stored measurement hash for single file or directory entries
        *
        * @param product                Software product (os, vpn client, etc.)
@@ -74,21 +65,42 @@ struct pts_database_t {
                                                                int id, bool is_dir);
 
        /**
+       * Get functional components to request evidence of
+       *
+       * @param keyid                  SHA-1 hash of AIK public key info
+       * @return                               Enumerator over all matching components
+       */
+       enumerator_t* (*create_comp_evid_enumerator)(pts_database_t *this,
+                                                                                                chunk_t keyid);
+
+       /**
        * Check a functional component measurement against value stored in database
        *
        * @param measurement    measurement hash
        * @param comp_name              Component Functional Name
-       * @param product                Software product (os, vpn client, etc.)
+       * @param keyid                  SHA-1 hash of AIK public key info
        * @param seq_no                 Measurement sequence number
        * @param prc                    Number of the PCR the measurement was extended into
        * @param algo                   Hash algorithm used for measurement
        * @return                               return code
        */
        status_t (*check_comp_measurement)(pts_database_t *this, chunk_t measurement,
-                                                       pts_comp_func_name_t *comp_name, char *product,
+                                                       pts_comp_func_name_t *comp_name, chunk_t keyid,
                                                        int seq_no, int pcr, pts_meas_algorithms_t algo);
 
        /**
+       * Get the number of measurements for a functional component and AIK
+       *
+       * @param comp_name              Component Functional Name
+       * @param keyid                  SHA-1 hash of AIK public key info
+       * @param algo                   Hash algorithm used for measurement
+       * @return                               measurement count
+       */
+       bool (*get_comp_measurement_count)(pts_database_t *this,
+                                                       pts_comp_func_name_t *comp_name, chunk_t keyid,
+                                                       pts_meas_algorithms_t algo, int *count);
+
+       /**
        * Destroys a pts_database_t object.
        */
        void (*destroy)(pts_database_t *this);