summaryrefslogtreecommitdiff
path: root/src/tspi/obj.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
commitc3649a2def02c41d837ae1f79dda729ccb91e677 (patch)
treebea46dff212fdef977fe9094a70a939e8cc21885 /src/tspi/obj.c
downloadtrousers-upstream/0.3.9.tar.gz
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tspi/obj.c')
-rw-r--r--src/tspi/obj.c297
1 files changed, 297 insertions, 0 deletions
diff --git a/src/tspi/obj.c b/src/tspi/obj.c
new file mode 100644
index 0000000..ad5c79a
--- /dev/null
+++ b/src/tspi/obj.c
@@ -0,0 +1,297 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004-2007
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "trousers/tss.h"
+#include "trousers/trousers.h"
+#include "trousers_types.h"
+#include "spi_utils.h"
+#include "tsplog.h"
+#include "obj.h"
+
+UINT32 nextObjectHandle = 0xC0000000;
+
+MUTEX_DECLARE_INIT(handle_lock);
+
+TPM_LIST_DECLARE;
+CONTEXT_LIST_DECLARE;
+HASH_LIST_DECLARE;
+PCRS_LIST_DECLARE;
+POLICY_LIST_DECLARE;
+RSAKEY_LIST_DECLARE;
+ENCDATA_LIST_DECLARE;
+DAACRED_LIST_DECLARE;
+DAAARAKEY_LIST_DECLARE;
+DAAISSUERKEY_LIST_DECLARE;
+NVSTORE_LIST_DECLARE;
+DELFAMILY_LIST_DECLARE;
+MIGDATA_LIST_DECLARE;
+
+void
+list_init(struct obj_list *list)
+{
+ list->head = NULL;
+ MUTEX_INIT(list->lock);
+}
+
+void
+__tspi_obj_list_init()
+{
+ TPM_LIST_INIT();
+ CONTEXT_LIST_INIT();
+ HASH_LIST_INIT();
+ PCRS_LIST_INIT();
+ POLICY_LIST_INIT();
+ RSAKEY_LIST_INIT();
+ ENCDATA_LIST_INIT();
+ DAACRED_LIST_INIT();
+ DAAARAKEY_LIST_INIT();
+ DAAISSUERKEY_LIST_INIT();
+ NVSTORE_LIST_INIT();
+ DELFAMILY_LIST_INIT();
+ MIGDATA_LIST_INIT();
+}
+
+TSS_HOBJECT
+obj_get_next_handle()
+{
+ MUTEX_LOCK(handle_lock);
+
+ /* return any object handle except NULL_HOBJECT */
+ do {
+ nextObjectHandle++;
+ } while (nextObjectHandle == NULL_HOBJECT);
+
+ MUTEX_UNLOCK(handle_lock);
+
+ return nextObjectHandle;
+}
+
+/* search through the provided list for an object with handle matching
+ * @handle. If found, return a pointer to the object with the list
+ * locked, else return NULL. To release the lock, caller should
+ * call obj_list_put() after manipulating the object.
+ */
+struct tsp_object *
+obj_list_get_obj(struct obj_list *list, UINT32 handle)
+{
+ struct tsp_object *obj;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; obj = obj->next) {
+ if (obj->handle == handle)
+ break;
+ }
+
+ if (obj == NULL)
+ MUTEX_UNLOCK(list->lock);
+
+ return obj;
+}
+
+/* search through the provided list for an object with TSP context
+ * matching @tspContext. If found, return a pointer to the object
+ * with the list locked, else return NULL. To release the lock,
+ * caller should call obj_list_put() after manipulating the object.
+ */
+struct tsp_object *
+obj_list_get_tspcontext(struct obj_list *list, UINT32 tspContext)
+{
+ struct tsp_object *obj;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; obj = obj->next) {
+ if (obj->tspContext == tspContext)
+ break;
+ }
+
+ return obj;
+}
+
+/* release a list whose handle was returned by obj_list_get_obj() */
+void
+obj_list_put(struct obj_list *list)
+{
+ MUTEX_UNLOCK(list->lock);
+}
+
+TSS_RESULT
+obj_list_add(struct obj_list *list, UINT32 tsp_context, TSS_FLAG flags, void *data,
+ TSS_HOBJECT *phObject)
+{
+ struct tsp_object *new_obj, *tmp;
+
+ new_obj = calloc(1, sizeof(struct tsp_object));
+ if (new_obj == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct tsp_object));
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+
+ new_obj->handle = obj_get_next_handle();
+ new_obj->flags = flags;
+ new_obj->data = data;
+
+ if (list == &context_list)
+ new_obj->tspContext = new_obj->handle;
+ else
+ new_obj->tspContext = tsp_context;
+
+ MUTEX_LOCK(list->lock);
+
+ if (list->head == NULL) {
+ list->head = new_obj;
+ } else {
+ tmp = list->head;
+ list->head = new_obj;
+ new_obj->next = tmp;
+ }
+
+ MUTEX_UNLOCK(list->lock);
+
+ *phObject = new_obj->handle;
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+obj_list_remove(struct obj_list *list, void (*freeFcn)(void *), TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
+{
+ struct tsp_object *obj, *prev = NULL;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; prev = obj, obj = obj->next) {
+ if (obj->handle == hObject) {
+ /* validate tspContext */
+ if (obj->tspContext != tspContext)
+ break;
+
+ (*freeFcn)(obj->data);
+
+ if (prev)
+ prev->next = obj->next;
+ else
+ list->head = obj->next;
+ free(obj);
+
+ MUTEX_UNLOCK(list->lock);
+ return TSS_SUCCESS;
+ }
+ }
+
+ MUTEX_UNLOCK(list->lock);
+
+ return TSPERR(TSS_E_INVALID_HANDLE);
+}
+
+/* a generic routine for removing all members of a list who's tsp context
+ * matches @tspContext */
+void
+obj_list_close(struct obj_list *list, void (*freeFcn)(void *), TSS_HCONTEXT tspContext)
+{
+ struct tsp_object *index;
+ struct tsp_object *next = NULL;
+ struct tsp_object *toKill;
+ struct tsp_object *prev = NULL;
+
+ MUTEX_LOCK(list->lock);
+
+ for (index = list->head; index; ) {
+ next = index->next;
+ if (index->tspContext == tspContext) {
+ toKill = index;
+ if (prev == NULL) {
+ list->head = toKill->next;
+ } else {
+ prev->next = toKill->next;
+ }
+
+ (*freeFcn)(toKill->data);
+ free(toKill);
+
+ index = next;
+ } else {
+ prev = index;
+ index = next;
+ }
+ }
+
+ MUTEX_UNLOCK(list->lock);
+}
+
+void
+obj_close_context(TSS_HCONTEXT tspContext)
+{
+ TPM_LIST_CLOSE(tspContext);
+ CONTEXT_LIST_CLOSE(tspContext);
+ HASH_LIST_CLOSE(tspContext);
+ PCRS_LIST_CLOSE(tspContext);
+ POLICY_LIST_CLOSE(tspContext);
+ RSAKEY_LIST_CLOSE(tspContext);
+ ENCDATA_LIST_CLOSE(tspContext);
+ DAACRED_LIST_CLOSE(tspContext);
+ DAAARAKEY_LIST_CLOSE(tspContext);
+ DAAISSUERKEY_LIST_CLOSE(tspContext);
+ NVSTORE_LIST_CLOSE(tspContext);
+ DELFAMILY_LIST_CLOSE(tspContext);
+ MIGDATA_LIST_CLOSE(tspContext);
+}
+
+/* When a policy object is closed, all references to it must be removed. This function
+ * calls the object specific routines for each working object type to remove all refs to the
+ * policy */
+void
+obj_lists_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext)
+{
+ obj_rsakey_remove_policy_refs(hPolicy, tspContext);
+ obj_encdata_remove_policy_refs(hPolicy, tspContext);
+ obj_tpm_remove_policy_refs(hPolicy, tspContext);
+}
+
+/* search all key lists (right now only RSA keys exist) looking for a TCS key handle, when
+ * found, return the hash of its TPM_STORE_PUBKEY structure */
+TSS_RESULT
+obj_tcskey_get_pubkeyhash(TCS_KEY_HANDLE hKey, BYTE *pubKeyHash)
+{
+ struct tsp_object *obj;
+ struct obj_list *list = &rsakey_list;
+ struct tr_rsakey_obj *rsakey = NULL;
+ TSS_RESULT result = TSS_SUCCESS;
+ Trspi_HashCtx hashCtx;
+
+ MUTEX_LOCK(list->lock);
+
+ for (obj = list->head; obj; obj = obj->next) {
+ rsakey = (struct tr_rsakey_obj *)obj->data;
+ if (rsakey->tcsHandle == hKey)
+ break;
+ }
+
+ if (obj == NULL || rsakey == NULL) {
+ MUTEX_UNLOCK(list->lock);
+ return TSPERR(TSS_E_KEY_NOT_LOADED);
+ }
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_STORE_PUBKEY(&hashCtx, &rsakey->key.pubKey);
+ if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash)))
+ result = TSPERR(TSS_E_INTERNAL_ERROR);
+
+ MUTEX_UNLOCK(list->lock);
+
+ return result;
+}