Loading AIK Blob from file configured
Finalized implementation of quote_tpm function
This commit is contained in:
committed by
Andreas Steffen
parent
fe247ba2a6
commit
d25b7b3d9a
@@ -432,11 +432,13 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
|||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
pts_simple_evid_final_flag_t flags;
|
pts_simple_evid_final_flag_t flags;
|
||||||
chunk_t pcr_composite, quote_signature;
|
chunk_t pcr_composite, quote_signature;
|
||||||
linked_list_t *pcrs;
|
u_int32_t num_of_evidences, i = 0;
|
||||||
|
u_int32_t *pcrs;
|
||||||
|
|
||||||
/* Send buffered Simple Component Evidences */
|
/* Send buffered Simple Component Evidences */
|
||||||
pcrs = linked_list_create();
|
num_of_evidences = evidences->get_count(evidences);
|
||||||
|
pcrs = (u_int32_t*)malloc(sizeof(u_int32_t)*num_of_evidences);
|
||||||
|
|
||||||
e = evidences->create_enumerator(evidences);
|
e = evidences->create_enumerator(evidences);
|
||||||
while (e->enumerate(e, &attr))
|
while (e->enumerate(e, &attr))
|
||||||
{
|
{
|
||||||
@@ -445,20 +447,20 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
|||||||
|
|
||||||
attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
|
attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
|
||||||
extended_pcr = attr_cast->get_extended_pcr(attr_cast);
|
extended_pcr = attr_cast->get_extended_pcr(attr_cast);
|
||||||
|
|
||||||
/* Add extended PCR number to PCR list to quote */
|
/* Add extended PCR number to PCR list to quote */
|
||||||
/* Duplicated PCR numbers have no influence */
|
/* Duplicated PCR numbers have no influence */
|
||||||
pcrs->insert_last(pcrs, &extended_pcr);
|
pcrs[i] = extended_pcr;
|
||||||
|
i++;
|
||||||
/* Send Simple Compoenent Evidence */
|
/* Send Simple Compoenent Evidence */
|
||||||
attr_list->insert_last(attr_list, attr);
|
attr_list->insert_last(attr_list, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Quote */
|
/* Quote */
|
||||||
if (!pts->quote_tpm(pts, pcrs, &pcr_composite, "e_signature))
|
if (!pts->quote_tpm(pts, pcrs, num_of_evidences, &pcr_composite, "e_signature))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMC, "error occured while TPM quote operation");
|
DBG1(DBG_IMC, "error occured during TPM quote operation");
|
||||||
DESTROY_IF(e);
|
DESTROY_IF(e);
|
||||||
DESTROY_IF(pcrs);
|
|
||||||
DESTROY_IF(evidences);
|
DESTROY_IF(evidences);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -471,7 +473,6 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
|||||||
attr_list->insert_last(attr_list, attr);
|
attr_list->insert_last(attr_list, attr);
|
||||||
|
|
||||||
DESTROY_IF(e);
|
DESTROY_IF(e);
|
||||||
DESTROY_IF(pcrs);
|
|
||||||
DESTROY_IF(evidences);
|
DESTROY_IF(evidences);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
+65
-46
@@ -99,6 +99,11 @@ struct private_pts_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t tpm_version_info;
|
chunk_t tpm_version_info;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains TSS Blob structure for AIK
|
||||||
|
*/
|
||||||
|
chunk_t aik_blob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains a Attestation Identity Key or Certificate
|
* Contains a Attestation Identity Key or Certificate
|
||||||
*/
|
*/
|
||||||
@@ -322,7 +327,49 @@ METHOD(pts_t, set_tpm_version_info, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load an AIK certificate or public key,
|
* Load an AIK Blob (TSS_TSPATTRIB_KEYBLOB_BLOB attribute)
|
||||||
|
*/
|
||||||
|
static void load_aik_blob(private_pts_t *this)
|
||||||
|
{
|
||||||
|
char *blob_path;
|
||||||
|
FILE *fp;
|
||||||
|
u_int32_t aikBlobLen;
|
||||||
|
|
||||||
|
blob_path = lib->settings->get_str(lib->settings,
|
||||||
|
"libimcv.plugins.imc-attestation.aik_blob", NULL);
|
||||||
|
|
||||||
|
if (blob_path)
|
||||||
|
{
|
||||||
|
/* Read aik key blob from a file */
|
||||||
|
if ((fp = fopen(blob_path, "r")) == NULL)
|
||||||
|
{
|
||||||
|
DBG1(DBG_PTS, "unable to open AIK Blob file: %s", blob_path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
aikBlobLen = ftell(fp);
|
||||||
|
fseek(fp, 0L, SEEK_SET);
|
||||||
|
|
||||||
|
this->aik_blob = chunk_alloc(aikBlobLen);
|
||||||
|
if (fread(this->aik_blob.ptr, 1, aikBlobLen, fp))
|
||||||
|
{
|
||||||
|
DBG2(DBG_PTS, "loaded AIK Blob from '%s'", blob_path);
|
||||||
|
DBG3(DBG_PTS, "AIK Blob: %B", &this->aik_blob);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_PTS, "unable to read AIK Blob file '%s'", blob_path);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG1(DBG_PTS, "AIK Blob is not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load an AIK certificate or public key
|
||||||
* the certificate having precedence over the public key if both are present
|
* the certificate having precedence over the public key if both are present
|
||||||
*/
|
*/
|
||||||
static void load_aik(private_pts_t *this)
|
static void load_aik(private_pts_t *this)
|
||||||
@@ -356,6 +403,7 @@ static void load_aik(private_pts_t *this)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG1(DBG_PTS, "neither AIK certificate nor public key is available");
|
DBG1(DBG_PTS, "neither AIK certificate nor public key is available");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,8 +810,8 @@ METHOD(pts_t, extend_pcr, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_t, quote_tpm, bool,
|
METHOD(pts_t, quote_tpm, bool,
|
||||||
private_pts_t *this, linked_list_t *pcrs, chunk_t *pcr_composite,
|
private_pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs,
|
||||||
chunk_t *quote_signature)
|
chunk_t *pcr_composite, chunk_t *quote_signature)
|
||||||
{
|
{
|
||||||
TSS_HCONTEXT hContext;
|
TSS_HCONTEXT hContext;
|
||||||
TSS_HTPM hTPM;
|
TSS_HTPM hTPM;
|
||||||
@@ -775,11 +823,9 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
TSS_HPCRS hPcrComposite;
|
TSS_HPCRS hPcrComposite;
|
||||||
TSS_VALIDATION valData;
|
TSS_VALIDATION valData;
|
||||||
TPM_QUOTE_INFO *quoteInfo;
|
TPM_QUOTE_INFO *quoteInfo;
|
||||||
u_int32_t i, pcr;
|
u_int32_t i;
|
||||||
TSS_RESULT result;
|
TSS_RESULT result;
|
||||||
chunk_t aik_key_encoding;
|
|
||||||
chunk_t pcr_composite_without_nonce;
|
chunk_t pcr_composite_without_nonce;
|
||||||
enumerator_t *enumerator;
|
|
||||||
|
|
||||||
result = Tspi_Context_Create(&hContext);
|
result = Tspi_Context_Create(&hContext);
|
||||||
if (result != TSS_SUCCESS)
|
if (result != TSS_SUCCESS)
|
||||||
@@ -817,38 +863,9 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
{
|
{
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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, PUBKEY_ASN1_DER, &aik_key_encoding))
|
|
||||||
{
|
|
||||||
DBG1(DBG_PTS, "encoding AIK certificate for quote operation failed");
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (this->aik->get_type(this->aik) == CERT_X509)
|
|
||||||
{
|
|
||||||
public_key_t *key = this->aik->get_public_key(this->aik);
|
|
||||||
if (key == NULL)
|
|
||||||
{
|
|
||||||
DBG1(DBG_PTS, "unable to retrieve public key from AIK certificate");
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
if (!key->get_encoding(key, PUBKEY_ASN1_DER, &aik_key_encoding))
|
|
||||||
{
|
|
||||||
DBG1(DBG_PTS, "encoding AIK Public Key for quote operation failed");
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_PTS, "AIK is neither X509 certificate nor Public Key");
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = Tspi_Context_LoadKeyByBlob (hContext, hSRK, aik_key_encoding.len,
|
result = Tspi_Context_LoadKeyByBlob (hContext, hSRK, this->aik_blob.len,
|
||||||
aik_key_encoding.ptr, &hAIK);
|
this->aik_blob.ptr, &hAIK);
|
||||||
if (result != TSS_SUCCESS)
|
if (result != TSS_SUCCESS)
|
||||||
{
|
{
|
||||||
goto err1;
|
goto err1;
|
||||||
@@ -862,21 +879,19 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Select PCR's */
|
/* Select PCR's */
|
||||||
enumerator = pcrs->create_enumerator(pcrs);
|
for (i = 0; i < num_of_pcrs ; i++)
|
||||||
while (enumerator->enumerate(enumerator, &pcr))
|
|
||||||
{
|
{
|
||||||
if (pcr < 0 || pcr >= MAX_NUM_PCR )
|
if (pcrs[i] < 0 || pcrs[i] >= MAX_NUM_PCR )
|
||||||
{
|
{
|
||||||
DBG1(DBG_PTS, "Invalid PCR number: %d", pcr);
|
DBG1(DBG_PTS, "Invalid PCR number: %d", pcrs[i]);
|
||||||
goto err3;
|
goto err3;
|
||||||
}
|
}
|
||||||
result = Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcr);
|
result = Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcrs[i]);
|
||||||
if (result != TSS_SUCCESS)
|
if (result != TSS_SUCCESS)
|
||||||
{
|
{
|
||||||
goto err3;
|
goto err3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
|
|
||||||
/* Set the Validation Data */
|
/* Set the Validation Data */
|
||||||
valData.ulExternalDataLength = this->secret.len;
|
valData.ulExternalDataLength = this->secret.len;
|
||||||
@@ -895,7 +910,7 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
DBG3(DBG_PTS, "version:");
|
DBG3(DBG_PTS, "version:");
|
||||||
for(i = 0 ; i < 4 ; i++)
|
for(i = 0 ; i < 4 ; i++)
|
||||||
{
|
{
|
||||||
DBG3(DBG_PTS, "%02x ",valData.rgbData[i]);
|
DBG3(DBG_PTS, "%02X ",valData.rgbData[i]);
|
||||||
}
|
}
|
||||||
DBG3(DBG_PTS, "fixed value:");
|
DBG3(DBG_PTS, "fixed value:");
|
||||||
for(i = 4 ; i < 8 ; i++)
|
for(i = 4 ; i < 8 ; i++)
|
||||||
@@ -905,12 +920,12 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
DBG3(DBG_PTS, "pcr digest:");
|
DBG3(DBG_PTS, "pcr digest:");
|
||||||
for(i = 8 ; i < 28 ; i++)
|
for(i = 8 ; i < 28 ; i++)
|
||||||
{
|
{
|
||||||
DBG3(DBG_PTS, "%02x ",valData.rgbData[i]);
|
DBG3(DBG_PTS, "%02X ",valData.rgbData[i]);
|
||||||
}
|
}
|
||||||
DBG3(DBG_PTS, "nonce:");
|
DBG3(DBG_PTS, "nonce:");
|
||||||
for(i = 28 ; i < valData.ulDataLength ; i++)
|
for(i = 28 ; i < valData.ulDataLength ; i++)
|
||||||
{
|
{
|
||||||
DBG3(DBG_PTS, "%c",valData.rgbData[i]);
|
DBG3(DBG_PTS, "%02X ",valData.rgbData[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set output chunks */
|
/* Set output chunks */
|
||||||
@@ -929,6 +944,7 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
Tspi_Context_CloseObject(hContext, hPcrComposite);
|
Tspi_Context_CloseObject(hContext, hPcrComposite);
|
||||||
Tspi_Context_CloseObject(hContext, hAIK);
|
Tspi_Context_CloseObject(hContext, hAIK);
|
||||||
Tspi_Context_Close(hContext);
|
Tspi_Context_Close(hContext);
|
||||||
|
free(pcrs);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
@@ -943,6 +959,7 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
|
|
||||||
err1:
|
err1:
|
||||||
Tspi_Context_Close(hContext);
|
Tspi_Context_Close(hContext);
|
||||||
|
free(pcrs);
|
||||||
DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
|
DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -955,6 +972,7 @@ METHOD(pts_t, destroy, void,
|
|||||||
free(this->initiator_nonce.ptr);
|
free(this->initiator_nonce.ptr);
|
||||||
free(this->responder_nonce.ptr);
|
free(this->responder_nonce.ptr);
|
||||||
free(this->platform_info);
|
free(this->platform_info);
|
||||||
|
free(this->aik_blob.ptr);
|
||||||
free(this->tpm_version_info.ptr);
|
free(this->tpm_version_info.ptr);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -1156,6 +1174,7 @@ pts_t *pts_create(bool is_imc)
|
|||||||
this->has_tpm = TRUE;
|
this->has_tpm = TRUE;
|
||||||
this->proto_caps |= PTS_PROTO_CAPS_T;
|
this->proto_caps |= PTS_PROTO_CAPS_T;
|
||||||
load_aik(this);
|
load_aik(this);
|
||||||
|
load_aik_blob(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -244,13 +244,14 @@ struct pts_t {
|
|||||||
* Quote over PCR's
|
* Quote over PCR's
|
||||||
* Expects owner and SRK secret to be WELL_KNOWN_SECRET and no password set for AIK
|
* Expects owner and SRK secret to be WELL_KNOWN_SECRET and no password set for AIK
|
||||||
*
|
*
|
||||||
* @param pcrs List of PCR's to make quotation over
|
* @param pcrs Array of PCR's to make quotation over
|
||||||
|
* @param num_of_pcrs Number of elements in pcrs array
|
||||||
* @param pcr_composite Chunk to save pcr composite structure
|
* @param pcr_composite Chunk to save pcr composite structure
|
||||||
* @param quote_signature Chunk to save quote operation output
|
* @param quote_signature Chunk to save quote operation output
|
||||||
* without external data (anti-replay protection)
|
* without external data (anti-replay protection)
|
||||||
* @return FALSE in case of TSS error, TRUE otherwise
|
* @return FALSE in case of TSS error, TRUE otherwise
|
||||||
*/
|
*/
|
||||||
bool (*quote_tpm)(pts_t *this, linked_list_t *pcrs,
|
bool (*quote_tpm)(pts_t *this, u_int32_t *pcrs, u_int32_t num_of_pcrs,
|
||||||
chunk_t *pcr_composite, chunk_t *quote_signature);
|
chunk_t *pcr_composite, chunk_t *quote_signature);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user