diff --git a/src/facilities.c b/src/facilities.c index 7335292..7eb2ade 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -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; diff --git a/src/saem.c b/src/saem.c index 359ad9d..bbef83f 100644 --- a/src/saem.c +++ b/src/saem.c @@ -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; } } diff --git a/src/tpm.c b/src/tpm.c index 0f19f1f..b5d18c2 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -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,45 +84,48 @@ int tpm_pay(void* fc, tolling_info_s* info, uint8_t* neighbour) { goto cleanup; } - // Sign - sreq = calloc(1, sizeof(SecurityRequest_t)); - sreq->present = SecurityRequest_PR_sign; - sreq->choice.sign.data.size = enc.encoded; - sreq->choice.sign.data.buf = malloc(enc.encoded); - memcpy(sreq->choice.sign.data.buf, buf, enc.encoded); + if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) { + // Sign + sreq = calloc(1, sizeof(SecurityRequest_t)); + sreq->present = SecurityRequest_PR_sign; + sreq->choice.sign.data.size = enc.encoded; + sreq->choice.sign.data.buf = malloc(enc.encoded); + memcpy(sreq->choice.sign.data.buf, buf, enc.encoded); - 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); - syslog_debug("[facilities]<-[security] SecurityReply.sign (%dB)", rl); + 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(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) { - syslog_err("[facilities] SecurityReply.sign decode failure"); - rv = 1; - goto cleanup; + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) { + syslog_err("[facilities] SecurityReply.sign decode failure"); + rv = 1; + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + syslog_err("[facilities] SecurityReply.sign rejected"); + rv = 1; + goto cleanup; + } + + 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; } - if (srep->returnCode == SecurityReplyReturnCode_rejected) { - syslog_err("[facilities] SecurityReply.sign rejected"); - rv = 1; - 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; - // 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,32 +136,96 @@ 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; - tr->choice.packet.present = TransportPacketRequest_PR_btp; - BTPPacketRequest_t* bpr = &tr->choice.packet.choice.btp; - bpr->id = rand() + 1; + uint64_t id = 0; - bpr->gn.securityProfile.encrypt = true; - bpr->gn.securityProfile.sign = true; + switch (facilities->tolling.protocol) { + case TOLLING_PROTOCOL_SIMPLE: + tr->choice.packet.present = TransportPacketRequest_PR_btp; + BTPPacketRequest_t* bpr = &tr->choice.packet.choice.btp; - bpr->gn.securityNeighbour = calloc(1, sizeof(OCTET_STRING_t)); - bpr->gn.securityNeighbour->size = 8; - bpr->gn.securityNeighbour->buf = malloc(8); - memcpy(bpr->gn.securityNeighbour->buf, neighbour, 8); + bpr->id = rand() + 1; + id = bpr->id; - bpr->data.size = tpm_uper_len; - bpr->data.buf = malloc(tpm_uper_len); - memcpy(bpr->data.buf, buf, tpm_uper_len); + bpr->gn.securityProfile.encrypt = true; + bpr->gn.securityProfile.sign = true; - bpr->destinationPort = 7011; - bpr->btpType = BTPType_btpB; - bpr->gn.destinationAddress.buf = malloc(6); - for (int i = 0; i < 6; ++i) { - bpr->gn.destinationAddress.buf[i] = 0xff; + bpr->gn.securityNeighbour = calloc(1, sizeof(OCTET_STRING_t)); + bpr->gn.securityNeighbour->size = 8; + bpr->gn.securityNeighbour->buf = malloc(8); + memcpy(bpr->gn.securityNeighbour->buf, neighbour, 8); + + bpr->data.size = tpm_uper_len; + bpr->data.buf = malloc(tpm_uper_len); + memcpy(bpr->data.buf, tpm_uper, tpm_uper_len); + + bpr->destinationPort = 7011; + bpr->btpType = BTPType_btpB; + bpr->gn.destinationAddress.buf = malloc(6); + for (int i = 0; i < 6; ++i) { + bpr->gn.destinationAddress.buf[i] = 0xff; + } + 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] "); + 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; } - bpr->gn.destinationAddress.size = 6; - bpr->gn.trafficClass = 2; - bpr->gn.packetTransportType = PacketTransportType_shb; // 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,68 +287,79 @@ 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; - // Encode TollingPaymentMessage - asn_enc_rval_t 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; + 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 + 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; + } + + // 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, 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); + // 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); + // 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); + // 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(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) { + syslog_err("[facilities] SecurityReply.verify decode failure"); + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + syslog_err("[facilities] SecurityReply.verify rejected"); + goto cleanup; + } + + if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { + syslog_debug("[facilities] signature verify failed"); + goto cleanup; + } + + ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); + ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); + sreq = NULL; + srep = NULL; } - // 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, 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); - // 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); - // 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); - // 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); - syslog_debug("[facilities]<-[security] SecurityReply.verify (%dB)", rl); - - if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) { - syslog_err("[facilities] SecurityReply.verify decode failure"); - goto cleanup; - } - - if (srep->returnCode == SecurityReplyReturnCode_rejected) { - syslog_err("[facilities] SecurityReply.verify rejected"); - goto cleanup; - } - - if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { - syslog_debug("[facilities] signature verify failed"); - goto cleanup; - } - - ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); - ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); - sreq = NULL; - srep = NULL; - // TPM tpm = calloc(1, sizeof(TPM_t)); @@ -305,80 +386,144 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, uint8_t* ne goto cleanup; } - // Sign - sreq = calloc(1, sizeof(SecurityRequest_t)); - sreq->present = SecurityRequest_PR_sign; - sreq->choice.sign.data.size = enc.encoded; - sreq->choice.sign.data.buf = malloc(enc.encoded); - memcpy(sreq->choice.sign.data.buf, buf, enc.encoded); + if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) { + // Sign + sreq = calloc(1, sizeof(SecurityRequest_t)); + sreq->present = SecurityRequest_PR_sign; + sreq->choice.sign.data.size = enc.encoded; + sreq->choice.sign.data.buf = malloc(enc.encoded); + memcpy(sreq->choice.sign.data.buf, buf, enc.encoded); - 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); + 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(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) { - syslog_err("[facilities] SecurityReply.sign decode failure"); - goto cleanup; + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rc).code) { + syslog_err("[facilities] SecurityReply.sign decode failure"); + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + syslog_err("[facilities] SecurityReply.sign rejected"); + 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; } - if (srep->returnCode == SecurityReplyReturnCode_rejected) { - syslog_err("[facilities] SecurityReply.sign rejected"); - 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; - // 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) - 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; + 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; + bpr->id = rand() + 1; + id = bpr->id; - bpr->gn.securityProfile.encrypt = true; - bpr->gn.securityProfile.sign = true; + 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); + bpr->data.size = tpm_uper_len; + bpr->data.buf = malloc(tpm_uper_len); + memcpy(bpr->data.buf, tpm_uper, tpm_uper_len); - bpr->destinationPort = 7011; - bpr->btpType = BTPType_btpB; - bpr->gn.destinationAddress.buf = malloc(6); - for (int i = 0; i < 6; ++i) { - bpr->gn.destinationAddress.buf[i] = 0xff; - } - bpr->gn.destinationAddress.size = 6; - bpr->gn.trafficClass = 2; - bpr->gn.packetTransportType = PacketTransportType_shb; + bpr->destinationPort = 7011; + bpr->btpType = BTPType_btpB; + bpr->gn.destinationAddress.buf = malloc(6); + for (int i = 0; i < 6; ++i) { + bpr->gn.destinationAddress.buf[i] = 0xff; + } + bpr->gn.destinationAddress.size = 6; + bpr->gn.trafficClass = 2; + bpr->gn.packetTransportType = PacketTransportType_shb; - if (neighbour) { /* neighbour ID for [security] encryption */ - bpr->gn.securityNeighbour = calloc(1, sizeof(OCTET_STRING_t)); - bpr->gn.securityNeighbour->size = 8; - bpr->gn.securityNeighbour->buf = malloc(8); - memcpy(bpr->gn.securityNeighbour->buf, neighbour, 8); + if (neighbour) { /* neighbour ID for [security] encryption */ + bpr->gn.securityNeighbour = calloc(1, sizeof(OCTET_STRING_t)); + bpr->gn.securityNeighbour->size = 8; + 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] "); + 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 @@ -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,51 +595,56 @@ static void veh_handle_recv(tolling_s* tolling, TPM_t* tpm_rx, uint8_t* neighbou 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, 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); - // 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); - // 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); - // signature type - sreq->choice.verify.type = tpm_rx->signature.type; + bool accepted = true; + if (tolling->protocol == TOLLING_PROTOCOL_SIMPLE) { + // 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, 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); + // 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); + // 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); + // 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); - syslog_debug("[facilities]<-[security] SecurityReply.verify (%dB)", rl); + 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(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) { - syslog_err("[facilities] SecurityReply.verify decode failure"); - goto cleanup; + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &srep, buf, rl).code) { + syslog_err("[facilities] SecurityReply.verify decode failure"); + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + syslog_err("[facilities] SecurityReply.verify rejected"); + goto cleanup; + } + + if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { + syslog_debug("[facilities] signature verify failed"); + goto cleanup; + } + + accepted = rep->confirmationCode == TollConfirmationCode_accepted; } - if (srep->returnCode == SecurityReplyReturnCode_rejected) { - syslog_err("[facilities] SecurityReply.verify rejected"); - goto cleanup; - } - - if (srep->data->choice.verify.report != SecurityVerifyConfirmCode_success) { - syslog_debug("[facilities] signature verify failed"); - 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"); + 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; } diff --git a/src/tpm.h b/src/tpm.h index 3e00ce9..967ccc4 100644 --- a/src/tpm.h +++ b/src/tpm.h @@ -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);