TCP&TLS close efforts

This commit is contained in:
emanuel 2022-06-22 11:16:26 +01:00
parent 7365019e70
commit dccfe25548
6 changed files with 143 additions and 36 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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;

124
src/tpm.c
View File

@ -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;
}

View File

@ -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);