diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-11-25 14:36:20 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-11-25 14:36:20 +0000 |
commit | c3649a2def02c41d837ae1f79dda729ccb91e677 (patch) | |
tree | bea46dff212fdef977fe9094a70a939e8cc21885 /src/tspi/tsp_ps.c | |
download | trousers-upstream.tar.gz |
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tspi/tsp_ps.c')
-rw-r--r-- | src/tspi/tsp_ps.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/src/tspi/tsp_ps.c b/src/tspi/tsp_ps.c new file mode 100644 index 0000000..96c267a --- /dev/null +++ b/src/tspi/tsp_ps.c @@ -0,0 +1,347 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <limits.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/file.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <limits.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "tcs_tsp.h" +#include "tspps.h" +#include "tsplog.h" +#include "obj.h" + +/* + * tsp_ps.c + * + * Functions used to query the user persistent storage file. + * + * Since other apps may be altering the file, all operations must be atomic WRT the file and no + * cache will be kept, since another app could delete keys from the file out from under us. + * + * Atomicity is guaranteed for operations inbetween calls to get_file() and put_file(). + * + * A PS file will have the lifetime of the TSP context. For instance, this code will store hKeyA + * and hKeyB in the file "a": + * + * setenv("TSS_USER_PS_FILE=a"); + * Tspi_Context_Create(&hContext); + * Tspi_Context_RegisterKey(hKeyA); + * setenv("TSS_USER_PS_FILE=b"); + * Tspi_Context_RegisterKey(hKeyB); + * + * but this code will store hKeyA in file "a" and hKeyB in file "b": + * + * setenv("TSS_USER_PS_FILE=a"); + * Tspi_Context_Create(&hContext); + * Tspi_Context_RegisterKey(hKeyA); + * Tspi_Context_Close(hContext); + * + * setenv("TSS_USER_PS_FILE=b"); + * Tspi_Context_Create(&hContext); + * Tspi_Context_RegisterKey(hKeyB); + * + */ + +TSS_RESULT +ps_get_registered_keys(TSS_UUID *uuid, TSS_UUID *tcs_uuid, UINT32 *size, TSS_KM_KEYINFO **keys) +{ + int fd; + UINT32 result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_get_registered_keys(fd, uuid, tcs_uuid, size, keys); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_get_registered_keys2(TSS_UUID *uuid, TSS_UUID *tcs_uuid, UINT32 *size, TSS_KM_KEYINFO2 **keys) +{ + int fd; + UINT32 result; + + if ((result = get_file(&fd))) + return result; + + /* Sets the proper TSS_KM_KEYINFO2 fields according to the UUID type */ + result = psfile_get_registered_keys2(fd, uuid, tcs_uuid, size, keys); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_is_key_registered(TSS_UUID *uuid, TSS_BOOL *answer) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_is_key_registered(fd, uuid, answer); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_write_key(TSS_UUID *uuid, TSS_UUID *parent_uuid, UINT32 parent_ps, UINT32 blob_size, BYTE *blob) +{ + int fd; + TSS_RESULT result; + UINT16 short_blob_size = (UINT16)blob_size; + + if (blob_size > USHRT_MAX) { + LogError("Blob data being written to disk is too large(%u bytes)!", blob_size); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if ((result = get_file(&fd))) + return result; + + result = psfile_write_key(fd, uuid, parent_uuid, parent_ps, blob, short_blob_size); + + put_file(fd); + return result; +} + + +TSS_RESULT +ps_remove_key(TSS_UUID *uuid) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_remove_key(fd, uuid); + + put_file(fd); + return result; +} + +TSS_RESULT +ps_get_key_by_pub(TSS_HCONTEXT tspContext, UINT32 pub_size, BYTE *pub, TSS_HKEY *hKey) +{ + int fd; + TSS_RESULT result = TSS_SUCCESS; + BYTE key[4096]; + TSS_UUID uuid; + + if ((result = get_file(&fd))) + return result; + + if ((result = psfile_get_key_by_pub(fd, &uuid, pub_size, pub, key))) { + put_file(fd); + return result; + } + + put_file(fd); + + result = obj_rsakey_add_by_key(tspContext, &uuid, key, TSS_OBJ_FLAG_USER_PS, hKey); + + return result; +} + +TSS_RESULT +ps_get_key_by_uuid(TSS_HCONTEXT tspContext, TSS_UUID *uuid, TSS_HKEY *hKey) +{ + int fd; + TSS_RESULT result = TSS_SUCCESS; + BYTE key[4096]; + + if ((result = get_file(&fd))) + return result; + + if ((result = psfile_get_key_by_uuid(fd, uuid, key))) { + put_file(fd); + return result; + } + + put_file(fd); + + result = obj_rsakey_add_by_key(tspContext, uuid, key, TSS_OBJ_FLAG_USER_PS, hKey); + + return result; +} + +TSS_RESULT +ps_get_parent_uuid_by_uuid(TSS_UUID *uuid, TSS_UUID *parent_uuid) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_get_parent_uuid_by_uuid(fd, uuid, parent_uuid); + + put_file(fd); + return result; +} + +TSS_RESULT +ps_get_parent_ps_type_by_uuid(TSS_UUID *uuid, UINT32 *type) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_get_parent_ps_type(fd, uuid, type); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_close() +{ + TSS_RESULT result; + int fd; + + if ((result = get_file(&fd))) + return result; + + psfile_close(fd); + + /* No need to call put_file() here, the file is closed */ + + return TSS_SUCCESS; +} + +TSS_RESULT +merge_key_hierarchies(TSS_HCONTEXT tspContext, UINT32 tsp_size, TSS_KM_KEYINFO *tsp_hier, + UINT32 tcs_size, TSS_KM_KEYINFO *tcs_hier, UINT32 *merged_size, + TSS_KM_KEYINFO **merged_hier) +{ + UINT32 i, j; + + *merged_hier = malloc((tsp_size + tcs_size) * sizeof(TSS_KM_KEYINFO)); + if (*merged_hier == NULL) { + LogError("malloc of %zu bytes failed.", (tsp_size + tcs_size) * + sizeof(TSS_KM_KEYINFO)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + for (i = 0; i < tsp_size; i++) + memcpy(&((*merged_hier)[i]), &tsp_hier[i], sizeof(TSS_KM_KEYINFO)); + + for (j = 0; j < tcs_size; j++) + memcpy(&((*merged_hier)[i + j]), &tcs_hier[j], sizeof(TSS_KM_KEYINFO)); + + *merged_size = i + j; + + return TSS_SUCCESS; +} + + +TSS_RESULT +merge_key_hierarchies2(TSS_HCONTEXT tspContext, UINT32 tsp_size, TSS_KM_KEYINFO2 *tsp_hier, + UINT32 tcs_size, TSS_KM_KEYINFO2 *tcs_hier, UINT32 *merged_size, + TSS_KM_KEYINFO2 **merged_hier) +{ + UINT32 i, j; + + *merged_hier = malloc((tsp_size + tcs_size) * sizeof(TSS_KM_KEYINFO2)); + if (*merged_hier == NULL) { + LogError("malloc of %zu bytes failed.", (tsp_size + tcs_size) * + sizeof(TSS_KM_KEYINFO2)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + for (i = 0; i < tsp_size; i++) + memcpy(&((*merged_hier)[i]), &tsp_hier[i], sizeof(TSS_KM_KEYINFO2)); + + for (j = 0; j < tcs_size; j++) + memcpy(&((*merged_hier)[i + j]), &tcs_hier[j], sizeof(TSS_KM_KEYINFO2)); + + *merged_size = i + j; + + return TSS_SUCCESS; +} + + +#if 0 +TSS_RESULT +load_from_system_ps(TSS_HCONTEXT tspContext, TSS_UUID *uuid, TSS_HKEY *phKey) +{ + TCS_KEY_HANDLE tcsKeyHandle; + TCS_LOADKEY_INFO info; + BYTE *keyBlob = NULL; + + memset(&info, 0, sizeof(TCS_LOADKEY_INFO)); + + result = TCSP_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle); + + if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) { + TSS_HKEY keyHandle; + TSS_HPOLICY hPolicy; + + /* load failed, due to some key in the chain needing auth + * which doesn't yet exist at the TCS level. However, the + * auth may already be set in policies at the TSP level. + * To find out, get the key handle of the key requiring + * auth. First, look at the list of keys in memory. */ + if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) { + /* If that failed, look on disk, in User PS. */ + if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID, &keyHandle)) + return result; + } + + if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE, &hPolicy, NULL)) + return result; + + if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, &info.paramDigest, + &info.authData)) + return result; + + if ((result = TCSP_LoadKeyByUUID(tspContext, *uuid, &info, &tcsKeyHandle))) + return result; + } else if (result) + return result; + + if ((result = TCS_GetRegisteredKeyBlob(tspContext, *uuid, &keyBlobSize, &keyBlob))) + return result; + + if ((result = obj_rsakey_add_by_key(tspContext, uuid, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, + phKey))) { + free(keyBlob); + return result; + } + + result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle); + + free(keyBlob); + + return result; +} +#endif + |