diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation.c b/src/libimcv/plugins/imc_attestation/imc_attestation.c index 452a05f42..19116318d 100644 --- a/src/libimcv/plugins/imc_attestation/imc_attestation.c +++ b/src/libimcv/plugins/imc_attestation/imc_attestation.c @@ -288,30 +288,17 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, case TCG_PTS_GET_AIK: { - certificate_t *aik_cert; - public_key_t *aik_key; - bool is_naked_key; + certificate_t *aik; - if (!pts->get_aik(pts, &aik_cert, &aik_key, &is_naked_key)) + aik = pts->get_aik(pts); + if (!aik) { - DBG1(DBG_IMC, "Obtaining AIK Certificate failed"); + DBG1(DBG_IMC, "no AIK certificate or public key available"); break; } /* Send AIK attribute */ - if(!is_naked_key && aik_cert) - { - attr = tcg_pts_attr_aik_create(is_naked_key, chunk_from_thing(aik_cert)); - } - else if(is_naked_key && aik_key) - { - attr = tcg_pts_attr_aik_create(is_naked_key, chunk_from_thing(aik_key)); - } - else - { - DBG1(DBG_IMC, "Neither AIK Certificate nor AIK public was provided"); - break; - } + attr = tcg_pts_attr_aik_create(aik); attr_list->insert_last(attr_list, attr); break; } diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c index 337167e0a..4f25d51e8 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c @@ -415,32 +415,16 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, case TCG_PTS_AIK: { tcg_pts_attr_aik_t *attr_cast; - chunk_t aik; - bool is_naked_key; - + certificate_t *aik; + 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); - - if(!is_naked_key) + if (!aik) { - certificate_t *aik_cert; - - aik_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_BLOB_PEM, aik, - BUILD_END); - pts->set_aik_cert(pts, aik_cert); + /* TODO generate error attribute */ + break; } - else - { - public_key_t *aik_key; - - aik_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, - BUILD_BLOB_PEM, aik, - BUILD_END); - pts->set_aik_key(pts, aik_key); - } - + pts->set_aik(pts, aik); attestation_state->set_handshake_state(attestation_state, IMV_ATTESTATION_STATE_END); break; diff --git a/src/libimcv/tcg/pts/pts.c b/src/libimcv/tcg/pts/pts.c index 16a53ea1d..e8cd632b9 100644 --- a/src/libimcv/tcg/pts/pts.c +++ b/src/libimcv/tcg/pts/pts.c @@ -65,19 +65,9 @@ struct private_pts_t { chunk_t tpm_version_info; /** - * Contains a Attestation Identity Certificate + * Contains a Attestation Identity Key or Certificate */ - certificate_t *aik_cert; - - /** - * Contains a Attestation Identity Public Key - */ - public_key_t *aik_key; - - /** - * True if AIK is naked public key, not a certificate - */ - bool is_naked_key; + certificate_t *aik; }; @@ -178,75 +168,55 @@ METHOD(pts_t, set_tpm_version_info, void, print_tpm_version_info(this); } - /** - * Obtain an AIK Certificate or public key - * If the certificate is available in give path, ignore whether key is there - * If certificate is not available take the public key at given path + * Load an AIK certificate or public key, + * the certificate having precedence over the public key if both are present */ -static bool obtain_aik(private_pts_t *this) +static void load_aik(private_pts_t *this) { - char *certificate_path; - char *key_path; + char *cert_path, *key_path; - certificate_path = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.aikcert", NULL); - + cert_path = lib->settings->get_str(lib->settings, + "libimcv.plugins.imc-attestation.aik_cert", NULL); key_path = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.aikkey", NULL); + "libimcv.plugins.imc-attestation.aik_key", NULL); - DBG2(DBG_IMC,"AIK Certificate path %s",certificate_path); - DBG2(DBG_IMC,"AIK Public Key path %s", key_path); - - if(certificate_path && (this->aik_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_FROM_FILE, certificate_path, - BUILD_END))) + if (cert_path) { - this->is_naked_key = FALSE; + DBG2(DBG_IMC,"AIK certificate path %s", cert_path); + this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE, + CERT_X509, BUILD_FROM_FILE, + cert_path, BUILD_END); + if (this->aik) + { + return; + } } - else if(key_path && (this->aik_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, - BUILD_FROM_FILE, key_path, - BUILD_END))) + if (key_path) { - this->is_naked_key = TRUE; + DBG2(DBG_IMC,"AIK public key path %s", key_path); + this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE, + CERT_TRUSTED_PUBKEY, BUILD_FROM_FILE, + key_path, BUILD_END); + if (this->aik) + { + return; + } } - else - { - DBG1(DBG_IMC, "Neither AIK Public Key nor AIK Certificate is available"); - return FALSE; - } - - DBG3(DBG_IMC, "Succeeded at obtaining AIK Certificate from Privacy CA!"); - return TRUE; + DBG1(DBG_IMC, "neither AIK certificate nor public key is available"); } -METHOD(pts_t, get_aik, bool, - private_pts_t *this, certificate_t **aik_cert, public_key_t **aik_key, bool *is_naked_key) +METHOD(pts_t, get_aik, certificate_t*, + private_pts_t *this) { - if (obtain_aik(this) != TRUE ) - { - return FALSE; - } - - *aik_cert = this->aik_cert; - *aik_key = this->aik_key; - *is_naked_key = this->is_naked_key; - - return TRUE; + return this->aik; } -METHOD(pts_t, set_aik_cert, void, - private_pts_t *this, certificate_t *aik_cert) +METHOD(pts_t, set_aik, void, + private_pts_t *this, certificate_t *aik) { - this->aik_cert = aik_cert; - this->is_naked_key = FALSE; -} - -METHOD(pts_t, set_aik_key, void, - private_pts_t *this, public_key_t *aik_key) -{ - this->aik_key = aik_key; - this->is_naked_key = TRUE; + DESTROY_IF(this->aik); + this->aik = aik->get_ref(aik); } /** @@ -378,6 +348,7 @@ METHOD(pts_t, do_measurements, pts_file_meas_t*, METHOD(pts_t, destroy, void, private_pts_t *this) { + DESTROY_IF(this->aik); free(this->platform_info); free(this->tpm_version_info.ptr); free(this); @@ -440,8 +411,7 @@ pts_t *pts_create(bool is_imc) .get_tpm_version_info = _get_tpm_version_info, .set_tpm_version_info = _set_tpm_version_info, .get_aik = _get_aik, - .set_aik_cert = _set_aik_cert, - .set_aik_key = _set_aik_key, + .set_aik = _set_aik, .do_measurements = _do_measurements, .destroy = _destroy, }, @@ -455,6 +425,7 @@ pts_t *pts_create(bool is_imc) { this->has_tpm = TRUE; this->proto_caps |= PTS_PROTO_CAPS_T; + load_aik(this); } } else diff --git a/src/libimcv/tcg/pts/pts.h b/src/libimcv/tcg/pts/pts.h index 61e29d821..c2de2ac32 100644 --- a/src/libimcv/tcg/pts/pts.h +++ b/src/libimcv/tcg/pts/pts.h @@ -93,31 +93,19 @@ struct pts_t { void (*set_tpm_version_info)(pts_t *this, chunk_t info); /** - * Get Attestation Identity Key + * Get Attestation Identity Certificate or Public Key * - * @param aik_cert structure containing a AIK naked public certificate - * @param aik_key structure containing a AIK naked public key - * @param is_naked_key TRUE if AIK is naked public key, without certificate - * @return TRUE if AIK available + * @return AIK Certificate or Public Key */ - bool (*get_aik)(pts_t *this, certificate_t **aik_cert, public_key_t **aik_key, bool *is_naked_key); + certificate_t* (*get_aik)(pts_t *this); /** - * Set Attestation Identity Certificate + * Set Attestation Identity Certificate or Public Key * - * @param aik_cert structure containing a AIK naked public certificate - * @param is_naked_key TRUE if AIK is naked public key, without certificate + * @param aik AIK Certificate or Public Key */ - void (*set_aik_cert)(pts_t *this, certificate_t *aik_cert); + void (*set_aik)(pts_t *this, certificate_t *aik); - /** - * Set Attestation Identity Key - * - * @param aik_key structure containing a AIK naked public key - * @param is_naked_key TRUE if AIK is naked public key, without certificate - */ - void (*set_aik_key)(pts_t *this, public_key_t *aik_key); - /** * Do PTS File Measurements * @@ -127,7 +115,7 @@ struct pts_t { * @return PTS File Measurements of NULL if FAILED */ pts_file_meas_t* (*do_measurements)(pts_t *this, u_int16_t request_id, - char *pathname, bool is_directory); + char *pathname, bool is_directory); /** * Destroys a pts_t object. diff --git a/src/libimcv/tcg/tcg_pts_attr_aik.c b/src/libimcv/tcg/tcg_pts_attr_aik.c index c6a241c07..b2c525a19 100644 --- a/src/libimcv/tcg/tcg_pts_attr_aik.c +++ b/src/libimcv/tcg/tcg_pts_attr_aik.c @@ -35,8 +35,9 @@ typedef struct private_tcg_pts_attr_aik_t private_tcg_pts_attr_aik_t; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define PTS_AIK_SIZE 4 - +#define PTS_AIK_SIZE 4 +#define PTS_AIK_FLAGS_NONE 0 +#define PTS_AIK_FLAGS_NAKED_KEY (1<<7) /** * Private data of an tcg_pts_attr_aik_t object. */ @@ -68,14 +69,9 @@ struct private_tcg_pts_attr_aik_t { bool noskip_flag; /** - * Naked Public Key flag + * AIK Certificate or Public Key */ - bool naked_pub_aik; - - /** - * Attestation Identity Key - */ - chunk_t aik; + certificate_t *aik; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -112,17 +108,21 @@ METHOD(pa_tnc_attr_t, build, void, private_tcg_pts_attr_aik_t *this) { bio_writer_t *writer; - u_int8_t flags = 0; + u_int8_t flags = PTS_AIK_FLAGS_NONE; + chunk_t aik_blob; - writer = bio_writer_create(PTS_AIK_SIZE); - - if (this->naked_pub_aik) + if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY) { - flags += 128; + flags |= PTS_AIK_FLAGS_NAKED_KEY; } - writer->write_uint8 (writer, flags); - writer->write_data(writer, this->aik); - + if (this->aik->get_encoding(this->aik, CERT_ASN1_DER, &aik_blob)) + { + DBG1(DBG_TNC, "encoding of Attestation Identity Key failed"); + aik_blob = chunk_empty; + } + writer = bio_writer_create(PTS_AIK_SIZE); + writer->write_uint8(writer, flags); + writer->write_data (writer, aik_blob); this->value = chunk_clone(writer->get_buf(writer)); writer->destroy(writer); } @@ -132,6 +132,8 @@ METHOD(pa_tnc_attr_t, process, status_t, { bio_reader_t *reader; u_int8_t flags; + certificate_type_t type; + chunk_t aik_blob; if (this->value.len < PTS_AIK_SIZE) { @@ -140,57 +142,42 @@ METHOD(pa_tnc_attr_t, process, status_t, return FAILED; } reader = bio_reader_create(this->value); - reader->read_uint8(reader, &flags); - if ((flags >> 7 ) & 1) - { - this->naked_pub_aik = true; - } - - reader->read_data (reader, this->value.len - 1, &this->aik); - this->aik = chunk_clone(this->aik); + reader->read_data (reader, reader->remaining(reader), &aik_blob); + + type = (flags & PTS_AIK_FLAGS_NAKED_KEY) ? CERT_TRUSTED_PUBKEY : CERT_X509; + + this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE, type, + BUILD_BLOB_PEM, aik_blob, BUILD_END); reader->destroy(reader); + if (!this->aik) + { + DBG1(DBG_TNC, "parsing of Attestation Identity Key failed"); + *offset = 0; + return FAILED; + } return SUCCESS; } METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_aik_t *this) { + DESTROY_IF(this->aik); free(this->value.ptr); - free(this->aik.ptr); free(this); } -METHOD(tcg_pts_attr_aik_t, get_naked_flag, bool, - private_tcg_pts_attr_aik_t *this) -{ - return this->naked_pub_aik; -} - -METHOD(tcg_pts_attr_aik_t, set_naked_flag, void, - private_tcg_pts_attr_aik_t *this, bool naked_pub_aik) -{ - this->naked_pub_aik = naked_pub_aik; -} - -METHOD(tcg_pts_attr_aik_t, get_aik, chunk_t, +METHOD(tcg_pts_attr_aik_t, get_aik, certificate_t*, private_tcg_pts_attr_aik_t *this) { return this->aik; } -METHOD(tcg_pts_attr_aik_t, set_aik, void, - private_tcg_pts_attr_aik_t *this, - chunk_t aik) -{ - this->aik = aik; -} - /** * Described in header. */ -pa_tnc_attr_t *tcg_pts_attr_aik_create(bool naked_pub_aik, chunk_t aik) +pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik) { private_tcg_pts_attr_aik_t *this; @@ -206,15 +193,11 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create(bool naked_pub_aik, chunk_t aik) .process = _process, .destroy = _destroy, }, - .get_naked_flag = _get_naked_flag, - .set_naked_flag = _set_naked_flag, .get_aik = _get_aik, - .set_aik = _set_aik, }, .vendor_id = PEN_TCG, .type = TCG_PTS_AIK, - .naked_pub_aik = naked_pub_aik, - .aik = aik, + .aik = aik->get_ref(aik), ); return &this->public.pa_tnc_attribute; @@ -240,10 +223,7 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(chunk_t data) .process = _process, .destroy = _destroy, }, - .get_naked_flag = _get_naked_flag, - .set_naked_flag = _set_naked_flag, .get_aik = _get_aik, - .set_aik = _set_aik, }, .vendor_id = PEN_TCG, .type = TCG_PTS_AIK, diff --git a/src/libimcv/tcg/tcg_pts_attr_aik.h b/src/libimcv/tcg/tcg_pts_attr_aik.h index 78d18d443..96e90582b 100644 --- a/src/libimcv/tcg/tcg_pts_attr_aik.h +++ b/src/libimcv/tcg/tcg_pts_attr_aik.h @@ -26,6 +26,8 @@ typedef struct tcg_pts_attr_aik_t tcg_pts_attr_aik_t; #include "tcg_attr.h" #include "pa_tnc/pa_tnc_attr.h" +#include + /** * Class implementing the TCG PTS Attestation Identity Key attribute * @@ -37,44 +39,21 @@ struct tcg_pts_attr_aik_t { */ pa_tnc_attr_t pa_tnc_attribute; - /** - * Get Naked Public Key flag - * - * @return Naked Public Key flag - */ - bool (*get_naked_flag)(tcg_pts_attr_aik_t *this); - - /** - * Set Naked Public Key flag - * - * @param naked flag - */ - void (*set_naked_flag)(tcg_pts_attr_aik_t *this, - bool naked_pub_aik); - /** * Get AIK * - * @return Attestation Identity Key + * @return AIK Certificate or Public Key */ - chunk_t (*get_aik)(tcg_pts_attr_aik_t *this); + certificate_t* (*get_aik)(tcg_pts_attr_aik_t *this); - /** - * Set AIK - * - * @param flags set of flags - */ - void (*set_aik)(tcg_pts_attr_aik_t *this, - chunk_t aik); }; /** * Creates an tcg_pts_attr_aik_t object * - * @param naked_pub_aik Sender only has naked public key * @param aik Attestation Identity Key */ -pa_tnc_attr_t* tcg_pts_attr_aik_create(bool naked_pub_aik, chunk_t aik); +pa_tnc_attr_t* tcg_pts_attr_aik_create(certificate_t *aik); /** * Creates an tcg_pts_attr_aik_t object from received data