selected_dh_group = pts->get_dh_group(pts);
if (!pts->create_dh(pts, selected_dh_group))
{
- return TNC_RESULT_FATAL;
+ goto err;
}
pts->get_my_pub_val(pts, &responder_pub_val);
if (!pts->calculate_secret(pts, initiator_nonce,
responder_non, selected_algorithm))
{
- return TNC_RESULT_FATAL;
+ goto err;
}
break;
{
DBG1(DBG_IMC, " hasher %N not available",
hash_algorithm_names, hash_alg);
- return TNC_RESULT_FATAL;
+ goto err;
}
if (!pts->hash_file(pts, hasher, "/etc/tnc_config", hash_output))
{
hasher->destroy(hasher);
- return TNC_RESULT_FATAL;
+ goto err;
}
measurement_time_t = time(NULL);
time_now->tm_sec) < 0)
{
DBG1(DBG_IMC, "Couldn not format local time to UTC");
- return TNC_RESULT_FATAL;
+ hasher->destroy(hasher);
+ goto err;
}
params.measurement_time = chunk_create(utc_time, 20);
+ params.measurement_time = chunk_clone(params.measurement_time);
+ free(utc_time);
+
}
params.measurement = chunk_create(hash_output, hasher->get_hash_size(hasher));
if (!pts->read_pcr(pts, EXTEND_PCR, ¶ms.pcr_before))
{
DBG1(DBG_IMC, "Error occured while reading PCR: %d", EXTEND_PCR);
- return TNC_RESULT_FATAL;
+ goto err;
}
+
if (!pts->extend_pcr(pts, EXTEND_PCR,
params.measurement, ¶ms.pcr_after))
{
DBG1(DBG_IMC, "Error occured while extending PCR: %d", EXTEND_PCR);
- return TNC_RESULT_FATAL;
+ goto err;
}
/* Buffer Simple Component Evidence attribute */
{
enumerator_t *e;
pts_simple_evid_final_flag_t flags;
-
+ chunk_t pcr_composite, quote_signature;
+ linked_list_t *pcrs;
+
/* Send buffered Simple Component Evidences */
+ pcrs = linked_list_create();
+
e = evidences->create_enumerator(evidences);
while (e->enumerate(e, &attr))
{
+ tcg_pts_attr_simple_comp_evid_t *attr_cast;
+ u_int32_t extended_pcr;
+
+ attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
+ extended_pcr = attr_cast->get_extended_pcr(attr_cast);
+
+ /* Add extended PCR number to PCR list to quote */
+ /* Duplicated PCR numbers have no influence */
+ pcrs->insert_last(pcrs, &extended_pcr);
+ /* Send Simple Compoenent Evidence */
attr_list->insert_last(attr_list, attr);
}
- /* TODO: TPM quote operation over included PCR's */
+ /* Quote */
+ if (!pts->quote_tpm(pts, pcrs, &pcr_composite, "e_signature))
+ {
+ DBG1(DBG_IMC, "Error occured while TPM quote operation");
+ DESTROY_IF(e);
+ DESTROY_IF(pcrs);
+ DESTROY_IF(evidences);
+ goto err;
+ }
+
/* Send Simple Evidence Final attribute */
- flags = PTS_SIMPLE_EVID_FINAL_FLAG_NO;
+ flags = PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
+
attr = tcg_pts_attr_simple_evid_final_create(flags, 0,
- chunk_empty, chunk_empty, chunk_empty);
+ pcr_composite, quote_signature, chunk_empty);
attr_list->insert_last(attr_list, attr);
- e->destroy(e);
+ DESTROY_IF(e);
+ DESTROY_IF(pcrs);
DESTROY_IF(evidences);
break;
if (!metadata)
{
/* TODO handle error codes from measurements */
- return TNC_RESULT_FATAL;
+ goto err;
}
attr = tcg_pts_attr_unix_file_meta_create(metadata);
attr->set_noskip_flag(attr, TRUE);
if (!measurements)
{
/* TODO handle error codes from measurements */
- return TNC_RESULT_FATAL;
+ goto err;
}
attr = tcg_pts_attr_file_meas_create(measurements);
attr->set_noskip_flag(attr, TRUE);
pa_tnc_msg->get_encoding(pa_tnc_msg));
pa_tnc_msg->destroy(pa_tnc_msg);
}
- attr_list->destroy(attr_list);
+ DESTROY_IF(attr_list);
return result;
+
+ err:
+ DESTROY_IF(attr_list);
+ return TNC_RESULT_FATAL;
}
/**
case TCG_PTS_SIMPLE_EVID_FINAL:
{
- /** TODO: Implement construct Quote structure over saved values from
- * TCG_PTS_SIMPLE_COMP_EVID and compare with received one
+ tcg_pts_attr_simple_evid_final_t *attr_cast;
+ pts_simple_evid_final_flag_t flags;
+ chunk_t pcr_comp = chunk_empty;
+ chunk_t tpm_quote_sign = chunk_empty;
+ chunk_t evid_sign = chunk_empty;
+
+ /** TODO: Ignoring Composite Hash Algorithm field
+ * No flag defined which indicates the precense of it
*/
+ attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr;
+ flags = attr_cast->get_flags(attr_cast);
+
+ if ((flags >> 6) & PTS_SIMPLE_EVID_FINAL_FLAG_NO)
+ {
+ pcr_comp = attr_cast->get_pcr_comp(attr_cast);
+ tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast);
+
+ /** TODO: Construct PCR Composite */
+ }
+ if (flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID)
+ {
+ /** TODO: What to do with Evidence Signature */
+ evid_sign = attr_cast->get_evid_sign(attr_cast);
+ }
+
break;
}
{
goto err;
}
+ pcr_value = chunk_alloc(PCR_LEN);
result = Tspi_TPM_PcrRead(hTPM, pcr_num, &pcr_length, &pcr_value.ptr);
if (result != TSS_SUCCESS)
{
*output = pcr_value;
*output = chunk_clone(*output);
+ chunk_clear(&pcr_value);
Tspi_Context_Close(hContext);
DBG3(DBG_PTS, "PCR %d value:%B", pcr_num, output);
return TRUE;
err:
+ chunk_clear(&pcr_value);
DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
Tspi_Context_Close(hContext);
return FALSE;
{
goto err;
}
- result = Tspi_TPM_PcrExtend(hTPM, pcr_num, 20, input.ptr, NULL, &pcr_length, &pcr_value.ptr);
+
+ pcr_value = chunk_alloc(PCR_LEN);
+ result = Tspi_TPM_PcrExtend(hTPM, pcr_num, PCR_LEN, input.ptr,
+ NULL, &pcr_length, &pcr_value.ptr);
if (result != TSS_SUCCESS)
{
goto err;
*output = pcr_value;
*output = chunk_clone(*output);
+ chunk_clear(&pcr_value);
Tspi_Context_Close(hContext);
DBG3(DBG_PTS, "PCR %d extended with: %B", pcr_num, &input);
DBG3(DBG_PTS, "PCR %d value after extend: %B", pcr_num, output);
-
return TRUE;
err:
+ chunk_clear(&pcr_value);
DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
Tspi_Context_Close(hContext);
return FALSE;
}
METHOD(pts_t, quote_tpm, bool,
- private_pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs,
+ private_pts_t *this, linked_list_t *pcrs,
chunk_t *pcr_composite, chunk_t *quote_signature)
{
TSS_HCONTEXT hContext;
TSS_HPCRS hPcrComposite;
TSS_VALIDATION valData;
TPM_QUOTE_INFO *quoteInfo;
- u_int32_t i;
+ u_int32_t i, pcr;
TSS_RESULT result;
chunk_t aik_key_encoding;
chunk_t pcr_composite_without_nonce;
+ enumerator_t *enumerator;
result = Tspi_Context_Create(&hContext);
if (result != TSS_SUCCESS)
/* Create from AIK public key a HKEY object to sign Quote operation output*/
if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY)
{
- if (!this->aik->get_encoding(this->aik, CERT_ASN1_DER, &aik_key_encoding))
+ if (!this->aik->get_encoding(this->aik, CERT_PEM, &aik_key_encoding))
{
DBG1(DBG_PTS, "encoding AIK certificate for quote operation failed");
goto err1;
DBG1(DBG_PTS, "unable to retrieve public key from AIK certificate");
goto err1;
}
- if (!key->get_encoding(key, PUBKEY_ASN1_DER, &aik_key_encoding))
+ if (!key->get_encoding(key, PUBKEY_PEM, &aik_key_encoding))
{
DBG1(DBG_PTS, "encoding AIK Public Key for quote operation failed");
goto err1;
}
/* Select PCR's */
- for (i = 0; i < num_of_pcrs; i++)
+ enumerator = pcrs->create_enumerator(pcrs);
+ while (enumerator->enumerate(enumerator, &pcr))
{
- u_int32_t pcr = pcrs[i];
if (pcr < 0 || pcr >= MAX_NUM_PCR )
{
DBG1(DBG_PTS, "Invalid PCR number: %d", pcr);
goto err3;
}
}
+ enumerator->destroy(enumerator);
/* Set the Validation Data */
valData.ulExternalDataLength = this->secret.len;
memcpy(pcr_composite_without_nonce.ptr, valData.rgbData,
valData.ulDataLength - ASSESSMENT_SECRET_LEN);
*pcr_composite = pcr_composite_without_nonce;
+ *pcr_composite = chunk_clone(*pcr_composite);
+ free(pcr_composite_without_nonce.ptr);
+
*quote_signature = chunk_from_thing(valData.rgbValidationData);
*quote_signature = chunk_clone(*quote_signature);
#include "pts_dh_group.h"
#include <library.h>
+#include <utils/linked_list.h>
/**
* UTF-8 encoding of the character used to delimiter the filename
#define MAX_NUM_PCR 24
/**
+ * Number of bytes can be savedin a PCR of TPM, TPM Spec 1.2
+ */
+#define PCR_LEN 20
+
+/**
* Class implementing the TCG Platform Trust System (PTS)
*
*/
* Quote over PCR's
* Expects owner and SRK secret to be WELL_KNOWN_SECRET and no password set for AIK
*
- * @param pcrs Set of PCR's to make quotation over
- * @param num_of_pcr Number of PCR's
+ * @param pcrs List of PCR's to make quotation over
* @param pcr_composite Chunk to save pcr composite structure
* @param quote_signature Chunk to save quote operation output
* without external data (anti-replay protection)
* @return FALSE in case of TSS error, TRUE otherwise
*/
- bool (*quote_tpm)(pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs,
+ bool (*quote_tpm)(pts_t *this, linked_list_t *pcrs,
chunk_t *pcr_composite, chunk_t *quote_signature);
/**