From 0205c1b16a58644a1b514047c325b0e2fd0b002b Mon Sep 17 00:00:00 2001 From: emanuel Date: Wed, 19 Jan 2022 17:28:11 +0000 Subject: [PATCH] TPM verify signatures --- src/tpm.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 6 deletions(-) diff --git a/src/tpm.c b/src/tpm.c index 09934b8..d496784 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -203,7 +203,9 @@ cleanup: return rv; } -static void rsu_handle_recv(facilities_t* facilities, TollRequest_t* req, uint8_t* neighbour) { +static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* neighbour) { + + TollRequest_t* req = &tpm_rx->tpm.tollingFlow.choice.request; syslog_info("[facilities] [tolling] received toll payment > client: %ld (certificate id: %02x%02x%02x) | nonce: %ld", req->clientId, @@ -221,6 +223,62 @@ static void rsu_handle_recv(facilities_t* facilities, TollRequest_t* req, uint8_ SecurityReply_t* srep = NULL; TPM_t* tpm = NULL; + // Encode TollingPaymentMessage + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, &tpm_rx->tpm, buf, buf_len); + if (enc.encoded == -1) { + syslog_err("[facilities] [tolling] error encoding TollingPaymentMessage (%s)", enc.failed_type->name); + goto cleanup; + } + + // Verify + sreq = calloc(1, sizeof(SecurityRequest_t)); + sreq->present = SecurityRequest_PR_verify; + // message + sreq->choice.verify.message.size = enc.encoded; + sreq->choice.verify.message.buf = malloc(enc.encoded); + memcpy(sreq->choice.verify.message.buf, buf, enc.encoded); + // r + sreq->choice.verify.r.size = tpm_rx->signature.r.size; + sreq->choice.verify.r.buf = malloc(tpm_rx->signature.r.size); + memcpy(sreq->choice.verify.r.buf, tpm_rx->signature.r.buf, tpm_rx->signature.r.size); + // s + sreq->choice.verify.s.size = tpm_rx->signature.s.size; + sreq->choice.verify.s.buf = malloc(tpm_rx->signature.s.size); + memcpy(sreq->choice.verify.s.buf, tpm_rx->signature.s.buf, tpm_rx->signature.s.size); + // signer + sreq->choice.verify.signer.size = tpm_rx->signature.signer.size; + sreq->choice.verify.signer.buf = malloc(tpm_rx->signature.signer.size); + memcpy(sreq->choice.verify.signer.buf, tpm_rx->signature.signer.buf, tpm_rx->signature.signer.size); + // signature type + sreq->choice.verify.type = tpm_rx->signature.type; + + buf[0] = 4; + enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, 2047); + syslog_debug("[facilities]->[security] SecurityRequest.verify (%ldB)", enc.encoded+1); + zmq_send(facilities->tolling.security_socket, buf, enc.encoded+1, 0); + int32_t rl = zmq_recv(facilities->tolling.security_socket, buf, buf_len, 0); + syslog_debug("[facilities]<-[security] SecurityReply.verify (%dB)", rl); + + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) { + syslog_err("[facilities] SecurityReply.verify decode failure"); + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + syslog_err("[facilities] SecurityReply.verify rejected"); + goto cleanup; + } + + if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { + syslog_debug("[facilities] signature verify failed"); + goto cleanup; + } + + ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); + ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); + sreq = NULL; + srep = NULL; + // TPM tpm = calloc(1, sizeof(TPM_t)); @@ -257,7 +315,7 @@ static void rsu_handle_recv(facilities_t* facilities, TollRequest_t* req, uint8_ // TODO dlt: check transaction // Encode TollingPaymentMessage - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, &tpm->tpm, buf, buf_len); + enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, &tpm->tpm, buf, buf_len); if (enc.encoded == -1) { syslog_err("[facilities] [tolling] error encoding TollingPaymentMessage (%s)", enc.failed_type->name); goto cleanup; @@ -274,7 +332,7 @@ static void rsu_handle_recv(facilities_t* facilities, TollRequest_t* req, uint8_ enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, 2047); syslog_debug("[facilities]->[security] SecurityRequest.sign (%ldB)", enc.encoded+1); zmq_send(facilities->tolling.security_socket, buf, enc.encoded+1, 0); - int32_t rl = zmq_recv(facilities->tolling.security_socket, buf, buf_len, 0); + rl = zmq_recv(facilities->tolling.security_socket, buf, buf_len, 0); syslog_debug("[facilities]<-[security] SecurityReply.sign (%dB)", rl); if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) { @@ -353,7 +411,9 @@ cleanup: ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); } -static void veh_handle_recv(tolling_s* tolling, TollReply_t* rep, uint8_t* neighbour) { +static void veh_handle_recv(tolling_s* tolling, TPM_t* tpm_rx, uint8_t* neighbour) { + + TollReply_t* rep = &tpm_rx->tpm.tollingFlow.choice.reply; if (rep->clientId != tolling->client_id) { syslog_debug("[facilities] [tolling]<- received TPM.reply clientId different from ego"); @@ -365,9 +425,70 @@ static void veh_handle_recv(tolling_s* tolling, TollReply_t* rep, uint8_t* neigh return; } + SecurityRequest_t* sreq = NULL; + SecurityReply_t* srep = NULL; + + uint16_t buf_len = 1024; + uint8_t buf[buf_len]; + + // Encode TollingPaymentMessage + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, &tpm_rx->tpm, buf, buf_len); + if (enc.encoded == -1) { + syslog_err("[facilities] [tolling] error encoding TollingPaymentMessage (%s)", enc.failed_type->name); + goto cleanup; + } + + // Verify + sreq = calloc(1, sizeof(SecurityRequest_t)); + sreq->present = SecurityRequest_PR_verify; + // message + sreq->choice.verify.message.size = enc.encoded; + sreq->choice.verify.message.buf = malloc(enc.encoded); + memcpy(sreq->choice.verify.message.buf, buf, enc.encoded); + // r + sreq->choice.verify.r.size = tpm_rx->signature.r.size; + sreq->choice.verify.r.buf = malloc(tpm_rx->signature.r.size); + memcpy(sreq->choice.verify.r.buf, tpm_rx->signature.r.buf, tpm_rx->signature.r.size); + // s + sreq->choice.verify.s.size = tpm_rx->signature.s.size; + sreq->choice.verify.s.buf = malloc(tpm_rx->signature.s.size); + memcpy(sreq->choice.verify.s.buf, tpm_rx->signature.s.buf, tpm_rx->signature.s.size); + // signer + sreq->choice.verify.signer.size = tpm_rx->signature.signer.size; + sreq->choice.verify.signer.buf = malloc(tpm_rx->signature.signer.size); + memcpy(sreq->choice.verify.signer.buf, tpm_rx->signature.signer.buf, tpm_rx->signature.signer.size); + // signature type + sreq->choice.verify.type = tpm_rx->signature.type; + + buf[0] = 4; + enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, 2047); + syslog_debug("[facilities]->[security] SecurityRequest.verify (%ldB)", enc.encoded+1); + zmq_send(tolling->security_socket, buf, enc.encoded+1, 0); + int32_t rl = zmq_recv(tolling->security_socket, buf, buf_len, 0); + syslog_debug("[facilities]<-[security] SecurityReply.verify (%dB)", rl); + + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) { + syslog_err("[facilities] SecurityReply.verify decode failure"); + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + syslog_err("[facilities] SecurityReply.verify rejected"); + goto cleanup; + } + + if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { + syslog_debug("[facilities] signature verify failed"); + goto cleanup; + } + syslog_info("[facilities] [tolling] received tolling payment reply > client: %ld | nonce: %ld | accepted: %s", tolling->client_id, tolling->nonce, rep->confirmationCode == TollConfirmationCode_accepted ? "yes" : "no"); tolling->active = false; + +cleanup: + ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); + ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); } int tpm_recv(void* fc, TPM_t* tpm_rx, uint8_t* neighbour) { @@ -387,7 +508,7 @@ int tpm_recv(void* fc, TPM_t* tpm_rx, uint8_t* neighbour) { syslog_debug("[facilities] [tolling] received TPM.request, ignoring"); goto cleanup; } - rsu_handle_recv(facilities, &tpm_rx->tpm.tollingFlow.choice.request, neighbour); + rsu_handle_recv(facilities, tpm_rx, neighbour); break; case TollingFlow_PR_reply: @@ -396,7 +517,7 @@ int tpm_recv(void* fc, TPM_t* tpm_rx, uint8_t* neighbour) { goto cleanup; } syslog_info("[facilities] [tolling] reply took %ld ms", it2s_tender_get_clock(&facilities->epv) - tolling->tz); - veh_handle_recv(tolling, &tpm_rx->tpm.tollingFlow.choice.reply, neighbour); + veh_handle_recv(tolling, tpm_rx, neighbour); break; default: