TPM for TLS

This commit is contained in:
emanuel 2022-04-19 12:25:59 +01:00
parent 4178fafbad
commit 5e1f612c03
4 changed files with 392 additions and 311 deletions

View File

@ -226,7 +226,7 @@ static int transport_indication(facilities_t *facilities, void* responder, void*
case 7011:
if (facilities->tolling.active) {
tpm_recv(facilities, its_msg, neighbour_cert);
tpm_recv(facilities, its_msg, security_socket, neighbour_cert, NULL, 0);
}
break;
@ -274,13 +274,6 @@ static int transport_indication(facilities_t *facilities, void* responder, void*
goto cleanup;
}
printf("n=%ld\n",srep->data->choice.tlsRecv.data.size);
for (int m = 0; m < srep->data->choice.tlsRecv.data.size; ++m) {
printf("%02x", srep->data->choice.tlsRecv.data.buf[m]);
}
printf("\n");
fflush(stdout);
// Forward to [transport]
if (srep->data->choice.tlsRecv.initializing) {
tr = calloc(1, sizeof(TransportRequest_t));
@ -316,12 +309,18 @@ static int transport_indication(facilities_t *facilities, void* responder, void*
it2s_tender_queue_send(facilities->tx_queue, buf, enc.encoded+1, ITSS_TRANSPORT, id, "TR.packet.tcp");
} else {
printf("tls message = ");
for (int m = 0; m < srep->data->choice.tlsRecv.data.size; ++m) {
printf("%c", srep->data->choice.tlsRecv.data.buf[m]);
if (facilities->tolling.active) {
dec = uper_decode_complete(NULL, &asn_DEF_TPM, (void**) &its_msg, tpi->choice.tcp.data.buf, tpi->choice.tcp.data.size);
if (dec.code) {
syslog_debug("[facilities]<- invalid %s received", its_msg_descriptor->name);
rv = 1;
goto cleanup;
}
if (!dec.code) {
tpm_recv(facilities, its_msg, security_socket, NULL, tpi->choice.tcp.sourceAddress->buf, tpi->choice.tcp.sourcePort);
}
}
printf("\n");
fflush(stdout);
}
break;

View File

@ -389,75 +389,15 @@ void *sa_service(void *fc) {
switch (facilities->tolling.protocol) {
case TOLLING_PROTOCOL_SIMPLE:
tpm_pay(facilities, info, bulletin->to_consume[a]->certificate_id);
tpm_pay(facilities, info, security_socket, bulletin->to_consume[a]->certificate_id, NULL, 0);
++bulletin->to_consume[a]->n_trigger;
bulletin->to_consume[a]->t_trigger = now;
break;
case TOLLING_PROTOCOL_TLS:;
SecurityRequest_t* sreq = calloc(1, sizeof(SecurityRequest_t));
sreq->present = SecurityRequest_PR_tlsSend;
sreq->choice.tlsSend.data.buf = malloc(7);
sreq->choice.tlsSend.data.size = 7;
char hello[] = "Hello!";
memcpy(sreq->choice.tlsSend.data.buf, hello, 7);
uint8_t buffer[1024];
buffer[0] = 4;
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buffer+1, 1023);
ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq);
syslog_debug("[facilities] [sa]-> SecurityRequest.tlsSend ->[security]");
zmq_send(security_socket, buffer, enc.encoded, 0);
zmq_recv(security_socket, buffer, 1024, 0);
syslog_debug("[facilities] [sa]<- SecurityReply <-[security]");
SecurityReply_t* srep = NULL;
asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buffer, 1024);
if (dec.code || srep->returnCode != SecurityReplyReturnCode_accepted) {
ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep);
continue;
}
TransportRequest_t* tr_etc = calloc(1, sizeof(TransportRequest_t));
tr_etc->present = TransportRequest_PR_packet;
TransportPacketRequest_t* tpr_etc = &tr_etc->choice.packet;
tpr_etc->present = TransportPacketRequest_PR_tcp;
tpr_etc->choice.tcp.destinationAddress = calloc(1, sizeof(OCTET_STRING_t));
tpr_etc->choice.tcp.destinationAddress->buf = malloc(16);
tpr_etc->choice.tcp.destinationAddress->size = 16;
memcpy(tpr_etc->choice.tcp.destinationAddress->buf, bulletin->to_consume[a]->endpoint.ipv6_addr, 16);
tpr_etc->choice.tcp.destinationPort = bulletin->to_consume[a]->endpoint.port;
tpr_etc->choice.tcp.sourcePort = 7011;
tpr_etc->choice.tcp.data.buf = malloc(srep->data->choice.tlsSend.data.size);
tpr_etc->choice.tcp.data.size = srep->data->choice.tlsSend.data.size;
memcpy(tpr_etc->choice.tcp.data.buf, srep->data->choice.tlsSend.data.buf, srep->data->choice.tlsSend.data.size);
ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep);
tpr_etc->choice.tcp.gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t));
tpr_etc->choice.tcp.gn->packetTransportType = PacketTransportType_shb;
tpr_etc->choice.tcp.gn->destinationAddress.buf = calloc(1, 6);
tpr_etc->choice.tcp.gn->destinationAddress.size = 6;
tpr_etc->choice.tcp.id = rand() + 1;
case TOLLING_PROTOCOL_TLS:
tpm_pay(facilities, info, security_socket, NULL, bulletin->to_consume[a]->endpoint.ipv6_addr, bulletin->to_consume[a]->endpoint.port);
++bulletin->to_consume[a]->n_trigger;
enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr_etc, tr_oer+1, 1023);
if (enc.encoded == -1) {
syslog_err("[facilities] encoding TR for ETC-Req failed");
continue;
} else {
it2s_tender_queue_send(facilities->tx_queue, tr_oer, enc.encoded+1, ITSS_TRANSPORT, tpr_etc->choice.tcp.id, "TR.packet.tcp");
}
ASN_STRUCT_FREE(asn_DEF_TransportRequest, tr_etc);
bulletin->to_consume[a]->t_trigger = now;
break;
}
}

305
src/tpm.c
View File

@ -29,7 +29,7 @@ int tpm_is_inside_zone(void* fc, tolling_info_s* ti) {
return 0;
}
int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
int tpm_pay(void* fc, tolling_info_s* info, void* security_socket, uint8_t* neighbour, uint8_t* dst_addr, uint16_t dst_port) {
int rv = 0;
facilities_t* facilities = (facilities_t*) fc;
@ -45,6 +45,7 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
TPM_t* tpm = NULL;
const size_t buf_len = 2048;
uint8_t tpm_uper[buf_len];
uint8_t buf[buf_len];
if (!tolling->enabled) {
@ -83,6 +84,7 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
goto cleanup;
}
if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) {
// Sign
sreq = calloc(1, sizeof(SecurityRequest_t));
sreq->present = SecurityRequest_PR_sign;
@ -93,8 +95,8 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
buf[0] = 4;
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(tolling->security_socket, buf, enc.encoded+1, 0);
int32_t rl = zmq_recv(tolling->security_socket, buf, buf_len, 0);
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.sign (%dB)", rl);
if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) {
@ -109,19 +111,21 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
goto cleanup;
}
tpm->signature.r.size = srep->data->choice.sign.r.size;
tpm->signature.r.buf = malloc(srep->data->choice.sign.r.size);
memcpy(tpm->signature.r.buf, srep->data->choice.sign.r.buf, srep->data->choice.sign.r.size);
tpm->signature.s.size = srep->data->choice.sign.s.size;
tpm->signature.s.buf = malloc(srep->data->choice.sign.s.size);
memcpy(tpm->signature.s.buf, srep->data->choice.sign.s.buf, srep->data->choice.sign.s.size);
tpm->signature.signer.size = srep->data->choice.sign.signer.size;
tpm->signature.signer.buf = malloc(srep->data->choice.sign.signer.size);
memcpy(tpm->signature.signer.buf, srep->data->choice.sign.signer.buf, srep->data->choice.sign.signer.size);
tpm->signature.type = srep->data->choice.sign.type;
tpm->signature = calloc(1, sizeof(TpmSignature_t));
tpm->signature->r.size = srep->data->choice.sign.r.size;
tpm->signature->r.buf = malloc(srep->data->choice.sign.r.size);
memcpy(tpm->signature->r.buf, srep->data->choice.sign.r.buf, srep->data->choice.sign.r.size);
tpm->signature->s.size = srep->data->choice.sign.s.size;
tpm->signature->s.buf = malloc(srep->data->choice.sign.s.size);
memcpy(tpm->signature->s.buf, srep->data->choice.sign.s.buf, srep->data->choice.sign.s.size);
tpm->signature->signer.size = srep->data->choice.sign.signer.size;
tpm->signature->signer.buf = malloc(srep->data->choice.sign.signer.size);
memcpy(tpm->signature->signer.buf, srep->data->choice.sign.signer.buf, srep->data->choice.sign.signer.size);
tpm->signature->type = srep->data->choice.sign.type;
}
// Encode TPM
enc = uper_encode_to_buffer(&asn_DEF_TPM, NULL, tpm, buf, buf_len);
enc = uper_encode_to_buffer(&asn_DEF_TPM, NULL, tpm, tpm_uper, buf_len);
if (enc.encoded == -1) {
syslog_err("[facilities] [tolling] error encoding TPM.request (%s)", enc.failed_type->name);
rv = 1;
@ -132,10 +136,16 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
// [transport] request (TR)
tr = calloc(1, sizeof(TransportRequest_t));
tr->present = TransportRequest_PR_packet;
uint64_t id = 0;
switch (facilities->tolling.protocol) {
case TOLLING_PROTOCOL_SIMPLE:
tr->choice.packet.present = TransportPacketRequest_PR_btp;
BTPPacketRequest_t* bpr = &tr->choice.packet.choice.btp;
bpr->id = rand() + 1;
id = bpr->id;
bpr->gn.securityProfile.encrypt = true;
bpr->gn.securityProfile.sign = true;
@ -147,7 +157,7 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
bpr->data.size = tpm_uper_len;
bpr->data.buf = malloc(tpm_uper_len);
memcpy(bpr->data.buf, buf, tpm_uper_len);
memcpy(bpr->data.buf, tpm_uper, tpm_uper_len);
bpr->destinationPort = 7011;
bpr->btpType = BTPType_btpB;
@ -158,6 +168,64 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
bpr->gn.destinationAddress.size = 6;
bpr->gn.trafficClass = 2;
bpr->gn.packetTransportType = PacketTransportType_shb;
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);
buf[0] = 4;
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, buf_len-1);
syslog_debug("[facilities] [tolling]-> SecurityRequest.tlsSend ->[security]");
zmq_send(security_socket, buf, enc.encoded, 0);
int rc = zmq_recv(security_socket, buf, buf_len, 0);
if (rc == -1) {
syslog_err("[facilities] [tolling]-> SecurityRequest.tlsSend ->[security] <TIMEOUT>");
rv = 1;
goto cleanup;
}
syslog_debug("[facilities] [tolling]<- SecurityReply.tlsSend <-[security]");
SecurityReply_t* srep = NULL;
asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, buf_len);
if (dec.code ||
srep->returnCode != SecurityReplyReturnCode_accepted ||
!srep->data ||
srep->data->present != SecurityReplyData_PR_tlsSend) {
syslog_err("[facilities] [tolling]<- SecurityReply.tlsSend rejected");
rv = 1;
goto cleanup;
}
// TR TCP
tr->choice.packet.present = TransportPacketRequest_PR_tcp;
TCPPacketRequest_t* tcp = &tr->choice.packet.choice.tcp;
tcp->id = rand() + 1;
id = tcp->id;
tcp->destinationAddress = calloc(1, sizeof(OCTET_STRING_t));
tcp->destinationAddress->buf = malloc(16);
tcp->destinationAddress->size = 16;
memcpy(tcp->destinationAddress->buf, dst_addr, 16);
tcp->destinationPort = dst_port;
tcp->sourcePort = 7011;
tcp->data.buf = malloc(srep->data->choice.tlsSend.data.size);
tcp->data.size = srep->data->choice.tlsSend.data.size;
memcpy(tcp->data.buf, srep->data->choice.tlsSend.data.buf, srep->data->choice.tlsSend.data.size);
tcp->gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t));
tcp->gn->packetTransportType = PacketTransportType_shb;
tcp->gn->destinationAddress.buf = calloc(1, 6);
tcp->gn->destinationAddress.size = 6;
tcp->gn->securityProfile.encrypt = false;
tcp->gn->securityProfile.sign = true;
break;
}
// encode TR
buf[0] = 4;
@ -168,14 +236,15 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
goto cleanup;
}
it2s_tender_queue_send(facilities->tx_queue, buf, enc.encoded+1, ITSS_TRANSPORT, bpr->id, "TR.packet.btp");
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");
// Logging
if (facilities->logging.dbms) {
pthread_mutex_lock(&facilities->id.lock);
uint64_t station_id = facilities->id.station_id;
pthread_mutex_unlock(&facilities->id.lock);
it2s_tender_db_add(facilities->logging.dbms, station_id, bpr->id, &facilities->epv, true, 117, NULL, bpr->data.buf, bpr->data.size);
it2s_tender_db_add(facilities->logging.dbms, station_id, id, &facilities->epv, true, 117, NULL, tpm_uper, tpm_uper_len);
}
if (facilities->logging.recorder) {
uint16_t buffer_len = 2048;
@ -183,14 +252,14 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) {
int e = it2s_tender_management_record_packet_sdu(
buffer,
buffer_len,
bpr->data.buf,
bpr->data.size,
bpr->id,
tpm_uper,
tpm_uper_len,
id,
it2s_tender_get_clock(&facilities->epv),
ITSS_FACILITIES,
true);
if (e != -1) {
it2s_tender_queue_send(facilities->tx_queue, buffer, e, ITSS_MANAGEMENT, bpr->id, "MReq.packet.set");
it2s_tender_queue_send(facilities->tx_queue, buffer, e, ITSS_MANAGEMENT, id, "MReq.packet.set");
}
}
@ -203,9 +272,10 @@ cleanup:
return rv;
}
static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* neighbour) {
static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour, uint8_t* dst_addr, uint16_t dst_port) {
TollRequest_t* req = &tpm_rx->tpm.tollingFlow.choice.request;
tolling_s* tolling = &facilities->tolling;
syslog_info("[facilities] [tolling] received toll payment > client: %ld (certificate id: %02x%02x%02x) | nonce: %ld",
req->clientId,
@ -217,14 +287,23 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
const size_t buf_len = 2048;
uint8_t buf[buf_len];
uint8_t tpm_uper[buf_len];
asn_enc_rval_t enc;
TransportRequest_t* tr = NULL;
SecurityRequest_t* sreq = NULL;
SecurityReply_t* srep = NULL;
TPM_t* tpm = NULL;
if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) {
if (!tpm_rx->signature) {
syslog_err("[facilities] [tolling] in simple mode but TPM without signature received");
goto cleanup;
}
// Encode TollingPaymentMessage
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TollingPaymentMessage, NULL, &tpm_rx->tpm, buf, buf_len);
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;
@ -237,26 +316,27 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
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);
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);
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);
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;
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);
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.verify (%dB)", rl);
if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) {
@ -278,6 +358,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep);
sreq = NULL;
srep = NULL;
}
// TPM
tpm = calloc(1, sizeof(TPM_t));
@ -305,6 +386,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
goto cleanup;
}
if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) {
// Sign
sreq = calloc(1, sizeof(SecurityRequest_t));
sreq->present = SecurityRequest_PR_sign;
@ -315,11 +397,11 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
buf[0] = 4;
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);
rl = zmq_recv(facilities->tolling.security_socket, buf, buf_len, 0);
syslog_debug("[facilities]<-[security] SecurityReply.sign (%dB)", rl);
zmq_send(security_socket, buf, enc.encoded+1, 0);
int rc = zmq_recv(security_socket, buf, buf_len, 0);
syslog_debug("[facilities]<-[security] SecurityReply.sign (%dB)", rc);
if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) {
if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rc).code) {
syslog_err("[facilities] SecurityReply.sign decode failure");
goto cleanup;
}
@ -329,40 +411,45 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
goto cleanup;
}
tpm->signature.r.size = srep->data->choice.sign.r.size;
tpm->signature.r.buf = malloc(srep->data->choice.sign.r.size);
memcpy(tpm->signature.r.buf, srep->data->choice.sign.r.buf, srep->data->choice.sign.r.size);
tpm->signature.s.size = srep->data->choice.sign.s.size;
tpm->signature.s.buf = malloc(srep->data->choice.sign.s.size);
memcpy(tpm->signature.s.buf, srep->data->choice.sign.s.buf, srep->data->choice.sign.s.size);
tpm->signature.signer.size = srep->data->choice.sign.signer.size;
tpm->signature.signer.buf = malloc(srep->data->choice.sign.signer.size);
memcpy(tpm->signature.signer.buf, srep->data->choice.sign.signer.buf, srep->data->choice.sign.signer.size);
tpm->signature.type = srep->data->choice.sign.type;
tpm->signature->r.size = srep->data->choice.sign.r.size;
tpm->signature->r.buf = malloc(srep->data->choice.sign.r.size);
memcpy(tpm->signature->r.buf, srep->data->choice.sign.r.buf, srep->data->choice.sign.r.size);
tpm->signature->s.size = srep->data->choice.sign.s.size;
tpm->signature->s.buf = malloc(srep->data->choice.sign.s.size);
memcpy(tpm->signature->s.buf, srep->data->choice.sign.s.buf, srep->data->choice.sign.s.size);
tpm->signature->signer.size = srep->data->choice.sign.signer.size;
tpm->signature->signer.buf = malloc(srep->data->choice.sign.signer.size);
memcpy(tpm->signature->signer.buf, srep->data->choice.sign.signer.buf, srep->data->choice.sign.signer.size);
tpm->signature->type = srep->data->choice.sign.type;
}
// encode TPM
enc = uper_encode_to_buffer(&asn_DEF_TPM, NULL, tpm, buf, buf_len);
enc = uper_encode_to_buffer(&asn_DEF_TPM, NULL, tpm, tpm_uper, buf_len);
if (enc.encoded == -1) {
syslog_err("[facilities] [tolling] error encoding TPM.reply (%s)", enc.failed_type->name);
goto cleanup;
}
size_t tpm_uper_len = (enc.encoded + 7) / 8;
uint64_t id = 0;
// [transport] request (TR)
switch (tolling->protocol) {
case TOLLING_PROTOCOL_SIMPLE:
tr = calloc(1, sizeof(TransportRequest_t));
tr->present = TransportRequest_PR_packet;
tr->choice.packet.present = TransportPacketRequest_PR_btp;
BTPPacketRequest_t* bpr = &tr->choice.packet.choice.btp;
bpr->id = rand() + 1;
id = bpr->id;
bpr->gn.securityProfile.encrypt = true;
bpr->gn.securityProfile.sign = true;
bpr->data.size = tpm_uper_len;
bpr->data.buf = malloc(tpm_uper_len);
memcpy(bpr->data.buf, buf, tpm_uper_len);
memcpy(bpr->data.buf, tpm_uper, tpm_uper_len);
bpr->destinationPort = 7011;
bpr->btpType = BTPType_btpB;
@ -380,6 +467,64 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
bpr->gn.securityNeighbour->buf = malloc(8);
memcpy(bpr->gn.securityNeighbour->buf, neighbour, 8);
}
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);
buf[0] = 4;
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, buf+1, buf_len-1);
syslog_debug("[facilities] [tolling]-> SecurityRequest.tlsSend ->[security]");
zmq_send(security_socket, buf, enc.encoded, 0);
int rc = zmq_recv(security_socket, buf, buf_len, 0);
if (rc == -1) {
syslog_err("[facilities] [tolling]-> SecurityRequest.tlsSend ->[security] <TIMEOUT>");
goto cleanup;
}
syslog_debug("[facilities] [tolling]<- SecurityReply.tlsSend <-[security]");
SecurityReply_t* srep = NULL;
asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, buf_len);
if (dec.code ||
srep->returnCode != SecurityReplyReturnCode_accepted ||
!srep->data ||
srep->data->present != SecurityReplyData_PR_tlsSend) {
syslog_err("[facilities] [tolling]<- SecurityReply.tlsSend rejected");
goto cleanup;
}
// TR TCP
tr->choice.packet.present = TransportPacketRequest_PR_tcp;
TCPPacketRequest_t* tcp = &tr->choice.packet.choice.tcp;
tcp->id = rand() + 1;
id = tcp->id;
tcp->destinationAddress = calloc(1, sizeof(OCTET_STRING_t));
tcp->destinationAddress->buf = malloc(16);
tcp->destinationAddress->size = 16;
memcpy(tcp->destinationAddress->buf, dst_addr, 16);
tcp->destinationPort = dst_port;
tcp->sourcePort = 7011;
tcp->data.buf = malloc(srep->data->choice.tlsSend.data.size);
tcp->data.size = srep->data->choice.tlsSend.data.size;
memcpy(tcp->data.buf, srep->data->choice.tlsSend.data.buf, srep->data->choice.tlsSend.data.size);
tcp->gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t));
tcp->gn->packetTransportType = PacketTransportType_shb;
tcp->gn->destinationAddress.buf = calloc(1, 6);
tcp->gn->destinationAddress.size = 6;
tcp->gn->securityProfile.encrypt = false;
tcp->gn->securityProfile.sign = true;
break;
}
// encode TR
buf[0] = 4;
@ -389,14 +534,15 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
goto cleanup;
}
it2s_tender_queue_send(facilities->tx_queue, buf, enc.encoded+1, ITSS_TRANSPORT, bpr->id, "TR.packet.btp");
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");
// Logging
if (facilities->logging.dbms) {
pthread_mutex_lock(&facilities->id.lock);
uint64_t station_id = facilities->id.station_id;
pthread_mutex_unlock(&facilities->id.lock);
it2s_tender_db_add(facilities->logging.dbms, station_id, bpr->id, &facilities->epv, true, 117, NULL, bpr->data.buf, bpr->data.size);
it2s_tender_db_add(facilities->logging.dbms, station_id, id, &facilities->epv, true, 117, NULL, tpm_uper, tpm_uper_len);
}
if (facilities->logging.recorder) {
uint16_t buffer_len = 2048;
@ -404,14 +550,14 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne
int e = it2s_tender_management_record_packet_sdu(
buffer,
buffer_len,
bpr->data.buf,
bpr->data.size,
bpr->id,
tpm_uper,
tpm_uper_len,
id,
it2s_tender_get_clock(&facilities->epv),
ITSS_FACILITIES,
true);
if (e != -1) {
it2s_tender_queue_send(facilities->tx_queue, buffer, e, ITSS_MANAGEMENT, bpr->id, "MReq.packet.set");
it2s_tender_queue_send(facilities->tx_queue, buffer, e, ITSS_MANAGEMENT, id, "MReq.packet.set");
}
}
@ -422,7 +568,7 @@ cleanup:
ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep);
}
static void veh_handle_recv(tolling_s* tolling, TPM_t* tpm_rx, uint8_t* neighbour) {
static void veh_handle_recv(tolling_s* tolling, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour) {
TollReply_t* rep = &tpm_rx->tpm.tollingFlow.choice.reply;
@ -449,6 +595,8 @@ static void veh_handle_recv(tolling_s* tolling, TPM_t* tpm_rx, uint8_t* neighbou
goto cleanup;
}
bool accepted = true;
if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) {
// Verify
sreq = calloc(1, sizeof(SecurityRequest_t));
sreq->present = SecurityRequest_PR_verify;
@ -457,25 +605,25 @@ static void veh_handle_recv(tolling_s* tolling, TPM_t* tpm_rx, uint8_t* neighbou
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);
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);
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);
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;
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);
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.verify (%dB)", rl);
if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) {
@ -493,7 +641,10 @@ static void veh_handle_recv(tolling_s* tolling, TPM_t* tpm_rx, uint8_t* neighbou
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");
accepted = rep->confirmationCode == TollConfirmationCode_accepted;
}
syslog_info("[facilities] [tolling] received tolling payment reply > client: %ld | nonce: %ld | accepted: %s", tolling->client_id, tolling->nonce, accepted ? "yes" : "no");
tolling->active = false;
@ -502,7 +653,7 @@ cleanup:
ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep);
}
int tpm_recv(void* fc, TPM_t* tpm_rx, uint8_t* neighbour) {
int tpm_recv(void* fc, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour, uint8_t* src_addr, uint16_t src_port) {
int rv = 0;
facilities_t* facilities = (facilities_t*) fc;
@ -519,7 +670,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, neighbour);
rsu_handle_recv(facilities, tpm_rx, security_socket, neighbour, src_addr, src_port);
break;
case TollingFlow_PR_reply:
@ -530,7 +681,7 @@ int tpm_recv(void* fc, TPM_t* tpm_rx, uint8_t* neighbour) {
pthread_mutex_lock(&facilities->epv.time.lock);
syslog_info("[facilities] [tolling] 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, neighbour);
veh_handle_recv(tolling, tpm_rx, security_socket, neighbour);
break;
default:
@ -543,12 +694,6 @@ cleanup:
}
int tolling_init(tolling_s* tolling, void* zmq_ctx, char* security_address) {
tolling->security_socket = zmq_socket(zmq_ctx, ZMQ_REQ);
int wait_ms = 1000;
zmq_setsockopt(tolling->security_socket, ZMQ_RCVTIMEO, &wait_ms, sizeof(int));
zmq_connect(tolling->security_socket, security_address);
return 0;
}

View File

@ -38,9 +38,6 @@ typedef struct tolling {
uint8_t length;
} infos;
// Security socket
void* security_socket;
} tolling_s;
/**
@ -53,8 +50,8 @@ typedef struct tolling {
*/
int tolling_init(tolling_s* tolling, void* zmq_ctx, char* security_address);
int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour);
int tpm_recv(void* fc, TPM_t* tpm_rx, uint8_t* neighbour);
int tpm_pay(void* fc, tolling_info_s* info, void* security_socket, uint8_t* neighbour, uint8_t* src_addr, uint16_t src_port);
int tpm_recv(void* fc, TPM_t* tpm_rx, void* security_socket, uint8_t* neighbour, uint8_t* src_addr, uint16_t src_port);
int tpm_is_inside_zone(void* fc, tolling_info_s* ti);
tolling_info_s* tolling_info_new(it2s_tender_epv_t* epv, TollingPaymentInfo_t* tpi);