Home | History | Annotate | Line # | Download | only in tcs
      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