TPM SPKI remove sec-verify check, fast fwd2apps on rx

This commit is contained in:
Mohannad 2023-08-01 13:28:12 +01:00
parent 40db7b666a
commit 01406cdbf3
4 changed files with 135 additions and 115 deletions

View File

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

View File

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

View File

@ -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 <TIMEOUT>",
(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;

234
src/tpm.c
View File

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