diff options
Diffstat (limited to 'src/libimcv')
-rw-r--r-- | src/libimcv/plugins/imc_attestation/imc_attestation.c | 24 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_attestation/imv_attestation.c | 21 | ||||
-rw-r--r-- | src/libimcv/tcg/pts/pts.c | 127 |
3 files changed, 105 insertions, 67 deletions
diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation.c b/src/libimcv/plugins/imc_attestation/imc_attestation.c index 9d70aa114..b267eef83 100644 --- a/src/libimcv/plugins/imc_attestation/imc_attestation.c +++ b/src/libimcv/plugins/imc_attestation/imc_attestation.c @@ -282,7 +282,19 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, case TCG_PTS_GET_AIK: { - /* TODO: Implement AIK retrieve */ + chunk_t aik; + bool is_naked_key; + + if (!pts->get_aik(pts, &aik, &is_naked_key)) + { + DBG1(DBG_IMC,"Obtaining AIK Certificate failed"); + break; + } + + /* Send AIK attribute */ + attr_to_send = tcg_pts_attr_aik_create(is_naked_key, aik); + attr_to_send = (pa_tnc_attr_t*)attr_to_send; + attr_list->insert_last(attr_list,attr_to_send); break; } @@ -309,9 +321,10 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, request_id = attr_cast->get_request_id(attr_cast); delimiter = attr_cast->get_delimiter(attr_cast); path = attr_cast->get_file_path(attr_cast); - - DBG3(DBG_IMC,"requested %s to be measured: %s", - (directory_flag)? "directory":"file", path.ptr); + path = chunk_clone(path); + + DBG3(DBG_IMC,"requested %s to be measured: %B", + (directory_flag)? "directory":"file", &path); /* Send File Measurement attribute */ selected_algorithm = pts->get_meas_algorithm(pts); @@ -342,8 +355,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, DBG1(DBG_IMC, "Hashing the given file has failed"); return TNC_RESULT_FATAL; } - attr_file_meas->add_file_meas(attr_file_meas, file_hash, chunk_clone(path)); - + attr_file_meas->add_file_meas(attr_file_meas, file_hash, path); } else { diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c index fda4e4e21..b9256c1ac 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c @@ -221,15 +221,15 @@ static TNC_Result send_message(TNC_ConnectionID connection_id) { pa_tnc_attr_t *attr_get_tpm_version, *attr_get_aik; + /* Send Get TPM Version attribute */ attr_get_tpm_version = tcg_pts_attr_get_tpm_version_info_create(); attr_get_tpm_version->set_noskip_flag(attr_get_tpm_version, TRUE); msg->add_attribute(msg, attr_get_tpm_version); /* Send Get AIK attribute */ - /* TODO: Uncomment when the retrieving of AIK on IMC side is implemented */ - //attr_get_aik = tcg_pts_attr_get_aik_create(); - //attr_get_aik->set_noskip_flag(attr_get_aik, TRUE); - //msg->add_attribute(msg, attr_get_aik); + attr_get_aik = tcg_pts_attr_get_aik_create(); + attr_get_aik->set_noskip_flag(attr_get_aik, TRUE); + msg->add_attribute(msg, attr_get_aik); } /* Send Request File Measurement attribute */ @@ -255,6 +255,7 @@ static TNC_Result send_message(TNC_ConnectionID connection_id) DBG2(DBG_IMV, "id = %d, type = %d, path = '%s'", id, type, path); is_directory = (type != 0) ? true : false; + path[strlen(path)] = '\0'; path_chunk = chunk_create(path, strlen(path)); path_chunk = chunk_clone(path_chunk); @@ -406,7 +407,15 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, } case TCG_PTS_AIK: { - /* TODO: Save the AIK key and certificate */ + tcg_pts_attr_aik_t *attr_cast; + chunk_t aik; + bool is_naked_key; + + attr_cast = (tcg_pts_attr_aik_t*)attr; + aik = attr_cast->get_aik(attr_cast); + is_naked_key = attr_cast->get_naked_flag(attr_cast); + pts->set_aik(pts, aik, is_naked_key); + attestation_state->set_handshake_state(attestation_state, IMV_ATTESTATION_STATE_END); break; @@ -457,7 +466,7 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, DBG3(DBG_IMV, "Expected measurement: %B", &db_measurement); /* Compare the received hash measurement with one saved in db */ - if(chunk_compare(db_measurement, meas_entry->measurement) == 0) + if(chunk_equals(db_measurement, meas_entry->measurement)) { DBG1(DBG_IMV, "Measurement comparison succeeded for: %s", meas_entry->file_name.ptr); } diff --git a/src/libimcv/tcg/pts/pts.c b/src/libimcv/tcg/pts/pts.c index de3345977..0d0304920 100644 --- a/src/libimcv/tcg/pts/pts.c +++ b/src/libimcv/tcg/pts/pts.c @@ -41,7 +41,7 @@ #define REQURL CAURL "api/pca/level%d?ResponseFormat=Binary" /* TPM has EK Certificate */ -/* #define REALEK */ +#define REALEK FALSE typedef struct private_pts_t private_pts_t; @@ -176,7 +176,7 @@ METHOD(pts_t, set_tpm_version_info, void, * Create a fake endorsement key cert using system's actual EK */ -static bool makeEKCert(TSS_HCONTEXT hContext, TSS_HTPM hTPM, UINT32 *pCertLen, BYTE **pCert) +static TSS_RESULT makeEKCert(TSS_HCONTEXT hContext, TSS_HTPM hTPM, UINT32 *pCertLen, BYTE **pCert) { TSS_RESULT result; TSS_HKEY hPubek; @@ -186,18 +186,21 @@ static bool makeEKCert(TSS_HCONTEXT hContext, TSS_HTPM hTPM, UINT32 *pCertLen, B result = Tspi_TPM_GetPubEndorsementKey (hTPM, TRUE, NULL, &hPubek); if (result != TSS_SUCCESS) { - goto err; + DBG1(DBG_IMC, "Error in: Tspi_TPM_GetPubEndorsementKey\n"); + return result; } result = Tspi_GetAttribData (hPubek, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modulusLen, &modulus); Tspi_Context_CloseObject (hContext, hPubek); if (result != TSS_SUCCESS) { - goto err; + DBG1(DBG_IMC, "Error in: Tspi_Context_CloseObject\n"); + return result; } if (modulusLen != 256) { + DBG1(DBG_IMC, "Tspi_GetAttribData modulusLen != 256\n"); Tspi_Context_FreeMemory (hContext, modulus); - goto err; + return result; } *pCertLen = sizeof(fakeEKCert); *pCert = malloc (*pCertLen); @@ -205,11 +208,7 @@ static bool makeEKCert(TSS_HCONTEXT hContext, TSS_HTPM hTPM, UINT32 *pCertLen, B memcpy (*pCert + 0xc6, modulus, modulusLen); Tspi_Context_FreeMemory (hContext, modulus); - return TRUE; - -err: - DBG1(DBG_TNC, "TPM not available: tss error 0x%x", result); - return FALSE; + return TSS_SUCCESS; } /** @@ -226,7 +225,7 @@ static X509* readPCAcert (int level) int result; hCurl = curl_easy_init (); - DBG1(DBG_IMC, url, CERTURL, level); + sprintf (url, CERTURL, level); curl_easy_setopt (hCurl, CURLOPT_URL, url); curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (BYTE **)f_tmp); @@ -248,7 +247,7 @@ static X509* readPCAcert (int level) * Obtain an AIK, SRK and TPM Owner secret has to be both set to well known secret * of 20 bytes of zero */ -static bool obtain_aik(chunk_t *aik, bool *is_naked_key) +static bool obtain_aik(private_pts_t *this) { TSS_HCONTEXT hContext; TSS_HTPM hTPM; @@ -278,24 +277,24 @@ static bool obtain_aik(chunk_t *aik, bool *is_naked_key) UINT32 asymBufSize; UINT32 symBufSize; UINT32 credBufSize; - BYTE *blob; - UINT32 blobLen; -#ifdef REALEK - const int level = 1; -#else - const int level = 0; + static int level = 0; BYTE *ekCert = NULL; UINT32 ekCertLen; -#endif char url[128]; int result; - *aik = chunk_empty; - *is_naked_key = false; + this->aik = chunk_empty; + this->is_naked_key = false; curl_global_init (CURL_GLOBAL_ALL); + DBG3(DBG_IMC, "Retrieving PCA certificate...\n"); - + + /* TPM has EK Certificate */ + if(REALEK) + { + level = 1; + } x509 = readPCAcert (level); if (x509 == NULL) { DBG1(DBG_IMC, "Error reading PCA key\n"); @@ -385,20 +384,21 @@ static bool obtain_aik(chunk_t *aik, bool *is_naked_key) goto err; } -#ifndef REALEK - result = makeEKCert(hContext, hTPM, &ekCertLen, &ekCert); - if (result != TSS_SUCCESS) { - DBG1(DBG_IMC, "Error 0x%x on makeEKCert\n", result); - goto err; - } - - result = Tspi_SetAttribData(hTPM, TSS_TSPATTRIB_TPM_CREDENTIAL, - TSS_TPMATTRIB_EKCERT, ekCertLen, ekCert); - if (result != TSS_SUCCESS) { - DBG1(DBG_IMC, "Error 0x%x on SetAttribData for EKCert\n", result); - goto err; + if(!REALEK) + { + result = makeEKCert(hContext, hTPM, &ekCertLen, &ekCert); + if (result != TSS_SUCCESS) { + DBG1(DBG_IMC, "Error 0x%x on makeEKCert\n", result); + goto err; + } + + result = Tspi_SetAttribData(hTPM, TSS_TSPATTRIB_TPM_CREDENTIAL, + TSS_TPMATTRIB_EKCERT, ekCertLen, ekCert); + if (result != TSS_SUCCESS) { + DBG1(DBG_IMC, "Error 0x%x on SetAttribData for EKCert\n", result); + goto err; + } } -#endif DBG3(DBG_IMC, "Generating attestation identity key...\n"); result = Tspi_TPM_CollateIdentityRequest(hTPM, hSRK, hPCAKey, 0, @@ -415,7 +415,7 @@ static bool obtain_aik(chunk_t *aik, bool *is_naked_key) /* Send to server */ f_tmp = tmpfile(); hCurl = curl_easy_init (); - DBG3(DBG_IMC, "URL: %s\nRequest URL: %s\n Certificate Level: %d", url, REQURL, level); + sprintf (url, REQURL, level); curl_easy_setopt (hCurl, CURLOPT_URL, url); curl_easy_setopt (hCurl, CURLOPT_POSTFIELDS, (void *)rgbTCPAIdentityReq); curl_easy_setopt (hCurl, CURLOPT_POSTFIELDSIZE, ulTCPAIdentityReqLength); @@ -468,19 +468,7 @@ static bool obtain_aik(chunk_t *aik, bool *is_naked_key) DBG1(DBG_IMC, "Error 0x%x on Tspi_TPM_ActivateIdentity\n", result); goto err; } - - /* Output key blob */ - result = Tspi_GetAttribData (hIdentKey, TSS_TSPATTRIB_KEY_BLOB, - TSS_TSPATTRIB_KEYBLOB_BLOB, &blobLen, &blob); - if (result != TSS_SUCCESS) { - DBG1(DBG_IMC, "Error 0x%x on Tspi_GetAttribData for key blob\n", result); - goto err; - } - - /* TODO: Do something with blob variable */ - - Tspi_Context_FreeMemory (hContext, blob); - + /* Output credential in PEM format */ tbuf = credBuf; x509 = d2i_X509(NULL, (const BYTE **)&tbuf, credBufSize); @@ -492,9 +480,34 @@ static bool obtain_aik(chunk_t *aik, bool *is_naked_key) DBG1(DBG_IMC, "Note, not all data from privacy ca was parsed correctly\n"); } - /* TODO: Do something with X509 object */ - X509_free (x509); + if(x509) + { + BUF_MEM *mem_buf; + BIO* bp; + u_int32_t len; + + bp = BIO_new(BIO_s_mem()); + PEM_write_bio_X509(bp, x509); + + len = BIO_get_mem_data(bp, &mem_buf); + char tmp[len+1]; + + memcpy(tmp, mem_buf, len); + tmp[len] = '\0'; + DBG3(DBG_IMC,"X509 Certificate (PEM format):\n%s\n", tmp); + this->aik = chunk_create(tmp, len + 1); + this->aik = chunk_clone(this->aik); + + X509_free (x509); + + } + else + { + DBG1(DBG_IMC, "Neither AIK Key blob, nor AIK Certificate is available\n"); + goto err; + } + DBG3(DBG_IMC, "Succeeded at obtaining AIK Certificate from Privacy CA!\n"); return TRUE; @@ -505,7 +518,7 @@ err: METHOD(pts_t, get_aik, bool, private_pts_t *this, chunk_t *aik, bool *is_naked_key) { - if(obtain_aik(aik, is_naked_key) != TSS_SUCCESS ) + if(obtain_aik(this) != TRUE ) { return FALSE; } @@ -527,6 +540,7 @@ METHOD(pts_t, hash_file, bool, private_pts_t *this, chunk_t path, chunk_t *out) { char buffer[PTS_BUF_SIZE]; + chunk_t path_chunk; FILE *file; int bytes_read; hasher_t *hasher; @@ -540,8 +554,9 @@ METHOD(pts_t, hash_file, bool, DBG1(DBG_IMC, "hasher %N not available", hash_algorithm_names, hash_alg); return false; } - - file = fopen(path.ptr, "rb"); + + path_chunk = chunk_create_clone(malloc(path.len), path); + file = fopen(path_chunk.ptr, "rb"); if (!file) { DBG1(DBG_IMC,"file '%s' can not be opened, %s", path.ptr, strerror(errno)); @@ -573,13 +588,15 @@ METHOD(pts_t, hash_directory, bool, { DIR *dir; struct dirent *ent; + chunk_t path_chunk; file_meas_entry_t *entry; linked_list_t *list = *file_measurements; list = linked_list_create(); entry = malloc_thing(file_meas_entry_t); - dir = opendir(path.ptr); + path_chunk = chunk_create_clone(malloc(path.len), path); + dir = opendir(path_chunk.ptr); if (dir == NULL) { DBG1(DBG_IMC, "opening directory '%s' failed: %s", path.ptr, strerror(errno)); |