1 2 /* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2004-2006 8 * 9 */ 10 11 12 #include <time.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <stdlib.h> 16 17 #include "trousers/tss.h" 18 #include "trousers_types.h" 19 #include "tcs_context.h" 20 #include "tcs_tsp.h" 21 #include "tcs_utils.h" 22 #include "tcs_int_literals.h" 23 #include "capabilities.h" 24 #include "tcslog.h" 25 26 MUTEX_DECLARE_EXTERN(tcs_ctx_lock); 27 28 /* runs through the list of all keys loaded by context c and decrements 29 * their ref count by 1, then free's their structures. 30 */ 31 void 32 ctx_ref_count_keys(struct tcs_context *c) 33 { 34 struct keys_loaded *cur, *prev; 35 36 if (c == NULL) 37 return; 38 39 cur = prev = c->keys; 40 41 while (cur != NULL) { 42 key_mgr_dec_ref_count(cur->key_handle); 43 cur = cur->next; 44 free(prev); 45 prev = cur; 46 } 47 } 48 /* Traverse loaded keys list and if matching key handle is found return TRUE else return FALSE 49 */ 50 TSS_BOOL 51 ctx_has_key_loaded(TCS_CONTEXT_HANDLE ctx_handle, TCS_KEY_HANDLE key_handle) 52 { 53 struct tcs_context *c; 54 struct keys_loaded *k = NULL; 55 56 MUTEX_LOCK(tcs_ctx_lock); 57 58 c = get_context(ctx_handle); 59 if (c == NULL) { 60 MUTEX_UNLOCK(tcs_ctx_lock); 61 return FALSE; 62 } 63 k = c->keys; 64 while (k != NULL) { 65 if (k->key_handle == key_handle) { 66 MUTEX_UNLOCK(tcs_ctx_lock); 67 return TRUE; 68 } 69 k = k->next; 70 } 71 72 MUTEX_UNLOCK(tcs_ctx_lock); 73 return FALSE; 74 } 75 76 /* Traverse loaded keys list and if matching key handle is found remove it */ 77 TSS_RESULT 78 ctx_remove_key_loaded(TCS_CONTEXT_HANDLE ctx_handle, TCS_KEY_HANDLE key_handle) 79 { 80 struct tcs_context *c; 81 struct keys_loaded *cur, *prev; 82 83 MUTEX_LOCK(tcs_ctx_lock); 84 85 c = get_context(ctx_handle); 86 if (c == NULL) { 87 MUTEX_UNLOCK(tcs_ctx_lock); 88 return TCSERR(TCS_E_INVALID_CONTEXTHANDLE); 89 } 90 91 for (prev = cur = c->keys; cur; prev = cur, cur = cur->next) { 92 if (cur->key_handle == key_handle) { 93 if (cur == c->keys) 94 c->keys = cur->next; 95 else 96 prev->next = cur->next; 97 98 free(cur); 99 MUTEX_UNLOCK(tcs_ctx_lock); 100 return TCS_SUCCESS; 101 } 102 } 103 104 MUTEX_UNLOCK(tcs_ctx_lock); 105 return TCSERR(TCS_E_INVALID_KEY); 106 } 107 108 /* make a new entry in the per-context list of loaded keys. If the list already 109 * contains a pointer to the key in memory, just return success. 110 */ 111 TSS_RESULT 112 ctx_mark_key_loaded(TCS_CONTEXT_HANDLE ctx_handle, TCS_KEY_HANDLE key_handle) 113 { 114 struct tcs_context *c; 115 struct keys_loaded *k = NULL, *new; 116 TSS_RESULT result; 117 118 MUTEX_LOCK(tcs_ctx_lock); 119 120 c = get_context(ctx_handle); 121 122 if (c != NULL) { 123 k = c->keys; 124 while (k != NULL) { 125 if (k->key_handle == key_handle) { 126 /* we've previously created a pointer to key_handle in the global 127 * list of loaded keys and incremented that key's reference count, 128 * so there's no need to do anything. 129 */ 130 result = TSS_SUCCESS; 131 break; 132 } 133 134 k = k->next; 135 } 136 } else { 137 MUTEX_UNLOCK(tcs_ctx_lock); 138 return TCSERR(TSS_E_FAIL); 139 } 140 141 /* if we have no record of this key being loaded by this context, create a new 142 * entry and increment the key's reference count in the global list. 143 */ 144 if (k == NULL) { 145 new = calloc(1, sizeof(struct keys_loaded)); 146 if (new == NULL) { 147 LogError("malloc of %zd bytes failed.", sizeof(struct keys_loaded)); 148 MUTEX_UNLOCK(tcs_ctx_lock); 149 return TCSERR(TSS_E_OUTOFMEMORY); 150 } 151 152 new->key_handle = key_handle; 153 new->next = c->keys; 154 c->keys = new; 155 result = key_mgr_inc_ref_count(new->key_handle); 156 } 157 158 MUTEX_UNLOCK(tcs_ctx_lock); 159 160 return result; 161 } 162 163