forked from acouzens/open5gs
204 lines
7.1 KiB
C
204 lines
7.1 KiB
C
/*
|
|
* Copyright (C) 2023 by Sukchan Lee <acetcom@gmail.com>
|
|
*
|
|
* This file is part of Open5GS.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "sbi-path.h"
|
|
|
|
#include "n32c-handler.h"
|
|
|
|
bool sepp_n32c_handshake_handle_security_capability_request(
|
|
sepp_node_t *sepp_node,
|
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
|
{
|
|
OpenAPI_sec_negotiate_req_data_t *SecNegotiateReqData = NULL;
|
|
|
|
OpenAPI_lnode_t *node = NULL;
|
|
bool tls = false, prins = false, none = false;
|
|
|
|
ogs_assert(sepp_node);
|
|
ogs_assert(stream);
|
|
ogs_assert(recvmsg);
|
|
|
|
SecNegotiateReqData = recvmsg->SecNegotiateReqData;
|
|
if (!SecNegotiateReqData) {
|
|
ogs_error("[%s] No SecNegotiateReqData", sepp_node->receiver);
|
|
ogs_assert(true ==
|
|
ogs_sbi_server_send_error(stream,
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
|
recvmsg, "No SecNegotiateReqData", sepp_node->receiver,
|
|
NULL));
|
|
return false;
|
|
}
|
|
|
|
if (!SecNegotiateReqData->sender) {
|
|
ogs_error("[%s] No SecNegotiateReqData.sender", sepp_node->receiver);
|
|
ogs_assert(true ==
|
|
ogs_sbi_server_send_error(stream,
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
|
recvmsg, "No SecNegotiateReqData.sender", sepp_node->receiver,
|
|
NULL));
|
|
return false;
|
|
}
|
|
|
|
ogs_assert(sepp_node->receiver);
|
|
if (strcmp(SecNegotiateReqData->sender, sepp_node->receiver) != 0) {
|
|
ogs_error("[%s] FQDN mismatch Sender [%s]",
|
|
sepp_node->receiver, SecNegotiateReqData->sender);
|
|
return false;
|
|
}
|
|
|
|
if (!SecNegotiateReqData->supported_sec_capability_list) {
|
|
ogs_error("[%s] No supported_sec_capability_list", sepp_node->receiver);
|
|
ogs_assert(true ==
|
|
ogs_sbi_server_send_error(stream,
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
|
recvmsg, "No supported_sec_capability_list",
|
|
sepp_node->receiver, NULL));
|
|
return false;
|
|
}
|
|
|
|
OpenAPI_list_for_each(
|
|
SecNegotiateReqData->supported_sec_capability_list, node) {
|
|
OpenAPI_security_capability_e security_capability =
|
|
(uintptr_t)node->data;
|
|
if (security_capability == OpenAPI_security_capability_TLS)
|
|
tls = true;
|
|
else if (security_capability == OpenAPI_security_capability_PRINS)
|
|
prins = true;
|
|
else if (security_capability == OpenAPI_security_capability_NONE)
|
|
none = true;
|
|
}
|
|
|
|
if (none == true) {
|
|
sepp_node->negotiated_security_scheme =
|
|
OpenAPI_security_capability_NONE;
|
|
} else if (tls == true && sepp_self()->security_capability.tls == true) {
|
|
sepp_node->negotiated_security_scheme =
|
|
OpenAPI_security_capability_TLS;
|
|
} else if (prins == true &&
|
|
sepp_self()->security_capability.prins == true) {
|
|
sepp_node->negotiated_security_scheme =
|
|
OpenAPI_security_capability_PRINS;
|
|
} else {
|
|
OpenAPI_list_for_each(
|
|
SecNegotiateReqData->supported_sec_capability_list, node) {
|
|
OpenAPI_security_capability_e security_capability =
|
|
(uintptr_t)node->data;
|
|
ogs_error("[%s] Unknown SupportedSecCapability [%d]",
|
|
sepp_node->receiver, security_capability);
|
|
}
|
|
ogs_assert(true ==
|
|
ogs_sbi_server_send_error(stream,
|
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
|
recvmsg, "Unknown SupportedSecCapability",
|
|
sepp_node->receiver, NULL));
|
|
return false;
|
|
}
|
|
|
|
if (SecNegotiateReqData->is__3_gpp_sbi_target_api_root_supported == true &&
|
|
SecNegotiateReqData->_3_gpp_sbi_target_api_root_supported == 1)
|
|
sepp_node->target_apiroot_supported = true;
|
|
|
|
sepp_node->num_of_plmn_id = 0;
|
|
OpenAPI_list_for_each(SecNegotiateReqData->plmn_id_list, node) {
|
|
OpenAPI_plmn_id_t *PlmnId = node->data;
|
|
if (PlmnId) {
|
|
ogs_sbi_parse_plmn_id(
|
|
&sepp_node->plmn_id[sepp_node->num_of_plmn_id], PlmnId);
|
|
sepp_node->num_of_plmn_id++;
|
|
}
|
|
}
|
|
|
|
if (SecNegotiateReqData->target_plmn_id) {
|
|
ogs_sbi_parse_plmn_id(
|
|
&sepp_node->target_plmn_id, SecNegotiateReqData->target_plmn_id);
|
|
sepp_node->target_plmn_id_presence = true;
|
|
}
|
|
|
|
if (SecNegotiateReqData->supported_features) {
|
|
uint64_t supported_features =
|
|
ogs_uint64_from_string(SecNegotiateReqData->supported_features);
|
|
sepp_node->supported_features &= supported_features;
|
|
} else {
|
|
sepp_node->supported_features = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool sepp_n32c_handshake_handle_security_capability_response(
|
|
sepp_node_t *sepp_node, ogs_sbi_message_t *recvmsg)
|
|
{
|
|
OpenAPI_sec_negotiate_rsp_data_t *SecNegotiateRspData = NULL;
|
|
|
|
OpenAPI_lnode_t *node = NULL;
|
|
|
|
ogs_assert(sepp_node);
|
|
ogs_assert(recvmsg);
|
|
|
|
SecNegotiateRspData = recvmsg->SecNegotiateRspData;
|
|
if (!SecNegotiateRspData) {
|
|
ogs_error("[%s] No SecNegotiateRspData", sepp_node->receiver);
|
|
return false;
|
|
}
|
|
|
|
if (!SecNegotiateRspData->sender) {
|
|
ogs_error("[%s] No SecNegotiateRspData.sender", sepp_node->receiver);
|
|
return false;
|
|
}
|
|
|
|
ogs_assert(sepp_node->receiver);
|
|
if (strcmp(SecNegotiateRspData->sender, sepp_node->receiver) != 0) {
|
|
ogs_error("[%s] FQDN mismatch Sender [%s]",
|
|
sepp_node->receiver, SecNegotiateRspData->sender);
|
|
return false;
|
|
}
|
|
|
|
if (!SecNegotiateRspData->selected_sec_capability) {
|
|
ogs_error("[%s] No selected_sec_capability", sepp_node->receiver);
|
|
return false;
|
|
}
|
|
|
|
sepp_node->negotiated_security_scheme =
|
|
SecNegotiateRspData->selected_sec_capability;
|
|
|
|
if (SecNegotiateRspData->is__3_gpp_sbi_target_api_root_supported == true &&
|
|
SecNegotiateRspData->_3_gpp_sbi_target_api_root_supported == 1)
|
|
sepp_node->target_apiroot_supported = true;
|
|
|
|
sepp_node->num_of_plmn_id = 0;
|
|
OpenAPI_list_for_each(SecNegotiateRspData->plmn_id_list, node) {
|
|
OpenAPI_plmn_id_t *PlmnId = node->data;
|
|
if (PlmnId) {
|
|
ogs_sbi_parse_plmn_id(
|
|
&sepp_node->plmn_id[sepp_node->num_of_plmn_id], PlmnId);
|
|
sepp_node->num_of_plmn_id++;
|
|
}
|
|
}
|
|
|
|
if (SecNegotiateRspData->supported_features) {
|
|
uint64_t supported_features =
|
|
ogs_uint64_from_string(SecNegotiateRspData->supported_features);
|
|
sepp_node->supported_features &= supported_features;
|
|
} else {
|
|
sepp_node->supported_features = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|