summaryrefslogtreecommitdiff
path: root/src/tcs/tcs_context_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcs/tcs_context_key.c')
-rw-r--r--src/tcs/tcs_context_key.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/tcs/tcs_context_key.c b/src/tcs/tcs_context_key.c
new file mode 100644
index 0000000..dcec6dc
--- /dev/null
+++ b/src/tcs/tcs_context_key.c
@@ -0,0 +1,162 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004-2006
+ *
+ */
+
+
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "tcs_context.h"
+#include "tcs_tsp.h"
+#include "tcs_utils.h"
+#include "tcs_int_literals.h"
+#include "capabilities.h"
+#include "tcslog.h"
+
+MUTEX_DECLARE_EXTERN(tcs_ctx_lock);
+
+/* runs through the list of all keys loaded by context c and decrements
+ * their ref count by 1, then free's their structures.
+ */
+void
+ctx_ref_count_keys(struct tcs_context *c)
+{
+ struct keys_loaded *cur, *prev;
+
+ if (c == NULL)
+ return;
+
+ cur = prev = c->keys;
+
+ while (cur != NULL) {
+ key_mgr_dec_ref_count(cur->key_handle);
+ cur = cur->next;
+ free(prev);
+ prev = cur;
+ }
+}
+/* Traverse loaded keys list and if matching key handle is found return TRUE else return FALSE
+ */
+TSS_BOOL
+ctx_has_key_loaded(TCS_CONTEXT_HANDLE ctx_handle, TCS_KEY_HANDLE key_handle)
+{
+ struct tcs_context *c;
+ struct keys_loaded *k = NULL;
+
+ MUTEX_LOCK(tcs_ctx_lock);
+
+ c = get_context(ctx_handle);
+ if (c == NULL) {
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return FALSE;
+ }
+ k = c->keys;
+ while (k != NULL) {
+ if (k->key_handle == key_handle) {
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return TRUE;
+ }
+ k = k->next;
+ }
+
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return FALSE;
+}
+
+/* Traverse loaded keys list and if matching key handle is found remove it */
+TSS_RESULT
+ctx_remove_key_loaded(TCS_CONTEXT_HANDLE ctx_handle, TCS_KEY_HANDLE key_handle)
+{
+ struct tcs_context *c;
+ struct keys_loaded *cur, *prev;
+
+ MUTEX_LOCK(tcs_ctx_lock);
+
+ c = get_context(ctx_handle);
+ if (c == NULL) {
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return TCSERR(TCS_E_INVALID_CONTEXTHANDLE);
+ }
+
+ for (prev = cur = c->keys; cur; prev = cur, cur = cur->next) {
+ if (cur->key_handle == key_handle) {
+ if (prev == c->keys)
+ c->keys = cur->next;
+ else
+ prev->next = cur->next;
+
+ free(cur);
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return TCS_SUCCESS;
+ }
+ }
+
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return TCSERR(TCS_E_INVALID_KEY);
+}
+
+/* make a new entry in the per-context list of loaded keys. If the list already
+ * contains a pointer to the key in memory, just return success.
+ */
+TSS_RESULT
+ctx_mark_key_loaded(TCS_CONTEXT_HANDLE ctx_handle, TCS_KEY_HANDLE key_handle)
+{
+ struct tcs_context *c;
+ struct keys_loaded *k = NULL, *new;
+ TSS_RESULT result;
+
+ MUTEX_LOCK(tcs_ctx_lock);
+
+ c = get_context(ctx_handle);
+
+ if (c != NULL) {
+ k = c->keys;
+ while (k != NULL) {
+ if (k->key_handle == key_handle) {
+ /* we've previously created a pointer to key_handle in the global
+ * list of loaded keys and incremented that key's reference count,
+ * so there's no need to do anything.
+ */
+ result = TSS_SUCCESS;
+ break;
+ }
+
+ k = k->next;
+ }
+ } else {
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return TCSERR(TSS_E_FAIL);
+ }
+
+ /* if we have no record of this key being loaded by this context, create a new
+ * entry and increment the key's reference count in the global list.
+ */
+ if (k == NULL) {
+ new = calloc(1, sizeof(struct keys_loaded));
+ if (new == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct keys_loaded));
+ MUTEX_UNLOCK(tcs_ctx_lock);
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+
+ new->key_handle = key_handle;
+ new->next = c->keys;
+ c->keys = new;
+ result = key_mgr_inc_ref_count(new->key_handle);
+ }
+
+ MUTEX_UNLOCK(tcs_ctx_lock);
+
+ return result;
+}
+