Example #1
0
TSS_RESULT
TCS_GetPcrEventLog_Internal(TCS_CONTEXT_HANDLE hContext,/* in  */
			    UINT32 *pEventCount,	/* out */
			    TSS_PCR_EVENT **ppEvents)	/* out */
{
	TSS_RESULT result;
	UINT32 i, j, event_count, aggregate_count = 0;
	struct event_wrapper *tmp;
	TSS_PCR_EVENT *event_list = NULL, *aggregate_list = NULL;

	if ((result = ctx_verify_context(hContext)))
		return result;

	MUTEX_LOCK(tcs_event_log->lock);

	/* for each PCR index, if its externally controlled, get the total number of events
	 * externally, else copy the events from the TCSD list. Then tack that list onto a
	 * master list to returned. */
	for (i = 0; i < tpm_metrics.num_pcrs; i++) {
		if ((tcsd_options.kernel_pcrs & (1 << i)) ||
		    (tcsd_options.firmware_pcrs & (1 << i))) {
			/* A kernel or firmware controlled PCR event list */
			event_count = UINT_MAX;
			if ((result = TCS_GetExternalPcrEventsByPcr(i, 0, &event_count,
								    &event_list))) {
				LogDebug("Getting External event list for PCR %u failed", i);
				free(aggregate_list);
				goto error;
			}
			LogDebug("Retrieved %u events from PCR %u (external)", event_count, i);
		} else {
			/* A TCSD controlled PCR event list */
			event_count = get_num_events(i);

			if (event_count == 0)
				continue;

			if ((event_list = calloc(event_count, sizeof(TSS_PCR_EVENT))) == NULL) {
				LogError("malloc of %zd bytes failed",
					 event_count * sizeof(TSS_PCR_EVENT));
				result = TCSERR(TSS_E_OUTOFMEMORY);
				free(aggregate_list);
				goto error;
			}

			tmp = tcs_event_log->lists[i];
			for (j = 0; j < event_count; j++) {
				copy_pcr_event(&event_list[j], &(tmp->event));
				tmp = tmp->next;
			}
		}

		if (event_count == 0)
			continue;

		/* Tack the list onto the aggregate_list */
		aggregate_list = concat_pcr_events(&aggregate_list, aggregate_count, event_list,
						   event_count);
		if (aggregate_list == NULL) {
			free(event_list);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto error;
		}
		aggregate_count += event_count;
		free(event_list);
	}

	*ppEvents = aggregate_list;
	*pEventCount = aggregate_count;
	result = TSS_SUCCESS;
error:
	MUTEX_UNLOCK(tcs_event_log->lock);

	return result;
}
Example #2
0
TSS_RESULT
tcs_wrap_SetCapability(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TCPA_CAPABILITY_AREA capArea;
	UINT32 subCapSize;
	BYTE *subCap;
	UINT32 valueSize;
	BYTE *value;
	TSS_RESULT result;
	TPM_AUTH ownerAuth, *pOwnerAuth;

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if (subCapSize == 0)
		subCap = NULL;
	else {
		subCap = calloc(1, subCapSize);
		if (subCap == NULL) {
			LogError("malloc of %u bytes failed.", subCapSize);
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &data->comm)) {
			free(subCap);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
	}

	if (getData(TCSD_PACKET_TYPE_UINT32, 4, &valueSize, 0, &data->comm)) {
		free(subCap);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (valueSize == 0)
		value = NULL;
	else {
		value = calloc(1, valueSize);
		if (value == NULL) {
			free(subCap);
			LogError("malloc of %u bytes failed.", valueSize);
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 5, value, valueSize, &data->comm)) {
			free(subCap);
			free(value);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
	}

	if (getData(TCSD_PACKET_TYPE_AUTH, 6, &ownerAuth, 0, &data->comm))
		pOwnerAuth = NULL;
	else
		pOwnerAuth = &ownerAuth;


	MUTEX_LOCK(tcsp_lock);

	result = TCSP_SetCapability_Internal(hContext, capArea, subCapSize, subCap, valueSize,
					     value, pOwnerAuth);

	MUTEX_UNLOCK(tcsp_lock);
	free(subCap);
	free(value);

	if (result == TSS_SUCCESS) {
		initData(&data->comm, 1);
		if (pOwnerAuth) {
			if (setData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &data->comm)) {
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;
	return TSS_SUCCESS;
}
Example #3
0
TSS_RESULT
tcs_wrap_DSAP(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	UINT16 entityType;
	TCS_KEY_HANDLE keyHandle;
	TPM_NONCE nonceOddDSAP, nonceEven, nonceEvenDSAP;
	UINT32 entityValueSize;
	BYTE *entityValue;
	TCS_AUTHHANDLE authHandle;
	TSS_RESULT result;

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT16, 1, &entityType, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &keyHandle, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_NONCE, 3, &nonceOddDSAP, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 4, &entityValueSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	entityValue = malloc(entityValueSize);
	if (entityValue == NULL) {
		LogError("malloc of %u bytes failed.", entityValueSize);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 5, entityValue, entityValueSize, &data->comm)) {
		free(entityValue);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_DSAP_Internal(hContext, entityType, keyHandle, &nonceOddDSAP, entityValueSize,
				    entityValue, &authHandle, &nonceEven, &nonceEvenDSAP);

	MUTEX_UNLOCK(tcsp_lock);
	free(entityValue);

	if (result == TSS_SUCCESS) {
		initData(&data->comm, 3);

		if (setData(TCSD_PACKET_TYPE_UINT32, 0, &authHandle, 0, &data->comm))
			return TCSERR(TSS_E_INTERNAL_ERROR);
		if (setData(TCSD_PACKET_TYPE_NONCE, 1, &nonceEven, 0, &data->comm))
			return TCSERR(TSS_E_INTERNAL_ERROR);
		if (setData(TCSD_PACKET_TYPE_NONCE, 2, &nonceEvenDSAP, 0, &data->comm))
			return TCSERR(TSS_E_INTERNAL_ERROR);
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #4
0
TSS_RESULT
TCS_GetPcrEventsByPcr_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				UINT32 PcrIndex,		/* in */
				UINT32 FirstEvent,		/* in */
				UINT32 *pEventCount,		/* in, out */
				TSS_PCR_EVENT **ppEvents)	/* out */
{
	UINT32 lastEventNumber, i, eventIndex;
	TSS_RESULT result;
	struct event_wrapper *tmp;

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (PcrIndex >= tpm_metrics.num_pcrs)
		return TCSERR(TSS_E_BAD_PARAMETER);

	/* if this is a kernel or firmware controlled PCR, call an external routine */
        if ((tcsd_options.kernel_pcrs & (1 << PcrIndex)) ||
	    (tcsd_options.firmware_pcrs & (1 << PcrIndex))) {
		MUTEX_LOCK(tcs_event_log->lock);
		result = TCS_GetExternalPcrEventsByPcr(PcrIndex, FirstEvent,
							pEventCount, ppEvents);
		MUTEX_UNLOCK(tcs_event_log->lock);

		return result;
	}

	MUTEX_LOCK(tcs_event_log->lock);

	lastEventNumber = get_num_events(PcrIndex);

	MUTEX_UNLOCK(tcs_event_log->lock);

	/* if pEventCount is larger than the number of events to return, just return less.
	 * *pEventCount will be set to the number returned below.
	 */
	lastEventNumber = MIN(lastEventNumber, FirstEvent + *pEventCount);

	if (FirstEvent > lastEventNumber)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if (lastEventNumber == 0) {
		*pEventCount = 0;
		*ppEvents = NULL;
		return TSS_SUCCESS;
	}

	/* FirstEvent is 0 indexed see TSS 1.1b spec section 4.7.2.2.3. That means that
	 * the following calculation is not off by one. :-)
	 */
	*ppEvents = calloc((lastEventNumber - FirstEvent), sizeof(TSS_PCR_EVENT));
	if (*ppEvents == NULL) {
		LogError("malloc of %zd bytes failed.",
			 sizeof(TSS_PCR_EVENT) * (lastEventNumber - FirstEvent));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	MUTEX_LOCK(tcs_event_log->lock);

	tmp = tcs_event_log->lists[PcrIndex];

	/* move through the list until we get to the first event requested */
	for (i = 0; i < FirstEvent; i++)
		tmp = tmp->next;

	/* copy events from the first requested to the last requested */
	for (eventIndex = 0; i < lastEventNumber; eventIndex++, i++) {
		copy_pcr_event(&((*ppEvents)[eventIndex]), &(tmp->event));
		tmp = tmp->next;
	}

	MUTEX_UNLOCK(tcs_event_log->lock);

	*pEventCount = eventIndex;

	return TSS_SUCCESS;
}
Example #5
0
TSS_RESULT
tcs_wrap_CreateWrapKey(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TCS_KEY_HANDLE hWrappingKey;
	TCPA_ENCAUTH KeyUsageAuth;
	TCPA_ENCAUTH KeyMigrationAuth;
	UINT32 keyInfoSize;
	BYTE *keyInfo;

	TPM_AUTH *pAuth, auth;

	UINT32 keyDataSize;
	BYTE *keyData;
	TSS_RESULT result;

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &hWrappingKey, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_ENCAUTH, 2, &KeyUsageAuth, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_ENCAUTH, 3, &KeyMigrationAuth, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 4, &keyInfoSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	keyInfo = calloc(1, keyInfoSize);
	if (keyInfo == NULL) {
		LogError("malloc of %d bytes failed.", keyInfoSize);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 5, keyInfo, keyInfoSize, &data->comm)) {
		free(keyInfo);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	if (getData(TCSD_PACKET_TYPE_AUTH, 6, &auth, 0, &data->comm))
		pAuth = NULL;
	else
		pAuth = &auth;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_CreateWrapKey_Internal(hContext, hWrappingKey, KeyUsageAuth, KeyMigrationAuth,
					     keyInfoSize, keyInfo, &keyDataSize, &keyData, pAuth);

	MUTEX_UNLOCK(tcsp_lock);

	free(keyInfo);
	if (result == TSS_SUCCESS) {
		initData(&data->comm, 3);
		if (setData(TCSD_PACKET_TYPE_UINT32, 0, &keyDataSize, 0, &data->comm)) {
			free(keyData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, 1, keyData, keyDataSize, &data->comm)) {
			free(keyData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		free(keyData);
		if (pAuth) {
			if (setData(TCSD_PACKET_TYPE_AUTH, 2, pAuth, 0, &data->comm))
				return TCSERR(TSS_E_INTERNAL_ERROR);
		}
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #6
0
TSS_RESULT
tcs_wrap_UnSeal(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TCS_KEY_HANDLE parentHandle;
	UINT32 inDataSize;
	BYTE *inData;

	TPM_AUTH parentAuth, dataAuth, emptyAuth;
	TPM_AUTH *pParentAuth, *pDataAuth;

	UINT32 outDataSize;
	BYTE *outData;
	TSS_RESULT result;

	memset(&emptyAuth, 0, sizeof(TPM_AUTH));

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &inDataSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	inData = calloc(1, inDataSize);
	if (inData == NULL) {
		LogError("malloc of %d bytes failed.", inDataSize);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	if (getData(TCSD_PACKET_TYPE_PBYTE, 3, inData, inDataSize, &data->comm)) {
		free(inData);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	result = getData(TCSD_PACKET_TYPE_AUTH, 4, &parentAuth, 0, &data->comm);
	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE)
		pParentAuth = NULL;
	else if (result) {
		free(inData);
		return result;
	} else
		pParentAuth = &parentAuth;

	result = getData(TCSD_PACKET_TYPE_AUTH, 5, &dataAuth, 0, &data->comm);
	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE) {
		pDataAuth = pParentAuth;
		pParentAuth = NULL;
	} else if (result) {
		free(inData);
		return result;
	} else
		pDataAuth = &dataAuth;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_Unseal_Internal(hContext, parentHandle, inDataSize, inData, pParentAuth,
				      pDataAuth, &outDataSize, &outData);

	MUTEX_UNLOCK(tcsp_lock);
	free(inData);

	if (result == TSS_SUCCESS) {
		initData(&data->comm, 4);
		if (pParentAuth != NULL) {
			if (setData(TCSD_PACKET_TYPE_AUTH, 0, pParentAuth, 0, &data->comm)) {
				free(outData);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		} else {
			if (setData(TCSD_PACKET_TYPE_AUTH, 0, &emptyAuth, 0, &data->comm)) {
				free(outData);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}

		if (setData(TCSD_PACKET_TYPE_AUTH, 1, &dataAuth, 0, &data->comm)) {
			free(outData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_UINT32, 2, &outDataSize, 0, &data->comm)) {
			free(outData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, 3, outData, outDataSize, &data->comm)) {
			free(outData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		free(outData);
	} else
		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #7
0
TSS_RESULT
tcs_wrap_Delegate_CreateOwnerDelegation(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TSS_BOOL increment;
	UINT32 publicInfoSize;
	BYTE *publicInfo;
	TPM_ENCAUTH encDelAuth;
	TPM_AUTH ownerAuth, nullAuth, *pAuth;
	UINT32 blobSize;
	BYTE *blob;
	TSS_RESULT result;
	int i;

	memset(&ownerAuth, 0, sizeof(TPM_AUTH));
	memset(&nullAuth, 0, sizeof(TPM_AUTH));

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_BOOL, 1, &increment, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &publicInfoSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	publicInfo = malloc(publicInfoSize);
	if (publicInfo == NULL) {
		LogError("malloc of %u bytes failed.", publicInfoSize);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 3, publicInfo, publicInfoSize, &data->comm)) {
		free(publicInfo);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (getData(TCSD_PACKET_TYPE_ENCAUTH, 4, &encDelAuth, 0, &data->comm)) {
		free(publicInfo);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (getData(TCSD_PACKET_TYPE_AUTH, 5, &ownerAuth, 0, &data->comm)) {
		free(publicInfo);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (memcmp(&nullAuth, &ownerAuth, sizeof(TPM_AUTH)))
		pAuth = &ownerAuth;
	else
		pAuth = NULL;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_Delegate_CreateOwnerDelegation_Internal(hContext, increment,
			publicInfoSize, publicInfo, &encDelAuth, pAuth, &blobSize, &blob);

	MUTEX_UNLOCK(tcsp_lock);
	free(publicInfo);

	if (result == TSS_SUCCESS) {
		i = 0;
		initData(&data->comm, 3);
		if (pAuth) {
			if (setData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &data->comm)) {
				free(blob);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}

		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &blobSize, 0, &data->comm)) {
			free(blob);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, i++, blob, blobSize, &data->comm)) {
			free(blob);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		free(blob);
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #8
0
int
main(int argc, char **argv)
{
	TSS_RESULT result;
	int newsd, c, rv, option_index = 0;
	int i;
	socklen_t client_len;
	char *hostname = NULL;
	fd_set rdfd_set;
	int num_fds = 0;
	int nfds = 0;
	int stor_errno;
	sigset_t sigmask, termmask, oldsigmask;
	struct sockaddr_storage client_addr;
	struct srv_sock_info socks_info[MAX_IP_PROTO];
	struct passwd *pwd;
	struct option long_options[] = {
		{"help", 0, NULL, 'h'},
		{"foreground", 0, NULL, 'f'},
		{"config", 1, NULL, 'c'},
		{0, 0, 0, 0}
	};

	unsetenv("TCSD_USE_TCP_DEVICE");
	while ((c = getopt_long(argc, argv, "fhec:", long_options, &option_index)) != -1) {
		switch (c) {
			case 'f':
				setenv("TCSD_FOREGROUND", "1", 1);
				break;
			case 'c':
				tcsd_config_file = optarg;
				break;
			case 'e':
				setenv("TCSD_USE_TCP_DEVICE", "1", 1);
				break;
			case 'h':
				/* fall through */
			default:
				usage();
				return -1;
				break;
		}
	}

	if (!tcsd_config_file)
		tcsd_config_file = TCSD_DEFAULT_CONFIG_FILE;

	if ((result = tcsd_startup()))
		return (int)result;

#ifdef NOUSERCHECK
    LogWarn("will not switch user or check for file permissions. "
            "(Compiled with --disable-usercheck)");
#else
#ifndef SOLARIS
	pwd = getpwnam(TSS_USER_NAME);
	if (pwd == NULL) {
		if (errno == 0) {
			LogError("User \"%s\" not found, please add this user"
					" manually.", TSS_USER_NAME);
		} else {
			LogError("getpwnam(%s): %s", TSS_USER_NAME, strerror(errno));
		}
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	setuid(pwd->pw_uid);
#endif
#endif

	if (setup_server_sockets(socks_info) == -1) {
		LogError("Could not create sockets to listen to connections. Aborting...");
		return -1;
	}

	if (getenv("TCSD_FOREGROUND") == NULL) {
		if (daemon(0, 0) == -1) {
			perror("daemon");
			tcsd_shutdown(socks_info);
			return -1;
		}
	}

	LogInfo("%s: TCSD up and running.", PACKAGE_STRING);

	sigemptyset(&sigmask);
	sigaddset(&sigmask, SIGTERM);
	sigaddset(&sigmask, SIGHUP);

	sigemptyset(&termmask);
	sigaddset(&termmask, SIGTERM);

	do {
		prepare_for_select(socks_info, &num_fds, &rdfd_set, &nfds);
		// Sanity check
		if (num_fds == 0) {
			LogError("No server sockets available to listen connections. Aborting...");
			return -1;
		}

		// Block TERM and HUP signals to prevent race condition
		if (sigprocmask(SIG_BLOCK, &sigmask, &oldsigmask) == -1) {
			LogError("Error setting interrupt mask before accept");
		}

		// TERM and HUP are blocked here, so its safe to test flags.
		if (hup) {
			// Config reading can be slow, so unmask SIGTERM.
			if (sigprocmask(SIG_UNBLOCK, &termmask, NULL) == -1) {
				LogError("Error unblocking SIGTERM before config reload");
			}
			if (reload_config() != TSS_SUCCESS)
				LogError("Failed reloading config");
			if (sigprocmask(SIG_BLOCK, &termmask, NULL) == -1) {
				LogError("Error blocking SIGTERM after config reload");
			}
		}
		if (term)
			break;

		// Select IPv4 and IPv6 socket descriptors with appropriate sigmask.
		LogDebug("Waiting for connections");
		rv = pselect(nfds+1, &rdfd_set, NULL, NULL, NULL, &oldsigmask);
		stor_errno = errno; // original mask must be set ASAP, so store errno.
		if (sigprocmask(SIG_SETMASK, &oldsigmask, NULL) == -1) {
			LogError("Error reseting signal mask to the original configuration.");
		}
		if (rv == -1) {
			if (stor_errno != EINTR) {
				LogError("Error monitoring server socket descriptors.");
				return -1;
			}
			continue;
		}

		for (i=0; i < num_fds; i++) { // accept connections from all IP versions (with valid sd)
			if (!FD_ISSET(socks_info[i].sd, &rdfd_set)) {
				continue;
			}
			client_len = socks_info[i].addr_len;
			newsd = accept(socks_info[i].sd, (struct sockaddr *) &client_addr, &client_len);
			if (newsd < 0) {
				if (errno != EINTR)
					LogError("Failed accept: %s", strerror(errno));
				continue;
			}
			LogDebug("accepted socket %i", newsd);

			hostname = fetch_hostname(&client_addr, client_len);
			if (hostname == NULL)
				hostname=INVALID_ADDR_STR;

			tcsd_thread_create(newsd, hostname);
			hostname = NULL;
		} // for (i=0; i < MAX_IP_PROTO; i++)
	} while (term ==0);

	/* To close correctly, we must receive a SIGTERM */
	tcsd_shutdown(socks_info);
	return 0;
}
Example #9
0
int
loadData(UINT64 *offset, TCSD_PACKET_TYPE data_type, void *data, int data_size, BYTE *blob)
{
	switch (data_type) {
		case TCSD_PACKET_TYPE_BYTE:
			LoadBlob_BYTE(offset, *((BYTE *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_BOOL:
			LoadBlob_BOOL(offset, *((TSS_BOOL *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_UINT16:
			LoadBlob_UINT16(offset, *((UINT16 *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_UINT32:
			LoadBlob_UINT32(offset, *((UINT32 *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_UINT64:
			LoadBlob_UINT64(offset, *((UINT64 *) (data)), blob);
			break;
		case TCSD_PACKET_TYPE_PBYTE:
			LoadBlob(offset, data_size, blob, data);
			break;
		case TCSD_PACKET_TYPE_NONCE:
			LoadBlob(offset, sizeof(TCPA_NONCE), blob, ((TCPA_NONCE *)data)->nonce);
			break;
		case TCSD_PACKET_TYPE_DIGEST:
			LoadBlob(offset, sizeof(TCPA_DIGEST), blob, ((TCPA_DIGEST *)data)->digest);
			break;
		case TCSD_PACKET_TYPE_AUTH:
			LoadBlob_Auth_Special(offset, blob, ((TPM_AUTH *)data));
			break;
#ifdef TSS_BUILD_PS
		case TCSD_PACKET_TYPE_UUID:
			LoadBlob_UUID(offset, blob, *((TSS_UUID *)data));
			break;
		case TCSD_PACKET_TYPE_KM_KEYINFO:
			LoadBlob_KM_KEYINFO(offset, blob, ((TSS_KM_KEYINFO *)data));
			break;
		case TCSD_PACKET_TYPE_KM_KEYINFO2:
			LoadBlob_KM_KEYINFO2(offset, blob, ((TSS_KM_KEYINFO2 *)data));
			break;
		case TCSD_PACKET_TYPE_LOADKEY_INFO:
			LoadBlob_LOADKEY_INFO(offset, blob, ((TCS_LOADKEY_INFO *)data));
			break;
#endif
		case TCSD_PACKET_TYPE_ENCAUTH:
			LoadBlob(offset, sizeof(TCPA_ENCAUTH), blob,
				 ((TCPA_ENCAUTH *)data)->authdata);
			break;
		case TCSD_PACKET_TYPE_VERSION:
			LoadBlob_VERSION(offset, blob, ((TPM_VERSION *)data));
			break;
#ifdef TSS_BUILD_PCR_EVENTS
		case TCSD_PACKET_TYPE_PCR_EVENT:
			LoadBlob_PCR_EVENT(offset, blob, ((TSS_PCR_EVENT *)data));
			break;
#endif
		case TCSD_PACKET_TYPE_SECRET:
			LoadBlob(offset, sizeof(TCPA_SECRET), blob,
				 ((TCPA_SECRET *)data)->authdata);
			break;
		default:
			LogError("TCSD packet type unknown! (0x%x)", data_type & 0xff);
			return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	return TSS_SUCCESS;
}
Example #10
0
UINT32
getData(TCSD_PACKET_TYPE dataType,
	unsigned int index,
	void *theData,
	int theDataSize,
	struct tcsd_comm_data *comm)
{
	UINT64 old_offset, offset;
	TCSD_PACKET_TYPE *type;

	if ((comm->hdr.type_offset + index) > comm->buf_size)
		return TSS_TCP_RPC_BAD_PACKET_TYPE;

	type = (comm->buf + comm->hdr.type_offset) + index;

	if ((UINT32)index >= comm->hdr.num_parms || dataType != *type) {
		LogDebug("Data type of TCS packet element %d doesn't match.", index);
		return TSS_TCP_RPC_BAD_PACKET_TYPE;
	}
	old_offset = offset = comm->hdr.parm_offset;
	switch (dataType) {
		case TCSD_PACKET_TYPE_BYTE:
			if (old_offset + sizeof(BYTE) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob_BYTE(&offset, (BYTE *) (theData), comm->buf);
			break;
		case TCSD_PACKET_TYPE_BOOL:
			if (old_offset + sizeof(TSS_BOOL) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob_BOOL(&offset, (TSS_BOOL *) (theData), comm->buf);
			break;
		case TCSD_PACKET_TYPE_UINT16:
			if (old_offset + sizeof(UINT16) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob_UINT16(&offset, (UINT16 *) (theData), comm->buf);
			break;
		case TCSD_PACKET_TYPE_UINT32:
			if (old_offset + sizeof(UINT32) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob_UINT32(&offset, (UINT32 *) (theData), comm->buf);
			break;
		case TCSD_PACKET_TYPE_PBYTE:
			if (old_offset + theDataSize > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob(&offset, theDataSize, comm->buf, theData);
			break;
		case TCSD_PACKET_TYPE_NONCE:
			if (old_offset + sizeof(TPM_NONCE) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob(&offset, sizeof(TCPA_NONCE), comm->buf,
					((TCPA_NONCE *) (theData))->nonce);
			break;
		case TCSD_PACKET_TYPE_DIGEST:
			if (old_offset + sizeof(TPM_DIGEST) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob(&offset, sizeof(TCPA_DIGEST), comm->buf,
					((TCPA_DIGEST *) (theData))->digest);
			break;
		case TCSD_PACKET_TYPE_AUTH:
			if ((old_offset + sizeof(TCS_AUTHHANDLE)
					+ sizeof(TPM_BOOL)
					+ (2 * sizeof(TPM_NONCE))) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob_Auth_Special(&offset, comm->buf, ((TPM_AUTH *) theData));
			break;
		case TCSD_PACKET_TYPE_ENCAUTH:
			if (old_offset + sizeof(TPM_ENCAUTH) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob(&offset, sizeof(TCPA_ENCAUTH), comm->buf,
					((TCPA_ENCAUTH *) theData)->authdata);
			break;
		case TCSD_PACKET_TYPE_VERSION:
			if (old_offset + sizeof(TPM_VERSION) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob_VERSION(&offset, comm->buf, ((TPM_VERSION *) theData));
			break;
#ifdef TSS_BUILD_PS
		case TCSD_PACKET_TYPE_KM_KEYINFO:
			UnloadBlob_KM_KEYINFO(&old_offset, comm->buf, NULL);

			if (old_offset > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			old_offset = offset;
			UnloadBlob_KM_KEYINFO(&offset, comm->buf, ((TSS_KM_KEYINFO *)theData));
			break;
		case TCSD_PACKET_TYPE_LOADKEY_INFO:
			UnloadBlob_LOADKEY_INFO(&old_offset, comm->buf, NULL);

			if (old_offset > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			old_offset = offset;
			UnloadBlob_LOADKEY_INFO(&offset, comm->buf, ((TCS_LOADKEY_INFO *)theData));
			break;
		case TCSD_PACKET_TYPE_UUID:
			if (old_offset + sizeof(TSS_UUID) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob_UUID(&offset, comm->buf, (TSS_UUID *) theData);
			break;
#endif
#ifdef TSS_BUILD_PCR_EVENTS
		case TCSD_PACKET_TYPE_PCR_EVENT:
		{
			TSS_RESULT result;

			(void)UnloadBlob_PCR_EVENT(&old_offset, comm->buf, NULL);

			if (old_offset > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			old_offset = offset;
			if ((result = UnloadBlob_PCR_EVENT(&offset, comm->buf,
							   ((TSS_PCR_EVENT *)theData))))
				return result;
			break;
		}
#endif
		case TCSD_PACKET_TYPE_SECRET:
			if (old_offset + sizeof(TPM_SECRET) > comm->hdr.packet_size)
				return TCSERR(TSS_E_INTERNAL_ERROR);

			UnloadBlob(&offset, sizeof(TCPA_SECRET), comm->buf,
					((TCPA_SECRET *) theData)->authdata);
			break;
		default:
			LogError("TCSD packet type unknown! (0x%x)", dataType & 0xff);
			return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	comm->hdr.parm_offset = offset;
	comm->hdr.parm_size -= (offset - old_offset);

	return TSS_SUCCESS;
}
Example #11
0
TSS_RESULT
ima_get_entries_by_pcr(FILE *handle, UINT32 pcr_index, UINT32 first,
			UINT32 *count, TSS_PCR_EVENT **events)
{
	int pcr_value;
	char page[IMA_READ_SIZE];
	int error_path = 1, ptr = 0;
	UINT32 copied_events = 0, i;
	struct event_wrapper *list, *cur;
	TSS_RESULT result = TCSERR(TSS_E_INTERNAL_ERROR);
	FILE *fp = (FILE *) handle;
	uint len;
	char name[EVLOG_FILENAME_MAXSIZE];

	if (!fp) {
		LogError("File handle is NULL!\n");
		return 1;
	}

	if (*count == 0)
		return TSS_SUCCESS;

	list = calloc(1, sizeof(struct event_wrapper));
	if (list == NULL) {
		LogError("malloc of %zd bytes failed.", sizeof(struct event_wrapper));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	cur = list;

	rewind(fp);

        while (fread(page, 24, 1, fp)) {
		/* copy the initial 4 bytes (PCR index) XXX endianess ignored */
		ptr = 0;
		memcpy(&pcr_value, &page[ptr], sizeof(int));
		cur->event.ulPcrIndex = pcr_value;
		ptr += sizeof(int);

		/* grab this entry */
		cur->event.ulPcrValueLength = 20;
		cur->event.rgbPcrValue = malloc(cur->event.ulPcrValueLength);
		if (cur->event.rgbPcrValue == NULL) {
			LogError("malloc of %d bytes failed.", 20);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto free_list;
		}

		/* copy the template SHA1 XXX endianess ignored */
		memcpy(cur->event.rgbPcrValue, &page[ptr],
		       cur->event.ulPcrValueLength);

/* Get the template name size, template name */
{
		char digest[20];

		if (fread(&len, 1, sizeof(len), fp) != (sizeof(len))) {
			LogError("Failed to read event log file");
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto free_list;
		}
		if (len > EVLOG_FILENAME_MAXSIZE) {
			LogError("Event log file name too big! Max size is %d", EVLOG_FILENAME_MAXSIZE);
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto free_list;
		}
		memset(name, 0, EVLOG_FILENAME_MAXSIZE);
		if (fread(name, 1, len, fp) != len) {
			LogError("Failed to read event log file");
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto free_list;
		}
		if (fread(digest, 1, sizeof digest, fp) != (sizeof(digest))) {
			LogError("Failed to read event log file");
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto free_list;
		}
}
		/* Get the template data namelen and data */
		if (fread(&cur->event.ulEventLength, 1, sizeof(int), fp) != sizeof(int)) {
			LogError("Failed to read event log file");
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto free_list;
		}
		cur->event.rgbEvent = malloc(cur->event.ulEventLength + 1);
		if (cur->event.rgbEvent == NULL) {
			free(cur->event.rgbPcrValue);
			LogError("malloc of %u bytes failed.",
				 cur->event.ulEventLength);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto free_list;
		}
		memset(cur->event.rgbEvent, 0, cur->event.ulEventLength);
		if (fread(cur->event.rgbEvent, 1, cur->event.ulEventLength, fp) != cur->event.ulEventLength) {
			free(cur->event.rgbPcrValue);
			LogError("Failed to read event log file");
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto free_list;
		}

		copied_events++;

		if (copied_events == *count)
			goto copy_events;

		cur->next = calloc(1, sizeof(struct event_wrapper));
		if (cur->next == NULL) {
			LogError("malloc of %zd bytes failed.",
				 sizeof(struct event_wrapper));
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto free_list;
		}
		cur = cur->next;
	}

copy_events:
	/* we've copied all the events we need to from this PCR, now
	 * copy them all into one contiguous memory block
	 */
	*events = calloc(copied_events, sizeof(TSS_PCR_EVENT));
	if (*events == NULL) {
		LogError("malloc of %zd bytes failed.", copied_events * sizeof(TSS_PCR_EVENT));
		result = TCSERR(TSS_E_OUTOFMEMORY);
		goto free_list;
	}

	cur = list;
	for (i = 0; i < copied_events; i++) {
		memcpy(&((*events)[i]), &(cur->event), sizeof(TSS_PCR_EVENT));
		cur = cur->next;
	}

	*count = copied_events;
	/* assume we're in an error path until we get here */
	error_path = 0;
	result = TSS_SUCCESS;

free_list:
	cur = list->next;
	while (cur != NULL) {
		if (error_path) {
			free(cur->event.rgbEvent);
			free(cur->event.rgbPcrValue);
		}
		free(list);
		list = cur;
		cur = list->next;
	}
	free(list);
	return result;
}
Example #12
0
TSS_RESULT
ima_get_entry(FILE *handle, UINT32 pcr_index, UINT32 *num, TSS_PCR_EVENT **ppEvent)
{
	int pcr_value, ptr = 0;
	uint len;
	char page[IMA_READ_SIZE];
	UINT32 seen_indices = 0;
	TSS_RESULT result = TCSERR(TSS_E_INTERNAL_ERROR);
	TSS_PCR_EVENT *event = NULL;
	FILE *fp = (FILE *) handle;
	char name[EVLOG_FILENAME_MAXSIZE];

	rewind(fp);
	while (fread(page, 24, 1, fp)) {
		/* copy the initial 4 bytes (PCR index) XXX endianess ignored */
		ptr = 0;
		memcpy(&pcr_value, &page[ptr], sizeof(int));

		if (pcr_index == (UINT32)pcr_value) {
			ptr += sizeof(int);
			/* This is the case where we're looking for a specific event number in a
			 * specific PCR index. When we've reached the correct event, malloc
			 * space for it, copy it in, then break out of the while loop */
			if (ppEvent && seen_indices == *num) {
				/* grab this entry */
				event = calloc(1, sizeof(TSS_PCR_EVENT));
				event->ulPcrIndex = pcr_value;
				event->rgbPcrValue = NULL;
				event->rgbEvent = NULL;
				event->ulPcrValueLength = 20;
				event->rgbPcrValue = malloc(event->ulPcrValueLength);
				if (event->rgbPcrValue == NULL) {
					LogError("malloc of %d bytes failed.", 20);
					free(event);
					result = TCSERR(TSS_E_OUTOFMEMORY);
					goto done;
				}

				/* copy the template SHA1 XXX endianess ignored */
				memcpy(event->rgbPcrValue, &page[ptr],
						event->ulPcrValueLength);

				/* Get the template name size, template name */
				{
					char digest[20];

					if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) {
						LogError("Failed to read event log file");
						result = TCSERR(TSS_E_INTERNAL_ERROR);
						goto done;
					}
					if (len > EVLOG_FILENAME_MAXSIZE) {
						LogError("Event log file name too big! Max size is %d", EVLOG_FILENAME_MAXSIZE);
						result = TCSERR(TSS_E_INTERNAL_ERROR);
						goto done;
					}
					memset(name, 0, EVLOG_FILENAME_MAXSIZE);
					if (fread(name, 1, len, fp) != len) {
						LogError("Failed to read event log file");
						result = TCSERR(TSS_E_INTERNAL_ERROR);
						goto done;
					}
					if (fread(digest, 1, sizeof(digest), fp) != sizeof(digest)) {
						LogError("Failed to read event log file");
						result = TCSERR(TSS_E_INTERNAL_ERROR);
						goto done;
					}
				}
				/* Get the template data namelen and data */
				if (fread(&event->ulEventLength, 1, sizeof(int), fp) != sizeof(int)) {
					LogError("Failed to read event log file");
					result = TCSERR(TSS_E_INTERNAL_ERROR);
					goto done;
				}
				event->rgbEvent = malloc(event->ulEventLength + 1);
				if (event->rgbEvent == NULL) {
					LogError("malloc of %u bytes failed.",
							event->ulEventLength);
					result = TCSERR(TSS_E_OUTOFMEMORY);
					goto done;
				}
				memset(event->rgbEvent, 0, event->ulEventLength + 1);
				if (fread(event->rgbEvent, 1, event->ulEventLength, fp) != event->ulEventLength ) {
					LogError("Failed to read event log file");
					result = TCSERR(TSS_E_INTERNAL_ERROR);
					goto done;
				}
				
				*ppEvent = event;
				result = TSS_SUCCESS;
				break;
			}
		}
		if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) {
			LogError("Failed to read event log file");
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		fseek(fp, len + 20, SEEK_CUR);
		if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) {
			LogError("Failed to read event log file");
			result = TCSERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		fseek(fp, len, SEEK_CUR);
		seen_indices++;
	}
done:
	if (result != TSS_SUCCESS) {
		if (event != NULL) {
			free(event->rgbPcrValue);
			free(event->rgbEvent);
		}
		free(event);
		event = NULL;
	}

	if (ppEvent == NULL)
		*num = seen_indices;

	return result;
}
Example #13
0
TSS_RESULT
tcs_common_Seal(UINT32 sealOrdinal,
		struct tcsd_thread_data *data)
{
	TSS_RESULT result;
	TCS_CONTEXT_HANDLE hContext;
	TCS_KEY_HANDLE keyHandle;
	TCPA_ENCAUTH KeyUsageAuth;
	UINT32 PCRInfoSize, inDataSize;
	BYTE *PCRInfo = NULL, *inData = NULL;
	TPM_AUTH emptyAuth, pubAuth, *pAuth;
	UINT32 outDataSize;
	BYTE *outData;

	int i = 0;

	memset(&emptyAuth, 0, sizeof(TPM_AUTH));
	memset(&pubAuth, 0, sizeof(TPM_AUTH));

	if (getData(TCSD_PACKET_TYPE_UINT32, i++, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, i++, &keyHandle, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_ENCAUTH, i++, &KeyUsageAuth, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, i++, &PCRInfoSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if (PCRInfoSize > 0) {
		PCRInfo = calloc(1, PCRInfoSize);
		if (PCRInfo == NULL) {
			LogError("malloc of %u bytes failed.", PCRInfoSize);
			return TCSERR(TSS_E_OUTOFMEMORY);
		}

		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, PCRInfo, PCRInfoSize, &data->comm)) {
			free(PCRInfo);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
	}

	if (getData(TCSD_PACKET_TYPE_UINT32, i++, &inDataSize, 0, &data->comm)) {
		free(PCRInfo);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (inDataSize > 0) {
		inData = calloc(1, inDataSize);
		if (inData == NULL) {
			LogError("malloc of %u bytes failed.", inDataSize);
			free(PCRInfo);
			return TCSERR(TSS_E_OUTOFMEMORY);
		}

		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, inData, inDataSize, &data->comm)) {
			free(inData);
			free(PCRInfo);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
	}

	result = getData(TCSD_PACKET_TYPE_AUTH, i++, &pubAuth, 0, &data->comm);
	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE)
		pAuth = NULL;
	else if (result) {
		free(inData);
		free(PCRInfo);
		return result;
	} else
		pAuth = &pubAuth;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_Seal_Internal(sealOrdinal, hContext, keyHandle, KeyUsageAuth, PCRInfoSize,
				    PCRInfo, inDataSize, inData, pAuth, &outDataSize, &outData);

	MUTEX_UNLOCK(tcsp_lock);
	free(inData);
	free(PCRInfo);

	if (result == TSS_SUCCESS) {
		initData(&data->comm, 3);
		if (pAuth != NULL) {
			if (setData(TCSD_PACKET_TYPE_AUTH, 0, pAuth, 0, &data->comm)) {
				free(outData);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}

		if (setData(TCSD_PACKET_TYPE_UINT32, 1, &outDataSize, 0, &data->comm)) {
			free(outData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, 2, outData, outDataSize, &data->comm)) {
			free(outData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		free(outData);
	} else
		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #14
0
TSS_RESULT
tcs_wrap_GetCapability(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TCPA_CAPABILITY_AREA capArea;
	UINT32 subCapSize;
	BYTE *subCap;
	UINT32 respSize;
	BYTE *resp;
	TSS_RESULT result;

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ldd context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if (subCapSize == 0)
		subCap = NULL;
	else {
		subCap = calloc(1, subCapSize);
		if (subCap == NULL) {
			LogError("malloc of %u bytes failed.", subCapSize);
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &data->comm)) {
			free(subCap);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
	}

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_GetCapability_Internal(hContext, capArea, subCapSize, subCap, &respSize,
					     &resp);

	MUTEX_UNLOCK(tcsp_lock);
	free(subCap);

	if (result == TSS_SUCCESS) {
		initData(&data->comm, 2);
		if (setData(TCSD_PACKET_TYPE_UINT32, 0, &respSize, 0, &data->comm)) {
			free(resp);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, 1, resp, respSize, &data->comm)) {
			free(resp);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		free(resp);
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;
	return TSS_SUCCESS;
}
Example #15
0
TSS_RESULT
tcs_wrap_Delegate_Manage(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TPM_FAMILY_ID familyId;
	TPM_FAMILY_OPERATION opFlag;
	UINT32 opDataSize;
	BYTE *opData;
	TPM_AUTH ownerAuth, nullAuth, *pAuth;
	UINT32 retDataSize;
	BYTE *retData;
	TSS_RESULT result;
	int i;

	memset(&ownerAuth, 0, sizeof(TPM_AUTH));
	memset(&nullAuth, 0, sizeof(TPM_AUTH));

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &familyId, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &opFlag, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if (getData(TCSD_PACKET_TYPE_UINT32, 3, &opDataSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	opData = malloc(opDataSize);
	if (opData == NULL) {
		LogError("malloc of %u bytes failed.", opDataSize);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 4, opData, opDataSize, &data->comm)) {
		free(opData);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (getData(TCSD_PACKET_TYPE_AUTH, 5, &ownerAuth, 0, &data->comm)) {
		free(opData);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (memcmp(&nullAuth, &ownerAuth, sizeof(TPM_AUTH)))
		pAuth = &ownerAuth;
	else
		pAuth = NULL;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_Delegate_Manage_Internal(hContext, familyId, opFlag,
			opDataSize, opData, pAuth, &retDataSize, &retData);

	MUTEX_UNLOCK(tcsp_lock);
	free(opData);

	if (result == TSS_SUCCESS) {
		i = 0;
		initData(&data->comm, 3);
		if (pAuth) {
			if (setData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &data->comm)) {
				free(retData);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}

		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &retDataSize, 0, &data->comm)) {
			free(retData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, i++, retData, retDataSize, &data->comm)) {
			free(retData);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		free(retData);
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #16
0
TSS_RESULT
tcsd_thread_create(int socket, char *hostname)
{
	UINT32 thread_num = -1;
	int rc = TCS_SUCCESS;
#ifndef TCSD_SINGLE_THREAD_DEBUG
	THREAD_ATTR_DECLARE(tcsd_thread_attr);

	/* init the thread attribute */
	if ((rc = THREAD_ATTR_INIT(tcsd_thread_attr))) {
		LogError("Initializing thread attribute failed: error=%d: %s", rc, strerror(rc));
		rc = TCSERR(TSS_E_INTERNAL_ERROR);
		goto out;
	}
	/* make all threads joinable */
	if ((rc = THREAD_ATTR_SETJOINABLE(tcsd_thread_attr))) {
		LogError("Making thread attribute joinable failed: error=%d: %s", rc, strerror(rc));
		rc = TCSERR(TSS_E_INTERNAL_ERROR);
		goto out;
	}

	MUTEX_LOCK(tm->lock);
#endif
	if (tm->num_active_threads == tm->max_threads) {
		if (hostname != NULL) {
			LogError("max number of connections reached (%d), new connection"
				 " from %s refused.", tm->max_threads, hostname);
		} else {
			LogError("max number of connections reached (%d), new connection"
				 " refused.", tm->max_threads);
		}
		rc = TCSERR(TSS_E_CONNECTION_FAILED);
#ifndef TCSD_SINGLE_THREAD_DEBUG
		goto out_unlock;
#else
		goto out;
#endif
	}

	/* search for an open slot to store the thread data in */
	for (thread_num = 0; thread_num < tm->max_threads; thread_num++) {
		if (tm->thread_data[thread_num].thread_id == THREAD_NULL)
			break;
	}

	DBG_ASSERT(thread_num != tm->max_threads);

	tm->thread_data[thread_num].sock = socket;
	tm->thread_data[thread_num].context = NULL_TCS_HANDLE;
	if (hostname != NULL)
		tm->thread_data[thread_num].hostname = hostname;

#ifdef TCSD_SINGLE_THREAD_DEBUG
	(void)tcsd_thread_run((void *)(&(tm->thread_data[thread_num])));
#else
	tm->thread_data[thread_num].thread_id = calloc(1, sizeof(THREAD_TYPE));
	if (tm->thread_data[thread_num].thread_id == NULL) {
		rc = TCSERR(TSS_E_OUTOFMEMORY);
		LogError("malloc of %zd bytes failed.", sizeof(THREAD_TYPE));
		goto out_unlock;
	}

	if ((rc = THREAD_CREATE(tm->thread_data[thread_num].thread_id,
				 &tcsd_thread_attr,
				 tcsd_thread_run,
				 (void *)(&(tm->thread_data[thread_num]))))) {
		LogError("Thread create failed: %d", rc);
		rc = TCSERR(TSS_E_INTERNAL_ERROR);
		goto out_unlock;
	}

	tm->num_active_threads++;

out_unlock:
	MUTEX_UNLOCK(tm->lock);
#endif
out:
	/* cleanup in case of error */
	if (rc != TCS_SUCCESS) {
		if (hostname != NULL) {
			tm->thread_data[thread_num].hostname = NULL;
			free(hostname);
		}
		close(socket);
	}
	return rc;
}
Example #17
0
TSS_RESULT
tcs_wrap_Delegate_LoadOwnerDelegation(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TPM_DELEGATE_INDEX index;
	UINT32 blobSize;
	BYTE *blob;
	TPM_AUTH ownerAuth, nullAuth, *pAuth;
	TSS_RESULT result;

	memset(&ownerAuth, 0, sizeof(TPM_AUTH));
	memset(&nullAuth, 0, sizeof(TPM_AUTH));

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &index, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &blobSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	blob = malloc(blobSize);
	if (blob == NULL) {
		LogError("malloc of %u bytes failed.", blobSize);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 3, blob, blobSize, &data->comm)) {
		free(blob);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (getData(TCSD_PACKET_TYPE_AUTH, 4, &ownerAuth, 0, &data->comm)) {
		free(blob);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (memcmp(&nullAuth, &ownerAuth, sizeof(TPM_AUTH)))
		pAuth = &ownerAuth;
	else
		pAuth = NULL;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_Delegate_LoadOwnerDelegation_Internal(hContext, index, blobSize, blob,
			pAuth);

	MUTEX_UNLOCK(tcsp_lock);
	free(blob);

	if (result == TSS_SUCCESS) {
		initData(&data->comm, 1);
		if (pAuth) {
			if (setData(TCSD_PACKET_TYPE_AUTH, 0, pAuth, 0, &data->comm)) {
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #18
0
TSS_RESULT
tcs_wrap_LoadKey2ByBlob(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TCS_KEY_HANDLE hUnwrappingKey;
	UINT32 cWrappedKeyBlob;
	BYTE *rgbWrappedKeyBlob;
	TPM_AUTH auth;
	TCS_KEY_HANDLE phKeyTCSI;
	TPM_AUTH *pAuth;
	TSS_RESULT result;
	int i;

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &hUnwrappingKey, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &cWrappedKeyBlob, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	rgbWrappedKeyBlob = calloc(1, cWrappedKeyBlob);
	if (rgbWrappedKeyBlob == NULL) {
		LogError("malloc of %d bytes failed.", cWrappedKeyBlob);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 3, rgbWrappedKeyBlob, cWrappedKeyBlob, &data->comm)) {
		free(rgbWrappedKeyBlob);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	result = getData(TCSD_PACKET_TYPE_AUTH, 4, &auth, 0, &data->comm);
	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE)
		pAuth = NULL;
	else if (result) {
		free(rgbWrappedKeyBlob);
		return result;
	} else
		pAuth = &auth;

	MUTEX_LOCK(tcsp_lock);

	result = key_mgr_load_by_blob(hContext, hUnwrappingKey, cWrappedKeyBlob, rgbWrappedKeyBlob,
				      pAuth, &phKeyTCSI, NULL);

	if (!result)
		result = ctx_mark_key_loaded(hContext, phKeyTCSI);

	MUTEX_UNLOCK(tcsp_lock);

	free(rgbWrappedKeyBlob);

	if (result == TSS_SUCCESS) {
		i = 0;
		initData(&data->comm, 2);
		if (pAuth != NULL) {
			if (setData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &data->comm)) {
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}
		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &phKeyTCSI, 0, &data->comm)) {
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
	} else
		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #19
0
TSS_RESULT
tcs_wrap_Delegate_UpdateVerificationCount(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	UINT32 inputSize;
	BYTE *input;
	TPM_AUTH ownerAuth, nullAuth, *pAuth;
	UINT32 outputSize;
	BYTE *output;
	TSS_RESULT result;
	int i;

	memset(&ownerAuth, 0, sizeof(TPM_AUTH));
	memset(&nullAuth, 0, sizeof(TPM_AUTH));

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &inputSize, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	input = malloc(inputSize);
	if (input == NULL) {
		LogError("malloc of %u bytes failed.", inputSize);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 2, input, inputSize, &data->comm)) {
		free(input);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (getData(TCSD_PACKET_TYPE_AUTH, 3, &ownerAuth, 0, &data->comm)) {
		free(input);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	if (memcmp(&nullAuth, &ownerAuth, sizeof(TPM_AUTH)))
		pAuth = &ownerAuth;
	else
		pAuth = NULL;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_Delegate_UpdateVerificationCount_Internal(hContext, inputSize, input,
			pAuth, &outputSize, &output);

	MUTEX_UNLOCK(tcsp_lock);
	free(input);

	if (result == TSS_SUCCESS) {
		i = 0;
		initData(&data->comm, 3);
		if (pAuth) {
			if (setData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &data->comm)) {
				free(output);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}

		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &outputSize, 0, &data->comm)) {
			free(output);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, i++, output, outputSize, &data->comm)) {
			free(output);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		free(output);
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;

	return TSS_SUCCESS;
}
Example #20
0
TSS_RESULT
tcs_wrap_KeyControlOwner(struct tcsd_thread_data *data)
{
	TCS_CONTEXT_HANDLE hContext;
	TCS_KEY_HANDLE hKey;
	UINT32 ulPublicKeyLength;
	BYTE* rgbPublicKey;
	UINT32 attribName;
	TSS_BOOL attribValue;
	TPM_AUTH ownerAuth;
	TSS_UUID uuidData;
	TSS_RESULT result;

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &ulPublicKeyLength, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	rgbPublicKey = (BYTE *) malloc(ulPublicKeyLength);
	if (rgbPublicKey == NULL) {
		LogError("malloc of %u bytes failed.", ulPublicKeyLength);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 3, rgbPublicKey, ulPublicKeyLength, &data->comm)) {
		free(rgbPublicKey);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	if (getData(TCSD_PACKET_TYPE_UINT32, 4, &attribName, 0, &data->comm)) {
		free(rgbPublicKey);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	if (getData(TCSD_PACKET_TYPE_BOOL, 5, &attribValue, 0, &data->comm)) {
		free(rgbPublicKey);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	if (getData(TCSD_PACKET_TYPE_AUTH, 6, &ownerAuth, 0, &data->comm)) {
		free(rgbPublicKey);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_KeyControlOwner_Internal(hContext, hKey, ulPublicKeyLength, rgbPublicKey,
					       attribName, attribValue, &ownerAuth, &uuidData);

	MUTEX_UNLOCK(tcsp_lock);

	if (result == TSS_SUCCESS) {
		initData(&data->comm, 2);
		if (setData(TCSD_PACKET_TYPE_AUTH, 0, &ownerAuth, 0, &data->comm))
			return TCSERR(TSS_E_INTERNAL_ERROR);
		if (setData(TCSD_PACKET_TYPE_UUID, 1, &uuidData, 0, &data->comm))
			return TCSERR(TSS_E_INTERNAL_ERROR);
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;
	return TSS_SUCCESS;

}
Example #21
0
TSS_RESULT
tcs_wrap_Quote2(struct tcsd_thread_data *data)
{
	/* Data to be forwarded to the next level */
	TCS_CONTEXT_HANDLE hContext;
	TCS_KEY_HANDLE hKey;
	TCPA_NONCE antiReplay;
	UINT32 pcrDataSizeIn;
	BYTE *pcrDataIn;
	TSS_BOOL addVersion;
	TPM_AUTH privAuth;  /* in/out */ 
	TPM_AUTH *pPrivAuth;

	UINT32 pcrDataSizeOut;
	BYTE *pcrDataOut;
	
	UINT32 versionInfoSize;
	BYTE * versionInfo;
	
	UINT32 sigSize;
	BYTE *sig;
	TSS_RESULT result;

	int i;

	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);

	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_NONCE, 2, &antiReplay, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	if (getData(TCSD_PACKET_TYPE_UINT32, 3, &pcrDataSizeIn, 0, &data->comm))
		return TCSERR(TSS_E_INTERNAL_ERROR);
	pcrDataIn = (BYTE *)calloc(1, pcrDataSizeIn);
	if (pcrDataIn == NULL) {
		LogError("malloc of %u bytes failed.", pcrDataSizeIn);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	if (getData(TCSD_PACKET_TYPE_PBYTE, 4, pcrDataIn, pcrDataSizeIn, &data->comm)) {
		free(pcrDataIn);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	if (getData(TCSD_PACKET_TYPE_BOOL,5,&addVersion, 0, &data->comm)) {
		free(pcrDataIn);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}
	result = getData(TCSD_PACKET_TYPE_AUTH, 6, &privAuth, 0, &data->comm);
	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE)
		pPrivAuth = NULL;
	else if (result) {
		free(pcrDataIn);
		return result;
	} else
		pPrivAuth = &privAuth;

	MUTEX_LOCK(tcsp_lock);

	result = TCSP_Quote2_Internal(hContext, hKey, antiReplay, pcrDataSizeIn, pcrDataIn,
				     addVersion,pPrivAuth, &pcrDataSizeOut, &pcrDataOut, &versionInfoSize, 
				     &versionInfo,&sigSize, &sig);

	MUTEX_UNLOCK(tcsp_lock);
	free(pcrDataIn);

	if (result == TSS_SUCCESS) {
		i = 0;

		initData(&data->comm,7); /* Add versionInfoSize and versionInfo */
		if (pPrivAuth != NULL) {
			if (setData(TCSD_PACKET_TYPE_AUTH, i++, pPrivAuth, 0, &data->comm)) {
				free(pcrDataOut);
				/* It's a null pointer when addVersion == FALSE */
				if (addVersion)
					free(versionInfo);
				free(sig);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}
		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &pcrDataSizeOut, 0, &data->comm)) {
			free(pcrDataOut);
			if (addVersion)
				free(versionInfo);
			free(sig);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, i++, pcrDataOut, pcrDataSizeOut, &data->comm)) {
			free(pcrDataOut);
			if (addVersion)
				free(versionInfo);
			free(sig);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &versionInfoSize, 0, &data->comm)) {
			free(pcrDataOut);
			free(versionInfo);
			free(sig);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (versionInfoSize > 0){
			if (setData(TCSD_PACKET_TYPE_PBYTE, i++, versionInfo, versionInfoSize, &data->comm)) {
				free(pcrDataOut);
				free(versionInfo);
				free(sig);
				return TCSERR(TSS_E_INTERNAL_ERROR);
			}
		}
		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &sigSize, 0, &data->comm)) {
			free(pcrDataOut);
			if (addVersion)
				free(versionInfo);
			free(sig);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}
		if (setData(TCSD_PACKET_TYPE_PBYTE, i++, sig, sigSize, &data->comm)) {
			free(pcrDataOut);
			if (addVersion)
				free(versionInfo);
			free(sig);
			return TCSERR(TSS_E_INTERNAL_ERROR);
		}

		free(pcrDataOut);
		if (versionInfoSize >0)
			free(versionInfo);
		free(sig);
	} else
done:		initData(&data->comm, 0);

	data->comm.hdr.u.result = result;
	return TSS_SUCCESS;
}