From dccfe255480c5eb9c9f89d58111b3efe704ea6d7 Mon Sep 17 00:00:00 2001 From: emanuel Date: Wed, 22 Jun 2022 11:16:26 +0100 Subject: [PATCH] TCP&TLS close efforts --- src/config.c | 6 +-- src/facilities.c | 12 ++++- src/indications.c | 2 +- src/saem.c | 4 +- src/tpm.c | 124 ++++++++++++++++++++++++++++++++++++---------- src/tpm.h | 31 +++++++++++- 6 files changed, 143 insertions(+), 36 deletions(-) diff --git a/src/config.c b/src/config.c index 987bf92..15bd1c3 100644 --- a/src/config.c +++ b/src/config.c @@ -308,12 +308,12 @@ int facilities_config(void* facilities_s) { // TPM facilities->tolling.enabled = config->facilities.tpm.activate; if (!strcmp("simple", config->facilities.tpm.protocol)) { - facilities->tolling.protocol = TOLLING_PROTOCOL_SIMPLE; + facilities->tolling.protocol.p = TOLLING_PROTOCOL_SIMPLE; } else if (!strcmp("tls", config->facilities.tpm.protocol)) { - facilities->tolling.protocol = TOLLING_PROTOCOL_TLS; + facilities->tolling.protocol.p = TOLLING_PROTOCOL_TLS; } else { syslog_err("[facilities] [config] unrecognized tolling protocol, defaulting to 'simple'"); - facilities->tolling.protocol = TOLLING_PROTOCOL_SIMPLE; + facilities->tolling.protocol.p = TOLLING_PROTOCOL_SIMPLE; } facilities->tolling.station.obu.client_id = config->facilities.tpm.client_id; diff --git a/src/facilities.c b/src/facilities.c index 21de462..c1d65d7 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -146,7 +146,7 @@ static int transport_indication(facilities_t *facilities, void* responder, void* break; default: - syslog_debug("[facilities] messsage with unhandled BTP port received (%ld), ignoring", tpi->choice.btp.destinationPort); + syslog_debug("[facilities] messsage with unhandled BTP port received (%lld), ignoring", tpi->choice.btp.destinationPort); goto cleanup; } @@ -255,6 +255,7 @@ static int transport_indication(facilities_t *facilities, void* responder, void* break; } break; + case TransportPacketIndication_PR_tcp: id = tpi->choice.tcp.id; packet = tpi->choice.tcp.data.buf; @@ -267,6 +268,15 @@ static int transport_indication(facilities_t *facilities, void* responder, void* sreq->choice.tlsRecv.data.buf = malloc(tpi->choice.tcp.data.size); memcpy(sreq->choice.tlsRecv.data.buf, tpi->choice.tcp.data.buf, tpi->choice.tcp.data.size); + tlsc_t* tlsc = tolling_tlsc_get(&facilities->tolling, tpi->choice.tcp.sourceAddress->buf, 7011); + if (tlsc) { + id = tlsc->id; + } else { + tlsc = tolling_tlsc_new(&facilities->tolling, tpi->choice.tcp.sourceAddress->buf, 7011); + id = tlsc->id; + } + sreq->choice.tlsSend.connId = id; + uint8_t b_sdu[2048]; b_sdu[0] = 4; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, b_sdu+1, 2047); diff --git a/src/indications.c b/src/indications.c index c9e02f7..203945c 100644 --- a/src/indications.c +++ b/src/indications.c @@ -12,7 +12,7 @@ static void tcp_conn_reset(facilities_t* facilities, TCPConnRSTInfo_t* cri, void // Reset tolling, tls tolling_t* tolling = &facilities->tolling; bulletin_t* bulletin = &facilities->bulletin; - if (tolling->enabled && tolling->protocol == TOLLING_PROTOCOL_TLS) { + if (tolling->enabled && tolling->protocol.p == TOLLING_PROTOCOL_TLS) { for (int i = 0; i < bulletin->to_consume_len; ++i) { if (!memcmp(bulletin->to_consume[i]->endpoint.ipv6_addr, cri->destinationAddress.buf, 16)) { sreq = calloc(1, sizeof(SecurityRequest_t)); diff --git a/src/saem.c b/src/saem.c index 610c25d..9472f1b 100644 --- a/src/saem.c +++ b/src/saem.c @@ -187,7 +187,7 @@ int mk_saem(facilities_t* facilities, uint8_t* b_saem, uint32_t* b_saem_len) { ServiceInfoExts_t* exts = saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions; - switch (facilities->tolling.protocol) { + switch (facilities->tolling.protocol.p) { case TOLLING_PROTOCOL_SIMPLE: exts->list.count = 3; exts->list.size = 3 * sizeof(void*); @@ -387,7 +387,7 @@ void *sa_service(void *fc) { continue; } - switch (facilities->tolling.protocol) { + switch (facilities->tolling.protocol.p) { case TOLLING_PROTOCOL_SIMPLE: tpm_pay(facilities, info, security_socket, bulletin->to_consume[a]->certificate_id, NULL); ++bulletin->to_consume[a]->n_trigger; diff --git a/src/tpm.c b/src/tpm.c index 6ac27a8..e66e4e8 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -171,7 +171,7 @@ int tpm_pay(void* fc, tolling_info_t* info, void* security_socket, uint8_t* neig goto cleanup; } - if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) { + if (tolling->protocol.p == TOLLING_PROTOCOL_SIMPLE) { // Sign sreq = calloc(1, sizeof(SecurityRequest_t)); sreq->present = SecurityRequest_PR_sign; @@ -226,7 +226,7 @@ int tpm_pay(void* fc, tolling_info_t* info, void* security_socket, uint8_t* neig uint64_t id = 0; - switch (facilities->tolling.protocol) { + switch (facilities->tolling.protocol.p) { case TOLLING_PROTOCOL_SIMPLE: tr->choice.packet.present = TransportPacketRequest_PR_btp; BTPPacketRequest_t* bpr = &tr->choice.packet.choice.btp; @@ -256,17 +256,22 @@ int tpm_pay(void* fc, tolling_info_t* info, void* security_socket, uint8_t* neig bpr->gn.trafficClass = 2; bpr->gn.packetTransportType = PacketTransportType_shb; break; + case TOLLING_PROTOCOL_TLS: sreq = calloc(1, sizeof(SecurityRequest_t)); sreq->present = SecurityRequest_PR_tlsSend; sreq->choice.tlsSend.data.buf = malloc(tpm_uper_len); sreq->choice.tlsSend.data.size = tpm_uper_len; memcpy(sreq->choice.tlsSend.data.buf, tpm_uper, tpm_uper_len); - id = rand() + 1; - if (!tolling->station.obu.tls_conn_id) { - tolling->station.obu.tls_conn_id = id; + + tlsc_t* tlsc = tolling_tlsc_get(tolling, dst_addr, 7011); + if (tlsc) { + id = tlsc->id; + } else { + tlsc = tolling_tlsc_new(tolling, dst_addr, 7011); + id = tlsc->id; } - sreq->choice.tlsSend.connId = tolling->station.obu.tls_conn_id; + sreq->choice.tlsSend.connId = id; buf[0] = 4; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, buf_len-1); @@ -329,7 +334,7 @@ int tpm_pay(void* fc, tolling_info_t* info, void* security_socket, uint8_t* neig } it2s_tender_queue_send(facilities->tx_queue, buf, enc.encoded+1, ITSS_TRANSPORT, id, - tolling->protocol == TOLLING_PROTOCOL_SIMPLE ? "TR.packet.btp" : "TR.packet.tcp"); + tolling->protocol.p == TOLLING_PROTOCOL_SIMPLE ? "TR.packet.btp" : "TR.packet.tcp"); // Logging if (facilities->logging.dbms) { @@ -437,7 +442,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur tolling_t* tolling = &facilities->tolling; - switch (tolling->protocol) { + switch (tolling->protocol.p) { case TOLLING_PROTOCOL_SIMPLE: syslog_info("[facilities] [tolling] received toll %s.request | client: %lld (certificate id: 0x%02x%02x%02x) nonce: %lld", tts(type_rx->present), @@ -468,7 +473,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur FacilitiesIndication_t* fi = NULL; TPM_t* tpm = NULL; - if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) { + if (tolling->protocol.p == TOLLING_PROTOCOL_SIMPLE) { if (!tpm_rx->tpmSignature) { syslog_err("[facilities] [tolling] in simple mode but TPM without signature received"); @@ -610,7 +615,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur goto cleanup; } - if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) { + if (tolling->protocol.p == TOLLING_PROTOCOL_SIMPLE) { // Sign sreq = calloc(1, sizeof(SecurityRequest_t)); sreq->present = SecurityRequest_PR_sign; @@ -661,7 +666,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur tr->present = TransportRequest_PR_packet; // [transport] request (TR) - switch (tolling->protocol) { + switch (tolling->protocol.p) { case TOLLING_PROTOCOL_SIMPLE: tr->choice.packet.present = TransportPacketRequest_PR_btp; BTPPacketRequest_t* bpr = &tr->choice.packet.choice.btp; @@ -700,12 +705,15 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur sreq->choice.tlsSend.data.buf = malloc(tpm_uper_len); sreq->choice.tlsSend.data.size = tpm_uper_len; memcpy(sreq->choice.tlsSend.data.buf, tpm_uper, tpm_uper_len); - id = rand() + 1; - // TODO handle various vehicles - if (!tolling->station.rsu.tls_conn_id) { - tolling->station.rsu.tls_conn_id = id; + + tlsc_t* tlsc = tolling_tlsc_get(tolling, src_addr, 7011); + if (tlsc) { + id = tlsc->id; + } else { + tlsc = tolling_tlsc_new(tolling, src_addr, 7011); + id = tlsc->id; } - sreq->choice.tlsSend.connId = tolling->station.rsu.tls_conn_id; + sreq->choice.tlsSend.connId = id; buf[0] = 4; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, buf_len-1); @@ -764,7 +772,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur } it2s_tender_queue_send(facilities->tx_queue, buf, enc.encoded+1, ITSS_TRANSPORT, id, - tolling->protocol == TOLLING_PROTOCOL_SIMPLE ? "TR.packet.btp" : "TR.packet.tcp"); + tolling->protocol.p == TOLLING_PROTOCOL_SIMPLE ? "TR.packet.btp" : "TR.packet.tcp"); // Logging if (facilities->logging.dbms) { @@ -814,7 +822,7 @@ cleanup: ASN_STRUCT_FREE(asn_DEF_FacilitiesIndication, fi); } -static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour) { +static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void* security_socket, it2s_tender_queue_t* tx_queue, uint8_t* neighbour, uint8_t* src_addr) { if (!tpm_rx->tpm->tollingType) { syslog_err("[facilities] [tolling] received TPM does not have a type"); @@ -826,6 +834,13 @@ static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void* security_so uint64_t client_id, nonce, info_id; int confirmation_code; + SecurityRequest_t* sreq = NULL; + SecurityReply_t* srep = NULL; + TransportRequest_t* tr = NULL; + + const uint16_t buf_len = 1024; + uint8_t buf[buf_len]; + switch (type_rx->present) { case TollingType_PR_entry: if (type_rx->choice.entry.present != TollingEntry_PR_reply) { @@ -898,11 +913,6 @@ static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void* security_so 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); @@ -912,7 +922,7 @@ static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void* security_so } bool accepted = true; - if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) { + if (tolling->protocol.p == TOLLING_PROTOCOL_SIMPLE) { // Verify sreq = calloc(1, sizeof(SecurityRequest_t)); sreq->present = SecurityRequest_PR_verify; @@ -983,6 +993,41 @@ static void veh_handle_recv(tolling_t* tolling, TPM_t* tpm_rx, void* security_so break; } + // Close TCP & TLS conn + if (tolling->protocol.p == TOLLING_PROTOCOL_TLS) { + tlsc_t* tlsc = tolling_tlsc_get(tolling, src_addr, 7011); + if (tlsc) { + sreq = calloc(1, sizeof(SecurityRequest_t)); + sreq->present = SecurityRequest_PR_tlsClose; + sreq->choice.tlsClose.connId = tlsc->id; + + buf[0] = 4; + enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, buf_len-1); + syslog_debug("[facilities]->[security] SecurityRequest.tlsClose (%ldB)", enc.encoded+1); + zmq_send(security_socket, buf, enc.encoded+1, 0); + int32_t rl = zmq_recv(security_socket, buf, buf_len, 0); + syslog_debug("[facilities]<-[security] SecurityReply.tlsClose (%dB)", rl); + } else { + syslog_debug("[facilities] [tolling] unable to close TLS connection, not found"); + } + + uint64_t id = rand() + 1; + tr = calloc(1, sizeof(TransportRequest_t)); + tr->present = TransportRequest_PR_data; + tr->choice.data.present = TransportDataRequest_PR_tcp; + tr->choice.data.choice.tcp.present = TCPDataRequest_PR_connCloseReq; + tr->choice.data.choice.tcp.choice.connCloseReq.closeByPeer = false; + tr->choice.data.choice.tcp.choice.connCloseReq.destinationPort = 7011; + tr->choice.data.choice.tcp.choice.connCloseReq.destinationAddress.size = 16; + tr->choice.data.choice.tcp.choice.connCloseReq.destinationAddress.buf = malloc(16); + memcpy(tr->choice.data.choice.tcp.choice.connCloseReq.destinationAddress.buf, src_addr, 16); + tr->choice.data.choice.tcp.choice.connCloseReq.id = id; + + buf[0] = 4; + enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, sreq, buf+1, buf_len-1); + it2s_tender_queue_send(tx_queue, buf, enc.encoded+1, ITSS_TRANSPORT, id, "TR.data.tcp.connClose"); + } + cleanup: ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); @@ -1028,7 +1073,7 @@ int tpm_recv(void* fc, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour, pthread_mutex_lock(&facilities->epv.time.lock); syslog_info("[facilities] [tolling] entry.reply took %ld us", it2s_tender_get_now(TIME_MICROSECONDS) - tolling->tz); pthread_mutex_unlock(&facilities->epv.time.lock); - veh_handle_recv(tolling, tpm_rx, security_socket, neighbour); + veh_handle_recv(tolling, tpm_rx, security_socket, facilities->tx_queue, neighbour, src_addr); break; default: break; @@ -1055,7 +1100,7 @@ int tpm_recv(void* fc, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour, pthread_mutex_lock(&facilities->epv.time.lock); syslog_info("[facilities] [tolling] exit.reply took %ld us", it2s_tender_get_now(TIME_MICROSECONDS) - tolling->tz); pthread_mutex_unlock(&facilities->epv.time.lock); - veh_handle_recv(tolling, tpm_rx, security_socket, neighbour); + veh_handle_recv(tolling, tpm_rx, security_socket, facilities->tx_queue, neighbour, src_addr); break; default: break; @@ -1079,7 +1124,7 @@ int tpm_recv(void* fc, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour, pthread_mutex_lock(&facilities->epv.time.lock); syslog_info("[facilities] [tolling] single.reply took %ld us", it2s_tender_get_now(TIME_MICROSECONDS) - tolling->tz); pthread_mutex_unlock(&facilities->epv.time.lock); - veh_handle_recv(tolling, tpm_rx, security_socket, neighbour); + veh_handle_recv(tolling, tpm_rx, security_socket, facilities->tx_queue, neighbour, src_addr); break; default: break; @@ -1126,3 +1171,28 @@ void tolling_info_free(tolling_info_t* ti) { free(ti->zone.polygon); free(ti); } + +tlsc_t* tolling_tlsc_new(tolling_t* tolling, uint8_t ipv6[16], uint16_t port) { + if (tolling->protocol.c.tls.n_tlsc >= TOLLING_MAX_CONNS - 1) { + return NULL; + } + tolling->protocol.c.tls.tls_conns[tolling->protocol.c.tls.n_tlsc] = calloc(1, sizeof(tlsc_t)); + tlsc_t* tlsc = tolling->protocol.c.tls.tls_conns[tolling->protocol.c.tls.n_tlsc]; + memcpy(tlsc->ipv6, ipv6, 16); + tlsc->port = port; + tlsc->id = rand(); + ++tolling->protocol.c.tls.n_tlsc; + return tlsc; +} + +tlsc_t* tolling_tlsc_get(tolling_t* tolling, uint8_t ipv6[16], uint16_t port) { + tlsc_t* tlsc = NULL; + for (int i = 0; i < tolling->protocol.c.tls.n_tlsc; ++i) { + if (!memcmp(tolling->protocol.c.tls.tls_conns[i]->ipv6, ipv6, 16) && + tolling->protocol.c.tls.tls_conns[i]->port == port) { + tlsc = tolling->protocol.c.tls.tls_conns[i]; + break; + } + } + return tlsc; +} diff --git a/src/tpm.h b/src/tpm.h index 9ef3054..4c16ca4 100644 --- a/src/tpm.h +++ b/src/tpm.h @@ -7,6 +7,7 @@ #define TOLLING_INFOS_MAX_LENGTH 16 #define TOLLING_PAYMENT_MIN_PERIOD_MS 60000 +#define TOLLING_MAX_CONNS 24 typedef enum TOLLING_PROTOCOL { TOLLING_PROTOCOL_SIMPLE, @@ -22,14 +23,37 @@ typedef struct tolling_info { TollingPaymentInfo_t* asn; } tolling_info_t; +/** + * TLS connections + */ +typedef struct tlsc { + uint8_t ipv6[16]; + uint16_t port; + uint64_t id; + uint64_t t_used; +} tlsc_t; + typedef struct tolling { bool enabled; - TOLLING_PROTOCOL_e protocol; + + struct { + TOLLING_PROTOCOL_e p; + union { + // Simple + struct { + } simple; + + // TLS + struct { + tlsc_t* tls_conns[TOLLING_MAX_CONNS]; + uint8_t n_tlsc; + } tls; + } c; + } protocol; union { // RSU struct { - uint64_t tls_conn_id; } rsu; // OBU @@ -68,3 +92,6 @@ int tpm_is_inside_zone(void* fc, tolling_info_t* ti); tolling_info_t* tolling_info_new(it2s_tender_epv_t* epv, TollingPaymentInfo_t* tpi); void tolling_info_free(tolling_info_t* ti); + +tlsc_t* tolling_tlsc_new(tolling_t* tolling, uint8_t ipv6[16], uint16_t port); +tlsc_t* tolling_tlsc_get(tolling_t* tolling, uint8_t ipv6[16], uint16_t port);