diff options
Diffstat (limited to 'src/tcs/tcs_context_key.c')
-rw-r--r-- | src/tcs/tcs_context_key.c | 162 |
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; +} + |