1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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;
}
|