/* * return the vendor data from PS given its cache entry. The disk cache must be * locked by the caller. */ TSS_RESULT psfile_get_vendor_data(int fd, struct key_disk_cache *c, UINT32 *size, BYTE **data) { int rc; UINT32 file_offset; /* jump to the location of the data */ file_offset = TSSPS_VENDOR_DATA_OFFSET(c); rc = lseek(fd, file_offset, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } if ((*data = malloc(c->vendor_data_size)) == NULL) { LogError("malloc of %u bytes failed", c->vendor_data_size); return TCSERR(TSS_E_OUTOFMEMORY); } if ((rc = read_data(fd, *data, c->vendor_data_size))) { LogError("%s: error reading %u bytes", __FUNCTION__, c->vendor_data_size); free(*data); *data = NULL; return TCSERR(TSS_E_INTERNAL_ERROR); } *size = c->vendor_data_size; return TSS_SUCCESS; }
TSS_RESULT psfile_remove_key(int fd, struct key_disk_cache *c) { TSS_RESULT result; UINT32 head_offset = 0, tail_offset, num_keys; BYTE buf[4096]; struct stat stat_buf; int rc, size = 0; if ((rc = fstat(fd, &stat_buf)) != 0) { LogError("fstat: %s", strerror(errno)); return TSS_E_INTERNAL_ERROR; } /* head_offset is the offset the beginning of the key */ head_offset = TSSPS_UUID_OFFSET(c); /* tail_offset is the offset the beginning of the next key */ tail_offset = TSSPS_VENDOR_DATA_OFFSET(c) + c->vendor_data_size; rc = lseek(fd, tail_offset, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } /* read in from tail, write out to head to fill the gap */ while ((rc = read(fd, buf, sizeof(buf))) > 0) { size = rc; tail_offset += size; /* set the file pointer to where we want to write */ rc = lseek(fd, head_offset, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } /* write the data */ if ((result = write_data(fd, (void *)buf, size))) { LogError("%s", __FUNCTION__); return result; } head_offset += size; /* set the file pointer to where we want to read in the next * loop */ rc = lseek(fd, tail_offset, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } } if (rc < 0) { LogError("read: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } /* set the file pointer to where we want to write */ rc = lseek(fd, head_offset, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } /* head_offset now contains a pointer to where we want to truncate the * file. Zero out the old tail end of the file and truncate it. */ memset(buf, 0, sizeof(buf)); /* Zero out the old tail end of the file */ if ((result = write_data(fd, (void *)buf, tail_offset - head_offset))) { LogError("%s", __FUNCTION__); return result; } if ((rc = ftruncate(fd, head_offset)) < 0) { LogError("ftruncate: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } /* we succeeded in removing a key from the disk. Decrement the number * of keys in the file */ rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } rc = read(fd, &num_keys, sizeof(UINT32)); if (rc != sizeof(UINT32)) { LogError("read of %zd bytes: %s", sizeof(UINT32), strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } /* decrement, then write back out to disk */ num_keys--; if ((result = write_data(fd, (void *)&num_keys, sizeof(UINT32)))) { LogError("%s", __FUNCTION__); return result; } return TSS_SUCCESS; }
TSS_RESULT psfile_remove_key(int fd, TSS_UUID *uuid) { TSS_RESULT result; UINT32 head_offset = 0, tail_offset; int rc, size = 0; struct key_disk_cache c; BYTE buf[4096]; if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &c))) return result; /* head_offset is the offset the beginning of the key */ head_offset = TSSPS_UUID_OFFSET(&c); /* tail_offset is the offset the beginning of the next key */ tail_offset = TSSPS_VENDOR_DATA_OFFSET(&c) + c.vendor_data_size; rc = lseek(fd, tail_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* read in from tail, write out to head to fill the gap */ while ((rc = read(fd, buf, sizeof(buf))) > 0) { size = rc; tail_offset += size; /* set the file pointer to where we want to write */ rc = lseek(fd, head_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* write the data */ if ((result = write_data(fd, (void *)buf, size))) { LogDebug("%s", __FUNCTION__); return result; } head_offset += size; /* set the file pointer to where we want to read in the next * loop */ rc = lseek(fd, tail_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } } if (rc < 0) { LogDebug("read: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* set the file pointer to where we want to write */ rc = lseek(fd, head_offset, SEEK_SET); if (rc == ((off_t)-1)) { LogDebug("lseek: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* head_offset now contains a pointer to where we want to truncate the * file. Zero out the old tail end of the file and truncate it. */ memset(buf, 0, sizeof(buf)); /* Zero out the old tail end of the file */ if ((result = write_data(fd, (void *)buf, tail_offset - head_offset))) { LogDebug("%s", __FUNCTION__); return result; } if ((rc = ftruncate(fd, head_offset)) < 0) { LogDebug("ftruncate: %s", strerror(errno)); return TSPERR(TSS_E_INTERNAL_ERROR); } /* we succeeded in removing a key from the disk. Decrement the number * of keys in the file */ if ((result = psfile_change_num_keys(fd, TSS_PSFILE_DECREMENT_NUM_KEYS))) return result; return TSS_SUCCESS; }