~ubuntu-branches/ubuntu/precise/trousers/precise-proposed

« back to all changes in this revision

Viewing changes to src/tspi/obj.c

  • Committer: Bazaar Package Importer
  • Author(s): William Lima
  • Date: 2007-04-18 16:39:38 UTC
  • Revision ID: james.westby@ubuntu.com-20070418163938-opscl2mvvi76jiec
Tags: upstream-0.2.9.1
ImportĀ upstreamĀ versionĀ 0.2.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <stdlib.h>
 
13
#include <stdio.h>
 
14
#include <errno.h>
 
15
#include <string.h>
 
16
#include <pthread.h>
 
17
 
 
18
#include "trousers/tss.h"
 
19
#include "trousers/trousers.h"
 
20
#include "spi_internal_types.h"
 
21
#include "spi_utils.h"
 
22
#include "capabilities.h"
 
23
#include "tsplog.h"
 
24
#include "obj.h"
 
25
 
 
26
UINT32 nextObjectHandle = 0xC0000000;
 
27
 
 
28
pthread_mutex_t keylist_lock = PTHREAD_MUTEX_INITIALIZER;
 
29
pthread_mutex_t handle_lock = PTHREAD_MUTEX_INITIALIZER;
 
30
 
 
31
struct obj_list tpm_list;
 
32
struct obj_list context_list;
 
33
struct obj_list hash_list;
 
34
struct obj_list pcrs_list;
 
35
struct obj_list policy_list;
 
36
struct obj_list rsakey_list;
 
37
struct obj_list encdata_list;
 
38
 
 
39
void
 
40
list_init(struct obj_list *list)
 
41
{
 
42
        list->head = NULL;
 
43
        pthread_mutex_init(&list->lock, NULL);
 
44
}
 
45
 
 
46
void
 
47
obj_list_init()
 
48
{
 
49
        list_init(&tpm_list);
 
50
        list_init(&context_list);
 
51
        list_init(&hash_list);
 
52
        list_init(&pcrs_list);
 
53
        list_init(&policy_list);
 
54
        list_init(&rsakey_list);
 
55
        list_init(&encdata_list);
 
56
}
 
57
 
 
58
TSS_HOBJECT
 
59
obj_get_next_handle()
 
60
{
 
61
        pthread_mutex_lock(&handle_lock);
 
62
 
 
63
        /* return any object handle except NULL_HOBJECT */
 
64
        do {
 
65
                nextObjectHandle++;
 
66
        } while (nextObjectHandle == NULL_HOBJECT);
 
67
 
 
68
        pthread_mutex_unlock(&handle_lock);
 
69
 
 
70
        return nextObjectHandle;
 
71
}
 
72
 
 
73
/* search through the provided list for an object with handle matching
 
74
 * @handle. If found, return a pointer to the object with the list
 
75
 * locked, else return NULL.  To release the lock, caller should
 
76
 * call obj_list_put() after manipulating the object.
 
77
 */
 
78
struct tsp_object *
 
79
obj_list_get_obj(struct obj_list *list, UINT32 handle)
 
80
{
 
81
        struct tsp_object *obj;
 
82
 
 
83
        pthread_mutex_lock(&list->lock);
 
84
 
 
85
        for (obj = list->head; obj; obj = obj->next) {
 
86
                if (obj->handle == handle)
 
87
                        break;
 
88
        }
 
89
 
 
90
        if (obj == NULL)
 
91
                pthread_mutex_unlock(&list->lock);
 
92
 
 
93
        return obj;
 
94
}
 
95
 
 
96
/* search through the provided list for an object with TSP context
 
97
 * matching @tspContext. If found, return a pointer to the object
 
98
 * with the list locked, else return NULL.  To release the lock,
 
99
 * caller should call obj_list_put() after manipulating the object.
 
100
 */
 
101
struct tsp_object *
 
102
obj_list_get_tspcontext(struct obj_list *list, UINT32 tspContext)
 
103
{
 
104
        struct tsp_object *obj;
 
105
 
 
106
        pthread_mutex_lock(&list->lock);
 
107
 
 
108
        for (obj = list->head; obj; obj = obj->next) {
 
109
                if (obj->tspContext == tspContext)
 
110
                        break;
 
111
        }
 
112
 
 
113
        return obj;
 
114
}
 
115
 
 
116
/* release a list whose handle was returned by obj_list_get_obj() */
 
117
void
 
118
obj_list_put(struct obj_list *list)
 
119
{
 
120
        pthread_mutex_unlock(&list->lock);
 
121
}
 
122
 
 
123
TSS_RESULT
 
124
obj_list_add(struct obj_list *list, UINT32 tsp_context, TSS_FLAG flags, void *data,
 
125
             TSS_HOBJECT *phObject)
 
126
{
 
127
        struct tsp_object *new_obj, *tmp;
 
128
 
 
129
        new_obj = calloc(1, sizeof(struct tsp_object));
 
130
        if (new_obj == NULL) {
 
131
                LogError("malloc of %zd bytes failed.", sizeof(struct tsp_object));
 
132
                return TSPERR(TSS_E_OUTOFMEMORY);
 
133
        }
 
134
 
 
135
        new_obj->handle = obj_get_next_handle();
 
136
        new_obj->flags = flags;
 
137
        new_obj->data = data;
 
138
 
 
139
        if (list == &context_list)
 
140
                new_obj->tspContext = new_obj->handle;
 
141
        else
 
142
                new_obj->tspContext = tsp_context;
 
143
 
 
144
        pthread_mutex_lock(&list->lock);
 
145
 
 
146
        if (list->head == NULL) {
 
147
                list->head = new_obj;
 
148
        } else {
 
149
                tmp = list->head;
 
150
                list->head = new_obj;
 
151
                new_obj->next = tmp;
 
152
        }
 
153
 
 
154
        pthread_mutex_unlock(&list->lock);
 
155
 
 
156
        *phObject = new_obj->handle;
 
157
 
 
158
        return TSS_SUCCESS;
 
159
}
 
160
 
 
161
TSS_RESULT
 
162
obj_list_remove(struct obj_list *list, TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
 
163
{
 
164
        struct tsp_object *obj, *prev = NULL;
 
165
        TSS_RESULT result = TSPERR(TSS_E_INVALID_HANDLE);
 
166
 
 
167
        pthread_mutex_lock(&list->lock);
 
168
 
 
169
        for (obj = list->head; obj; prev = obj, obj = obj->next) {
 
170
                if (obj->handle == hObject) {
 
171
                        /* validate tspContext */
 
172
                        if (obj->tspContext != tspContext)
 
173
                                break;
 
174
 
 
175
                        free(obj->data);
 
176
                        if (prev)
 
177
                                prev->next = obj->next;
 
178
                        else
 
179
                                list->head = obj->next;
 
180
                        free(obj);
 
181
                        result = TSS_SUCCESS;
 
182
                        break;
 
183
                }
 
184
        }
 
185
 
 
186
        pthread_mutex_unlock(&list->lock);
 
187
 
 
188
        return result;
 
189
}
 
190
 
 
191
/* a generic routine for removing all members of a list who's tsp context
 
192
 * matches @tspContext */
 
193
void
 
194
obj_list_close(struct obj_list *list, TSS_HCONTEXT tspContext)
 
195
{
 
196
        struct tsp_object *index;
 
197
        struct tsp_object *next = NULL;
 
198
        struct tsp_object *toKill;
 
199
        struct tsp_object *prev = NULL;
 
200
 
 
201
        pthread_mutex_lock(&list->lock);
 
202
 
 
203
        for (index = list->head; index; ) {
 
204
                next = index->next;
 
205
                if (index->tspContext == tspContext) {
 
206
                        toKill = index;
 
207
                        if (prev == NULL) {
 
208
                                list->head = toKill->next;
 
209
                        } else {
 
210
                                prev->next = toKill->next;
 
211
                        }
 
212
 
 
213
                        free(toKill->data);
 
214
                        free(toKill);
 
215
 
 
216
                        index = next;
 
217
                } else {
 
218
                        prev = index;
 
219
                        index = next;
 
220
                }
 
221
        }
 
222
 
 
223
        pthread_mutex_unlock(&list->lock);
 
224
}
 
225
 
 
226
void
 
227
obj_close_context(TSS_HCONTEXT tspContext)
 
228
{
 
229
        obj_list_close(&tpm_list, tspContext);
 
230
        obj_list_close(&context_list, tspContext);
 
231
        obj_list_close(&pcrs_list, tspContext);
 
232
        obj_list_close(&policy_list, tspContext);
 
233
 
 
234
        /* these three must be custom due to the need to free members of their
 
235
         * private data areas. */
 
236
        obj_list_hash_close(&hash_list, tspContext);
 
237
        obj_list_rsakey_close(&rsakey_list, tspContext);
 
238
        obj_list_encdata_close(&encdata_list, tspContext);
 
239
}
 
240
 
 
241
/* When a policy object is closed, all references to it must be removed. This function
 
242
 * calls the object specific routines for each working object type to remove all refs to the
 
243
 * policy */
 
244
void
 
245
obj_lists_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext)
 
246
{
 
247
        obj_rsakey_remove_policy_refs(hPolicy, tspContext);
 
248
        obj_encdata_remove_policy_refs(hPolicy, tspContext);
 
249
        obj_tpm_remove_policy_refs(hPolicy, tspContext);
 
250
}
 
251