From 01406cdbf312fe9b4099fb1d2f33445f3cf613f0 Mon Sep 17 00:00:00 2001 From: Mohannad Date: Tue, 1 Aug 2023 13:28:12 +0100 Subject: [PATCH] TPM SPKI remove sec-verify check, fast fwd2apps on rx --- src/facilities.c | 1 + src/facilities.h | 1 + src/requests.c | 14 ++- src/tpm.c | 234 ++++++++++++++++++++++++----------------------- 4 files changed, 135 insertions(+), 115 deletions(-) diff --git a/src/facilities.c b/src/facilities.c index 54fe63f..e2e3ea7 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -501,6 +501,7 @@ int main() { edm_init(); } + facilities.apps_socket = itss_0connect(facilities.zmq.applications_address, ZMQ_REQ); security_socket = itss_0connect(facilities.zmq.security_address, ZMQ_REQ); uint8_t buffer[ITSS_SDU_MAX_LEN]; diff --git a/src/facilities.h b/src/facilities.h index 36273a3..f39260f 100644 --- a/src/facilities.h +++ b/src/facilities.h @@ -51,6 +51,7 @@ typedef struct facilities { // Transmitter itss_queue_t* tx_queue; + void* apps_socket; /* alternative to tx queue, only used in rx/main thread */ // CA lightship_t lightship; diff --git a/src/requests.c b/src/requests.c index 5d2b9d7..95083f6 100644 --- a/src/requests.c +++ b/src/requests.c @@ -40,7 +40,15 @@ static void fwd_to_apps(uint8_t* msg, uint16_t msg_len, int its_msg_type, uint32 buffer[0] = 4; // Facilities asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); - itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, iid, "FI.message"); + log_debug("-> FI.message ->[applications] | id:%08x size:%dB", + (uint32_t)iid, enc.encoded+1); + uint8_t code; + itss_0send(facilities.apps_socket, buffer, enc.encoded+1); + int rv = itss_0recv_rt(&facilities.apps_socket, &code, 1, buffer, enc.encoded+1, 1000); + if (rv == -1) { + log_error("-> FI.message ->[applications] | id:%08x size:%dB ", + (uint32_t)iid, enc.encoded+1); + } ASN_STRUCT_FREE(asn_DEF_FacilitiesIndication, fi); } @@ -787,10 +795,12 @@ int transport_indication_btp(BTPPacketIndication_t* bpi, void** security_socket) case 7011: if (facilities.tolling.protocol.p == TOLLING_PROTOCOL_GN_SPKI) { /* do not wait for facilities process if spki */ fwd_to_apps(bpi->data.buf, bpi->data.size, bpi->destinationPort, bpi->id); + fwd = false; + } else { + fwd = true; } if (facilities.tolling.enabled) { tpm_recv(its_msg, security_socket, neighbour_cert, NULL); - fwd = facilities.tolling.protocol.p != TOLLING_PROTOCOL_GN_SPKI; } break; diff --git a/src/tpm.c b/src/tpm.c index ce2102d..34f4a1f 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -45,7 +45,7 @@ int tpm_is_inside_zone(tolling_info_t* ti) { } int tpm_should_retransmit() { - + tolling_t* tolling = &facilities.tolling; uint64_t now = itss_ts_get(TIME_MICROSECONDS); @@ -59,7 +59,7 @@ int tpm_should_retransmit() { return 1; } } - + return 0; } @@ -134,7 +134,7 @@ int tpm_pay(tolling_info_t* info, void** security_socket, uint8_t* neighbour, ui switch (info->asn->tollType) { case TollType_entry: if (tolling->station.obu.toll_type != -1 && - !tolling->station.obu.rt_on) { + !tolling->station.obu.rt_on) { log_error("[tolling] trying to issue entry.request but current tolling state is %s - resetting", tts(tolling->station.obu.toll_type)); tolling->station.obu.toll_type = -1; @@ -159,7 +159,7 @@ int tpm_pay(tolling_info_t* info, void** security_socket, uint8_t* neighbour, ui type->choice.exit->choice.request->transactionNonce = tolling->station.obu.nonce; if (tolling->station.obu.toll_type != TollingType_PR_entry && - !tolling->station.obu.rt_on) { + !tolling->station.obu.rt_on) { log_error("[tolling] trying to issue exit.request but current tolling state is %s - will not provide entry proof", tts(tolling->station.obu.toll_type)); } else { @@ -178,7 +178,7 @@ int tpm_pay(tolling_info_t* info, void** security_socket, uint8_t* neighbour, ui case TollType_single: if (tolling->station.obu.toll_type != -1 && - !tolling->station.obu.rt_on) { + !tolling->station.obu.rt_on) { log_error("[tolling] trying to issue single.request but current tolling state is %s", tts(tolling->station.obu.toll_type)); rv = 1; @@ -316,7 +316,7 @@ int tpm_pay(tolling_info_t* info, void** security_socket, uint8_t* neighbour, ui buf1[0] = 4; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf1+1, buf_len-1); - + log_debug("[tolling]-> SecurityRequest.tlsSend ->[security] | size:%ldB", enc.encoded); itss_0send(*security_socket, buf1, enc.encoded+1); int rc = itss_0recv_rt(security_socket, buf2, buf_len, buf1, enc.encoded+1, 1000); @@ -329,11 +329,11 @@ int tpm_pay(tolling_info_t* info, void** security_socket, uint8_t* neighbour, ui SecurityReply_t* srep = NULL; asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf2, buf_len); - + if (dec.code || - srep->returnCode != SecurityReplyReturnCode_accepted || - !srep->data || - srep->data->present != SecurityReplyData_PR_tlsSend) { + srep->returnCode != SecurityReplyReturnCode_accepted || + !srep->data || + srep->data->present != SecurityReplyData_PR_tlsSend) { log_error("[tolling]<- SecurityReply.tlsSend rejected"); rv = 1; goto cleanup; @@ -357,7 +357,7 @@ int tpm_pay(tolling_info_t* info, void** security_socket, uint8_t* neighbour, ui memcpy(tcp->data.buf, srep->data->choice.tlsSend.data.buf, srep->data->choice.tlsSend.data.size); if (tolling->protocol.p == TOLLING_PROTOCOL_TLS_GN || - tolling->protocol.p == TOLLING_PROTOCOL_TLS_SHS) { + tolling->protocol.p == TOLLING_PROTOCOL_TLS_SHS) { tcp->gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t)); tcp->gn->packetTransportType = PacketTransportType_shb; tcp->gn->destinationAddress.buf = calloc(1, 6); @@ -379,7 +379,7 @@ int tpm_pay(tolling_info_t* info, void** security_socket, uint8_t* neighbour, ui itss_queue_send(facilities.tx_queue, buf1, enc.encoded+1, ITSS_TRANSPORT, id, (tolling->protocol.p == TOLLING_PROTOCOL_GN_SPKI || tolling->protocol.p == TOLLING_PROTOCOL_GN_DPKI) - ? "TR.packet.btp" : "TR.packet.tcp"); + ? "TR.packet.btp" : "TR.packet.tcp"); // Retransmission uint64_t now = itss_ts_get(TIME_MICROSECONDS); @@ -458,6 +458,8 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig SecurityRequest_t* sreq = NULL; SecurityReply_t* srep = NULL; + tolling_t* tolling = &facilities.tolling; + switch (type_rx->present) { case TollingType_PR_entry: if (type_rx->choice.entry.present != TollingEntry_PR_request) { @@ -471,84 +473,89 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig case TollingType_PR_exit: if (!type_rx->choice.exit || - type_rx->choice.exit->present != TollingExit_PR_request || - !type_rx->choice.exit->choice.request - ) { + type_rx->choice.exit->present != TollingExit_PR_request || + !type_rx->choice.exit->choice.request + ) { log_error("[tolling] received TPM.exit is not request"); return; } - client_id = type_rx->choice.exit->choice.request->clientId; - nonce = type_rx->choice.exit->choice.request->transactionNonce; - info_id = type_rx->choice.exit->choice.request->infoId; - if (!type_rx->choice.exit->choice.request->entryProof) { - log_error("[tolling] received TPM.exit.request does not contain entry proof"); - return; + if (tolling->protocol.p != TOLLING_PROTOCOL_GN_DPKI) { + log_warn("[tolling] cannot cryptographically verify entryProof in mode different than GN-DPKI"); + } else { + client_id = type_rx->choice.exit->choice.request->clientId; + nonce = type_rx->choice.exit->choice.request->transactionNonce; + info_id = type_rx->choice.exit->choice.request->infoId; + + if (!type_rx->choice.exit->choice.request->entryProof) { + log_error("[tolling] received TPM.exit.request does not contain entry proof"); + return; + } + + TPM_t* ep = (TPM_t*) type_rx->choice.exit->choice.request->entryProof; + + if (!ep->tpmSignature) { + log_error("[tolling] received TPM.exit.request.entryProof does not contain signature");; + return; + } + + // Encode TollingPaymentMessage + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, ep->tpm, buf1, buf_len); + if (enc.encoded == -1) { + log_error("[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, buf1, enc.encoded); + + // r + sreq->choice.verify.r.size = ep->tpmSignature->r.size; + sreq->choice.verify.r.buf = malloc(ep->tpmSignature->r.size); + memcpy(sreq->choice.verify.r.buf, ep->tpmSignature->r.buf, ep->tpmSignature->r.size); + // s + sreq->choice.verify.s.size = ep->tpmSignature->s.size; + sreq->choice.verify.s.buf = malloc(ep->tpmSignature->s.size); + memcpy(sreq->choice.verify.s.buf, ep->tpmSignature->s.buf, ep->tpmSignature->s.size); + // signer + sreq->choice.verify.signer.size = ep->tpmSignature->signer.size; + sreq->choice.verify.signer.buf = malloc(ep->tpmSignature->signer.size); + memcpy(sreq->choice.verify.signer.buf, ep->tpmSignature->signer.buf, ep->tpmSignature->signer.size); + // signature type + sreq->choice.verify.type = ep->tpmSignature->type; + + buf1[0] = 4; + enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf1+1, buf_len-1); + log_debug("->[security] SecurityRequest.verify (%ldB)", enc.encoded+1); + itss_0send(*security_socket, buf1, enc.encoded+1); + int32_t rl = itss_0recv_rt(security_socket, buf2, buf_len, buf1, enc.encoded+1, 1000); + log_debug("<-[security] SecurityReply.verify (%dB)", rl); + + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf2, rl).code) { + log_error("SecurityReply.verify decode failure"); + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + log_error("SecurityReply.verify rejected"); + goto cleanup; + } + + if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { + log_debug("entry proof signature verify failed"); + goto cleanup; + } + + ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); + ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); + sreq = NULL; + srep = NULL; } - - TPM_t* ep = (TPM_t*) type_rx->choice.exit->choice.request->entryProof; - - if (!ep->tpmSignature) { - log_error("[tolling] received TPM.exit.request.entryProof does not contain signature");; - return; - } - - // Encode TollingPaymentMessage - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, ep->tpm, buf1, buf_len); - if (enc.encoded == -1) { - log_error("[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, buf1, enc.encoded); - - // r - sreq->choice.verify.r.size = ep->tpmSignature->r.size; - sreq->choice.verify.r.buf = malloc(ep->tpmSignature->r.size); - memcpy(sreq->choice.verify.r.buf, ep->tpmSignature->r.buf, ep->tpmSignature->r.size); - // s - sreq->choice.verify.s.size = ep->tpmSignature->s.size; - sreq->choice.verify.s.buf = malloc(ep->tpmSignature->s.size); - memcpy(sreq->choice.verify.s.buf, ep->tpmSignature->s.buf, ep->tpmSignature->s.size); - // signer - sreq->choice.verify.signer.size = ep->tpmSignature->signer.size; - sreq->choice.verify.signer.buf = malloc(ep->tpmSignature->signer.size); - memcpy(sreq->choice.verify.signer.buf, ep->tpmSignature->signer.buf, ep->tpmSignature->signer.size); - // signature type - sreq->choice.verify.type = ep->tpmSignature->type; - - buf1[0] = 4; - enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf1+1, buf_len-1); - log_debug("->[security] SecurityRequest.verify (%ldB)", enc.encoded+1); - itss_0send(*security_socket, buf1, enc.encoded+1); - int32_t rl = itss_0recv_rt(security_socket, buf2, buf_len, buf1, enc.encoded+1, 1000); - log_debug("<-[security] SecurityReply.verify (%dB)", rl); - - if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf2, rl).code) { - log_error("SecurityReply.verify decode failure"); - goto cleanup; - } - - if (srep->returnCode == SecurityReplyReturnCode_rejected) { - log_error("SecurityReply.verify rejected"); - goto cleanup; - } - - if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { - log_debug("entry proof signature verify failed"); - goto cleanup; - } - - ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); - ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); - sreq = NULL; - srep = NULL; break; case TollingType_PR_single: @@ -566,28 +573,27 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig return; } - tolling_t* tolling = &facilities.tolling; switch (tolling->protocol.p) { case TOLLING_PROTOCOL_GN_SPKI: case TOLLING_PROTOCOL_GN_DPKI: log_info("[tolling] received toll %s.request | client: %lld (certificate id: 0x%02x%02x%02x) nonce: %lld", - tts(type_rx->present), - (long long) client_id, - neighbour ? neighbour[5] : 0, - neighbour ? neighbour[6] : 0, - neighbour ? neighbour[7] : 0, - (long long) nonce - ); + tts(type_rx->present), + (long long) client_id, + neighbour ? neighbour[5] : 0, + neighbour ? neighbour[6] : 0, + neighbour ? neighbour[7] : 0, + (long long) nonce + ); break; case TOLLING_PROTOCOL_TLS: case TOLLING_PROTOCOL_TLS_GN: case TOLLING_PROTOCOL_TLS_SHS: log_info("[tolling] received toll %s.request | client: %lld nonce: %lld", - tts(type_rx->present), - (long long) client_id, - (long long) nonce - ); + tts(type_rx->present), + (long long) client_id, + (long long) nonce + ); break; } @@ -706,7 +712,7 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig free(tolling->station.rsu.clients[i]); tolling->station.rsu.clients[i] = NULL; for (int j = i; j < tolling->station.rsu.clients_len-1; ++j) { - tolling->station.rsu.clients[j] = tolling->station.rsu.clients[j+1]; + tolling->station.rsu.clients[j] = tolling->station.rsu.clients[j+1]; } --tolling->station.rsu.clients_len; } @@ -736,11 +742,11 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig uint8_t confirmation_code = TollingConfirmationCode_rejected; if (itss_time_get() > client->ts + TOLLING_PAYMENT_MIN_PERIOD_MS || - client->accepted == -1) { + client->accepted == -1) { confirmation_code = TollingConfirmationCode_accepted; client->accepted = true; } else if (client->accepted && - itss_time_get() < client->ts + TOLLING_PAYMENT_MIN_PERIOD_MS) { + itss_time_get() < client->ts + TOLLING_PAYMENT_MIN_PERIOD_MS) { confirmation_code = TollingConfirmationCode_alreadyAccepted; } @@ -776,7 +782,7 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig } // TODO check clientId - + // Encode TollingPaymentMessage enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, tpm->tpm, buf1, buf_len); if (enc.encoded == -1) { @@ -784,6 +790,7 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig goto cleanup; } + if (tolling->protocol.p == TOLLING_PROTOCOL_GN_DPKI) { // Sign sreq = calloc(1, sizeof(SecurityRequest_t)); sreq->present = SecurityRequest_PR_sign; @@ -828,6 +835,7 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); sreq = NULL; srep = NULL; + } // encode TPM enc = uper_encode_to_buffer(&asn_DEF_TPM, NULL, tpm, tpm_uper, buf_len); @@ -903,7 +911,7 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig buf1[0] = 4; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf1+1, buf_len-1); - + log_debug("[tolling]-> SecurityRequest.tlsSend ->[security] | size:%ldB", enc.encoded); itss_0send(*security_socket, buf1, enc.encoded+1); int rc = itss_0recv_rt(security_socket, buf2, buf_len, buf1, enc.encoded+1, 1000); @@ -916,9 +924,9 @@ static void rsu_handle_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neig asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf2, rc); if (dec.code || - srep->returnCode != SecurityReplyReturnCode_accepted || - !srep->data || - srep->data->present != SecurityReplyData_PR_tlsSend) { + srep->returnCode != SecurityReplyReturnCode_accepted || + !srep->data || + srep->data->present != SecurityReplyData_PR_tlsSend) { log_error("[tolling]<- SecurityReply.tlsSend rejected"); goto cleanup; } @@ -1055,8 +1063,8 @@ static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void** security_s case TollingType_PR_exit: if (!type_rx->choice.exit || - type_rx->choice.exit->present != TollingExit_PR_reply - ) { + type_rx->choice.exit->present != TollingExit_PR_reply + ) { log_error("[tolling] received TPM.exit is not reply"); return; } @@ -1183,8 +1191,8 @@ static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void** security_s // Close TCP & TLS conn if (tolling->protocol.p == TOLLING_PROTOCOL_TLS || - tolling->protocol.p == TOLLING_PROTOCOL_TLS_GN || - tolling->protocol.p == TOLLING_PROTOCOL_TLS_SHS) { + tolling->protocol.p == TOLLING_PROTOCOL_TLS_GN || + tolling->protocol.p == TOLLING_PROTOCOL_TLS_SHS) { tlsc_t* tlsc = tolling_tlsc_get(src_addr, 7011); if (tlsc) { sreq = calloc(1, sizeof(SecurityRequest_t)); @@ -1282,7 +1290,7 @@ int tpm_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neighbour, uint8_t* break; } break; - // Exit + // Exit case TollingType_PR_exit: if (!tpm_rx->tpm->tollingType->choice.exit) { return 1; @@ -1310,7 +1318,7 @@ int tpm_recv(TPM_t* tpm_rx, void** security_socket, uint8_t* neighbour, uint8_t* break; } break; - // Single + // Single case TollingType_PR_single: switch (tpm_rx->tpm->tollingType->choice.single.present) { case TollingSingle_PR_request: @@ -1365,7 +1373,7 @@ int tolling_init(uint8_t station_type) { tolling_info_t* tolling_info_new(TollingPaymentInfo_t* tpi) { tolling_info_t* ti = calloc(1, sizeof(tolling_info_t)); - + ti->timestamp = itss_time_get(); ti->asn = tpi; @@ -1445,7 +1453,7 @@ void tolling_tlsc_mgmt(itss_queue_t* tx_queue, void** security_socket) { itss_0send(*security_socket, buf1, enc.encoded+1); int32_t rl = itss_0recv_rt(security_socket, buf2, buf_len, buf1, enc.encoded+1, 1000); log_debug("<-[security] SecurityReply.tlsClose (%dB)", rl); - + uint64_t id = rand() + 1; tr = calloc(1, sizeof(TransportRequest_t)); tr->present = TransportRequest_PR_data;