From: Andreas Steffen Date: Sun, 6 Apr 2014 05:18:28 +0000 (+0200) Subject: Optimized PTS measurements X-Git-Tag: 5.2.0dr1~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b138bbee4e492520dfbe9ef1b4d9add9818ffc67;p=thirdparty%2Fstrongswan.git Optimized PTS measurements --- diff --git a/src/libpts/plugins/imv_attestation/attest_db.c b/src/libpts/plugins/imv_attestation/attest_db.c index 7a8a1135ad..147a633475 100644 --- a/src/libpts/plugins/imv_attestation/attest_db.c +++ b/src/libpts/plugins/imv_attestation/attest_db.c @@ -1780,22 +1780,6 @@ METHOD(attest_db_t, add, bool, { bool success = FALSE; - /* add key/component pair */ - if (this->kid && this->cid) - { - success = this->db->execute(this->db, NULL, - "INSERT INTO key_component (key, component, seq_no) " - "VALUES (?, ?, ?)", - DB_UINT, this->kid, DB_UINT, this->cid, - DB_UINT, this->seq_no) == 1; - - printf("key/component pair (%d/%d) %sinserted into database at " - "position %d\n", this->kid, this->cid, - success ? "" : "could not be ", this->seq_no); - - return success; - } - /* add directory or file hash measurement for a given product */ if (this->did && this->pid) { @@ -1869,19 +1853,6 @@ METHOD(attest_db_t, delete, bool, return success; } - /* delete key/component pair */ - if (this->kid && this->cid) - { - success = this->db->execute(this->db, NULL, - "DELETE FROM key_component " - "WHERE key = ? AND component = ?", - DB_UINT, this->kid, DB_UINT, this->cid) > 0; - - printf("key/component pair (%d/%d) %sdeleted from database\n", - this->kid, this->cid, success ? "" : "could not be "); - return success; - } - if (this->cid) { success = this->db->execute(this->db, NULL, diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c index 2adb3750b9..397f14636c 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c @@ -391,7 +391,6 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, imv_msg_t *out_msg; imv_state_t *state; imv_session_t *session; - imv_os_info_t *os_info; imv_attestation_state_t *attestation_state; imv_attestation_handshake_state_t handshake_state; imv_workitem_t *workitem; @@ -400,6 +399,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, TNC_IMVID imv_id; TNC_Result result = TNC_RESULT_SUCCESS; pts_t *pts; + int pid; uint32_t actions; enumerator_t *enumerator; @@ -500,8 +500,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, return TNC_RESULT_SUCCESS; } - os_info = session->get_os_info(session); - pts->set_platform_info(pts, os_info->get_info(os_info)); + session->get_session_id(session, &pid, NULL); + pts->set_platform_id(pts, pid); /* create an empty out message - we might need it */ out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY, diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.c b/src/libpts/plugins/imv_attestation/imv_attestation_build.c index a2beeec9ed..3750a0a5ba 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_build.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_build.c @@ -89,7 +89,6 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state, tcg_pts_attr_req_func_comp_evid_t *attr_cast; enumerator_t *enumerator; pts_comp_func_name_t *name; - chunk_t keyid; uint8_t flags; uint32_t depth; bool first_component = TRUE; @@ -97,7 +96,7 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state, attestation_state->set_handshake_state(attestation_state, IMV_ATTESTATION_STATE_END); - if (!pts->get_aik_keyid(pts, &keyid)) + if (!pts->get_aik_id(pts)) { attestation_state->set_measurement_error(attestation_state, IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK); diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.c b/src/libpts/plugins/imv_attestation/imv_attestation_process.c index e10a6c0dcf..03834c71f5 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_process.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.c @@ -160,6 +160,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, certificate_t *aik, *issuer; public_key_t *public; chunk_t keyid, keyid_hex, device_id; + int aik_id; enumerator_t *e; bool trusted = FALSE, trusted_chain = FALSE; @@ -214,7 +215,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, break; } } - pts->set_aik(pts, aik); + session->get_session_id(session, NULL, &aik_id); + pts->set_aik(pts, aik, aik_id); break; } case TCG_PTS_FILE_MEAS: @@ -228,13 +230,12 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, pts_file_meas_t *measurements; imv_workitem_t *workitem, *found = NULL; imv_workitem_type_t type; - char result_str[BUF_LEN], *platform_info; + char result_str[BUF_LEN]; bool is_dir, correct; enumerator_t *enumerator; eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT; algo = pts->get_meas_algorithm(pts); - platform_info = pts->get_platform_info(pts); attr_cast = (tcg_pts_attr_file_meas_t*)attr; measurements = attr_cast->get_measurements(attr_cast); request_id = measurements->get_request_id(measurements); @@ -287,7 +288,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, /* check hashes from database against measurements */ e = pts_db->create_file_hash_enumerator(pts_db, - platform_info, algo, is_dir, arg_int); + pts->get_platform_id(pts), + algo, is_dir, arg_int); if (!e) { eval = TNC_IMV_EVALUATION_RESULT_ERROR; @@ -319,8 +321,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, while (e->enumerate(e, &filename, &measurement)) { if (pts_db->add_file_measurement(pts_db, - platform_info, algo, measurement, filename, - is_dir, arg_int) != SUCCESS) + pts->get_platform_id(pts), algo, measurement, + filename, is_dir, arg_int) != SUCCESS) { eval = TNC_IMV_EVALUATION_RESULT_ERROR; } @@ -343,7 +345,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, } else { - measurements->check(measurements, pts_db, platform_info, algo); + measurements->check(measurements, pts_db, + pts->get_platform_id(pts), algo); } break; } diff --git a/src/libpts/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c index c6b4131bf4..04bc84eef5 100644 --- a/src/libpts/pts/components/ita/ita_comp_ima.c +++ b/src/libpts/pts/components/ita/ita_comp_ima.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -65,11 +65,6 @@ struct pts_ita_comp_ima_t { */ pts_comp_func_name_t *name; - /** - * AIK keyid - */ - chunk_t keyid; - /** * Sub-component depth */ @@ -83,7 +78,7 @@ struct pts_ita_comp_ima_t { /** * Primary key for AIK database entry */ - int kid; + int aik_id; /** * Primary key for IMA BIOS Component Functional Name database entry @@ -613,22 +608,7 @@ METHOD(pts_component_t, verify, status_t, status_t status; char *uri; - /* some first time initializations */ - if (!this->keyid.ptr) - { - if (!pts->get_aik_keyid(pts, &this->keyid)) - { - DBG1(DBG_PTS, "AIK keyid not available"); - return FAILED; - } - this->keyid = chunk_clone(this->keyid); - if (!this->pts_db) - { - DBG1(DBG_PTS, "pts database not available"); - return FAILED; - } - } - + this->aik_id = pts->get_aik_id(pts); pcrs = pts->get_pcrs(pts); measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform, &measurement_time); @@ -641,8 +621,8 @@ METHOD(pts_component_t, verify, status_t, case IMA_STATE_INIT: this->name->set_qualifier(this->name, qualifier); status = this->pts_db->get_comp_measurement_count(this->pts_db, - this->name, this->keyid, algo, &this->bios_cid, - &this->kid, &this->bios_count); + this->name, this->aik_id, algo, + &this->bios_cid, &this->bios_count); this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN); if (status != SUCCESS) { @@ -670,8 +650,8 @@ METHOD(pts_component_t, verify, status_t, if (this->is_bios_registering) { status = this->pts_db->insert_comp_measurement(this->pts_db, - measurement, this->bios_cid, this->kid, - ++this->seq_no, pcr, algo); + measurement, this->bios_cid, this->aik_id, + ++this->seq_no, pcr, algo); if (status != SUCCESS) { return status; @@ -681,8 +661,8 @@ METHOD(pts_component_t, verify, status_t, else { status = this->pts_db->check_comp_measurement(this->pts_db, - measurement, this->bios_cid, this->kid, - ++this->seq_no, pcr, algo); + measurement, this->bios_cid, this->aik_id, + ++this->seq_no, pcr, algo); if (status == FAILED) { return status; @@ -711,8 +691,8 @@ METHOD(pts_component_t, verify, status_t, case IMA_STATE_INIT: this->name->set_qualifier(this->name, qualifier); status = this->pts_db->get_comp_measurement_count(this->pts_db, - this->name, this->keyid, algo, - &this->ima_cid, &this->kid, &ima_count); + this->name, this->aik_id, algo, + &this->ima_cid, &ima_count); this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN); if (status != SUCCESS) { @@ -728,7 +708,7 @@ METHOD(pts_component_t, verify, status_t, "measurement", pen_names, vid, names, name); status = this->pts_db->check_comp_measurement(this->pts_db, measurement, this->ima_cid, - this->kid, 1, pcr, algo); + this->aik_id, 1, pcr, algo); } else { @@ -737,7 +717,7 @@ METHOD(pts_component_t, verify, status_t, this->is_ima_registering = TRUE; status = this->pts_db->insert_comp_measurement(this->pts_db, measurement, this->ima_cid, - this->kid, 1, pcr, algo); + this->aik_id, 1, pcr, algo); } this->state = IMA_STATE_RUNTIME; @@ -756,7 +736,7 @@ METHOD(pts_component_t, verify, status_t, return FAILED; } status = this->pts_db->check_file_measurement(this->pts_db, - pts->get_platform_info(pts), + pts->get_platform_id(pts), PTS_MEAS_ALGO_SHA1_IMA, measurement, uri); switch (status) @@ -904,14 +884,14 @@ METHOD(pts_component_t, destroy, void, if (this->is_bios_registering) { count = this->pts_db->delete_comp_measurements(this->pts_db, - this->bios_cid, this->kid); + this->bios_cid, this->aik_id); DBG1(DBG_PTS, "deleted %d registered %N '%N' BIOS evidence " "measurements", count, pen_names, vid, names, name); } if (this->is_ima_registering) { count = this->pts_db->delete_comp_measurements(this->pts_db, - this->ima_cid, this->kid); + this->ima_cid, this->aik_id); DBG1(DBG_PTS, "deleted registered %N '%N' boot aggregate evidence " "measurement", pen_names, vid, names, name); } @@ -920,7 +900,6 @@ METHOD(pts_component_t, destroy, void, this->ima_list->destroy_function(this->ima_list, (void *)free_ima_entry); this->name->destroy(this->name); - free(this->keyid.ptr); free(this); } } diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.c b/src/libpts/pts/components/ita/ita_comp_tboot.c index f4859f8018..05cbb9f1df 100644 --- a/src/libpts/pts/components/ita/ita_comp_tboot.c +++ b/src/libpts/pts/components/ita/ita_comp_tboot.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -40,11 +40,6 @@ struct pts_ita_comp_tboot_t { */ pts_comp_func_name_t *name; - /** - * AIK keyid - */ - chunk_t keyid; - /** * Sub-component depth */ @@ -55,6 +50,11 @@ struct pts_ita_comp_tboot_t { */ pts_database_t *pts_db; + /** + * Primary key for AIK database entry + */ + int aik_id; + /** * Primary key for Component Functional Name database entry */ @@ -201,51 +201,38 @@ METHOD(pts_component_t, verify, status_t, chunk_t measurement, pcr_before, pcr_after; status_t status; + this->aik_id = pts->get_aik_id(pts); pcrs = pts->get_pcrs(pts); measurement = evidence->get_measurement(evidence, &extended_pcr, &algo, &transform, &measurement_time); - if (!this->keyid.ptr) + status = this->pts_db->get_comp_measurement_count(this->pts_db, + this->name, this->aik_id, algo, + &this->cid, &this->count); + if (status != SUCCESS) { - if (!pts->get_aik_keyid(pts, &this->keyid)) - { - return FAILED; - } - this->keyid = chunk_clone(this->keyid); - - if (!this->pts_db) - { - DBG1(DBG_PTS, "pts database not available"); - return FAILED; - } - status = this->pts_db->get_comp_measurement_count(this->pts_db, - this->name, this->keyid, algo, &this->cid, - &this->kid, &this->count); - if (status != SUCCESS) - { - return status; - } - 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); + return status; + } + 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) - { - DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence " - "measurements", this->count, pen_names, vid, names, name); - } - else - { - DBG1(DBG_PTS, "registering %N '%N' functional component evidence " - "measurements", pen_names, vid, names, name); - this->is_registering = TRUE; - } + if (this->count) + { + DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence " + "measurements", this->count, pen_names, vid, names, name); + } + else + { + DBG1(DBG_PTS, "registering %N '%N' functional component evidence " + "measurements", pen_names, vid, names, name); + this->is_registering = TRUE; } if (this->is_registering) { status = this->pts_db->insert_comp_measurement(this->pts_db, - measurement, this->cid, this->kid, + measurement, this->cid, this->aik_id, ++this->seq_no, extended_pcr, algo); if (status != SUCCESS) { @@ -329,7 +316,7 @@ METHOD(pts_component_t, destroy, void, if (this->is_registering) { count = this->pts_db->delete_comp_measurements(this->pts_db, - this->cid, this->kid); + this->cid, this->aik_id); 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); @@ -337,7 +324,6 @@ METHOD(pts_component_t, destroy, void, "evidence measurements", count, pen_names, vid, names, name); } this->name->destroy(this->name); - free(this->keyid.ptr); free(this); } } diff --git a/src/libpts/pts/pts.c b/src/libpts/pts/pts.c index d155f2dcfc..d43dce9edc 100644 --- a/src/libpts/pts/pts.c +++ b/src/libpts/pts/pts.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen + * Copyright (C) 2011-2012 Sansar Choinyambuu + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -88,9 +89,9 @@ struct private_pts_t { chunk_t secret; /** - * Platform and OS Info + * Primary key of platform entry in database */ - char *platform_info; + int platform_id; /** * TRUE if IMC-PTS, FALSE if IMV-PTS @@ -117,6 +118,11 @@ struct private_pts_t { */ certificate_t *aik; + /** + * Primary key referening AIK in database + */ + int aik_id; + /** * Shadow PCR set */ @@ -330,17 +336,16 @@ static void print_tpm_version_info(private_pts_t *this) #endif /* TSS_TROUSERS */ -METHOD(pts_t, get_platform_info, char*, +METHOD(pts_t, get_platform_id, int, private_pts_t *this) { - return this->platform_info; + return this->platform_id; } -METHOD(pts_t, set_platform_info, void, - private_pts_t *this, char *info) +METHOD(pts_t, set_platform_id, void, + private_pts_t *this, int pid) { - free(this->platform_info); - this->platform_info = strdup(info); + this->platform_id = pid; } METHOD(pts_t, get_tpm_version_info, bool, @@ -451,37 +456,17 @@ METHOD(pts_t, get_aik, certificate_t*, } METHOD(pts_t, set_aik, void, - private_pts_t *this, certificate_t *aik) + private_pts_t *this, certificate_t *aik, int aik_id) { DESTROY_IF(this->aik); this->aik = aik->get_ref(aik); + this->aik_id = aik_id; } -METHOD(pts_t, get_aik_keyid, bool, - private_pts_t *this, chunk_t *keyid) +METHOD(pts_t, get_aik_id, int, + private_pts_t *this) { - 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; + return this->aik_id; } METHOD(pts_t, is_path_valid, bool, @@ -1088,7 +1073,6 @@ METHOD(pts_t, destroy, void, free(this->initiator_nonce.ptr); free(this->responder_nonce.ptr); free(this->secret.ptr); - free(this->platform_info); free(this->aik_blob.ptr); free(this->tpm_version_info.ptr); free(this); @@ -1182,13 +1166,13 @@ pts_t *pts_create(bool is_imc) .get_my_public_value = _get_my_public_value, .set_peer_public_value = _set_peer_public_value, .calculate_secret = _calculate_secret, - .get_platform_info = _get_platform_info, - .set_platform_info = _set_platform_info, + .get_platform_id = _get_platform_id, + .set_platform_id = _set_platform_id, .get_tpm_version_info = _get_tpm_version_info, .set_tpm_version_info = _set_tpm_version_info, .get_aik = _get_aik, .set_aik = _set_aik, - .get_aik_keyid = _get_aik_keyid, + .get_aik_id = _get_aik_id, .is_path_valid = _is_path_valid, .get_metadata = _get_metadata, .read_pcr = _read_pcr, diff --git a/src/libpts/pts/pts.h b/src/libpts/pts/pts.h index bff1dba84e..fead588aec 100644 --- a/src/libpts/pts/pts.h +++ b/src/libpts/pts/pts.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Sansar Choinyambuu + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -162,19 +163,18 @@ struct pts_t { bool (*calculate_secret) (pts_t *this); /** - * Get Platform and OS Info + * Get primary key of platform entry in database * * @return Platform and OS info */ - char* (*get_platform_info)(pts_t *this); + int (*get_platform_id)(pts_t *this); /** - * Set Platform and OS Info + * Set primary key of platform entry in database * - * @param name OS name - * @param version OS version + * @param pid Primary key of platform entry in database */ - void (*set_platform_info)(pts_t *this, char *info); + void (*set_platform_id)(pts_t *this, int pid); /** * Get TPM 1.2 Version Info @@ -202,16 +202,16 @@ struct pts_t { * Set Attestation Identity Certificate or Public Key * * @param aik AIK Certificate or Public Key + * @param aik_id Primary key referencing AIK in database */ - void (*set_aik)(pts_t *this, certificate_t *aik); + void (*set_aik)(pts_t *this, certificate_t *aik, int aik_id); /** - * Get SHA-1 Attestation Identity Public Key Info ID + * Get primary key referencing AIK in database * - * @param keyid AIK ID - * @return TRUE if AIK ID exists + * @return Primary key referencing AIK in database */ - bool (*get_aik_keyid)(pts_t *this, chunk_t *keyid); + int (*get_aik_id)(pts_t *this); /** * Check whether path is valid file/directory on filesystem diff --git a/src/libpts/pts/pts_database.c b/src/libpts/pts/pts_database.c index 30002d7ef5..21c3ab9537 100644 --- a/src/libpts/pts/pts_database.c +++ b/src/libpts/pts/pts_database.c @@ -83,7 +83,7 @@ METHOD(pts_database_t, get_pathname, char*, } METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*, - private_pts_database_t *this, char *product, pts_meas_algorithms_t algo, + private_pts_database_t *this, int pid, pts_meas_algorithms_t algo, bool is_dir, int id) { enumerator_t *e; @@ -93,76 +93,32 @@ METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*, e = this->db->query(this->db, "SELECT f.name, fh.hash FROM file_hashes AS fh " "JOIN files AS f ON f.id = fh.file " - "JOIN products AS p ON p.id = fh.product " "JOIN directories as d ON d.id = f.dir " - "WHERE p.name = ? AND fh.algo = ? AND d.id = ? " + "WHERE fh.product = ? AND fh.algo = ? AND d.id = ? " "ORDER BY f.name", - DB_TEXT, product, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB); + DB_INT, pid, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB); } else { e = this->db->query(this->db, "SELECT f.name, fh.hash FROM file_hashes AS fh " "JOIN files AS f ON f.id = fh.file " - "JOIN products AS p ON p.id = fh.product " - "WHERE p.name = ? AND fh.algo = ? AND fh.file = ?", - DB_TEXT, product, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB); + "WHERE fh.product = ? AND fh.algo = ? AND fh.file = ?", + DB_INT, pid, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB); } return e; } -METHOD(pts_database_t, check_aik_keyid, status_t, - private_pts_database_t *this, chunk_t keyid, int *kid) -{ - enumerator_t *e; - chunk_t keyid_hex; - - /* Convert keyid into a hex-encoded string */ - keyid_hex = chunk_to_hex(keyid, NULL, FALSE); - - /* If the AIK is registered get the primary key */ - e = this->db->query(this->db, - "SELECT id FROM devices WHERE name = ?", - DB_TEXT, keyid_hex.ptr, DB_INT); - if (!e) - { - DBG1(DBG_PTS, "no database query enumerator returned"); - return FAILED; - } - if (!e->enumerate(e, kid)) - { - DBG1(DBG_PTS, "AIK %#B is not registered in database", &keyid); - e->destroy(e); - return FAILED; - } - e->destroy(e); - - return SUCCESS; -} - METHOD(pts_database_t, add_file_measurement, status_t, - private_pts_database_t *this, char *product, pts_meas_algorithms_t algo, + private_pts_database_t *this, int pid, pts_meas_algorithms_t algo, chunk_t measurement, char *filename, bool is_dir, int id) { enumerator_t *e; char *name; chunk_t hash_value; - int hash_id, fid, pid = 0; + int hash_id, fid; status_t status = SUCCESS; - /* get primary key of product string */ - e = this->db->query(this->db, - "SELECT id FROM products WHERE name = ?", DB_TEXT, product, DB_INT); - if (e) - { - e->enumerate(e, &pid); - e->destroy(e); - } - if (pid == 0) - { - return FAILED; - } - if (is_dir) { /* does filename entry already exist? */ @@ -249,7 +205,7 @@ METHOD(pts_database_t, add_file_measurement, status_t, } METHOD(pts_database_t, check_file_measurement, status_t, - private_pts_database_t *this, char *product, pts_meas_algorithms_t algo, + private_pts_database_t *this, int pid, pts_meas_algorithms_t algo, chunk_t measurement, char *filename) { enumerator_t *e; @@ -271,9 +227,8 @@ METHOD(pts_database_t, check_file_measurement, status_t, e = this->db->query(this->db, "SELECT fh.hash FROM file_hashes AS fh " "JOIN files AS f ON f.id = fh.file " - "JOIN products AS p ON p.id = fh.product " - "WHERE p.name = ? AND f.name = ? AND fh.algo = ?", - DB_TEXT, product, DB_TEXT, file, DB_INT, algo, DB_BLOB); + "WHERE fh.product = ? AND f.name = ? AND fh.algo = ?", + DB_INT, pid, DB_TEXT, file, DB_INT, algo, DB_BLOB); } else { /* absolute pathname */ @@ -300,9 +255,8 @@ METHOD(pts_database_t, check_file_measurement, status_t, e = this->db->query(this->db, "SELECT fh.hash FROM file_hashes AS fh " "JOIN files AS f ON f.id = fh.file " - "JOIN products AS p ON p.id = fh.product " - "WHERE p.name = ? AND f.dir = ? AND f.name = ? AND fh.algo = ?", - DB_TEXT, product, DB_INT, did, DB_TEXT, file, DB_INT, algo, + "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); } if (!e) @@ -332,23 +286,8 @@ err: return status; } -METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*, - private_pts_database_t *this, int kid) -{ - enumerator_t *e; - - /* look for all entries belonging to an AIK 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 " - "WHERE kc.key = ? ORDER BY kc.seq_no", - DB_INT, kid, 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, int cid, int kid, + private_pts_database_t *this, chunk_t measurement, int cid, int aik_id, int seq_no, int pcr, pts_meas_algorithms_t algo) { enumerator_t *e; @@ -359,7 +298,7 @@ METHOD(pts_database_t, check_comp_measurement, status_t, "SELECT hash FROM component_hashes " "WHERE component = ? AND key = ? " "AND seq_no = ? AND pcr = ? AND algo = ? ", - DB_INT, cid, DB_INT, kid, DB_INT, seq_no, + DB_INT, cid, DB_INT, aik_id, DB_INT, seq_no, DB_INT, pcr, DB_INT, algo, DB_BLOB); if (!e) { @@ -396,7 +335,7 @@ METHOD(pts_database_t, check_comp_measurement, status_t, } METHOD(pts_database_t, insert_comp_measurement, status_t, - private_pts_database_t *this, chunk_t measurement, int cid, int kid, + private_pts_database_t *this, chunk_t measurement, int cid, int aik_id, int seq_no, int pcr, pts_meas_algorithms_t algo) { int id; @@ -405,7 +344,7 @@ METHOD(pts_database_t, insert_comp_measurement, status_t, "INSERT INTO component_hashes " "(component, key, seq_no, pcr, algo, hash) " "VALUES (?, ?, ?, ?, ?, ?)", - DB_INT, cid, DB_INT, kid, DB_INT, seq_no, DB_INT, pcr, + DB_INT, cid, DB_INT, aik_id, DB_INT, seq_no, DB_INT, pcr, DB_INT, algo, DB_BLOB, measurement) == 1) { return SUCCESS; @@ -416,17 +355,17 @@ METHOD(pts_database_t, insert_comp_measurement, status_t, } METHOD(pts_database_t, delete_comp_measurements, int, - private_pts_database_t *this, int cid, int kid) + private_pts_database_t *this, int cid, int aik_id) { return this->db->execute(this->db, NULL, "DELETE FROM component_hashes " "WHERE component = ? AND key = ?", - DB_INT, cid, DB_INT, kid); + DB_INT, cid, DB_INT, aik_id); } METHOD(pts_database_t, get_comp_measurement_count, status_t, private_pts_database_t *this, pts_comp_func_name_t *comp_name, - chunk_t keyid, pts_meas_algorithms_t algo, int *cid, int *kid, int *count) + int aik_id, pts_meas_algorithms_t algo, int *cid, int *count) { enumerator_t *e; status_t status = SUCCESS; @@ -434,11 +373,6 @@ METHOD(pts_database_t, get_comp_measurement_count, status_t, /* Initialize count */ *count = 0; - if (_check_aik_keyid(this, keyid, kid) != SUCCESS) - { - return FAILED; - } - /* Get the primary key of the Component Functional Name */ e = this->db->query(this->db, "SELECT id FROM components " @@ -464,7 +398,7 @@ METHOD(pts_database_t, get_comp_measurement_count, status_t, e = this->db->query(this->db, "SELECT COUNT(*) FROM component_hashes AS ch " "WHERE component = ? AND key = ? AND algo = ?", - DB_INT, *cid, DB_INT, *kid, DB_INT, algo, DB_INT); + DB_INT, *cid, DB_INT, aik_id, DB_INT, algo, DB_INT); if (!e) { DBG1(DBG_PTS, "no database query enumerator returned"); @@ -501,7 +435,6 @@ pts_database_t *pts_database_create(imv_database_t *imv_db) INIT(this, .public = { .get_pathname = _get_pathname, - .create_comp_evid_enumerator = _create_comp_evid_enumerator, .create_file_hash_enumerator = _create_file_hash_enumerator, .add_file_measurement = _add_file_measurement, .check_file_measurement = _check_file_measurement, diff --git a/src/libpts/pts/pts_database.h b/src/libpts/pts/pts_database.h index 323d1b8543..46704f5e14 100644 --- a/src/libpts/pts/pts_database.h +++ b/src/libpts/pts/pts_database.h @@ -47,37 +47,20 @@ struct pts_database_t { /** * Get stored measurement hash for single file or directory entries * - * @param product Software product (os, vpn client, etc.) + * @param pid Primary key of software product in database * @param algo Hash algorithm used for measurement * @param is_dir TRUE if directory was measured * @param id Primary key of measured file/directory * @return Enumerator over all matching measurement hashes */ enumerator_t* (*create_file_hash_enumerator)(pts_database_t *this, - char *product, pts_meas_algorithms_t algo, + int pid, pts_meas_algorithms_t algo, bool is_dir, int id); - /** - * Check if an AIK given by its keyid is registered in the database - * - * @param keyid AIK keyid (SHA-1 hash of the AIK public key info) - * @param kid Primary key of AIK entry in devices table - * @return SUCCESS if AIK is present, FAILED otherwise - */ - status_t (*check_aik_keyid)(pts_database_t *this, chunk_t keyid, int *kid); - - /** - * Get functional components to request evidence of - * - * @param kid Primary key of AIK entry in keys table - * @return Enumerator over all matching components - */ - enumerator_t* (*create_comp_evid_enumerator)(pts_database_t *this, int kid); - /** * Add PTS file measurement reference value * - * @param product Software product (os, vpn client, etc.) + * @param pid Primary key of software product in database * @param algo File measurement hash algorithm used * @param measurement File measurement hash * @param filename Optional name of the file to be checked @@ -85,7 +68,7 @@ struct pts_database_t { * @param id Primary key into direcories/files table * @return Status */ - status_t (*add_file_measurement)(pts_database_t *this, char *product, + 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); @@ -93,13 +76,13 @@ struct pts_database_t { /** * Check PTS file measurement against reference stored in database * - * @param product Software product (os, vpn client, etc.) + * @param pid Primary key of software product in database * @param algo File measurement hash algorithm used * @param measurement File measurement hash * @param filename Optional name of the file to be checked * @return Status */ - status_t (*check_file_measurement)(pts_database_t *this, char *product, + status_t (*check_file_measurement)(pts_database_t *this, int pid, pts_meas_algorithms_t algo, chunk_t measurement, char *filename); @@ -108,14 +91,14 @@ struct pts_database_t { * * @param measurement measurement hash * @param cid Primary key of Component Functional Name entry - * @param kid Primary key of AIK entry in keys table + * @param aik_id Primary key of AIK entry in database * @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 SUCCESS if check was successful */ status_t (*check_comp_measurement)(pts_database_t *this, chunk_t measurement, - int cid, int kid, int seq_no, int pcr, + int cid, int aik_id, int seq_no, int pcr, pts_meas_algorithms_t algo); /** @@ -123,40 +106,38 @@ struct pts_database_t { * * @param measurement Measurement hash * @param cid Primary key of Component Functional Name entry - * @param kid Primary key of AIK entry in keys table + * @param aik_id Primary key of AIK entry in database * @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 SUCCESS if INSERT was successful */ status_t (*insert_comp_measurement)(pts_database_t *this, chunk_t measurement, - int cid, int kid, int seq_no, int pcr, + int cid, int aik_id, int seq_no, int pcr, pts_meas_algorithms_t algo); /** * Delete functional component measurements from the database * * @param cid Primary key of Component Functional Name entry - * @param kid Primary key of AIK entry in keys table + * @param aik_id Primary key of AIK entry in database * @return number of deleted measurement entries */ - int (*delete_comp_measurements)(pts_database_t *this, int cid, int kid); + int (*delete_comp_measurements)(pts_database_t *this, int cid, int aik_id); /** * 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 aik_id Primary key of AIK entry in database * @param algo Hash algorithm used for measurement * @param cid Primary key of Component Functional Name entry - * @param kid Primary key of AIK entry in keys table * @param count measurement count * @return SUCCESS if COUNT was successful */ status_t (*get_comp_measurement_count)(pts_database_t *this, - pts_comp_func_name_t *comp_name, chunk_t keyid, - pts_meas_algorithms_t algo, int *cid, int *kid, - int *count); + pts_comp_func_name_t *comp_name, int aik_id, + pts_meas_algorithms_t algo, int *cid, int *count); /** * Destroys a pts_database_t object. diff --git a/src/libpts/pts/pts_file_meas.c b/src/libpts/pts/pts_file_meas.c index 77a0957bbb..1e68436cf4 100644 --- a/src/libpts/pts/pts_file_meas.c +++ b/src/libpts/pts/pts_file_meas.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Sansar Choinyambuu + * Copyright (C) 2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -112,7 +113,7 @@ METHOD(pts_file_meas_t, create_enumerator, enumerator_t*, } METHOD(pts_file_meas_t, check, bool, - private_pts_file_meas_t *this, pts_database_t *pts_db, char *product, + private_pts_file_meas_t *this, pts_database_t *pts_db, int pid, pts_meas_algorithms_t algo) { enumerator_t *enumerator; @@ -123,7 +124,7 @@ METHOD(pts_file_meas_t, check, bool, enumerator = this->list->create_enumerator(this->list); while (enumerator->enumerate(enumerator, &entry)) { - status = pts_db->check_file_measurement(pts_db, product, algo, + status = pts_db->check_file_measurement(pts_db, pid, algo, entry->measurement, entry->filename); switch (status) { diff --git a/src/libpts/pts/pts_file_meas.h b/src/libpts/pts/pts_file_meas.h index a13bb29ba2..4bf28e2803 100644 --- a/src/libpts/pts/pts_file_meas.h +++ b/src/libpts/pts/pts_file_meas.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Sansar Choinyambuu + * Copyright (C) 2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -65,11 +66,11 @@ struct pts_file_meas_t { * Check PTS File Measurements against reference value in the database * * @param db PTS Measurement database - * @param product Software product (os, vpn client, etc.) + * @param pid Primary key of software product in database * @param algo PTS Measurement algorithm used * @return TRUE if all measurements agreed */ - bool (*check)(pts_file_meas_t *this, pts_database_t *db, char* product, + bool (*check)(pts_file_meas_t *this, pts_database_t *db, int pid, pts_meas_algorithms_t algo); /**