diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libimcv/imv/data.sql | 118 | ||||
-rw-r--r-- | src/libimcv/imv/tables.sql | 12 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_attestation/attest_db.c | 239 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_attestation/attest_usage.c | 7 | ||||
-rw-r--r-- | src/libimcv/pts/components/ita/ita_comp_ima.c | 9 | ||||
-rw-r--r-- | src/libimcv/pts/pts_database.c | 27 |
6 files changed, 257 insertions, 155 deletions
diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql index fb0db91ee..a872499d2 100644 --- a/src/libimcv/imv/data.sql +++ b/src/libimcv/imv/data.sql @@ -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' ); diff --git a/src/libimcv/imv/tables.sql b/src/libimcv/imv/tables.sql index 5c2a6563b..1ac51efd9 100644 --- a/src/libimcv/imv/tables.sql +++ b/src/libimcv/imv/tables.sql @@ -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 diff --git a/src/libimcv/plugins/imv_attestation/attest_db.c b/src/libimcv/plugins/imv_attestation/attest_db.c index 034418428..fb894f393 100644 --- a/src/libimcv/plugins/imv_attestation/attest_db.c +++ b/src/libimcv/plugins/imv_attestation/attest_db.c @@ -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; diff --git a/src/libimcv/plugins/imv_attestation/attest_usage.c b/src/libimcv/plugins/imv_attestation/attest_usage.c index 8f4afdbad..2966529e1 100644 --- a/src/libimcv/plugins/imv_attestation/attest_usage.c +++ b/src/libimcv/plugins/imv_attestation/attest_usage.c @@ -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\ diff --git a/src/libimcv/pts/components/ita/ita_comp_ima.c b/src/libimcv/pts/components/ita/ita_comp_ima.c index 448ca9ffb..9ba72d01d 100644 --- a/src/libimcv/pts/components/ita/ita_comp_ima.c +++ b/src/libimcv/pts/components/ita/ita_comp_ima.c @@ -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)) { diff --git a/src/libimcv/pts/pts_database.c b/src/libimcv/pts/pts_database.c index 1a4c4212d..4a47b06f0 100644 --- a/src/libimcv/pts/pts_database.c +++ b/src/libimcv/pts/pts_database.c @@ -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: |