implemented support if functional sub-components
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 30 Jul 2012 18:48:05 +0000 (20:48 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 30 Jul 2012 18:49:42 +0000 (20:49 +0200)
19 files changed:
src/libpts/plugins/imc_attestation/imc_attestation_process.c
src/libpts/plugins/imc_attestation/imc_attestation_state.c
src/libpts/plugins/imc_attestation/imc_attestation_state.h
src/libpts/plugins/imv_attestation/data.sql
src/libpts/plugins/imv_attestation/imv_attestation_build.c
src/libpts/plugins/imv_attestation/imv_attestation_process.c
src/libpts/plugins/imv_attestation/imv_attestation_state.c
src/libpts/plugins/imv_attestation/imv_attestation_state.h
src/libpts/pts/components/ita/ita_comp_ima.c
src/libpts/pts/components/ita/ita_comp_ima.h
src/libpts/pts/components/ita/ita_comp_tboot.c
src/libpts/pts/components/ita/ita_comp_tboot.h
src/libpts/pts/components/ita/ita_comp_tgrub.c
src/libpts/pts/components/ita/ita_comp_tgrub.h
src/libpts/pts/components/pts_comp_func_name.c
src/libpts/pts/components/pts_comp_func_name.h
src/libpts/pts/components/pts_component.h
src/libpts/pts/components/pts_component_manager.c
src/libpts/pts/components/pts_component_manager.h

index f2540a9..8be7a31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
 
 #include <ietf/ietf_attr_pa_tnc_error.h>
 
-#include <libpts.h>
 #include <pts/pts.h>
 
 #include <tcg/tcg_pts_attr_proto_caps.h>
@@ -378,7 +377,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                                                  "support sub component measurements");
                                        return FALSE;
                                }
-                               comp = pts_components->create(pts_components, name, depth, NULL);
+                               comp = attestation_state->create_component(attestation_state,
+                                                                                                                  name, depth);
                                if (!comp)
                                {
                                        DBG2(DBG_IMC, "    not registered: no evidence provided");
@@ -388,7 +388,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                /* do the component evidence measurement[s] and cache them */
                                do
                                {
-                                       status = comp->measure(comp, pts, &evid);
+                                       status = comp->measure(comp, name->get_qualifier(name),
+                                                                                  pts, &evid);
                                        if (status == FAILED)
                                        {
                                                break;
@@ -396,7 +397,6 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                        attestation_state->add_evidence(attestation_state, evid);
                                }
                                while (status == NEED_MORE);
-                               comp->destroy(comp);
                        }
                        e->destroy(e);
                        break;
index 5872724..65662db 100644 (file)
 
 #include "imc_attestation_state.h"
 
+#include <libpts.h>
+
 #include <utils/linked_list.h>
 #include <debug.h>
 
 typedef struct private_imc_attestation_state_t private_imc_attestation_state_t;
+typedef struct func_comp_t func_comp_t;
 
 /**
  * Private data of an imc_attestation_state_t object.
@@ -61,7 +64,12 @@ struct private_imc_attestation_state_t {
        pts_t *pts;
 
        /**
-        * PA-TNC attribute cache list
+        * List of Functional Components
+        */
+       linked_list_t *components;
+
+       /**
+        * Functional Component Evidence cache list
         */
        linked_list_t *list;
 
@@ -110,12 +118,14 @@ METHOD(imc_state_t, change_state, void,
        this->state = new_state;
 }
 
-
 METHOD(imc_state_t, destroy, void,
        private_imc_attestation_state_t *this)
 {
        this->pts->destroy(this->pts);
-       this->list->destroy_offset(this->list, offsetof(pts_comp_evidence_t, destroy));
+       this->components->destroy_offset(this->components,
+                                                       offsetof(pts_component_t, destroy));
+       this->list->destroy_offset(this->list,
+                                                       offsetof(pts_comp_evidence_t, destroy));
        free(this);
 }
 
@@ -125,6 +135,38 @@ METHOD(imc_attestation_state_t, get_pts, pts_t*,
        return this->pts;
 }
 
+METHOD(imc_attestation_state_t, create_component, pts_component_t*,
+       private_imc_attestation_state_t *this, pts_comp_func_name_t *name,
+       u_int32_t depth)
+{
+       enumerator_t *enumerator;
+       pts_component_t *component;
+       bool found = FALSE;
+
+       enumerator = this->components->create_enumerator(this->components);
+       while (enumerator->enumerate(enumerator, &component))
+       {
+               if (name->equals(name, component->get_comp_func_name(component)))
+               {
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       if (!found)
+       {
+               component = pts_components->create(pts_components, name, depth, NULL);
+               if (!component)
+               {
+                       return NULL;
+               }
+               this->components->insert_last(this->components, component);
+
+       }
+       return component;
+}
+
 METHOD(imc_attestation_state_t, add_evidence, void,
        private_imc_attestation_state_t *this, pts_comp_evidence_t *evid)
 {
@@ -158,12 +200,14 @@ imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
                                .destroy = _destroy,
                        },
                        .get_pts = _get_pts,
+                       .create_component = _create_component,
                        .add_evidence = _add_evidence,
                        .next_evidence = _next_evidence,
                },
                .connection_id = connection_id,
                .state = TNC_CONNECTION_STATE_CREATE,
                .pts = pts_create(TRUE),
+               .components = linked_list_create(),
                .list = linked_list_create(),
        );
 
index 548b128..e4fca71 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <imc/imc_state.h>
 #include <pts/pts.h>
+#include <pts/components/pts_component.h>
 #include <pts/components/pts_comp_evidence.h>
 #include <library.h>
 
@@ -47,6 +48,16 @@ struct imc_attestation_state_t {
        pts_t* (*get_pts)(imc_attestation_state_t *this);
 
        /**
+        * Create and add an entry to the list of Functional Components
+        *
+        * @param name                          Component Functional Name
+        * @param depth                         Sub-component Depth
+        * @return                                      created functional component instance or NULL
+        */
+       pts_component_t* (*create_component)(imc_attestation_state_t *this,
+                                                        pts_comp_func_name_t *name, u_int32_t depth);
+
+       /**
         * Add an entry to the Component Evidence cache list
         *
         * @param evid                          Component Evidence entry
index e014711..adeae3e 100644 (file)
@@ -1599,7 +1599,13 @@ INSERT INTO components (
 INSERT INTO components (
   vendor_id, name, qualifier
 ) VALUES (
-  36906, 3, 33  /* ITA IMA */
+  36906, 3, 33  /* ITA IMA - Trusted Platform */
+);
+
+INSERT INTO components (
+  vendor_id, name, qualifier
+) VALUES (
+  36906, 3, 34  /* ITA IMA - Operating System */
 );
 
 /* AIK Component */
@@ -1607,18 +1613,18 @@ INSERT INTO components (
 INSERT INTO key_component (
   key, component, depth, seq_no
 ) VALUES (
-  2, 2, 0, 1
+  1, 3, 0, 1
 );
 
 INSERT INTO key_component (
   key, component, depth, seq_no
 ) VALUES (
-  1, 3, 0, 1
+  1, 2, 0, 2
 );
 
 INSERT INTO key_component (
   key, component, depth, seq_no
 ) VALUES (
-  1, 2, 0, 2
+  1, 4, 0, 3
 );
 
index a44e933..1071fc9 100644 (file)
@@ -16,7 +16,6 @@
 #include "imv_attestation_build.h"
 #include "imv_attestation_state.h"
 
-#include <libpts.h>
 #include <tcg/tcg_pts_attr_proto_caps.h>
 #include <tcg/tcg_pts_attr_meas_algo.h>
 #include <tcg/tcg_pts_attr_dh_nonce_params_req.h>
@@ -252,15 +251,15 @@ bool imv_attestation_build(linked_list_t *attr_list,
                                comp_name = pts_comp_func_name_create(vid, name, qualifier);
                                comp_name->log(comp_name, "  ");
 
-                               comp = pts_components->create(pts_components, comp_name,
-                                                                                         depth, pts_db);
+                               comp = attestation_state->create_component(attestation_state,
+                                                                                                       comp_name, depth, pts_db);
                                if (!comp)
                                {
-                                       DBG2(DBG_IMV, "    not registered: removed from request");
+                                       DBG2(DBG_IMV, "    not registered or duplicate"
+                                                                 " - removed from request");
                                        comp_name->destroy(comp_name);
                                        continue;
                                }
-                               attestation_state->add_component(attestation_state, comp);
                                if (first_component)
                                {
                                        attr = tcg_pts_attr_req_func_comp_evid_create();
index 5efcf7f..e1d56fe 100644 (file)
@@ -294,7 +294,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                DBG1(DBG_IMV, "  no entry found for component evidence request");
                                break;
                        }
-                       if (comp->verify(comp, pts, evidence) != SUCCESS)
+                       if (comp->verify(comp, name->get_qualifier(name), pts,
+                                                        evidence) != SUCCESS)
                        {
                                attestation_state->set_measurement_error(attestation_state);
                                name->log(name, "  measurement mismatch for ");
index a093e63..1dbc883 100644 (file)
 
 #include "imv_attestation_state.h"
 
+#include <libpts.h>
+
 #include <utils/lexparser.h>
 #include <utils/linked_list.h>
 #include <debug.h>
 
 typedef struct private_imv_attestation_state_t private_imv_attestation_state_t;
 typedef struct file_meas_request_t file_meas_request_t;
-
-/**
- * PTS File/Directory Measurement request entry
- */
-struct file_meas_request_t {
-       u_int16_t id;
-       int file_id;
-       bool is_dir;
-};
+typedef struct func_comp_t func_comp_t;
 
 /**
  * Private data of an imv_attestation_state_t object.
@@ -108,6 +102,32 @@ struct private_imv_attestation_state_t {
 
 };
 
+/**
+ * PTS File/Directory Measurement request entry
+ */
+struct file_meas_request_t {
+       u_int16_t id;
+       int file_id;
+       bool is_dir;
+};
+
+/**
+ * PTS Functional Component entry
+ */
+struct func_comp_t {
+       pts_component_t *comp;
+       u_int8_t qualifier;
+};
+
+/**
+ * Frees a func_comp_t object
+ */
+static void free_func_comp(func_comp_t *this)
+{
+       this->comp->destroy(this->comp);
+       free(this);
+}
+
 typedef struct entry_t entry_t;
 
 /**
@@ -237,8 +257,7 @@ METHOD(imv_state_t, destroy, void,
        private_imv_attestation_state_t *this)
 {
        this->file_meas_requests->destroy_function(this->file_meas_requests, free);
-       this->components->destroy_offset(this->components,
-                                                                        offsetof(pts_component_t, destroy));
+       this->components->destroy_function(this->components, (void *)free_func_comp);
        this->pts->destroy(this->pts);
        free(this);
 }
@@ -307,24 +326,69 @@ METHOD(imv_attestation_state_t, get_file_meas_request_count, int,
        return this->file_meas_requests->get_count(this->file_meas_requests);
 }
 
-METHOD(imv_attestation_state_t, add_component, void,
-       private_imv_attestation_state_t *this, pts_component_t *entry)
+METHOD(imv_attestation_state_t, create_component, pts_component_t*,
+       private_imv_attestation_state_t *this, pts_comp_func_name_t *name,
+       u_int32_t depth, pts_database_t *pts_db)
 {
-       this->components->insert_last(this->components, entry);
+       enumerator_t *enumerator;
+       func_comp_t *entry, *new_entry;
+       pts_component_t *component;
+       bool found = FALSE;
+
+       enumerator = this->components->create_enumerator(this->components);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)))
+               {
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       if (found)
+       {
+               if (name->get_qualifier(name) == entry->qualifier)
+               {
+                       /* duplicate entry */
+                       return NULL;
+               }
+               new_entry = malloc_thing(func_comp_t);
+               new_entry->qualifier = name->get_qualifier(name);
+               new_entry->comp = entry->comp->get_ref(entry->comp);
+               this->components->insert_last(this->components, new_entry);
+               return entry->comp;
+       }
+       else
+       {
+               component = pts_components->create(pts_components, name, depth, pts_db);
+               if (!component)
+               {
+                       /* unsupported component */
+                       return NULL;
+               }
+               new_entry = malloc_thing(func_comp_t);
+               new_entry->qualifier = name->get_qualifier(name);
+               new_entry->comp = component;
+               this->components->insert_last(this->components, new_entry);
+               return component;
+       }
 }
 
 METHOD(imv_attestation_state_t, get_component, pts_component_t*,
        private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
 {
        enumerator_t *enumerator;
-       pts_component_t *entry, *found = NULL;
+       func_comp_t *entry;
+       pts_component_t *found = NULL;
 
        enumerator = this->components->create_enumerator(this->components);
        while (enumerator->enumerate(enumerator, &entry))
        {
-               if (name->equals(name, entry->get_comp_func_name(entry)))
+               if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)) &&
+                       name->get_qualifier(name) == entry->qualifier)
                {
-                       found = entry;
+                       found = entry->comp;
                        break;
                }
        }
@@ -347,16 +411,16 @@ METHOD(imv_attestation_state_t, set_measurement_error, void,
 METHOD(imv_attestation_state_t, finalize_components, void,
        private_imv_attestation_state_t *this)
 {
-       pts_component_t *entry;
+       func_comp_t *entry;
 
        while (this->components->remove_last(this->components,
                                                                                (void**)&entry) == SUCCESS)
        {
-               if (!entry->finalize(entry))
+               if (!entry->comp->finalize(entry->comp, entry->qualifier))
                {
                        _set_measurement_error(this);
                }
-               entry->destroy(entry);
+               free_func_comp(entry);
        }
 }
 
@@ -395,7 +459,7 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
                        .add_file_meas_request = _add_file_meas_request,
                        .check_off_file_meas_request = _check_off_file_meas_request,
                        .get_file_meas_request_count = _get_file_meas_request_count,
-                       .add_component = _add_component,
+                       .create_component = _create_component,
                        .get_component = _get_component,
                        .finalize_components = _finalize_components,
                        .components_finalized = _components_finalized,
index 1fd983b..901d4b1 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <imv/imv_state.h>
 #include <pts/pts.h>
+#include <pts/pts_database.h>
 #include <pts/components/pts_component.h>
 #include <library.h>
 
@@ -105,11 +106,17 @@ struct imv_attestation_state_t {
                                                                                u_int16_t id, int *file_id, bool *is_dir);
 
        /**
-        * Add an entry to the list of Functional Components waiting for evidence
+        * Create and add an entry to the list of Functional Components
         *
-        * @param entry                         Functional Component
+        * @param name                          Component Functional Name
+        * @param depth                         Sub-component Depth
+        * @param pts_db                        PTS measurement database
+        * @return                                      created functional component instance or NULL
         */
-       void (*add_component)(imv_attestation_state_t *this, pts_component_t *entry);
+       pts_component_t* (*create_component)(imv_attestation_state_t *this,
+                                                                                pts_comp_func_name_t *name,
+                                                                                u_int32_t depth,
+                                                                                pts_database_t *pts_db);
 
        /**
         * Get a Functional Component with a given name
index 8fbf6c0..dc3fc79 100644 (file)
@@ -81,19 +81,29 @@ struct pts_ita_comp_ima_t {
        pts_database_t *pts_db;
 
        /**
-        * Primary key for Component Functional Name database entry
+        * Primary key for AIK database entry
         */
-       int cid;
+       int kid;
 
        /**
-        * Primary key for AIK database entry
+        * Primary key for IMA BIOS Component Functional Name database entry
         */
-       int kid;
+       int bios_cid;
+
+       /**
+        * Primary key for IMA Runtime Component Functional Name database entry
+        */
+       int ima_cid;
+
+       /**
+        * Component is registering IMA BIOS measurements 
+        */
+       bool is_bios_registering;
 
        /**
-        * Component is registering measurements 
+        * Component is registering IMA boot aggregate measurement 
         */
-       bool is_registering;
+       bool is_ima_registering;
 
        /**
         * Measurement sequence number
@@ -155,6 +165,11 @@ struct pts_ita_comp_ima_t {
         */
        int count_failed;
 
+       /**
+        * Reference count
+        */
+       refcount_t ref;
+
 };
 
 /**
@@ -369,12 +384,14 @@ static bool load_runtime_measurements(char *file, linked_list_t *list,
 /**
  * Extend measurement into PCR an create evidence
  */
-static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs,
+static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this,
+                                                                          u_int8_t qualifier, pts_pcr_t *pcrs,
                                                                           u_int32_t pcr, chunk_t measurement)
 {
        size_t pcr_len;
        pts_pcr_transform_t pcr_transform;
        pts_meas_algorithms_t hash_algo;
+       pts_comp_func_name_t *name;
        pts_comp_evidence_t *evidence;
        chunk_t pcr_before = chunk_empty, pcr_after = chunk_empty;
 
@@ -392,9 +409,10 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs
                free(pcr_before.ptr);
                return NULL;
        }
-       evidence = pts_comp_evidence_create(this->name->clone(this->name),
-                                                               this->depth, pcr, hash_algo, pcr_transform,
-                                                               this->measurement_time, measurement);
+       name = this->name->clone(this->name);
+       name->set_qualifier(name, qualifier);
+       evidence = pts_comp_evidence_create(name, this->depth, pcr, hash_algo,
+                                       pcr_transform, this->measurement_time, measurement);
        if (this->pcr_info)
        {
                pcr_after =chunk_clone(pcrs->get(pcrs, pcr));
@@ -406,20 +424,21 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs
 /**
  * Compute and check boot aggregate value by hashing PCR0 to PCR7
  */
-static void check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
+static bool check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
 {
        u_int32_t i;
        u_char filename_buffer[IMA_FILENAME_LEN_MAX + 1];
        u_char pcr_buffer[HASH_SIZE_SHA1];
        chunk_t file_name, boot_aggregate;
        hasher_t *hasher;
-       bool pcr_ok = TRUE;
+       bool success, pcr_ok = TRUE;
 
        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
        if (!hasher)
        {
                DBG1(DBG_PTS, "%N hasher could not be created",
                         hash_algorithm_short_names, HASH_SHA1);
+               return FALSE;
        }
        for (i = 0; i < 8 && pcr_ok; i++)
        {
@@ -440,12 +459,15 @@ static void check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
 
        if (pcr_ok)
        {
+               success = chunk_equals(boot_aggregate, measurement);
                DBG1(DBG_PTS, "boot aggregate value is %scorrect",
-                        chunk_equals(boot_aggregate, measurement) ? "":"in");
+                                          success ? "":"in");
+               return success;
        }
        else
        {
                DBG1(DBG_PTS, "failed to compute boot aggregate value");
+               return FALSE;
        }
 }
 
@@ -468,7 +490,8 @@ METHOD(pts_component_t, get_depth, u_int32_t,
 }
 
 METHOD(pts_component_t, measure, status_t,
-       pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+       pts_ita_comp_ima_t *this, u_int8_t qualifier, pts_t *pts,
+       pts_comp_evidence_t **evidence)
 {
        bios_entry_t *bios_entry;
        ima_entry_t *ima_entry;
@@ -478,84 +501,107 @@ METHOD(pts_component_t, measure, status_t,
 
        pcrs = pts->get_pcrs(pts);
 
-       switch (this->state)
+       if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                         PTS_ITA_QUALIFIER_TYPE_TRUSTED))
        {
-               case IMA_STATE_INIT:
-                       if (!load_bios_measurements(IMA_BIOS_MEASUREMENTS, this->bios_list,
-                               &this->measurement_time))
-                       {
-                               return FAILED;
-                       }
-                       this->state = IMA_STATE_BIOS;
-                       /* fall through to next state */
-               case IMA_STATE_BIOS:
-                       status = this->bios_list->remove_first(this->bios_list,
-                                                                                                 (void**)&bios_entry);
-                       if (status != SUCCESS)
-                       {
-                               DBG1(DBG_PTS, "could not retrieve bios measurement entry");
-                               return status;
-                       }
-                       evid = extend_pcr(this, pcrs, bios_entry->pcr,
-                                                                                 bios_entry->measurement);
-                       free(bios_entry);
+               switch (this->state)
+               {
+                       case IMA_STATE_INIT:
+                               if (!load_bios_measurements(IMA_BIOS_MEASUREMENTS,
+                                       this->bios_list, &this->measurement_time))
+                               {
+                                       return FAILED;
+                               }
+                               this->bios_count = this->bios_list->get_count(this->bios_list);
+                               this->state = IMA_STATE_BIOS;
+                               /* fall through to next state */
+                       case IMA_STATE_BIOS:
+                               status = this->bios_list->remove_first(this->bios_list,
+                                                                                                         (void**)&bios_entry);
+                               if (status != SUCCESS)
+                               {
+                                       DBG1(DBG_PTS, "could not retrieve bios measurement entry");
+                                       return status;
+                               }
+                               evid = extend_pcr(this, qualifier, pcrs, bios_entry->pcr,
+                                                                 bios_entry->measurement);
+                               free(bios_entry);
        
-                       /* break if still some BIOS measurements are left */
-                       if (this->bios_list->get_count(this->bios_list))
-                       {
+                               this->state = this->bios_list->get_count(this->bios_list) ?
+                                                                               IMA_STATE_BIOS : IMA_STATE_INIT;
                                break;
-                       }
-
-                       /* check if IMA runtime measurements are enabled */
-                       if (!load_runtime_measurements(IMA_RUNTIME_MEASUREMENTS,
-                                                       this->ima_list, &this->measurement_time))
-                       {
+                       default:
                                return FAILED;
-                       }
-
-                       this->state = this->ima_list->get_count(this->ima_list) ?
-                                                                       IMA_STATE_BOOT_AGGREGATE : IMA_STATE_END;
-                       break;
-               case IMA_STATE_BOOT_AGGREGATE:
-               case IMA_STATE_RUNTIME:
-                       status = this->ima_list->remove_first(this->ima_list,
-                                                                                                (void**)&ima_entry);
-                       if (status != SUCCESS)
-                       {
-                               DBG1(DBG_PTS, "could not retrieve ima measurement entry");
-                               return status;
-                       }
-                       if (this->state == IMA_STATE_BOOT_AGGREGATE)
-                       {
-                               check_boot_aggregate(pcrs, ima_entry->measurement);
-                       }
-
-                       evid = extend_pcr(this, pcrs, IMA_PCR, ima_entry->measurement);
-                       if (evid)
-                       {
-                               evid->set_validation(evid, PTS_COMP_EVID_VALIDATION_PASSED,
-                                                                                  ima_entry->filename);
-                       }
-                       free(ima_entry->filename);
-                       free(ima_entry);
+               }
+       }
+       else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                                  PTS_ITA_QUALIFIER_TYPE_OS))
+       {
+               switch (this->state)
+               {
+                       case IMA_STATE_INIT:
+                               if (!load_runtime_measurements(IMA_RUNTIME_MEASUREMENTS,
+                                                               this->ima_list, &this->measurement_time))
+                               {
+                                       return FAILED;
+                               }
+                               this->state = IMA_STATE_BOOT_AGGREGATE;
+                               /* fall through to next state */
+                       case IMA_STATE_BOOT_AGGREGATE:
+                       case IMA_STATE_RUNTIME:
+                               status = this->ima_list->remove_first(this->ima_list,
+                                                                                                        (void**)&ima_entry);
+                               if (status != SUCCESS)
+                               {
+                                       DBG1(DBG_PTS, "could not retrieve ima measurement entry");
+                                       return status;
+                               }
+                               if (this->state == IMA_STATE_BOOT_AGGREGATE && this->bios_count)
+                               {
+                                       if (!check_boot_aggregate(pcrs, ima_entry->measurement))
+                                       {
+                                               return FAILED;
+                                       }
+                               }
+                               evid = extend_pcr(this, qualifier, pcrs, IMA_PCR,
+                                                                 ima_entry->measurement);
+                               if (evid)
+                               {
+                                       evid->set_validation(evid, PTS_COMP_EVID_VALIDATION_PASSED,
+                                                                                          ima_entry->filename);
+                               }
+                               free(ima_entry->filename);
+                               free(ima_entry);
 
-                       this->state = this->ima_list->get_count(this->ima_list) ?
+                               this->state = this->ima_list->get_count(this->ima_list) ?
                                                                        IMA_STATE_RUNTIME : IMA_STATE_END;
-                       break;
-               case IMA_STATE_END:
-                       break;
+                               break;
+                       default:
+                               return FAILED;
+               }
+       }
+       else
+       {
+               DBG1(DBG_PTS, "unsupported functional component name qualifier");
+               return FAILED;
        }
 
        *evidence = evid;
-       return evid ? ((this->state == IMA_STATE_END) ? SUCCESS : NEED_MORE) :
-                                       FAILED;
+       if (!evid)
+       {
+               return FAILED;
+       }
+
+       return (this->state == IMA_STATE_INIT || this->state == IMA_STATE_END) ?
+                       SUCCESS : NEED_MORE;
 }
 
 METHOD(pts_component_t, verify, status_t,
-       pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+       pts_ita_comp_ima_t *this, u_int8_t qualifier, pts_t *pts,
+       pts_comp_evidence_t *evidence)
 {
        bool has_pcr_info;
-       u_int32_t extended_pcr, vid, name;
+       u_int32_t pcr, vid, name;
        enum_name_t *names;
        pts_meas_algorithms_t algo;
        pts_pcr_transform_t transform;
@@ -565,56 +611,65 @@ 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;
+               }
+       }
+
        pcrs = pts->get_pcrs(pts);
-       measurement = evidence->get_measurement(evidence, &extended_pcr,
-                                                               &algo, &transform, &measurement_time);
+       measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
+                                                                                       &measurement_time);
 
-       switch (this->state)
+       if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                         PTS_ITA_QUALIFIER_TYPE_TRUSTED))
        {
-               case IMA_STATE_INIT:
-                       if (!pts->get_aik_keyid(pts, &this->keyid))
-                       {
-                               return FAILED;
-                       }
-                       this->keyid = chunk_clone(this->keyid);
+               switch (this->state)
+               {
+                       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->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
+                               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);
 
-                       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->bios_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);
-
-                       if (this->bios_count)
-                       {
-                               DBG1(DBG_PTS, "checking %d %N '%N' BIOS evidence measurements",
-                                                          this->bios_count, pen_names, vid, names, name);
-                       }
-                       else
-                       {
-                               DBG1(DBG_PTS, "registering %N '%N' BIOS evidence measurements",
-                                                          pen_names, vid, names, name);
-                               this->is_registering = TRUE;
-                       }
-                       this->state = IMA_STATE_BIOS;
-                       /* fall through to next state */
-               case IMA_STATE_BIOS:
-                       if (extended_pcr != IMA_PCR)
-                       {
-                               if (this->is_registering)
+                               if (this->bios_count)
+                               {
+                                       DBG1(DBG_PTS, "checking %d %N '%N' BIOS evidence measurements",
+                                                                  this->bios_count, pen_names, vid, names, name);
+                               }
+                               else
+                               {
+                                       DBG1(DBG_PTS, "registering %N '%N' BIOS evidence measurements",
+                                                                  pen_names, vid, names, name);
+                                       this->is_bios_registering = TRUE;
+                               }
+
+                               this->state = IMA_STATE_BIOS;
+                               /* fall through to next state */
+                       case IMA_STATE_BIOS:
+                               if (this->is_bios_registering)
                                {
                                        status = this->pts_db->insert_comp_measurement(this->pts_db,
-                                                                                       measurement, this->cid, this->kid,
-                                                                                       ++this->seq_no, extended_pcr, algo);
+                                                                               measurement, this->bios_cid, this->kid,
+                                                                               ++this->seq_no, pcr, algo);
                                        if (status != SUCCESS)
                                        {
                                                return status;
@@ -624,75 +679,129 @@ METHOD(pts_component_t, verify, status_t,
                                else
                                {
                                        status = this->pts_db->check_comp_measurement(this->pts_db,
-                                                                                       measurement, this->cid, this->kid,
-                                                                                       ++this->seq_no, extended_pcr, algo);
+                                                                               measurement, this->bios_cid, this->kid,
+                                                                               ++this->seq_no, pcr, algo);
                                        if (status != SUCCESS)
                                        {
                                                return status;
                                        }
                                }
                                break;
-                       }
-                       this->state = IMA_STATE_BOOT_AGGREGATE;
-                       /* fall through to next state */
-               case IMA_STATE_BOOT_AGGREGATE:
-                       check_boot_aggregate(pcrs, measurement);
-                       this->state = IMA_STATE_RUNTIME;
-                       break;
-               case IMA_STATE_RUNTIME:
-                       this->count++;
-                       if (evidence->get_validation(evidence, &uri) !=
-                               PTS_COMP_EVID_VALIDATION_PASSED)
-                       {
-                               DBG1(DBG_PTS, "policy URI could no be retrieved");
-                               this->count_failed++;
+                       default:
                                return FAILED;
-                       }
-                       status = this->pts_db->check_file_measurement(this->pts_db,
-                                                                                       pts->get_platform_info(pts),
-                                                                                       PTS_MEAS_ALGO_SHA1_IMA,
-                                                                                       measurement, uri);
-                       switch (status)
-                       {
-                               case SUCCESS:
-                                       DBG3(DBG_PTS, "%#B for '%s' is ok", &measurement, uri);
-                                       this->count_ok++;
-                               break;
-                               case NOT_FOUND:
-                               DBG2(DBG_PTS, "%#B for '%s' not found", &measurement, uri);
-                               this->count_unknown++;
+               }
+       }
+       else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                                  PTS_ITA_QUALIFIER_TYPE_OS))
+       {
+               int ima_count;
+
+               switch (this->state)
+               {
+                       case IMA_STATE_BIOS:
+                               if (!check_boot_aggregate(pcrs, measurement))
+                               {
+                                       return FAILED;
+                               }
+                               this->state = IMA_STATE_INIT;
+                               /* fall through to next state */
+                       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->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
+                               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);
+
+                               if (ima_count)
+                               {
+                                       DBG1(DBG_PTS, "checking %N '%N' boot aggregate evidence "
+                                                                 "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);
+                               }
+                               else
+                               {
+                                       DBG1(DBG_PTS, "registering %N '%N' boot aggregate evidence "
+                                                                  "measurement", pen_names, vid, names, name);
+                                       this->is_ima_registering = TRUE;
+                                       status = this->pts_db->insert_comp_measurement(this->pts_db,
+                                                                                                       measurement, this->ima_cid,
+                                                                                                       this->kid, 1, pcr, algo);
+                               }
+                               if (status != SUCCESS)
+                               {
+                                       return status;
+                               }
+                               this->state = IMA_STATE_RUNTIME;
                                break;
-                       case VERIFY_ERROR:
-                               DBG1(DBG_PTS, "%#B for '%s' differs", &measurement, uri);
-                               this->count_differ++;
+                       case IMA_STATE_RUNTIME:
+                               this->count++;
+                               if (evidence->get_validation(evidence, &uri) !=
+                                       PTS_COMP_EVID_VALIDATION_PASSED)
+                               {
+                                       DBG1(DBG_PTS, "policy URI could no be retrieved");
+                                       this->count_failed++;
+                                       return FAILED;
+                               }
+                               status = this->pts_db->check_file_measurement(this->pts_db,
+                                                                                               pts->get_platform_info(pts),
+                                                                                               PTS_MEAS_ALGO_SHA1_IMA,
+                                                                                               measurement, uri);
+                               switch (status)
+                               {
+                                       case SUCCESS:
+                                               DBG3(DBG_PTS, "%#B for '%s' is ok", &measurement, uri);
+                                               this->count_ok++;
+                                       break;
+                                       case NOT_FOUND:
+                                       DBG2(DBG_PTS, "%#B for '%s' not found", &measurement, uri);
+                                       this->count_unknown++;
+                                       break;
+                               case VERIFY_ERROR:
+                                       DBG1(DBG_PTS, "%#B for '%s' differs", &measurement, uri);
+                                       this->count_differ++;
+                                       break;
+                               case FAILED:
+                               default:
+                                       DBG1(DBG_PTS, "%#B for '%s' failed", &measurement, uri);
+                                       this->count_failed++;
+                       }
+
                                break;
-                       case FAILED:
                        default:
-                               DBG1(DBG_PTS, "%#B for '%s' failed", &measurement, uri);
-                               this->count_failed++;
+                               return FAILED;
                }
-
-                       break;
-               case IMA_STATE_END:
-                       break;
+       }
+       else
+       {
+               DBG1(DBG_PTS, "unsupported functional component name qualifier");
+               return FAILED;
        }
 
        has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
        if (has_pcr_info)
        {
-               if (!chunk_equals(pcr_before, pcrs->get(pcrs, extended_pcr)))
+               if (!chunk_equals(pcr_before, pcrs->get(pcrs, pcr)))
                {
                        DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value",
-                                                  extended_pcr);
+                                                  pcr);
                }
-               if (pcrs->set(pcrs, extended_pcr, pcr_after))
+               if (pcrs->set(pcrs, pcr, pcr_after))
                {
                        return SUCCESS;
                }
        }
        else
        {
-               pcr_after = pcrs->extend(pcrs, extended_pcr, measurement);
+               pcr_after = pcrs->extend(pcrs, pcr, measurement);
                if (pcr_after.ptr)
                {
                        return SUCCESS;
@@ -702,44 +811,74 @@ METHOD(pts_component_t, verify, status_t,
 }
 
 METHOD(pts_component_t, finalize, bool,
-       pts_ita_comp_ima_t *this)
+       pts_ita_comp_ima_t *this, u_int8_t qualifier)
 {
        u_int32_t vid, name;
        enum_name_t *names;
+       bool success = TRUE;
                
+       this->name->set_qualifier(this->name, qualifier);
        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->is_registering)
+       if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                         PTS_ITA_QUALIFIER_TYPE_TRUSTED))
        {
-               /* close registration */
-               this->is_registering = FALSE;
+               /* finalize BIOS measurements */
+               if (this->is_bios_registering)
+               {
+                       /* close registration */
+                       this->is_bios_registering = FALSE;
 
-               DBG1(DBG_PTS, "registered %d %N '%N' BIOS evidence measurements",
-                                          this->seq_no, pen_names, vid, names, name);
+                       DBG1(DBG_PTS, "registered %d %N '%N' BIOS evidence measurements",
+                                                  this->seq_no, pen_names, vid, names, name);
+               }
+               else if (this->seq_no < this->bios_count)
+               {
+                       DBG1(DBG_PTS, "%d of %d %N '%N' BIOS evidence measurements missing",
+                                                  this->bios_count - this->seq_no, this->bios_count,
+                                                  pen_names, vid, names, name);
+                       success = FALSE;
+               }
        }
-       else if (this->seq_no < this->bios_count)
+       else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                                  PTS_ITA_QUALIFIER_TYPE_OS))
        {
-               DBG1(DBG_PTS, "%d of %d %N '%N' BIOS evidence measurements missing",
-                                          this->bios_count - this->seq_no, this->bios_count,
-                                          pen_names, vid, names, name);
-               return FALSE;
-       }
+               /* finalize IMA file measurements */
+               if (this->is_ima_registering)
+               {
+                       /* close registration */
+                       this->is_ima_registering = FALSE;
 
-       /* finalize IMA file measurements */
-       if (this->count)
+                       DBG1(DBG_PTS, "registered %N '%N' boot aggregate evidence "
+                                                 "measurement", pen_names, vid, names, name);
+               }
+               if (this->count)
+               {
+                       DBG1(DBG_PTS, "processed %d %N '%N' file evidence measurements: "
+                                                 "%d ok, %d unknown, %d differ, %d failed",
+                                                  this->count, pen_names, vid, names, name,
+                                                  this->count_ok, this->count_unknown,
+                                                  this->count_differ, this->count_failed);
+                       success = !this->count_differ && !this->count_failed;
+               }
+       }
+       else
        {
-               DBG1(DBG_PTS, "processed %d %N '%N' file evidence measurements: "
-                                         "%d ok, %d unknown, %d differ, %d failed",
-                                          this->count, pen_names, vid, names, name,
-                                          this->count_ok, this->count_unknown, this->count_differ,
-                                          this->count_failed);
-
-               return !this->count_differ && !this->count_failed;
+               DBG1(DBG_PTS, "unsupported functional component name qualifier");
+               success = FALSE;
        }
+       this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
+
+       return success;
+}
 
-       return TRUE;
+METHOD(pts_component_t, get_ref, pts_component_t*,
+       pts_ita_comp_ima_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
 }
 
 METHOD(pts_component_t, destroy, void,
@@ -749,27 +888,40 @@ METHOD(pts_component_t, destroy, void,
        u_int32_t vid, name;
        enum_name_t *names;
 
-       if (this->is_registering)
+       if (ref_put(&this->ref))
        {
-               count = this->pts_db->delete_comp_measurements(this->pts_db,
-                                                                                                          this->cid, this->kid);
                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);
-               DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
-                        "evidence measurements", count, pen_names, vid, names, name);
+
+               if (this->is_bios_registering)
+               {
+                       count = this->pts_db->delete_comp_measurements(this->pts_db,
+                                                                                                       this->bios_cid, this->kid);
+                       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);
+                       DBG1(DBG_PTS, "deleted registered %N '%N' boot aggregate evidence "
+                                                 "measurement", pen_names, vid, names, name);
+               }
+               this->bios_list->destroy_function(this->bios_list,
+                                                                                (void *)free_bios_entry);
+               this->ima_list->destroy_function(this->ima_list, 
+                                                                                (void *)free_ima_entry);
+               this->name->destroy(this->name);
+               free(this->keyid.ptr);
+               free(this);
        }
-       this->bios_list->destroy_function(this->bios_list, (void *)free_bios_entry);
-       this->ima_list->destroy_function(this->ima_list, (void *)free_ima_entry);
-       this->name->destroy(this->name);
-       free(this->keyid.ptr);
-       free(this);
 }
 
 /**
  * See header
  */
-pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
+pts_component_t *pts_ita_comp_ima_create(u_int32_t depth,
                                                                                 pts_database_t *pts_db)
 {
        pts_ita_comp_ima_t *this;
@@ -782,16 +934,18 @@ pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
                        .measure = _measure,
                        .verify = _verify,
                        .finalize = _finalize,
+                       .get_ref = _get_ref,
                        .destroy = _destroy,
                },
                .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_IMA,
-                                                                                 qualifier),
+                                                                                 PTS_QUALIFIER_UNKNOWN),
                .depth = depth,
                .pts_db = pts_db,
                .bios_list = linked_list_create(),
                .ima_list = linked_list_create(),
                .pcr_info = lib->settings->get_bool(lib->settings,
                                                "libimcv.plugins.imc-attestation.pcr_info", TRUE),
+               .ref = 1,
        );
 
        return &this->public;
index 1ca27e6..546d0a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2012 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 /**
  * Create a PTS ITS Functional Component object
  *
- * @param qualifier            PTS Component Functional Name Qualifier
  * @param depth                        Sub-component depth
  * @param pts_db               PTS measurement database
  */
-pts_component_t* pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
+pts_component_t* pts_ita_comp_ima_create(u_int32_t depth,
                                                                                 pts_database_t *pts_db);
 
 #endif /** PTS_ITA_COMP_IMA_H_ @}*/
index c3e4434..9deeb19 100644 (file)
@@ -85,6 +85,11 @@ struct pts_ita_comp_tboot_t {
         */
        int seq_no;
 
+       /**
+        * Reference count
+        */
+       refcount_t ref;
+
 };
 
 METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
@@ -106,7 +111,8 @@ METHOD(pts_component_t, get_depth, u_int32_t,
 }
 
 METHOD(pts_component_t, measure, status_t,
-       pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+       pts_ita_comp_tboot_t *this, u_int8_t qualifier, pts_t *pts,
+       pts_comp_evidence_t **evidence)
 
 {
        size_t pcr_len;
@@ -182,7 +188,8 @@ METHOD(pts_component_t, measure, status_t,
 }
 
 METHOD(pts_component_t, verify, status_t,
-       pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+       pts_ita_comp_tboot_t *this, u_int8_t qualifier,pts_t *pts,
+       pts_comp_evidence_t *evidence)
 {
        bool has_pcr_info;
        u_int32_t extended_pcr, vid, name;
@@ -275,7 +282,7 @@ METHOD(pts_component_t, verify, status_t,
 }
 
 METHOD(pts_component_t, finalize, bool,
-       pts_ita_comp_tboot_t *this)
+       pts_ita_comp_tboot_t *this, u_int8_t qualifier)
 {
        u_int32_t vid, name;
        enum_name_t *names;
@@ -303,6 +310,13 @@ METHOD(pts_component_t, finalize, bool,
        return TRUE;
 }
 
+METHOD(pts_component_t, get_ref, pts_component_t*,
+       pts_ita_comp_tboot_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
+}
+
 METHOD(pts_component_t, destroy, void,
           pts_ita_comp_tboot_t *this)
 {
@@ -310,25 +324,28 @@ METHOD(pts_component_t, destroy, void,
        u_int32_t vid, name;
        enum_name_t *names;
 
-       if (this->is_registering)
+       if (ref_put(&this->ref))
        {
-               count = this->pts_db->delete_comp_measurements(this->pts_db,
-                                                                                                          this->cid, this->kid);
-               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);
-               DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
-                        "evidence measurements", count, pen_names, vid, names, name);
+               if (this->is_registering)
+               {
+                       count = this->pts_db->delete_comp_measurements(this->pts_db,
+                                                                                                       this->cid, this->kid);
+                       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);
+                       DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
+                                "evidence measurements", count, pen_names, vid, names, name);
+               }
+               this->name->destroy(this->name);
+               free(this->keyid.ptr);
+               free(this);
        }
-       this->name->destroy(this->name);
-       free(this->keyid.ptr);
-       free(this);
 }
 
 /**
  * See header
  */
-pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
+pts_component_t *pts_ita_comp_tboot_create(u_int32_t depth,
                                                                                   pts_database_t *pts_db)
 {
        pts_ita_comp_tboot_t *this;
@@ -341,12 +358,15 @@ pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
                        .measure = _measure,
                        .verify = _verify,
                        .finalize = _finalize,
+                       .get_ref = _get_ref,
                        .destroy = _destroy,
                },
                .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TBOOT,
-                                                                                 qualifier),
+                                                                                 PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                                                                 PTS_ITA_QUALIFIER_TYPE_TRUSTED),
                .depth = depth,
                .pts_db = pts_db,
+               .ref = 1,
        );
 
        return &this->public;
index 39554fb..1e1a148 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 /**
  * Create a PTS ITS Functional Component object
  *
- * @param qualifier            PTS Component Functional Name Qualifier
  * @param depth                        Sub-component depth
  * @param pts_db               PTS measurement database
  */
-pts_component_t* pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
+pts_component_t* pts_ita_comp_tboot_create(u_int32_t depth,
                                                                                   pts_database_t *pts_db);
 
 #endif /** PTS_ITA_COMP_TBOOT_H_ @}*/
index c6bbb67..986f7ac 100644 (file)
@@ -49,6 +49,12 @@ struct pts_ita_comp_tgrub_t {
         */
        pts_database_t *pts_db;
 
+
+       /**
+        * Reference count
+        */
+       refcount_t ref;
+
 };
 
 METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
@@ -70,7 +76,8 @@ METHOD(pts_component_t, get_depth, u_int32_t,
 }
 
 METHOD(pts_component_t, measure, status_t,
-       pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+       pts_ita_comp_tgrub_t *this, u_int8_t qualifier, pts_t *pts,
+       pts_comp_evidence_t **evidence)
 {
        size_t pcr_len;
        pts_pcr_transform_t pcr_transform;
@@ -110,7 +117,8 @@ METHOD(pts_component_t, measure, status_t,
 }
 
 METHOD(pts_component_t, verify, status_t,
-       pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+       pts_ita_comp_tgrub_t *this, u_int8_t qualifier, pts_t *pts,
+       pts_comp_evidence_t *evidence)
 {
        bool has_pcr_info;
        u_int32_t extended_pcr;
@@ -147,22 +155,32 @@ METHOD(pts_component_t, verify, status_t,
 }
 
 METHOD(pts_component_t, finalize, bool,
-       pts_ita_comp_tgrub_t *this)
+       pts_ita_comp_tgrub_t *this, u_int8_t qualifier)
 {
        return FALSE;
 }
 
+METHOD(pts_component_t, get_ref, pts_component_t*,
+       pts_ita_comp_tgrub_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
+}
+
 METHOD(pts_component_t, destroy, void,
        pts_ita_comp_tgrub_t *this)
 {
-       this->name->destroy(this->name);
-       free(this);
+       if (ref_put(&this->ref))
+       {
+               this->name->destroy(this->name);
+               free(this);
+       }
 }
 
 /**
  * See header
  */
-pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
+pts_component_t *pts_ita_comp_tgrub_create(u_int32_t depth,
                                                                                   pts_database_t *pts_db)
 {
        pts_ita_comp_tgrub_t *this;
@@ -175,12 +193,15 @@ pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
                        .measure = _measure,
                        .verify = _verify,
                        .finalize = _finalize,
+                       .get_ref = _get_ref,
                        .destroy = _destroy,
                },
                .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TGRUB,
-                                                                                 qualifier),
+                                                                                 PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                                                                 PTS_ITA_QUALIFIER_TYPE_TRUSTED),
                .depth = depth,
                .pts_db = pts_db,
+               .ref = 1,
        );
 
        return &this->public;
index 52ecc32..59913c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 /**
  * Create a PTS ITS Functional Component object
  *
- * @param qualifier            PTS Component Functional Name Qualifier
  * @param depth                        Sub-component depth
  * @param pts_db               PTS measurement database
  */
-pts_component_t* pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
+pts_component_t* pts_ita_comp_tgrub_create(u_int32_t depth,
                                                                                   pts_database_t *pts_db);
 
 #endif /** PTS_ITA_COMP_TGRUB_H_ @}*/
index d98850d..7501be0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2012 Andreas Steffen
  *
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -67,6 +67,12 @@ METHOD(pts_comp_func_name_t, get_qualifier, u_int8_t,
        return this->qualifier;
 }
 
+METHOD(pts_comp_func_name_t, set_qualifier, void,
+       private_pts_comp_func_name_t *this, u_int8_t qualifier)
+{
+       this->qualifier = qualifier;
+}
+
 static bool equals(private_pts_comp_func_name_t *this,
                                   private_pts_comp_func_name_t *other)
 {
@@ -137,6 +143,7 @@ pts_comp_func_name_t* pts_comp_func_name_create(u_int32_t vid, u_int32_t name,
                        .get_vendor_id = _get_vendor_id,
                        .get_name = _get_name,
                        .get_qualifier = _get_qualifier,
+                       .set_qualifier = _set_qualifier,
                        .equals = (bool(*)(pts_comp_func_name_t*,pts_comp_func_name_t*))equals,
                        .clone = _clone_,
                        .log = _log_,
index 2c7a841..a3ffa1b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -55,6 +55,13 @@ struct pts_comp_func_name_t {
        u_int8_t (*get_qualifier)(pts_comp_func_name_t *this);
 
        /**
+        * Set the PTS Component Functional Name Qualifier
+        *
+        * @param qualifier             PTS Component Functional Name Qualifier to be set
+        */
+       void (*set_qualifier)(pts_comp_func_name_t *this, u_int8_t qualifier);
+
+       /**
         * Check to PTS Component Functional Names for equality
         *
         * @param other                 Other PTS Component Functional Name
index e1f4069..da339a5 100644 (file)
@@ -60,31 +60,41 @@ struct pts_component_t {
        /**
         * Do evidence measurements on the PTS Functional Component
         *
+        * @param qualifier             PTS Component Functional Name Qualifier
         * @param pts                   PTS interface
         * @param evidence              returns component evidence measureemt
         * @param measurements  additional file measurements (NULL if not present)
         * @return                              status return code
         */
-       status_t (*measure)(pts_component_t *this, pts_t *pts,
+       status_t (*measure)(pts_component_t *this, u_int8_t qualifier, pts_t *pts,
                                                pts_comp_evidence_t** evidence);
 
        /**
         * Verify the evidence measurements of the PTS Functional Component
         *
+        * @param qualifier             PTS Component Functional Name Qualifier
         * @param pts                   PTS interface
         * @param evidence              component evidence measurement to be verified
         * @return                              status return code
         */
-       status_t (*verify)(pts_component_t *this, pts_t *pts,
+       status_t (*verify)(pts_component_t *this, u_int8_t qualifier, pts_t *pts,
                                           pts_comp_evidence_t *evidence);
 
        /**
         * Tell the PTS Functional Component to finalize pending registrations
         * and check for missing measurements
         *
+        * @param qualifier             PTS Component Functional Name Qualifier
         * @return                              TRUE if finalization successful
         */
-       bool (*finalize)(pts_component_t *this);
+       bool (*finalize)(pts_component_t *this, u_int8_t qualifier);
+
+       /**
+        * Get a new reference to the PTS Functional Component
+        *
+        * @return                      this, with an increased refcount
+        */
+       pts_component_t* (*get_ref)(pts_component_t *this);
 
        /**
         * Destroys a pts_component_t object.
index 8ac4767..e330aee 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2011 Andreas Steffen
- *
+ * Copyright (C) 2011-2012 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -270,8 +269,7 @@ METHOD(pts_component_manager_t, create, pts_component_t*,
                        {
                                if (entry2->name == name->get_name(name) && entry2->create)
                                {
-                                       component = entry2->create(name->get_qualifier(name),
-                                                                                          depth, pts_db);
+                                       component = entry2->create(depth, pts_db);
                                        break;
                                }
                        }
index 0079d0e..61055ec 100644 (file)
@@ -30,8 +30,7 @@ typedef struct pts_component_manager_t pts_component_manager_t;
 #include <library.h>
 #include <pen/pen.h>
 
-typedef pts_component_t* (*pts_component_create_t)(u_int8_t qualifier,
-                                                                                                  u_int32_t depth,
+typedef pts_component_t* (*pts_component_create_t)(u_int32_t depth,
                                                                                                   pts_database_t *pts_db);
 
 /**