summaryrefslogtreecommitdiff
path: root/src/libimcv/pts
diff options
context:
space:
mode:
Diffstat (limited to 'src/libimcv/pts')
-rw-r--r--src/libimcv/pts/pts.c2
-rw-r--r--src/libimcv/pts/pts_database.c108
-rw-r--r--src/libimcv/pts/pts_database.h21
-rw-r--r--src/libimcv/pts/pts_file_meas.c12
4 files changed, 108 insertions, 35 deletions
diff --git a/src/libimcv/pts/pts.c b/src/libimcv/pts/pts.c
index d771d07ed..09ffd7160 100644
--- a/src/libimcv/pts/pts.c
+++ b/src/libimcv/pts/pts.c
@@ -762,7 +762,7 @@ METHOD(pts_t, verify_quote_signature, bool,
return FALSE;
}
- if (!aik_pubkey->verify(aik_pubkey, scheme, digest, signature))
+ if (!aik_pubkey->verify(aik_pubkey, scheme, NULL, digest, signature))
{
DBG1(DBG_PTS, "signature verification failed for TPM Quote Info");
DESTROY_IF(aik_pubkey);
diff --git a/src/libimcv/pts/pts_database.c b/src/libimcv/pts/pts_database.c
index 4a47b06f0..8b99d689b 100644
--- a/src/libimcv/pts/pts_database.c
+++ b/src/libimcv/pts/pts_database.c
@@ -121,15 +121,69 @@ METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
return e;
}
-METHOD(pts_database_t, add_file_measurement, status_t,
- private_pts_database_t *this, int pid, pts_meas_algorithms_t algo,
+
+METHOD(pts_database_t, get_product_version, bool,
+ private_pts_database_t *this, int pid, int *vid)
+{
+ enumerator_t *e;
+ int pkg_id;
+
+ /* does empty package name already exist? */
+ e = this->db->query(this->db,
+ "SELECT id FROM packages WHERE name = ''", DB_INT);
+ if (!e)
+ {
+ return FALSE;
+ }
+ if (!e->enumerate(e, &pkg_id))
+ {
+ /* create generic product version entry */
+ if (this->db->execute(this->db, &pkg_id,
+ "INSERT INTO packages (name) VALUES ('')") != 1)
+ {
+ DBG1(DBG_PTS, "could not insert package into database");
+ e->destroy(e);
+ return FALSE;
+ }
+ }
+ e->destroy(e);
+
+ /* does generic product version already exist? */
+ e = this->db->query(this->db,
+ "SELECT id FROM versions WHERE product = ? AND package = ?",
+ DB_INT, pid, DB_INT, pkg_id);
+ if (!e)
+ {
+ return FALSE;
+ }
+ if (!e->enumerate(e, vid))
+ {
+ /* create generic product version entry */
+ if (this->db->execute(this->db, vid,
+ "INSERT INTO versions (product, package) VALUES (?, ?)",
+ DB_INT, pid, DB_INT, pkg_id) != 1)
+ {
+ DBG1(DBG_PTS, "could not insert version into database");
+ e->destroy(e);
+ return FALSE;
+ }
+ }
+ e->destroy(e);
+
+ return TRUE;
+}
+
+METHOD(pts_database_t, add_file_measurement, bool,
+ private_pts_database_t *this, int vid, pts_meas_algorithms_t algo,
chunk_t measurement, char *filename, bool is_dir, int id)
{
enumerator_t *e;
char *name;
- chunk_t hash_value;
+ uint8_t hash_buf[HASH_SIZE_SHA512];
+ uint8_t hex_meas_buf[2*HASH_SIZE_SHA512+1], *hex_hash_buf;
+ chunk_t hash, hex_hash, hex_meas;
int hash_id, fid;
- status_t status = SUCCESS;
+ bool success = TRUE;
if (is_dir)
{
@@ -139,7 +193,7 @@ METHOD(pts_database_t, add_file_measurement, status_t,
DB_TEXT, filename, DB_INT, id, DB_INT);
if (!e)
{
- return FAILED;
+ return FALSE;
}
if (!e->enumerate(e, &fid))
{
@@ -149,7 +203,7 @@ METHOD(pts_database_t, add_file_measurement, status_t,
DB_TEXT, filename, DB_INT, id) != 1)
{
DBG1(DBG_PTS, "could not insert filename into database");
- status = FAILED;
+ success = FALSE;
}
}
e->destroy(e);
@@ -163,58 +217,63 @@ METHOD(pts_database_t, add_file_measurement, status_t,
"SELECT name FROM files WHERE id = ?", DB_INT, fid, DB_TEXT);
if (!e)
{
- return FAILED;
+ return FALSE;
}
if (!e->enumerate(e, &name) || !streq(name, filename))
{
DBG1(DBG_PTS, "filename of reference measurement does not match");
- status = FAILED;
+ success = FALSE;
}
e->destroy(e);
}
- if (status != SUCCESS)
+ if (!success)
{
- return status;
+ return FALSE;
}
/* does hash measurement value already exist? */
e = this->db->query(this->db,
- "SELECT fh.id, fh.hash FROM file_hashes AS fh "
- "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);
+ "SELECT id, hash FROM file_hashes "
+ "WHERE algo = ? AND file = ? AND version = ?",
+ DB_INT, algo, DB_INT, fid, DB_INT, vid, DB_INT, DB_TEXT);
if (!e)
{
- return FAILED;
+ return FALSE;
}
- if (e->enumerate(e, &hash_id, &hash_value))
+ if (e->enumerate(e, &hash_id, &hex_hash_buf))
{
- if (!chunk_equals_const(measurement, hash_value))
+ hex_hash = chunk_from_str(hex_hash_buf);
+ hash = chunk_from_hex(hex_hash, hash_buf);
+
+ if (!chunk_equals(measurement, hash))
{
/* update hash measurement value */
if (this->db->execute(this->db, &hash_id,
"UPDATE file_hashes SET hash = ? WHERE id = ?",
DB_BLOB, measurement, DB_INT, hash_id) != 1)
{
- status = FAILED;
+ success = FALSE;
}
}
}
else
{
+ hex_meas = chunk_to_hex(measurement, hex_meas_buf, FALSE);
+ hex_meas_buf[hex_meas.len] = '\0';
+
/* insert hash measurement value */
if (this->db->execute(this->db, &hash_id,
- "INSERT INTO file_hashes (file, product, algo, hash) "
- "VALUES (?, ?, ?, ?)", DB_INT, fid, DB_INT, pid,
- DB_INT, algo, DB_BLOB, measurement) != 1)
+ "INSERT INTO file_hashes (file, version, algo, hash) "
+ "VALUES (?, ?, ?, ?)", DB_INT, fid, DB_INT, vid,
+ DB_INT, algo, DB_TEXT, hex_meas_buf) != 1)
{
- status = FAILED;
+ success = FALSE;
}
}
e->destroy(e);
- return status;
+ return success;
}
METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
@@ -296,7 +355,7 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
while (e->enumerate(e, &hash))
{
- if (chunk_equals_const(hash, measurement))
+ if (chunk_equals(hash, measurement))
{
status = SUCCESS;
break;
@@ -424,6 +483,7 @@ pts_database_t *pts_database_create(imv_database_t *imv_db)
.public = {
.get_pathname = _get_pathname,
.create_file_hash_enumerator = _create_file_hash_enumerator,
+ .get_product_version = _get_product_version,
.add_file_measurement = _add_file_measurement,
.create_file_meas_enumerator = _create_file_meas_enumerator,
.check_comp_measurement = _check_comp_measurement,
diff --git a/src/libimcv/pts/pts_database.h b/src/libimcv/pts/pts_database.h
index a6c9fb3b6..3a5ff5992 100644
--- a/src/libimcv/pts/pts_database.h
+++ b/src/libimcv/pts/pts_database.h
@@ -60,18 +60,27 @@ struct pts_database_t {
/**
* Add PTS file measurement reference value
*
- * @param pid Primary key of software product in database
+ * @param pid Primary key of platform product
+ * @param vid Primary key of generic product version
+ * @return TRUE if successful
+ */
+ bool (*get_product_version)(pts_database_t *this, int pid, int *vid);
+
+ /**
+ * Add PTS file measurement reference value
+ *
+ * @param vid Primary key of generic product version
* @param algo File measurement hash algorithm used
* @param measurement File measurement hash
* @param filename Optional name of the file to be checked
* @param is_dir TRUE if part of directory measurement
* @param id Primary key into direcories/files table
- * @return Status
+ * @return TRUE if successful
*/
- status_t (*add_file_measurement)(pts_database_t *this, int pid,
- pts_meas_algorithms_t algo,
- chunk_t measurement, char *filename,
- bool is_dir, int id);
+ bool (*add_file_measurement)(pts_database_t *this, int vid,
+ pts_meas_algorithms_t algo,
+ chunk_t measurement, char *filename,
+ bool is_dir, int id);
/**
* Get PTS measurement[s] for a given filename stored in database
diff --git a/src/libimcv/pts/pts_file_meas.c b/src/libimcv/pts/pts_file_meas.c
index 92f513a2d..2f8935a87 100644
--- a/src/libimcv/pts/pts_file_meas.c
+++ b/src/libimcv/pts/pts_file_meas.c
@@ -140,7 +140,7 @@ METHOD(pts_file_meas_t, check, bool,
{
while (e->enumerate(e, &hash))
{
- if (chunk_equals_const(entry->measurement, hash))
+ if (chunk_equals(entry->measurement, hash))
{
status = SUCCESS;
break;
@@ -193,12 +193,13 @@ METHOD(pts_file_meas_t, verify, bool,
{
int fid, fid_last = 0;
char *filename;
- chunk_t measurement;
+ uint8_t measurement_buf[HASH_SIZE_SHA512], *hex_meas_buf;
+ chunk_t measurement, hex_meas;
entry_t *entry;
enumerator_t *enumerator = NULL;
bool found = FALSE, match = FALSE, success = TRUE;
- while (e_hash->enumerate(e_hash, &fid, &filename, &measurement))
+ while (e_hash->enumerate(e_hash, &fid, &filename, &hex_meas_buf))
{
if (fid != fid_last)
{
@@ -241,7 +242,10 @@ METHOD(pts_file_meas_t, verify, bool,
if (found && !match)
{
- if (chunk_equals_const(measurement, entry->measurement))
+ hex_meas = chunk_from_str(hex_meas_buf);
+ measurement = chunk_from_hex(hex_meas, measurement_buf);
+
+ if (chunk_equals(measurement, entry->measurement))
{
match = TRUE;
DBG2(DBG_PTS, " %#B for '%s' is ok",