improved performance of database access by caching primary keys
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 28 Nov 2011 13:27:03 +0000 (14:27 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 28 Nov 2011 20:24:00 +0000 (21:24 +0100)
src/libpts/pts/components/ita/ita_comp_ima.c
src/libpts/pts/components/ita/ita_comp_tboot.c
src/libpts/pts/pts_database.c
src/libpts/pts/pts_database.h

index c8a5469..a7da766 100644 (file)
@@ -52,6 +52,11 @@ struct pts_ita_comp_ima_t {
        pts_comp_func_name_t *name;
 
        /**
+        * AIK keyid
+        */
+       chunk_t keyid;
+
+       /**
         * Sub-component depth
         */
        u_int32_t depth;
@@ -62,9 +67,14 @@ struct pts_ita_comp_ima_t {
        pts_database_t *pts_db;
 
        /**
-        * AIK keyid
+        * Primary key for Component Functional Name database entry
         */
-       chunk_t keyid;
+       int cid;
+
+       /**
+        * Primary key for AIK database entry
+        */
+       int kid;
 
        /**
         * Component is registering measurements 
@@ -289,8 +299,9 @@ METHOD(pts_component_t, verify, status_t,
                        DBG1(DBG_PTS, "pts database not available");
                        return FAILED;
                }
-               if (this->pts_db->get_comp_measurement_count(this->pts_db, this->name,
-                                                               this->keyid, algo, &this->count) != SUCCESS)
+               if (this->pts_db->get_comp_measurement_count(this->pts_db,
+                                                       this->name, this->keyid, algo,
+                                                       &this->cid, &this->kid, &this->count) != SUCCESS)
                {
                        return FAILED;
                }
@@ -314,8 +325,8 @@ METHOD(pts_component_t, verify, status_t,
        if (this->is_registering)
        {
                if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
-                                                                       this->name, this->keyid, ++this->seq_no,
-                                                                       extended_pcr, algo) != SUCCESS)
+                                                                               this->cid, this->kid, ++this->seq_no,
+                                                                               extended_pcr, algo) != SUCCESS)
                {
                        return FAILED;
                }
@@ -324,8 +335,8 @@ METHOD(pts_component_t, verify, status_t,
        else
        {
                if (this->pts_db->check_comp_measurement(this->pts_db, measurement,
-                                                                       this->name, this->keyid, ++this->seq_no,
-                                                                       extended_pcr, algo) != SUCCESS)
+                                                                               this->cid, this->kid, ++this->seq_no,
+                                                                               extended_pcr, algo) != SUCCESS)
                {
                        return FAILED;
                }
@@ -378,8 +389,8 @@ METHOD(pts_component_t, destroy, void,
        }
        if (this->is_registering)
        {
-               count = this->pts_db->delete_comp_measurements(this->pts_db, this->name,
-                                                                                                          this->keyid);
+               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);
index 57b8091..287aae7 100644 (file)
@@ -42,6 +42,11 @@ struct pts_ita_comp_tboot_t {
        pts_comp_func_name_t *name;
 
        /**
+        * AIK keyid
+        */
+       chunk_t keyid;
+
+       /**
         * Sub-component depth
         */
        u_int32_t depth;
@@ -52,9 +57,14 @@ struct pts_ita_comp_tboot_t {
        pts_database_t *pts_db;
 
        /**
-        * AIK keyid
+        * Primary key for Component Functional Name database entry
         */
-       chunk_t keyid;
+       int cid;
+
+       /**
+        * Primary key for AIK database entry
+        */
+       int kid;
 
        /**
         * Component is registering measurements 
@@ -192,8 +202,9 @@ METHOD(pts_component_t, verify, status_t,
                        DBG1(DBG_PTS, "pts database not available");
                        return FAILED;
                }
-               if (this->pts_db->get_comp_measurement_count(this->pts_db, this->name,
-                                                       this->keyid, algo, &this->count) != SUCCESS)
+               if (this->pts_db->get_comp_measurement_count(this->pts_db,
+                                                       this->name, this->keyid, algo,
+                                                       &this->cid, &this->kid, &this->count) != SUCCESS)
                {
                        return FAILED;
                }
@@ -217,8 +228,8 @@ METHOD(pts_component_t, verify, status_t,
        if (this->is_registering)
        {
                if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
-                                                                       this->name, this->keyid, ++this->seq_no,
-                                                                       extended_pcr, algo) != SUCCESS)
+                                                                               this->cid, this->kid, ++this->seq_no,
+                                                                               extended_pcr, algo) != SUCCESS)
                {
                        return FAILED;
                }
@@ -227,8 +238,8 @@ METHOD(pts_component_t, verify, status_t,
        else
        {
                if (this->pts_db->check_comp_measurement(this->pts_db, measurement,
-                                                                       this->name, this->keyid, ++this->seq_no,
-                                                                       extended_pcr, algo) != SUCCESS)
+                                                                               this->cid, this->kid, ++this->seq_no,
+                                                                               extended_pcr, algo) != SUCCESS)
                {
                        return FAILED;
                }
@@ -277,8 +288,8 @@ METHOD(pts_component_t, destroy, void,
 
        if (this->is_registering)
        {
-               count = this->pts_db->delete_comp_measurements(this->pts_db, this->name,
-                                                                                                          this->keyid);
+               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);
index 1b7b00e..aedabc8 100644 (file)
@@ -114,8 +114,7 @@ METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*,
 }
 
 METHOD(pts_database_t, check_comp_measurement, status_t,
-       private_pts_database_t *this, chunk_t measurement,
-       pts_comp_func_name_t *comp_name, chunk_t keyid,
+       private_pts_database_t *this, chunk_t measurement, int cid, int kid,
        int seq_no, int pcr, pts_meas_algorithms_t algo)
 {
        enumerator_t *e;
@@ -123,16 +122,11 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
        status_t status = NOT_FOUND;
        
        e = this->db->query(this->db,
-                       "SELECT ch.hash FROM component_hashes AS ch "
-                       "JOIN keys AS k ON ch.key = k.id "
-                       "JOIN components AS c ON ch.component = c.id "
-                       "WHERE c.vendor_id = ?  AND c.name = ? AND c.qualifier = ? "
-                       "AND k.keyid = ? AND ch.seq_no = ? AND ch.pcr = ? AND ch.algo = ? ",
-                       DB_INT, comp_name->get_vendor_id(comp_name),
-                       DB_INT, comp_name->get_name(comp_name),
-                       DB_INT, comp_name->get_qualifier(comp_name),
-                       DB_BLOB, keyid, DB_INT, seq_no, DB_INT, pcr, DB_INT, algo,
-                       DB_BLOB);
+                                       "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, pcr, DB_INT, algo, DB_BLOB);
        if (!e)
        {
                DBG1(DBG_PTS, "no database query enumerator returned"); 
@@ -168,23 +162,17 @@ 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,
-       pts_comp_func_name_t *comp_name, chunk_t keyid,
+       private_pts_database_t *this, chunk_t measurement, int cid, int kid,
        int seq_no, int pcr, pts_meas_algorithms_t algo)
 {
        int id;
        
        if (this->db->execute(this->db, &id,
-                               "INSERT INTO component_hashes "
-                               "(component, key, seq_no, pcr, algo, hash) VALUES ("
-                               "(SELECT id FROM components"
-                               " WHERE vendor_id = ?  AND name = ? AND qualifier = ?), "
-                               "(SELECT id FROM keys WHERE keyid = ?), ?, ?, ?, ?)",
-                               DB_INT, comp_name->get_vendor_id(comp_name),
-                               DB_INT, comp_name->get_name(comp_name),
-                               DB_INT, comp_name->get_qualifier(comp_name),
-                               DB_BLOB, keyid, DB_INT, seq_no, DB_INT, pcr,
-                               DB_INT, algo, DB_BLOB, measurement) == 1)
+                                       "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, algo, DB_BLOB, measurement) == 1)
        {
                return SUCCESS;
        }
@@ -194,39 +182,33 @@ METHOD(pts_database_t, insert_comp_measurement, status_t,
 }
 
 METHOD(pts_database_t, delete_comp_measurements, int,
-       private_pts_database_t *this, pts_comp_func_name_t *comp_name, chunk_t keyid)
+       private_pts_database_t *this, int cid, int kid)
 {
        return this->db->execute(this->db, NULL,
-                               "DELETE FROM component_hashes WHERE "
-                               "component = (SELECT id FROM components"
-                               " WHERE vendor_id = ?  AND name = ? AND qualifier = ?) AND "
-                               "key = (SELECT id FROM keys WHERE keyid = ?)",
-                               DB_INT, comp_name->get_vendor_id(comp_name),
-                               DB_INT, comp_name->get_name(comp_name),
-                               DB_INT, comp_name->get_qualifier(comp_name),
-                               DB_BLOB, keyid);
+                                       "DELETE FROM component_hashes "
+                                       "WHERE component = ? AND key = ?",
+                                       DB_INT, cid, DB_INT, kid);
 }
 
 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 *count)
+       chunk_t keyid, pts_meas_algorithms_t algo, int *cid, int *kid, int *count)
 {
        enumerator_t *e;
-       int kid;
        status_t status = SUCCESS;
 
        /* Initialize count */
        *count = 0;
 
-       /* Is the AIK registered? */
+       /* If the AIK is registered get the primary key */
        e = this->db->query(this->db,
-                       "SELECT id FROM keys WHERE keyid = ?", DB_BLOB, keyid, DB_INT);
+                               "SELECT id FROM keys WHERE keyid = ?", DB_BLOB, keyid, DB_INT);
        if (!e)
        {
                DBG1(DBG_PTS, "no database query enumerator returned");
                return FAILED;
        }
-       if (!e->enumerate(e, &kid))
+       if (!e->enumerate(e, kid))
        {
                DBG1(DBG_PTS, "AIK %#B is not registered in database", &keyid);
                e->destroy(e);
@@ -234,16 +216,32 @@ METHOD(pts_database_t, get_comp_measurement_count, status_t,
        }
        e->destroy(e);
 
+       /* Get the primary key of the Component Functional Name */
+       e = this->db->query(this->db,
+                               "SELECT id FROM components "
+                       "       WHERE vendor_id = ?  AND name = ? AND qualifier = ?",
+                               DB_INT, comp_name->get_vendor_id(comp_name),
+                               DB_INT, comp_name->get_name(comp_name),
+                               DB_INT, comp_name->get_qualifier(comp_name),
+                               DB_INT);
+       if (!e)
+       {
+               DBG1(DBG_PTS, "no database query enumerator returned");
+               return FAILED;
+       }
+       if (!e->enumerate(e, cid))
+       {
+               DBG1(DBG_PTS, "component functional name not found in database");
+               e->destroy(e);
+               return FAILED;
+       }
+       e->destroy(e);
+
        /* Get the number of stored measurements for a given AIK and component */
        e = this->db->query(this->db,
-                       "SELECT COUNT(*) FROM component_hashes AS ch "
-                       "JOIN components AS c ON ch.component = c.id "
-                       "WHERE c.vendor_id = ?  AND c.name = ? AND c.qualifier = ? "
-                       "AND ch.key = ? AND ch.algo = ? ",
-                       DB_INT, comp_name->get_vendor_id(comp_name),
-                       DB_INT, comp_name->get_name(comp_name),
-                       DB_INT, comp_name->get_qualifier(comp_name),
-                       DB_INT, kid, DB_INT, algo, DB_INT);
+                               "SELECT COUNT(*) FROM component_hashes AS ch "
+                               "WHERE component = ?  AND key = ? AND algo = ?",
+                               DB_INT, *cid, DB_INT, *kid, DB_INT, algo, DB_INT);
        if (!e)
        {
                DBG1(DBG_PTS, "no database query enumerator returned");
index dd87a5b..a9f5fa4 100644 (file)
@@ -77,41 +77,40 @@ struct pts_database_t {
        * Check a functional component measurement against value stored in database
        *
        * @param measurement    measurement hash
-       * @param comp_name              Component Functional Name
-       * @param keyid                  SHA-1 hash of AIK public key info
+       * @param cid                    Primary key of Component Functional Name entry
+       * @param kid                    Primary key of AIK entry in keys table
        * @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,
-                                                       pts_comp_func_name_t *comp_name, chunk_t keyid,
-                                                       int seq_no, int pcr, pts_meas_algorithms_t algo);
+                                                                          int cid, int kid, int seq_no, int pcr,
+                                                                          pts_meas_algorithms_t algo);
 
        /**
        * Insert a functional component measurement into the database
        *
-       * @param measurement    measurement hash
-       * @param comp_name              Component Functional Name
-       * @param keyid                  SHA-1 hash of AIK public key info
+       * @param measurement    Measurement hash
+       * @param cid                    Primary key of Component Functional Name entry
+       * @param kid                    Primary key of AIK entry in keys table
        * @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,
-                                                       pts_comp_func_name_t *comp_name, chunk_t keyid,
-                                                       int seq_no, int pcr, pts_meas_algorithms_t algo);
+                                                                               int cid, int kid, int seq_no, int pcr,
+                                                                               pts_meas_algorithms_t algo);
 
        /**
        * Delete functional component measurements from the database
        *
-       * @param comp_name              Component Functional Name
-       * @param keyid                  SHA-1 hash of AIK public key info
+       * @param cid                    Primary key of Component Functional Name entry
+       * @param kid                    Primary key of AIK entry in keys table
        * @return                               number of deleted measurement entries
        */
-       int (*delete_comp_measurements)(pts_database_t *this,
-                                                       pts_comp_func_name_t *comp_name, chunk_t keyid);
+       int (*delete_comp_measurements)(pts_database_t *this, int cid, int kid);
 
        /**
        * Get the number of measurements for a functional component and AIK
@@ -119,12 +118,15 @@ struct pts_database_t {
        * @param comp_name              Component Functional Name
        * @param keyid                  SHA-1 hash of AIK public key info
        * @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 *count);
+                                                       pts_meas_algorithms_t algo, int *cid, int *kid,
+                                                       int *count);
 
        /**
        * Destroys a pts_database_t object.