~ubuntu-branches/ubuntu/karmic/trousers/karmic

« back to all changes in this revision

Viewing changes to src/tspi/tspi_ps.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-01-23 22:03:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123220300-fhtqja3c0oq0gp6z
Tags: 0.3.1-4
* Added patch from Aaron M. Ucko <ucko@debian.org> to allow trousers to
  build successfully on amd64, and presumably also other 64-bit
  architectures (Closes: #457400).
* Including udev rule for /dev/tpm from William Lima
  <wlima.amadeus@gmail.com> as suggested by David Smith <dds@google.com>
  (Closes: #459682).
* Added lintian overrides.

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 <string.h>
 
15
 
 
16
#include "trousers/tss.h"
 
17
#include "trousers/trousers.h"
 
18
#include "trousers_types.h"
 
19
#include "trousers_types.h"
 
20
#include "spi_utils.h"
 
21
#include "capabilities.h"
 
22
#include "tsplog.h"
 
23
#include "tcs_tsp.h"
 
24
#include "tspps.h"
 
25
#include "hosttable.h"
 
26
#include "tcsd_wrap.h"
 
27
#include "tcsd.h"
 
28
#include "obj.h"
 
29
 
 
30
 
 
31
TSS_RESULT
 
32
Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext,             /* in */
 
33
                           TSS_FLAG persistentStorageType,      /* in */
 
34
                           TSS_UUID uuidData,                   /* in */
 
35
                           TSS_HKEY * phKey)                    /* out */
 
36
{
 
37
        TSS_RESULT result;
 
38
        TSS_UUID parentUUID;
 
39
        UINT32 keyBlobSize, parentPSType;
 
40
        BYTE *keyBlob = NULL;
 
41
        TCS_KEY_HANDLE tcsKeyHandle;
 
42
        TSS_HKEY parentTspHandle;
 
43
        TCS_LOADKEY_INFO info;
 
44
 
 
45
        if (phKey == NULL)
 
46
                return TSPERR(TSS_E_BAD_PARAMETER);
 
47
 
 
48
        if ((!obj_is_context(tspContext)))
 
49
                return TSPERR(TSS_E_INVALID_HANDLE);
 
50
 
 
51
        /* This key is in the System Persistant storage */
 
52
        if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
 
53
#if 1
 
54
                memset(&info, 0, sizeof(TCS_LOADKEY_INFO));
 
55
 
 
56
                result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle);
 
57
 
 
58
                if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) {
 
59
                        TSS_HKEY keyHandle;
 
60
                        TSS_HPOLICY hPolicy;
 
61
 
 
62
                        /* load failed, due to some key in the chain needing auth
 
63
                         * which doesn't yet exist at the TCS level. However, the
 
64
                         * auth may already be set in policies at the TSP level.
 
65
                         * To find out, get the key handle of the key requiring
 
66
                         * auth. First, look at the list of keys in memory. */
 
67
                        if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) {
 
68
                                /* If that failed, look on disk, in User PS. */
 
69
                                if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID,
 
70
                                                       &keyHandle))
 
71
                                        return result;
 
72
                        }
 
73
 
 
74
                        if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE,
 
75
                                                  &hPolicy, NULL))
 
76
                                return result;
 
77
 
 
78
                        if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, FALSE,
 
79
                                                    &info.paramDigest, &info.authData))
 
80
                                return result;
 
81
 
 
82
                        if ((result = RPC_LoadKeyByUUID(tspContext, uuidData, &info,
 
83
                                                        &tcsKeyHandle)))
 
84
                                return result;
 
85
                } else if (result)
 
86
                        return result;
 
87
 
 
88
                if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize,
 
89
                                                       &keyBlob)))
 
90
                        return result;
 
91
 
 
92
                if ((result = obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob,
 
93
                                                    TSS_OBJ_FLAG_SYSTEM_PS, phKey))) {
 
94
                        free (keyBlob);
 
95
                        return result;
 
96
                }
 
97
 
 
98
                result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle);
 
99
 
 
100
                free (keyBlob);
 
101
#else
 
102
                if ((result = load_from_system_ps(tspContext, &uuidData, phKey)))
 
103
                        return result;
 
104
#endif
 
105
        } else if (persistentStorageType == TSS_PS_TYPE_USER) {
 
106
                if ((result = ps_get_parent_uuid_by_uuid(&uuidData, &parentUUID)))
 
107
                        return result;
 
108
 
 
109
                /* If the parent is not in memory, recursively call ourselves on it */
 
110
                if (obj_rsakey_get_by_uuid(&parentUUID, &parentTspHandle) != TSS_SUCCESS) {
 
111
                        if ((result = ps_get_parent_ps_type_by_uuid(&uuidData, &parentPSType)))
 
112
                                return result;
 
113
 
 
114
                        if ((result = Tspi_Context_LoadKeyByUUID(tspContext, parentPSType,
 
115
                                                                 parentUUID, &parentTspHandle)))
 
116
                                return result;
 
117
                }
 
118
 
 
119
                if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey)))
 
120
                        return result;
 
121
 
 
122
                /* The parent is loaded and we have the parent key handle, so call the TCS to
 
123
                 * actually load the child. */
 
124
                return Tspi_Key_LoadKey(*phKey, parentTspHandle);
 
125
        } else {
 
126
                return TSPERR(TSS_E_BAD_PARAMETER);
 
127
        }
 
128
 
 
129
        return TSS_SUCCESS;
 
130
}
 
131
 
 
132
TSS_RESULT
 
133
Tspi_Context_RegisterKey(TSS_HCONTEXT tspContext,               /* in */
 
134
                         TSS_HKEY hKey,                         /* in */
 
135
                         TSS_FLAG persistentStorageType,        /* in */
 
136
                         TSS_UUID uuidKey,                      /* in */
 
137
                         TSS_FLAG persistentStorageTypeParent,  /* in */
 
138
                         TSS_UUID uuidParentKey)                /* in */
 
139
{
 
140
        BYTE *keyBlob;
 
141
        UINT32 keyBlobSize;
 
142
        TSS_RESULT result;
 
143
        TSS_BOOL answer;
 
144
 
 
145
        if (!obj_is_context(tspContext) || !obj_is_rsakey(hKey))
 
146
                return TSPERR(TSS_E_INVALID_HANDLE);
 
147
 
 
148
        if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
 
149
                if (persistentStorageTypeParent == TSS_PS_TYPE_USER) {
 
150
                        return TSPERR(TSS_E_NOTIMPL);
 
151
                } else if (persistentStorageTypeParent == TSS_PS_TYPE_SYSTEM) {
 
152
                        if ((result = obj_rsakey_get_blob(hKey, &keyBlobSize,
 
153
                                                          &keyBlob)))
 
154
                                return result;
 
155
 
 
156
                        if ((result = RPC_RegisterKey(tspContext, uuidParentKey, uuidKey,
 
157
                                                      keyBlobSize, keyBlob,
 
158
                                                      strlen(PACKAGE_STRING) + 1,
 
159
                                                      (BYTE *)PACKAGE_STRING)))
 
160
                                return result;
 
161
                } else {
 
162
                        return TSPERR(TSS_E_BAD_PARAMETER);
 
163
                }
 
164
        } else if (persistentStorageType == TSS_PS_TYPE_USER) {
 
165
                if ((result = ps_is_key_registered(&uuidKey, &answer)))
 
166
                        return result;
 
167
 
 
168
                if (answer == TRUE)
 
169
                        return TSPERR(TSS_E_KEY_ALREADY_REGISTERED);
 
170
 
 
171
                if ((result = obj_rsakey_get_blob (hKey, &keyBlobSize, &keyBlob)))
 
172
                        return result;
 
173
 
 
174
                if ((result = ps_write_key(&uuidKey, &uuidParentKey,
 
175
                                           persistentStorageTypeParent,
 
176
                                           keyBlobSize, keyBlob)))
 
177
                        return result;
 
178
        } else {
 
179
                return TSPERR(TSS_E_BAD_PARAMETER);
 
180
        }
 
181
 
 
182
        if ((result = obj_rsakey_set_uuid(hKey, persistentStorageType, &uuidKey)))
 
183
                return result;
 
184
 
 
185
        return TSS_SUCCESS;
 
186
}
 
187
 
 
188
TSS_RESULT
 
189
Tspi_Context_UnregisterKey(TSS_HCONTEXT tspContext,             /* in */
 
190
                           TSS_FLAG persistentStorageType,      /* in */
 
191
                           TSS_UUID uuidKey,                    /* in */
 
192
                           TSS_HKEY *phKey)                     /* out */
 
193
{
 
194
        BYTE *keyBlob = NULL;
 
195
        UINT32 keyBlobSize;
 
196
        TSS_RESULT result;
 
197
 
 
198
        if (phKey == NULL)
 
199
                return TSPERR(TSS_E_BAD_PARAMETER);
 
200
 
 
201
        if ((!obj_is_context(tspContext)))
 
202
                return TSPERR(TSS_E_INVALID_HANDLE);
 
203
 
 
204
        if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
 
205
                /* get the key first, so it doesn't disappear when we
 
206
                 * unregister it */
 
207
                if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidKey, &keyBlobSize,
 
208
                                                       &keyBlob)))
 
209
                        return result;
 
210
 
 
211
                if ((obj_rsakey_add_by_key(tspContext, &uuidKey, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS,
 
212
                                           phKey))) {
 
213
                        free(keyBlob);
 
214
                        return result;
 
215
                }
 
216
 
 
217
                free(keyBlob);
 
218
 
 
219
                /* now unregister it */
 
220
                if ((result = RPC_UnregisterKey(tspContext, uuidKey)))
 
221
                        return result;
 
222
        } else if (persistentStorageType == TSS_PS_TYPE_USER) {
 
223
                /* get the key first, so it doesn't disappear when we
 
224
                 * unregister it */
 
225
                if ((result = ps_get_key_by_uuid(tspContext, &uuidKey, phKey)))
 
226
                        return result;
 
227
 
 
228
                /* now unregister it */
 
229
                if ((result = ps_remove_key(&uuidKey)))
 
230
                        return result;
 
231
        } else {
 
232
                return TSPERR(TSS_E_BAD_PARAMETER);
 
233
        }
 
234
 
 
235
        return TSS_SUCCESS;
 
236
}
 
237
 
 
238
TSS_RESULT
 
239
Tspi_Context_GetKeyByUUID(TSS_HCONTEXT tspContext,              /* in */
 
240
                          TSS_FLAG persistentStorageType,       /* in */
 
241
                          TSS_UUID uuidData,                    /* in */
 
242
                          TSS_HKEY * phKey)                     /* out */
 
243
{
 
244
        TCPA_RESULT result;
 
245
        UINT32 keyBlobSize = 0;
 
246
        BYTE *keyBlob = NULL;
 
247
 
 
248
        if (phKey == NULL)
 
249
                return TSPERR(TSS_E_BAD_PARAMETER);
 
250
 
 
251
        if ((!obj_is_context(tspContext)))
 
252
                return TSPERR(TSS_E_INVALID_HANDLE);
 
253
 
 
254
        if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
 
255
                if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize,
 
256
                                                       &keyBlob)))
 
257
                        return result;
 
258
 
 
259
                if ((obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS,
 
260
                                           phKey))) {
 
261
                        free(keyBlob);
 
262
                        return result;
 
263
                }
 
264
 
 
265
                free(keyBlob);
 
266
        } else if (persistentStorageType == TSS_PS_TYPE_USER) {
 
267
                if (!obj_is_context(tspContext))
 
268
                        return TSPERR(TSS_E_INVALID_HANDLE);
 
269
 
 
270
                if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey)))
 
271
                        return result;
 
272
        } else
 
273
                return TSPERR(TSS_E_BAD_PARAMETER);
 
274
 
 
275
        return TSS_SUCCESS;
 
276
}
 
277
 
 
278
TSS_RESULT
 
279
Tspi_Context_GetKeyByPublicInfo(TSS_HCONTEXT tspContext,        /* in */
 
280
                                TSS_FLAG persistentStorageType, /* in */
 
281
                                TSS_ALGORITHM_ID algID,         /* in */
 
282
                                UINT32 ulPublicInfoLength,      /* in */
 
283
                                BYTE * rgbPublicInfo,           /* in */
 
284
                                TSS_HKEY * phKey)               /* out */
 
285
{
 
286
        TCPA_ALGORITHM_ID tcsAlgID;
 
287
        UINT32 keyBlobSize;
 
288
        BYTE *keyBlob;
 
289
        TSS_RESULT result;
 
290
        TSS_HKEY keyOutHandle;
 
291
        UINT32 flag = 0;
 
292
        TSS_KEY keyContainer;
 
293
        UINT64 offset;
 
294
 
 
295
        if (phKey == NULL)
 
296
                return TSPERR(TSS_E_BAD_PARAMETER);
 
297
 
 
298
        if (!obj_is_context(tspContext))
 
299
                return TSPERR(TSS_E_INVALID_HANDLE);
 
300
 
 
301
        switch (algID) {
 
302
                case TSS_ALG_RSA:
 
303
                        tcsAlgID = TCPA_ALG_RSA;
 
304
                        break;
 
305
                default:
 
306
                        LogError("Algorithm ID was not type RSA.");
 
307
                        return TSPERR(TSS_E_BAD_PARAMETER);
 
308
        }
 
309
 
 
310
        if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
 
311
                if ((result = RPC_GetRegisteredKeyByPublicInfo(tspContext, tcsAlgID,
 
312
                                                               ulPublicInfoLength, rgbPublicInfo,
 
313
                                                               &keyBlobSize, &keyBlob)))
 
314
                        return result;
 
315
 
 
316
        } else if (persistentStorageType == TSS_PS_TYPE_USER) {
 
317
                return ps_get_key_by_pub(tspContext, ulPublicInfoLength, rgbPublicInfo,
 
318
                                         phKey);
 
319
        } else
 
320
                return TSPERR(TSS_E_BAD_PARAMETER);
 
321
 
 
322
        /* need to setup the init flags of the create object based on
 
323
         * the size of the blob's pubkey */
 
324
        offset = 0;
 
325
        if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer))) {
 
326
                free(keyBlob);
 
327
                return result;
 
328
        }
 
329
 
 
330
        /* begin setting up the key object */
 
331
        switch (keyContainer.pubKey.keyLength) {
 
332
                case 16384/8:
 
333
                        flag |= TSS_KEY_SIZE_16384;
 
334
                        break;
 
335
                case 8192/8:
 
336
                        flag |= TSS_KEY_SIZE_8192;
 
337
                        break;
 
338
                case 4096/8:
 
339
                        flag |= TSS_KEY_SIZE_4096;
 
340
                        break;
 
341
                case 2048/8:
 
342
                        flag |= TSS_KEY_SIZE_2048;
 
343
                        break;
 
344
                case 1024/8:
 
345
                        flag |= TSS_KEY_SIZE_1024;
 
346
                        break;
 
347
                case 512/8:
 
348
                        flag |= TSS_KEY_SIZE_512;
 
349
                        break;
 
350
                default:
 
351
                        LogError("Key was not a known keylength.");
 
352
                        free(keyBlob);
 
353
                        free_key_refs(&keyContainer);
 
354
                        return TSPERR(TSS_E_INTERNAL_ERROR);
 
355
        }
 
356
 
 
357
        if (keyContainer.keyUsage == TPM_KEY_SIGNING)
 
358
                flag |= TSS_KEY_TYPE_SIGNING;
 
359
        else if (keyContainer.keyUsage == TPM_KEY_STORAGE)
 
360
                flag |= TSS_KEY_TYPE_STORAGE;
 
361
        else if (keyContainer.keyUsage == TPM_KEY_IDENTITY)
 
362
                flag |= TSS_KEY_TYPE_IDENTITY;
 
363
        else if (keyContainer.keyUsage == TPM_KEY_AUTHCHANGE)
 
364
                flag |= TSS_KEY_TYPE_AUTHCHANGE;
 
365
        else if (keyContainer.keyUsage == TPM_KEY_BIND)
 
366
                flag |= TSS_KEY_TYPE_BIND;
 
367
        else if (keyContainer.keyUsage == TPM_KEY_LEGACY)
 
368
                flag |= TSS_KEY_TYPE_LEGACY;
 
369
 
 
370
        if (keyContainer.authDataUsage == TPM_AUTH_NEVER)
 
371
                flag |= TSS_KEY_NO_AUTHORIZATION;
 
372
        else
 
373
                flag |= TSS_KEY_AUTHORIZATION;
 
374
 
 
375
        if (keyContainer.keyFlags & TPM_MIGRATABLE)
 
376
                flag |= TSS_KEY_MIGRATABLE;
 
377
        else
 
378
                flag |= TSS_KEY_NOT_MIGRATABLE;
 
379
 
 
380
        if (keyContainer.keyFlags & TPM_VOLATILE)
 
381
                flag |= TSS_KEY_VOLATILE;
 
382
        else
 
383
                flag |= TSS_KEY_NON_VOLATILE;
 
384
 
 
385
#ifdef TSS_BUILD_CMK
 
386
        if (keyContainer.keyFlags & TPM_MIGRATEAUTHORITY)
 
387
                flag |= TSS_KEY_CERTIFIED_MIGRATABLE;
 
388
        else
 
389
                flag |= TSS_KEY_NOT_CERTIFIED_MIGRATABLE;
 
390
#endif
 
391
 
 
392
        /* Create a new Key Object */
 
393
        if ((result = obj_rsakey_add(tspContext, flag, &keyOutHandle))) {
 
394
                free(keyBlob);
 
395
                free_key_refs(&keyContainer);
 
396
                return result;
 
397
        }
 
398
        /* Stick the info into this net KeyObject */
 
399
        if ((result = obj_rsakey_set_tcpakey(keyOutHandle, keyBlobSize, keyBlob))) {
 
400
                free(keyBlob);
 
401
                free_key_refs(&keyContainer);
 
402
                return result;
 
403
        }
 
404
 
 
405
        free(keyBlob);
 
406
        free_key_refs(&keyContainer);
 
407
        *phKey = keyOutHandle;
 
408
 
 
409
        return TSS_SUCCESS;
 
410
}
 
411
 
 
412
TSS_RESULT
 
413
Tspi_Context_GetRegisteredKeysByUUID(TSS_HCONTEXT tspContext,           /* in */
 
414
                                     TSS_FLAG persistentStorageType,    /* in */
 
415
                                     TSS_UUID * pUuidData,              /* in */
 
416
                                     UINT32 * pulKeyHierarchySize,      /* out */
 
417
                                     TSS_KM_KEYINFO ** ppKeyHierarchy)  /* out */
 
418
{
 
419
        TSS_RESULT result;
 
420
        TSS_KM_KEYINFO *tcsHier, *tspHier;
 
421
        UINT32 tcsHierSize, tspHierSize;
 
422
        TSS_UUID tcs_uuid;
 
423
 
 
424
        if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
 
425
                return TSPERR(TSS_E_BAD_PARAMETER);
 
426
 
 
427
        if (!obj_is_context(tspContext))
 
428
                return TSPERR(TSS_E_INVALID_HANDLE);
 
429
 
 
430
        if (pUuidData) {
 
431
                if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
 
432
                        if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData,
 
433
                                                             pulKeyHierarchySize,
 
434
                                                             ppKeyHierarchy)))
 
435
                                return result;
 
436
                } else if (persistentStorageType == TSS_PS_TYPE_USER) {
 
437
                        if ((result = ps_get_registered_keys(pUuidData, &tcs_uuid,
 
438
                                                             &tspHierSize, &tspHier)))
 
439
                                return result;
 
440
 
 
441
                        if ((result = RPC_EnumRegisteredKeys(tspContext, &tcs_uuid, &tcsHierSize,
 
442
                                                             &tcsHier))) {
 
443
                                free(tspHier);
 
444
                                return result;
 
445
                        }
 
446
 
 
447
                        result = merge_key_hierarchies(tspContext, tspHierSize, tspHier,
 
448
                                                       tcsHierSize, tcsHier, pulKeyHierarchySize,
 
449
                                                       ppKeyHierarchy);
 
450
                        free(tcsHier);
 
451
                        free(tspHier);
 
452
                } else
 
453
                        return TSPERR(TSS_E_BAD_PARAMETER);
 
454
        } else {
 
455
                if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, &tcsHierSize,
 
456
                                                     &tcsHier)))
 
457
                        return result;
 
458
 
 
459
                if ((result = ps_get_registered_keys(pUuidData, NULL, &tspHierSize, &tspHier))) {
 
460
                        free(tcsHier);
 
461
                        return result;
 
462
                }
 
463
 
 
464
                result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, tcsHierSize,
 
465
                                               tcsHier, pulKeyHierarchySize, ppKeyHierarchy);
 
466
                free(tcsHier);
 
467
                free(tspHier);
 
468
        }
 
469
 
 
470
        if ((result = add_mem_entry(tspContext, *ppKeyHierarchy))) {
 
471
                free(*ppKeyHierarchy);
 
472
                *ppKeyHierarchy = NULL;
 
473
                *pulKeyHierarchySize = 0;
 
474
        }
 
475
 
 
476
        return result;
 
477
}
 
478
 
 
479
TSS_RESULT
 
480
Tspi_Context_GetRegisteredKeysByUUID2(TSS_HCONTEXT tspContext,          /* in */
 
481
                                     TSS_FLAG persistentStorageType,    /* in */
 
482
                                     TSS_UUID * pUuidData,              /* in */
 
483
                                     UINT32 * pulKeyHierarchySize,      /* out */
 
484
                                     TSS_KM_KEYINFO2 ** ppKeyHierarchy) /* out */
 
485
{
 
486
        TSS_RESULT result;
 
487
        TSS_KM_KEYINFO2 *tcsHier, *tspHier;
 
488
        UINT32 tcsHierSize, tspHierSize;
 
489
        TSS_UUID tcs_uuid;
 
490
 
 
491
        /* If out parameters are NULL, return error */
 
492
        if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
 
493
                        return TSPERR(TSS_E_BAD_PARAMETER);
 
494
 
 
495
        if (!obj_is_context(tspContext))
 
496
                        return TSPERR(TSS_E_INVALID_HANDLE);
 
497
 
 
498
        if (pUuidData) {
 
499
                /* TSS 1.2 Spec: If a certain key UUID is provided, the returned array of
 
500
                 * TSS_KM_KEYINFO2 structures only contains data reflecting the path of the key
 
501
                 * hierarchy regarding that key. The first array entry is the key addressed by the
 
502
                 * given UUID followed by its parent key up to and including the root key. */
 
503
                if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
 
504
                        if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData,
 
505
                                                              pulKeyHierarchySize, ppKeyHierarchy)))
 
506
                                return result;
 
507
                } else if (persistentStorageType == TSS_PS_TYPE_USER) {
 
508
                        if ((result = ps_get_registered_keys2(pUuidData, &tcs_uuid, &tspHierSize,
 
509
                                                              &tspHier)))
 
510
                                return result;
 
511
                        /* The tcs_uuid returned by ps_get_registered_key2 will always be a parent
 
512
                         * of some key into the system ps of a user key into the user ps. This key
 
513
                         * needs to be searched for in the system ps to be merged */
 
514
                        if ((result = RPC_EnumRegisteredKeys2(tspContext, &tcs_uuid, &tcsHierSize,
 
515
                                                              &tcsHier))) {
 
516
                                free(tspHier);
 
517
                                return result;
 
518
                        }
 
519
 
 
520
                        result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier,
 
521
                                                        tcsHierSize, tcsHier, pulKeyHierarchySize,
 
522
                                                        ppKeyHierarchy);
 
523
                        free(tcsHier);
 
524
                        free(tspHier);
 
525
                } else
 
526
                        return TSPERR(TSS_E_BAD_PARAMETER);
 
527
        } else {
 
528
                /* If this field is set to NULL, the returned array of TSS_KM_KEYINFO2 structures
 
529
                 * contains data reflecting the entire key hierarchy starting with root key. The
 
530
                 * array will include keys from both the user and the system TSS key store. The
 
531
                 * persistentStorageType field will be ignored. */
 
532
                if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, &tcsHierSize,
 
533
                                                      &tcsHier)))
 
534
                        return result;
 
535
 
 
536
                if ((result = ps_get_registered_keys2(pUuidData, NULL, &tspHierSize, &tspHier))) {
 
537
                        free(tcsHier);
 
538
                        return result;
 
539
                }
 
540
 
 
541
                result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, tcsHierSize,
 
542
                                                tcsHier, pulKeyHierarchySize, ppKeyHierarchy);
 
543
                free(tcsHier);
 
544
                free(tspHier);
 
545
        }
 
546
 
 
547
        if ((result = add_mem_entry(tspContext, *ppKeyHierarchy))) {
 
548
                free(*ppKeyHierarchy);
 
549
                *ppKeyHierarchy = NULL;
 
550
                *pulKeyHierarchySize = 0;
 
551
        }
 
552
 
 
553
        return result;
 
554
}