libimcv: Update database to ISO 19770-2:2015 SWID standard
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 31 Mar 2017 11:12:57 +0000 (13:12 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 8 Jul 2017 21:19:51 +0000 (23:19 +0200)
src/libimcv/imv/data.sql
src/libimcv/imv/tables.sql
src/libimcv/plugins/imv_attestation/attest_db.c
src/libimcv/plugins/imv_attestation/attest_usage.c
src/libimcv/pts/components/ita/ita_comp_ima.c
src/libimcv/pts/pts_database.c

index fb0db91..a872499 100644 (file)
@@ -652,114 +652,120 @@ INSERT INTO algorithms (
   8192, 'SHA384'
 );
 
+INSERT INTO algorithms (
+  id, name
+) VALUES (
+  4096, 'SHA512'
+);
+
 /* File Hashes */
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 2, 32768, X'6c6f8e12f6cbfba612e780374c4cdcd40f20968a'
+  2, 2, 32768, '6c6f8e12f6cbfba612e780374c4cdcd40f20968a'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 2, 16384, X'dbcecd19d59310183cf5c31ddee29e8d7bec64d3f9583aad074330a1b3024b07'
+  2, 2, 16384, 'dbcecd19d59310183cf5c31ddee29e8d7bec64d3f9583aad074330a1b3024b07'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 2, 8192, X'197c5385e5853003188833d4f991136c1b0875fa416a60b1159f64e57e457b3184762c884a802a2bda194c058e3bd953'
+  2, 2, 8192, '197c5385e5853003188833d4f991136c1b0875fa416a60b1159f64e57e457b3184762c884a802a2bda194c058e3bd953'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 4, 32768, X'3ad204f99eb7262efab79cfca02628870ea76361'
+  2, 4, 32768, '3ad204f99eb7262efab79cfca02628870ea76361'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 4, 16384, X'3a2170aad92fdd58b55e0e199822bc873cf587b2d1eb1ed7ed8dcea97ae86376'
+  2, 4, 16384, '3a2170aad92fdd58b55e0e199822bc873cf587b2d1eb1ed7ed8dcea97ae86376'
 );
 
 INSERT INTO file_hashes (
 product, file, algo, hash
version, file, algo, hash
 ) VALUES (
-  28, 4, 8192, X'f778076baa876b5e4b502494a3db081fb09dd870dee6991d54104a74b7e009c58fe261db5ffd13c11e08ef0cefcfa59f'
+  2, 4, 8192, 'f778076baa876b5e4b502494a3db081fb09dd870dee6991d54104a74b7e009c58fe261db5ffd13c11e08ef0cefcfa59f'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 5, 32768, X'ecd9c7076cc0572724c7a67db7f19c2831e0445f'
+  4, 5, 32768, 'ecd9c7076cc0572724c7a67db7f19c2831e0445f'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 5, 16384, X'28f3ea5afd34444c8232ea75003131e294a0c9b847de300e4b205d38c1a41305'
+  4, 5, 16384, '28f3ea5afd34444c8232ea75003131e294a0c9b847de300e4b205d38c1a41305'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 5, 8192, X'51921a8b9322f2d3f06d55002ff40a79da67e70cb563b2a50977642d603dfac2ccbb68b3d32a8bb350769b75d6254208'
+  4, 5, 8192, '51921a8b9322f2d3f06d55002ff40a79da67e70cb563b2a50977642d603dfac2ccbb68b3d32a8bb350769b75d6254208'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 1, 32768, X'd9309b9e45928239d7a7b18711e690792632cce4'
+  5, 1, 32768, 'd9309b9e45928239d7a7b18711e690792632cce4'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 1, 16384, X'dbfa1856d278d8707c4989b30dd065b4bcd309908f0f2e6e66ff2aa83ff93f59'
+  5, 1, 16384, 'dbfa1856d278d8707c4989b30dd065b4bcd309908f0f2e6e66ff2aa83ff93f59'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 1, 8192, X'fb8d027f03bb5ebb47741ed247eb9e174127b714d20229885feb37e0979aeb14a1b74020cded891d680441093625729c'
+  5, 1, 8192, 'fb8d027f03bb5ebb47741ed247eb9e174127b714d20229885feb37e0979aeb14a1b74020cded891d680441093625729c'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 3, 32768, X'3715f2f94016a91fab5bbc503f0f1d43c5a9fc2b'
+  5, 3, 32768, '3715f2f94016a91fab5bbc503f0f1d43c5a9fc2b'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 3, 16384, X'c03a5296b5decb87b01517f9927a8b2349dfb29ff9f5ba084f994c155ca5d4be'
+  5, 3, 16384, 'c03a5296b5decb87b01517f9927a8b2349dfb29ff9f5ba084f994c155ca5d4be'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 3, 8192, X'b8bc345f56115235cc6091f61e312ce43ea54a5b99e7295002ae7b415fd35e06ec4c731ab70ad00d784bb53a318a2fa0'
+  5, 3, 8192, 'b8bc345f56115235cc6091f61e312ce43ea54a5b99e7295002ae7b415fd35e06ec4c731ab70ad00d784bb53a318a2fa0'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 5, 32768, X'e59602f4edf24c1b36199588886d06665d4adcd7'
+  6, 5, 32768, 'e59602f4edf24c1b36199588886d06665d4adcd7'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 5, 16384, X'090e1b77bda7fe665e498c6b5e09dbb7ddc5cfe57f213de48f4fb6736484f500'
+  6, 5, 16384, '090e1b77bda7fe665e498c6b5e09dbb7ddc5cfe57f213de48f4fb6736484f500'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 5, 8192, X'7cbdb4612a13443dba910ecdef5161f2213e52c9b4a2eef14bcee5d287e9df931cd022e9e9715518ad9c9b6e3384a668'
+  6, 5, 8192, '7cbdb4612a13443dba910ecdef5161f2213e52c9b4a2eef14bcee5d287e9df931cd022e9e9715518ad9c9b6e3384a668'
 );
 
 /* Packages */
@@ -790,30 +796,42 @@ INSERT INTO packages (                    /*  4 */
 
 /* Versions */
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  1 */
   package, product, release, time
 ) VALUES (
   1, 28, '1.0.1e-2', 1366531494
 );
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  2 */
   package, product, release, time
 ) VALUES (
   2, 28, '1.0.1e-2', 1366531494
 );
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  3 */
   package, product, release, time
 ) VALUES (
   3, 28, '1.0.1e-2', 1366531494
 );
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  4 */
   package, product, release, time
 ) VALUES (
   4, 28, '1.0.1e-2', 1366531494
 );
 
+INSERT INTO versions (             /*  5 */
+  package, product, time
+) VALUES (
+  2, 18, 1350544774
+);
+
+INSERT INTO versions (             /*  6 */
+  package, product, time
+) VALUES (
+  4, 18, 1350544774
+);
+
 /* Components */
 
 INSERT INTO components (
@@ -1681,59 +1699,59 @@ INSERT INTO enforcements (      /* 18 */
 INSERT INTO "swid_entities" (          /*  1 */
   "name", "regid"
 ) VALUES (
-  'strongSwan Project', 'regid.2004-03.org.strongswan'
+  'strongSwan Project', 'strongswan.org'
 );
 
 INSERT INTO swid_entities (                    /*  2 */
   "name", "regid"
 ) VALUES (
-  'Adobe Systems Inc.', 'regid.1986-12.com.adobe'
+  'Adobe Systems Inc.', 'adobe.com'
 );
 
 INSERT INTO swid_entities (                    /*  3 */
   "name", "regid"
 ) VALUES (
-  'Microsoft Corporation', 'regid.1991-06.com.microsoft'
+  'Microsoft Corporation', 'microsoft.com'
 );
 
 INSERT INTO swid_entities (                    /*  4 */
   "name", "regid"
 ) VALUES (
-  'Ubuntu Project', 'regid.2004-05.com.ubuntu'
+  'Ubuntu Project', 'ubuntu.com'
 );
 
 INSERT INTO swid_entities (                    /*  5 */
   "name", "regid"
 ) VALUES (
-  'Apache Software Foundation', 'regid.1995-04.org.apache'
+  'Apache Software Foundation', 'apache.org'
 );
 
 INSERT INTO swid_entities (                    /*  6 */
   "name", "regid"
 ) VALUES (
-  'Debian Project', 'regid.1999-03.org.debian'
+  'Debian Project', 'debian.org'
 );
 
 INSERT INTO swid_entities (                    /*  7 */
   "name", "regid"
 ) VALUES (
-  'Internet Systems Consortium', 'regid.1994-04.org.isc'
+  'Internet Systems Consortium', 'isc.org'
 );
 
 INSERT INTO swid_entities (                    /*  8 */
   "name", "regid"
 ) VALUES (
-  'OpenSSL Project', 'regid.1998-12.org.openssl'
+  'OpenSSL Project', 'openssl.org'
 );
 
 INSERT INTO swid_entities (                    /*  9 */
   "name", "regid"
 ) VALUES (
-  'Samba Project', 'regid.1998-01.org.samba'
+  'Samba Project', 'samba.org'
 );
 
 INSERT INTO swid_entities (                    /* 10 */
   "name", "regid"
 ) VALUES (
-  'SQLite Project', 'regid.2002-08.org.sqlite'
+  'SQLite Project', 'sqlite.org'
 );
index 5c2a656..1ac51ef 100644 (file)
@@ -41,10 +41,12 @@ DROP TABLE IF EXISTS file_hashes;
 CREATE TABLE file_hashes (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   file INTEGER NOT NULL REFERENCES files(id),
-  product INTEGER NOT NULL REFERENCES products(id),
-  device INTEGER DEFAULT 0 REFERENCES devices(id),
+  version INTEGER REFERENCES versions(id),
+  device INTEGER REFERENCES devices(id),
+  size INTEGER,
   algo INTEGER NOT NULL REFERENCES algorithms(id),
-  hash BLOB NOT NULL
+  hash VARCHAR(64) NOT NULL,
+  mutable INTEGER DEFAULT 0
 );
 
 DROP TABLE IF EXISTS groups;
@@ -177,9 +179,9 @@ CREATE INDEX packages_name ON packages (
 DROP TABLE IF EXISTS versions;
 CREATE TABLE versions (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-  package INTEGER NOT NULL REFERENCES packages(id),
   product INTEGER NOT NULL REFERENCES products(id),
-  release TEXT NOT NULL,
+  package INTEGER NOT NULL REFERENCES packages(id),
+  release TEXT,
   security INTEGER DEFAULT 0,
   blacklist INTEGER DEFAULT 0,
   time INTEGER DEFAULT 0
index 0344184..fb894f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -134,6 +134,11 @@ struct private_attest_db_t {
        char *version;
 
        /**
+        * Primary key of software package version to be queried
+        */
+       int vid;
+
+       /**
         * TRUE if version has been set
         */
        bool version_set;
@@ -975,7 +980,7 @@ METHOD(attest_db_t, list_files, void,
                {
                        while (e->enumerate(e, &fid, &file))
                        {
-                               printf("%4d: %s\n", fid, file);
+                               printf("%6d: %s\n", fid, file);
                                count++;
                        }
                        e->destroy(e);
@@ -996,10 +1001,10 @@ METHOD(attest_db_t, list_files, void,
                        {
                                if (did != last_did)
                                {
-                                       printf("%4d: %s\n", did, dir);
+                                       printf("%6d: %s\n", did, dir);
                                        last_did = did;
                                }
-                               printf("%4d:   %s\n", fid, file);
+                               printf("%6d:   %s\n", fid, file);
                                count++;
                        }
                        e->destroy(e);
@@ -1182,24 +1187,24 @@ METHOD(attest_db_t, list_hashes, void,
        private_attest_db_t *this)
 {
        enumerator_t *e;
-       chunk_t hash;
-       char *file, *dir, *product;
+       char *file, *dir, *product, *hash;
        int id, fid, fid_old = 0, did, did_old = 0, pid, pid_old = 0, count = 0;
 
        if (this->pid && this->fid && this->did)
        {
-               printf("%4d: %s\n", this->did, this->dir);
-               printf("%4d:   %s\n", this->fid, this->file);
+               printf("%6d: %s\n", this->did, this->dir);
+               printf("%6d:   %s\n", this->fid, this->file);
                e = this->db->query(this->db,
-                               "SELECT id, hash FROM file_hashes "
-                               "WHERE algo = ? AND file = ? AND product = ?",
+                               "SELECT h.id, h.hash FROM file_hashes AS h "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "WHERE h.algo = ? AND h.file = ? AND v.product = ?",
                                DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->pid,
-                               DB_INT, DB_BLOB);
+                               DB_INT, DB_TEXT);
                if (e)
                {
                        while (e->enumerate(e, &id, &hash))
                        {
-                               printf("%4d:     %#B\n", id, &hash);
+                               printf("%6d:     %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1216,25 +1221,26 @@ METHOD(attest_db_t, list_hashes, void,
                                "FROM file_hashes AS h "
                                "JOIN files AS f ON h.file = f.id "
                                "JOIN directories AS d ON f.dir = d.id "
-                               "WHERE h.algo = ? AND h.product = ? AND f.name = ? "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "WHERE h.algo = ? AND v.product = ? AND f.name = ? "
                                "ORDER BY d.path, f.name, h.hash",
                                DB_INT, this->algo, DB_INT, this->pid, DB_TEXT, this->file,
-                               DB_INT, DB_BLOB, DB_INT, DB_INT, DB_TEXT);
+                               DB_INT, DB_TEXT, DB_INT, DB_INT, DB_TEXT);
                if (e)
                {
                        while (e->enumerate(e, &id, &hash, &fid, &did, &dir))
                        {
                                if (did != did_old)
                                {
-                                       printf("%4d: %s\n", did, dir);
+                                       printf("%6d: %s\n", did, dir);
                                        did_old = did;
                                }
                                if (fid != fid_old)
                                {
-                                       printf("%4d:   %s\n", fid, this->file);
+                                       printf("%6d:   %s\n", fid, this->file);
                                        fid_old = fid;
                                }
-                               printf("%4d:     %#B\n", id, &hash);
+                               printf("%6d:     %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1246,25 +1252,26 @@ METHOD(attest_db_t, list_hashes, void,
        }
        else if (this->pid && this->did)
        {
-               printf("%4d: %s\n", this->did, this->dir);
+               printf("%6d: %s\n", this->did, this->dir);
                e = this->db->query(this->db,
                                "SELECT h.id, h.hash, f.id, f.name "
                                "FROM file_hashes AS h "
                                "JOIN files AS f ON h.file = f.id "
-                               "WHERE h.algo = ? AND h.product = ? AND f.dir = ? "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "WHERE h.algo = ? AND v.product = ? AND f.dir = ? "
                                "ORDER BY f.name, h.hash",
                                DB_INT, this->algo, DB_INT, this->pid, DB_INT, this->did,
-                               DB_INT, DB_BLOB, DB_INT, DB_TEXT);
+                               DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
                        while (e->enumerate(e, &id, &hash, &fid, &file))
                        {
                                if (fid != fid_old)
                                {
-                                       printf("%4d:   %s\n", fid, file);
+                                       printf("%6d:   %s\n", fid, file);
                                        fid_old = fid;
                                }
-                               printf("%4d:     %#B\n", id, &hash);
+                               printf("%6d:     %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1281,25 +1288,26 @@ METHOD(attest_db_t, list_hashes, void,
                                "FROM file_hashes AS h "
                                "JOIN files AS f ON h.file = f.id "
                                "JOIN directories AS d ON f.dir = d.id "
-                               "WHERE h.algo = ? AND h.product = ? "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "WHERE h.algo = ? AND v.product = ? "
                                "ORDER BY d.path, f.name, h.hash",
                                DB_INT, this->algo, DB_INT, this->pid,
-                               DB_INT, DB_BLOB, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+                               DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
                        while (e->enumerate(e, &id, &hash, &fid, &file, &did, &dir))
                        {
                                if (did != did_old)
                                {
-                                       printf("%4d: %s\n", did, dir);
+                                       printf("%6d: %s\n", did, dir);
                                        did_old = did;
                                }
                                if (fid != fid_old)
                                {
-                                       printf("%4d:   %s\n", fid, file);
+                                       printf("%6d:   %s\n", fid, file);
                                        fid_old = fid;
                                }
-                               printf("%4d:     %#B\n", id, &hash);
+                               printf("%6d:     %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1313,21 +1321,22 @@ METHOD(attest_db_t, list_hashes, void,
        {
                e = this->db->query(this->db,
                                "SELECT h.id, h.hash, p.id, p.name FROM file_hashes AS h "
-                               "JOIN products AS p ON h.product = p.id "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "JOIN products AS p ON v.product = p.id "
                                "WHERE h.algo = ? AND h.file = ? "
                                "ORDER BY p.name, h.hash",
                                DB_INT, this->algo, DB_INT, this->fid,
-                               DB_INT, DB_BLOB, DB_INT, DB_TEXT);
+                               DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
                        while (e->enumerate(e, &id, &hash, &pid, &product))
                        {
                                if (pid != pid_old)
                                {
-                                       printf("%4d: %s\n", pid, product);
+                                       printf("%6d: %s\n", pid, product);
                                        pid_old = pid;
                                }
-                               printf("%4d:   %#B\n", id, &hash);
+                               printf("%6d:   %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1345,32 +1354,33 @@ METHOD(attest_db_t, list_hashes, void,
                                "FROM file_hashes AS h "
                                "JOIN files AS f ON h.file = f.id "
                                "JOIN directories AS d ON f.dir = d.id "
-                               "JOIN products AS p ON h.product = p.id "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "JOIN products AS p ON v.product = p.id "
                                "WHERE h.algo = ? AND f.name = ? "
                                "ORDER BY d.path, f.name, p.name, h.hash",
                                DB_INT, this->algo, DB_TEXT, this->file,
-                               DB_INT, DB_BLOB, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+                               DB_INT, DB_TEXT, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
                        while (e->enumerate(e, &id, &hash, &fid, &did, &dir, &pid, &product))
                        {
                                if (did != did_old)
                                {
-                                       printf("%4d: %s\n", did, dir);
+                                       printf("%6d: %s\n", did, dir);
                                        did_old = did;
                                }
                                if (fid != fid_old)
                                {
-                                       printf("%4d:   %s\n", fid, this->file);
+                                       printf("%6d:   %s\n", fid, this->file);
                                        fid_old = fid;
                                        pid_old = 0;
                                }
                                if (pid != pid_old)
                                {
-                                       printf("%4d:     %s\n", pid, product);
+                                       printf("%6d:     %s\n", pid, product);
                                        pid_old = pid;
                                }
-                               printf("%4d:     %#B\n", id, &hash);
+                               printf("%6d:     %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1386,27 +1396,28 @@ METHOD(attest_db_t, list_hashes, void,
                                "SELECT h.id, h.hash, f.id, f.name, p.id, p.name "
                                "FROM file_hashes AS h "
                                "JOIN files AS f ON h.file = f.id "
-                               "JOIN products AS p ON h.product = p.id "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "JOIN products AS p ON v.product = p.id "
                                "WHERE h.algo = ? AND f.dir = ? "
                                "ORDER BY f.name, p.name, h.hash",
                                DB_INT, this->algo, DB_INT, this->did,
-                               DB_INT, DB_BLOB, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+                               DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
                        while (e->enumerate(e, &id, &hash, &fid, &file, &pid, &product))
                        {
                                if (fid != fid_old)
                                {
-                                       printf("%4d: %s\n", fid, file);
+                                       printf("%6d: %s\n", fid, file);
                                        fid_old = fid;
                                        pid_old = 0;
                                }
                                if (pid != pid_old)
                                {
-                                       printf("%4d:   %s\n", pid, product);
+                                       printf("%6d:   %s\n", pid, product);
                                        pid_old = pid;
                                }
-                               printf("%4d:     %#B\n", id, &hash);
+                               printf("%6d:     %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1423,10 +1434,11 @@ METHOD(attest_db_t, list_hashes, void,
                                "FROM file_hashes AS h "
                                "JOIN files AS f ON h.file = f.id "
                                "JOIN directories AS d ON f.dir = d.id "
-                               "JOIN products AS p on h.product = p.id "
+                               "JOIN versions AS v ON h.version = v.id "
+                               "JOIN products AS p on v.product = p.id "
                                "WHERE h.algo = ? "
                                "ORDER BY d.path, f.name, p.name, h.hash",
-                               DB_INT, this->algo, DB_INT, DB_BLOB, DB_INT, DB_TEXT,
+                               DB_INT, this->algo, DB_INT, DB_TEXT, DB_INT, DB_TEXT,
                                DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
@@ -1435,21 +1447,21 @@ METHOD(attest_db_t, list_hashes, void,
                        {
                                if (did != did_old)
                                {
-                                       printf("%4d: %s\n", did, dir);
+                                       printf("%6d: %s\n", did, dir);
                                        did_old = did;
                                }
                                if (fid != fid_old)
                                {
-                                       printf("%4d:   %s\n", fid, file);
+                                       printf("%6d:   %s\n", fid, file);
                                        fid_old = fid;
                                        pid_old = 0;
                                }
                                if (pid != pid_old)
                                {
-                                       printf("%4d:     %s\n", pid, product);
+                                       printf("%6d:     %s\n", pid, product);
                                        pid_old = pid;
                                }
-                               printf("%4d:       %#B\n", id, &hash);
+                               printf("%6d:       %s\n", id, hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1610,28 +1622,32 @@ static bool insert_file_hash(private_attest_db_t *this,
                                                         int *hashes_added, int *hashes_updated)
 {
        enumerator_t *e;
-       chunk_t hash;
+       uint8_t hex_measurement_buf[2*HASH_SIZE_SHA512 + 1];
+       uint8_t *hex_hash_buf;
+       chunk_t hex_hash, hex_measurement;
        char *label;
        bool insert = TRUE, update = FALSE;
 
        label = "could not be created";
 
        e = this->db->query(this->db,
-               "SELECT hash FROM file_hashes WHERE algo = ? "
-               "AND file = ? AND product = ? AND device = 0",
-               DB_INT, algo, DB_UINT, fid, DB_UINT, this->pid, DB_BLOB);
+               "SELECT hash FROM file_hashes "
+               "WHERE algo = ? AND file = ? AND version = ?",
+               DB_INT, algo, DB_UINT, fid, DB_UINT, this->vid, DB_TEXT);
 
        if (!e)
        {
                printf("file_hashes query failed\n");
                return FALSE;
        }
+       hex_measurement = chunk_to_hex(measurement, hex_measurement_buf, FALSE);
 
-       while (e->enumerate(e, &hash))
+       while (e->enumerate(e, &hex_hash_buf))
        {
                update = TRUE;
+               hex_hash = chunk_from_str(hex_hash_buf);
 
-               if (chunk_equals(measurement, hash))
+               if (chunk_equals(hex_measurement, hex_hash))
                {
                        label = "exists and equals";
                        insert = FALSE;
@@ -1644,10 +1660,10 @@ static bool insert_file_hash(private_attest_db_t *this,
        {
                if (this->db->execute(this->db, NULL,
                        "INSERT INTO file_hashes "
-                       "(file, product, device, algo, hash) "
-                       "VALUES (?, ?, 0, ?, ?)",
-                       DB_UINT, fid, DB_UINT, this->pid,
-                       DB_INT, algo, DB_BLOB, measurement) != 1)
+                       "(file, version, algo, hash) "
+                       "VALUES (?, ?, ?, ?)",
+                       DB_UINT, fid, DB_UINT, this->vid,
+                       DB_INT, algo, DB_TEXT, hex_measurement) != 1)
                {
                        printf("file_hash insertion failed\n");
                        return FALSE;
@@ -1668,6 +1684,75 @@ static bool insert_file_hash(private_attest_db_t *this,
 }
 
 /**
+ * Add a package version
+ */
+static bool add_version(private_attest_db_t *this)
+{
+       int vid, security_old, security, blacklist_old, blacklist;
+       time_t t = time(NULL);
+       enumerator_t *e;
+       bool success;
+
+       security =  this->package_state == OS_PACKAGE_STATE_SECURITY;
+       blacklist = this->package_state == OS_PACKAGE_STATE_BLACKLIST;
+
+       e = this->db->query(this->db,
+                               "SELECT id, security, blacklist FROM versions "
+                               "WHERE package = ? AND product = ? AND release = ?",
+                               DB_UINT, this->gid, DB_UINT, this->pid, DB_TEXT, this->version,
+                               DB_INT, DB_INT, DB_INT, DB_INT);
+       if (e)
+       {
+               if (e->enumerate(e, &vid, &security_old, &blacklist_old))
+               {
+                       this->vid = vid;
+               }
+               e->destroy(e);
+       }
+       if (this->vid)
+       {
+               if (security != security_old || blacklist != blacklist_old)
+               {
+                       /* update security and/or blacklist flag */
+                       success = this->db->execute(this->db, NULL, "UPDATE versions "
+                                       "SET security = ?, blacklist = ?, time = ? WHERE id = ?",
+                                       DB_INT, security, DB_INT, blacklist, DB_INT, t,
+                                       DB_INT, this->vid) == 1;
+
+                       printf("'%s' package %s (%s)%N %s updated in database\n",
+                                  this->product, this->package, this->version,
+                                  os_package_state_names, this->package_state,
+                                  success ? "" : "could not be ");
+               }
+               else
+               {
+                       success = TRUE;
+
+                       printf("'%s' package %s (%s)%N exists in database\n",
+                                  this->product, this->package, this->version,
+                                  os_package_state_names, this->package_state);
+               }
+               return success;
+       }
+
+       /* create a new version */
+       success = this->db->execute(this->db, NULL,
+                               "INSERT INTO versions "
+                               "(package, product, release, security, blacklist, time) "
+                               "VALUES (?, ?, ?, ?, ?, ?)",
+                               DB_UINT, this->gid, DB_INT, this->pid, DB_TEXT,
+                               this->version, DB_INT, security, DB_INT, blacklist,
+                               DB_INT, t) == 1;
+
+       printf("'%s' package %s (%s)%N %sinserted into database\n",
+                       this->product, this->package, this->version,
+                       os_package_state_names, this->package_state,
+                       success ? "" : "could not be ");
+
+       return success;
+}
+
+/**
  * Add hash measurement for a single file or all files in a directory
  */
 static bool add_hash(private_attest_db_t *this)
@@ -1771,7 +1856,14 @@ static bool add_hash(private_attest_db_t *this)
 METHOD(attest_db_t, add, bool,
        private_attest_db_t *this)
 {
-       bool success = FALSE;
+       /* insert package version */
+       if (this->version_set && this->gid && this->pid)
+       {
+               if (!add_version(this))
+               {
+                       return FALSE;
+               }
+       }
 
        /* add directory or file hash measurement for a given product */
        if (this->did && this->pid)
@@ -1779,29 +1871,7 @@ METHOD(attest_db_t, add, bool,
                return add_hash(this);
        }
 
-       /* insert package version */
-       if (this->version_set && this->gid && this->pid)
-       {
-               time_t t = time(NULL);
-               int security, blacklist;
-
-               security =  this->package_state == OS_PACKAGE_STATE_SECURITY;
-               blacklist = this->package_state == OS_PACKAGE_STATE_BLACKLIST;
-
-               success = this->db->execute(this->db, NULL,
-                                       "INSERT INTO versions "
-                                       "(package, product, release, security, blacklist, time) "
-                                       "VALUES (?, ?, ?, ?, ?, ?)",
-                                       DB_UINT, this->gid, DB_INT, this->pid, DB_TEXT,
-                                       this->version, DB_INT, security, DB_INT, blacklist,
-                                       DB_INT, t) == 1;
-
-               printf("'%s' package %s (%s)%N %sinserted into database\n",
-                               this->product, this->package, this->version,
-                               os_package_state_names, this->package_state,
-                               success ? "" : "could not be ");
-       }
-       return success;
+       return FALSE;
 }
 
 METHOD(attest_db_t, delete, bool,
@@ -1816,8 +1886,9 @@ METHOD(attest_db_t, delete, bool,
        if (this->algo && this->pid && this->fid)
        {
                success = this->db->execute(this->db, NULL,
-                                                               "DELETE FROM file_hashes "
-                                                               "WHERE algo = ? AND product = ? AND file = ?",
+                                                               "DELETE FROM file_hashes AS h "
+                                                               "JOIN versions AS v ON h.version = v.id "
+                                                               "WHERE h.algo = ? AND v.product = ? AND h.file = ?",
                                                                DB_UINT, this->algo, DB_UINT, this->pid,
                                                                DB_UINT, this->fid) > 0;
 
index 8f4afdb..2966529 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -77,8 +77,9 @@ Usage:\n\
   ipsec attest --add [--owner <name>] --key <digest>|--aik <path>\n\
     Add an AIK public key digest entry preceded by an optional owner name\n\
   \n\
-  ipsec attest --add --product <name>|--pid <id> --sha1|--sha1-ima|--sha256|--sha384\n\
-              [--relative|--rel] --dir <path>|--file <path>\n\
+  ipsec attest --add --product <name>|--pid <id> --sha1|--sha256|--sha384\n\
+              [--relative|--rel] [--package <name> --version <string>]\n\
+               --dir <path>|--file <path>\n\
     Add hashes of a single file or all files in a directory under absolute or relative filenames\n\
   \n\
   ipsec attest --add --key <digest|--kid <id> --component <cfn>|--cid <id> --sequence <no>|--seq <no>\n\
index 448ca9f..9ba72d0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -667,7 +667,8 @@ METHOD(pts_component_t, verify, status_t,
                        case IMA_STATE_RUNTIME:
                        {
                                uint8_t hash_buf[HASH_SIZE_SHA512];
-                               chunk_t digest, hash;
+                               uint8_t digest_buf[HASH_SIZE_SHA512], *hex_digest_buf;
+                               chunk_t hex_digest, digest, hash;
                                enumerator_t *e;
 
                                this->count++;
@@ -685,8 +686,10 @@ METHOD(pts_component_t, verify, status_t,
                                                                                                hash_algo, ima_name);
                                if (e)
                                {
-                                       while (e->enumerate(e, &digest))
+                                       while (e->enumerate(e, &hex_digest_buf))
                                        {
+                                               hex_digest = chunk_from_str(hex_digest_buf);
+                                               digest = chunk_from_hex(hex_digest, digest_buf);
                                                if (!ima_hash(digest, ima_algo, ima_name,
                                                                          FALSE, algo, hash_buf))
                                                {
index 1a4c421..4a47b06 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2012-2014 Andreas Steffen
+ * Copyright (C) 2012-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -104,17 +104,19 @@ METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
                                "SELECT f.id, f.name, fh.hash FROM file_hashes AS fh "
                                "JOIN files AS f ON f.id = fh.file "
                                "JOIN directories as d ON d.id = f.dir "
-                               "WHERE fh.product = ? AND fh.algo = ? AND d.id = ? "
+                               "JOIN versions as v ON v.id = fh.version "
+                               "WHERE v.product = ? AND fh.algo = ? AND d.id = ? "
                                "ORDER BY f.name",
-                               DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_BLOB);
+                               DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_TEXT);
        }
        else
        {
                e = this->db->query(this->db,
                                "SELECT f.id, f.name, fh.hash FROM file_hashes AS fh "
                                "JOIN files AS f ON f.id = fh.file "
-                               "WHERE fh.product = ? AND fh.algo = ? AND fh.file = ?",
-                               DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_BLOB);
+                               "JOIN versions AS v ON v.id = fh.version "
+                               "WHERE v.product = ? AND fh.algo = ? AND fh.file = ?",
+                               DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_TEXT);
        }
        return e;
 }
@@ -179,7 +181,8 @@ METHOD(pts_database_t, add_file_measurement, status_t,
        /* does hash measurement value already exist? */
        e = this->db->query(this->db,
                        "SELECT fh.id, fh.hash FROM file_hashes AS fh "
-                       "WHERE fh.product = ? AND fh.algo = ? AND fh.file = ?",
+                       "JOIN versions AS v ON v.id = fh.version "
+                       "WHERE v.product = ? AND fh.algo = ? AND fh.file = ?",
                         DB_INT, pid, DB_INT, algo, DB_INT, fid, DB_INT, DB_BLOB);
        if (!e)
        {
@@ -235,8 +238,10 @@ METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
                e = this->db->query(this->db,
                                "SELECT fh.hash FROM file_hashes AS fh "
                                "JOIN files AS f ON f.id = fh.file "
-                               "WHERE fh.product = ? AND f.name = ? AND fh.algo = ?",
-                               DB_INT, pid, DB_TEXT, file, DB_INT, algo, DB_BLOB);
+                               "JOIN versions AS v ON v.id = fh.version "
+                               "WHERE v.product = ? AND f.name = ? AND fh.algo = ? "
+                               "ORDER BY v.time DESC",
+                               DB_INT, pid, DB_TEXT, file, DB_INT, algo, DB_TEXT);
        }
        else
        {       /* absolute pathname */
@@ -256,8 +261,10 @@ METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
                e = this->db->query(this->db,
                                "SELECT fh.hash FROM file_hashes AS fh "
                                "JOIN files AS f ON f.id = fh.file "
-                               "WHERE fh.product = ? AND f.dir = ? AND f.name = ? AND fh.algo = ?",
-                               DB_INT, pid, DB_INT, did, DB_TEXT, file, DB_INT, algo, DB_BLOB);
+                               "JOIN versions AS v ON v.id = fh.version "
+                               "WHERE v.product = ? AND f.dir = ? AND f.name = ? AND fh.algo = ? "
+                               "ORDER BY v.time DESC",
+                               DB_INT, pid, DB_INT, did, DB_TEXT, file, DB_INT, algo, DB_TEXT);
        }
 
 err: