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 <stdlib.h>
     13 #include <stdio.h>
     14 #include <string.h>
     15 #include <unistd.h>
     16 #include <errno.h>
     17 
     18 #include "trousers/tss.h"
     19 #include "trousers_types.h"
     20 #include "trousers_types.h"
     21 #include "tcs_tsp.h"
     22 #include "tcs_utils.h"
     23 #include "tcs_int_literals.h"
     24 #include "capabilities.h"
     25 #include "tcslog.h"
     26 #include "tcsps.h"
     27 #include "req_mgr.h"
     28 
     29 
     30 TSS_RESULT
     31 ps_init_disk_cache(void)
     32 {
     33 	int fd;
     34 	TSS_RESULT rc;
     35 
     36 	MUTEX_INIT(disk_cache_lock);
     37 
     38 	if ((fd = get_file()) < 0)
     39 		return TCSERR(TSS_E_INTERNAL_ERROR);
     40 
     41 	if ((rc = init_disk_cache(fd)))
     42 		return rc;
     43 
     44 	/* this is temporary, to clear out a PS file from trousers
     45 	 * versions before 0.2.1 */
     46 	if ((rc = clean_disk_cache(fd)))
     47 		return rc;
     48 
     49 	put_file(fd);
     50 	return TSS_SUCCESS;
     51 }
     52 
     53 void
     54 ps_close_disk_cache(void)
     55 {
     56 	int fd;
     57 
     58 	if ((fd = get_file()) < 0) {
     59 		LogError("get_file() failed while trying to close disk cache.");
     60 		return;
     61 	}
     62 
     63 	close_disk_cache(fd);
     64 
     65 	put_file(fd);
     66 }
     67 
     68 TSS_BOOL
     69 ps_is_key_registered(TCPA_STORE_PUBKEY *pub)
     70 {
     71 	TSS_UUID *uuid;
     72 	int fd;
     73 	TSS_RESULT rc;
     74 	TSS_BOOL is_reg = FALSE;
     75 
     76 	if ((fd = get_file()) < 0)
     77 		return FALSE;
     78 
     79 	if ((rc = psfile_get_uuid_by_pub(fd, pub, &uuid))) {
     80 		put_file(fd);
     81 		return FALSE;
     82 	}
     83 
     84 	put_file(fd);
     85 
     86 	if ((isUUIDRegistered(uuid, &is_reg)))
     87 		is_reg = FALSE;
     88 
     89 	free(uuid);
     90 	return is_reg;
     91 }
     92 
     93 TSS_RESULT
     94 getParentUUIDByUUID(TSS_UUID *uuid, TSS_UUID *ret_uuid)
     95 {
     96 	struct key_disk_cache *disk_tmp;
     97 
     98 	/* check the registered key disk cache */
     99 	MUTEX_LOCK(disk_cache_lock);
    100 
    101 	for (disk_tmp = key_disk_cache_head; disk_tmp; disk_tmp = disk_tmp->next) {
    102 		if ((disk_tmp->flags & CACHE_FLAG_VALID) &&
    103 		    !memcmp(&disk_tmp->uuid, uuid, sizeof(TSS_UUID))) {
    104 			memcpy(ret_uuid, &disk_tmp->parent_uuid, sizeof(TSS_UUID));
    105 			MUTEX_UNLOCK(disk_cache_lock);
    106 			return TSS_SUCCESS;
    107 		}
    108 	}
    109 	MUTEX_UNLOCK(disk_cache_lock);
    110 
    111 	return TCSERR(TSS_E_FAIL);
    112 }
    113 
    114 TSS_RESULT
    115 isUUIDRegistered(TSS_UUID *uuid, TSS_BOOL *is_reg)
    116 {
    117 	struct key_disk_cache *disk_tmp;
    118 
    119 	/* check the registered key disk cache */
    120 	MUTEX_LOCK(disk_cache_lock);
    121 
    122 	for (disk_tmp = key_disk_cache_head; disk_tmp; disk_tmp = disk_tmp->next) {
    123 		if ((disk_tmp->flags & CACHE_FLAG_VALID) &&
    124 		    !memcmp(&disk_tmp->uuid, uuid, sizeof(TSS_UUID))) {
    125 			*is_reg = TRUE;
    126 			MUTEX_UNLOCK(disk_cache_lock);
    127 			return TSS_SUCCESS;
    128 		}
    129 	}
    130 	MUTEX_UNLOCK(disk_cache_lock);
    131 	*is_reg = FALSE;
    132 
    133 	return TSS_SUCCESS;
    134 }
    135 
    136 void
    137 disk_cache_shift(struct key_disk_cache *c)
    138 {
    139 	UINT32 key_size, offset;
    140 	struct key_disk_cache *tmp = key_disk_cache_head;
    141 
    142 	/* offset is the end of the key location in the file */
    143 	offset = TSSPS_VENDOR_DATA_OFFSET(c) + c->vendor_data_size;
    144 	/* key_size is the size of the key entry on disk */
    145 	key_size = offset - TSSPS_UUID_OFFSET(c);
    146 
    147 	/* for each disk cache entry, if the data for that entry is at an
    148 	 * offset greater than the key beign removed, then the entry needs to
    149 	 * be decremented by the size of key's disk footprint (the key_size
    150 	 * variable) */
    151 	while (tmp) {
    152 		if (tmp->offset >= offset) {
    153 			tmp->offset -= key_size;
    154 		}
    155 
    156 		tmp = tmp->next;
    157 	}
    158 }
    159 
    160 TSS_RESULT
    161 ps_remove_key(TSS_UUID *uuid)
    162 {
    163 	struct key_disk_cache *tmp, *prev = NULL;
    164 	TSS_RESULT rc;
    165         int fd = -1;
    166 
    167 	MUTEX_LOCK(disk_cache_lock);
    168 	tmp = key_disk_cache_head;
    169 
    170 	for (; tmp; prev = tmp, tmp = tmp->next) {
    171 		if ((tmp->flags & CACHE_FLAG_VALID) &&
    172 		    !memcmp(uuid, &tmp->uuid, sizeof(TSS_UUID))) {
    173 			if ((fd = get_file()) < 0) {
    174 				rc = TCSERR(TSS_E_INTERNAL_ERROR);
    175 				break;
    176 			}
    177 
    178 			rc = psfile_remove_key(fd, tmp);
    179 
    180 			put_file(fd);
    181 
    182 			/* if moving the file contents around succeeded, then
    183 			 * change the offsets of the keys in the cache in
    184 			 * mem_cache_shift() and remove the key from the
    185 			 * cache. */
    186 			if (!rc) {
    187 				disk_cache_shift(tmp);
    188 				if (prev) {
    189 					prev->next = tmp->next;
    190 				} else {
    191 					key_disk_cache_head = tmp->next;
    192 				}
    193 				free(tmp);
    194 			} else {
    195 				LogError("Error removing registered key.");
    196 			}
    197 
    198 			MUTEX_UNLOCK(disk_cache_lock);
    199 			return rc;
    200 		}
    201 	}
    202 
    203 	MUTEX_UNLOCK(disk_cache_lock);
    204 
    205 	return TCSERR(TCSERR(TSS_E_PS_KEY_NOTFOUND));
    206 }
    207 
    208 /*
    209  * temporary function to clean out blanked keys from a PS file from
    210  * trousers 0.2.0 and before
    211  */
    212 TSS_RESULT
    213 clean_disk_cache(int fd)
    214 {
    215 	struct key_disk_cache *tmp, *prev = NULL;
    216 	TSS_RESULT rc;
    217 
    218 	MUTEX_LOCK(disk_cache_lock);
    219 	tmp = key_disk_cache_head;
    220 
    221 	for (; tmp; prev = tmp, tmp = tmp->next) {
    222 		if (!(tmp->flags & CACHE_FLAG_VALID)) {
    223 			rc = psfile_remove_key(fd, tmp);
    224 
    225 			/* if moving the file contents around succeeded, then
    226 			 * change the offsets of the keys in the cache in
    227 			 * mem_cache_shift() and remove the key from the
    228 			 * cache. */
    229 			if (!rc) {
    230 				disk_cache_shift(tmp);
    231 				if (prev) {
    232 					prev->next = tmp->next;
    233 				}
    234 				free(tmp);
    235 			} else {
    236 				LogError("Error removing blank key.");
    237 			}
    238 
    239 			MUTEX_UNLOCK(disk_cache_lock);
    240 			return rc;
    241 		}
    242 	}
    243 
    244 	MUTEX_UNLOCK(disk_cache_lock);
    245 	return TSS_SUCCESS;
    246 }
    247 
    248 TSS_RESULT
    249 ps_get_key_by_uuid(TSS_UUID *uuid, BYTE *blob, UINT16 *blob_size)
    250 {
    251         int fd = -1;
    252         TSS_RESULT rc = TSS_SUCCESS;
    253 
    254         if ((fd = get_file()) < 0)
    255                 return TCSERR(TSS_E_INTERNAL_ERROR);
    256 
    257         rc = psfile_get_key_by_uuid(fd, uuid, blob, blob_size);
    258 
    259         put_file(fd);
    260         return rc;
    261 }
    262 
    263 TSS_RESULT
    264 ps_get_key_by_cache_entry(struct key_disk_cache *c, BYTE *blob, UINT16 *blob_size)
    265 {
    266         int fd = -1;
    267         TSS_RESULT rc = TSS_SUCCESS;
    268 
    269         if ((fd = get_file()) < 0)
    270                 return TCSERR(TSS_E_INTERNAL_ERROR);
    271 
    272         rc = psfile_get_key_by_cache_entry(fd, c, blob, blob_size);
    273 
    274         put_file(fd);
    275         return rc;
    276 }
    277 
    278 TSS_RESULT
    279 ps_get_vendor_data(struct key_disk_cache *c, UINT32 *size, BYTE **data)
    280 {
    281         int fd = -1;
    282         TSS_RESULT rc;
    283 
    284         if ((fd = get_file()) < 0)
    285                 return TCSERR(TSS_E_INTERNAL_ERROR);
    286 
    287         rc = psfile_get_vendor_data(fd, c, size, data);
    288 
    289         put_file(fd);
    290         return rc;
    291 }
    292 
    293 TSS_RESULT
    294 ps_is_pub_registered(TCPA_STORE_PUBKEY *key)
    295 {
    296         int fd = -1;
    297         TSS_BOOL answer;
    298 
    299         if ((fd = get_file()) < 0)
    300                 return FALSE;
    301 
    302         if (psfile_is_pub_registered(fd, key, &answer)) {
    303                 put_file(fd);
    304                 return FALSE;
    305         }
    306 
    307         put_file(fd);
    308         return answer;
    309 }
    310 
    311 TSS_RESULT
    312 ps_get_uuid_by_pub(TCPA_STORE_PUBKEY *pub, TSS_UUID **uuid)
    313 {
    314         int fd = -1;
    315 	TSS_RESULT ret;
    316 
    317         if ((fd = get_file()) < 0)
    318                 return TCSERR(TSS_E_INTERNAL_ERROR);
    319 
    320         ret = psfile_get_uuid_by_pub(fd, pub, uuid);
    321 
    322         put_file(fd);
    323         return ret;
    324 }
    325 
    326 TSS_RESULT
    327 ps_get_key_by_pub(TCPA_STORE_PUBKEY *pub, UINT32 *size, BYTE **key)
    328 {
    329         int fd = -1;
    330 	TSS_RESULT ret;
    331 
    332         if ((fd = get_file()) < 0)
    333                 return TCSERR(TSS_E_INTERNAL_ERROR);
    334 
    335         ret = psfile_get_key_by_pub(fd, pub, size, key);
    336 
    337         put_file(fd);
    338         return ret;
    339 }
    340 
    341 TSS_RESULT
    342 ps_write_key(TSS_UUID *uuid, TSS_UUID *parent_uuid, BYTE *vendor_data,
    343 	     UINT32 vendor_size, BYTE *blob, UINT32 blob_size)
    344 {
    345         int fd = -1;
    346         TSS_RESULT rc;
    347 	UINT32 parent_ps;
    348 	UINT16 short_blob_size = (UINT16)blob_size;
    349 
    350         if ((fd = get_file()) < 0)
    351                 return TCSERR(TSS_E_INTERNAL_ERROR);
    352 
    353 	/* this case needed for PS file init. if the key file doesn't yet exist, the
    354 	 * psfile_get_parent_ps_type_by_uuid() call would fail. */
    355 	if (!memcmp(parent_uuid, &NULL_UUID, sizeof(TSS_UUID))) {
    356 		parent_ps = TSS_PS_TYPE_SYSTEM;
    357 	} else {
    358 		if ((rc = psfile_get_ps_type_by_uuid(fd, parent_uuid, &parent_ps)))
    359 			return rc;
    360 	}
    361 
    362         rc = psfile_write_key(fd, uuid, parent_uuid, &parent_ps, vendor_data,
    363 			      vendor_size, blob, short_blob_size);
    364 
    365         put_file(fd);
    366         return TSS_SUCCESS;
    367 }
    368