发布时间:2022-08-19 11:47
本文将承接上一篇博客OpenHarmony解读之设备认证:数据接收管理-消息解析的内容,主要介绍HiChain本端接收数据的处理过程中的消息处理阶段。
这一模块的源码位于:/base/security/deviceauth。
//导航消息,得到 "消息模块-消息类型(消息码低四位)-是否请求消息" 一一对应
struct header_analysis navigate_message(uint32_t message_code)
{
struct header_analysis nav = { INVALID_MODULAR, 0, 0 };
for (uint32_t i = 0; i < sizeof(G_MESSAGE_CODE_MAP) / sizeof(G_MESSAGE_CODE_MAP[0]); i++) {//sizeof(G_MESSAGE_CODE_MAP) / sizeof(G_MESSAGE_CODE_MAP[0])表示消息码数组的元素个数
if (G_MESSAGE_CODE_MAP[i].code == message_code) {//根据消息码查表,如果存在,就进行相关数据更新
nav.modular = G_MESSAGE_CODE_MAP[i].modular;//赋予消息模块
nav.msg_type = message_code & 0xf; /* message_code & 0xf get low four bits of message code 获取低四位的消息码作为msg_type*/
nav.is_request_msg = G_MESSAGE_CODE_MAP[i].is_request_msg;
break;
}
}
LOGI("Message code %u, nav is %d, %d, %d", message_code, nav.modular, nav.msg_type, nav.is_request_msg);
return nav;
}
/*
函数功能:检查消息是否是系统可支持
函数参数:
hichain:HiChain实例
nav:导航消息头
receive:解析后的消息
函数返回值:
成功:返回0
失败:返回错误码
详细:将解析出来的操作码保存到hichain中且与消息码对应正确,一致
*/
int32_t check_message_support(struct hichain *hichain, const struct header_analysis *nav,
const struct message *receive)
{
if (nav->modular == 0) {//表示未知消息
LOGE("Receive unknow message, message code is 0x%04x", receive->msg_code);
return HC_UNKNOW_MESSAGE;
}
if (!check_hichain_state_is_success(hichain, nav)) {//检查hichain实例的状态是否正确
return HC_STATE_ERROR;
}
int32_t operation_code = get_operation_code(nav, receive);//根据消息模块类型获取解析不同协议的操作码,这里有PAKE和STS协议
if (operation_code == INVALID_OPERATION_CODE) {//如果操作码无效,则返回错误码
return HC_OPERATION_CODE_ERROR;
} else if (operation_code == NO_OPERATION_CODE) {//如果操作码为0,表示“无操作”
/* compare with recorded operation code and verify */
if (is_message_illegal(hichain->operation_code, nav->modular)) {//判断消息是否属于非法消息
LOGE("Operation code is %d, message code is %u, it is inconsistency",
hichain->operation_code, receive->msg_code);
return HC_MESSAGE_INCONSISTENCY;//返回'消息不一致'的代码
}
} else {//如果是其他操作码
int32_t ret = hichain->cb.confirm_receive_request(&hichain->identity, operation_code);//确认收到的请求,调用HC回调函数处理,目前版本暂不可用
if (ret != 0) {
LOGE("Service does not allow response %d", operation_code);
return HC_SERVICE_CONFIRM_ERROR;
}
hichain->operation_code = operation_code;
}
return HC_OK;
}
//检查hichain实例的状态是否正确,成功返回true,失败返回false
static bool check_hichain_state_is_success(struct hichain *hichain, const struct header_analysis *nav)
{
if ((nav->modular == PAKE_MODULAR) || (nav->modular == STS_MODULAR)) {//如果消息属于PAKE协议或者STS协议的消息,则判断其状态是否是初始化状态和密钥协商状态
if ((hichain->state != INIT_STATE) && (hichain->state != KEY_AGREEMENT_STATE) &&
(hichain->last_state != INIT_STATE) && (hichain->last_state != KEY_AGREEMENT_STATE)) {//如果状态不是初始化状态和密钥协商状态,返回失败
goto error;
}
} else {//如果属于其他类型的消息,则判断其状态是否是密钥协商状态和操作状态
if ((hichain->state != KEY_AGREEMENT_STATE) && (hichain->state != OPERATION_STATE) &&
(hichain->last_state != KEY_AGREEMENT_STATE) && (hichain->last_state != OPERATION_STATE)) {
goto error;//如果状态不是密钥协商状态和运行状态,返回失败
}
}
return true;//返回正确
error:
LOGE("Check hichain state failed, state is %d, message nav is %d-%d-%d", hichain->state, nav->modular,
nav->msg_type, nav->is_request_msg);//处理错误,打印错误日志信息
return false;//返回错误
}
static int32_t get_operation_from_pake(void *payload);//函数声明
static int32_t get_operation_from_sts(void *payload);//函数声明
//根据消息模块类型获取解析不同协议的操作码,这里有PAKE和STS协议
static int32_t get_operation_code(const struct header_analysis *nav, const struct message *receive)
{
int32_t operation_code = NO_OPERATION_CODE;//初始化为无操作
if ((nav->modular == PAKE_MODULAR) && (nav->msg_type == PAKE_START_MSG) && nav->is_request_msg) {//如果消息属于PAKE协议,且是"请求开始"消息,则获取PAKE协议的操作码
operation_code = get_operation_from_pake(receive->payload);//获取解析出的pake协议的操作码
} else if ((nav->modular == STS_MODULAR) && (nav->msg_type == STS_START_MSG) && nav->is_request_msg) {//如果消息属于STS协议,且是"请求开始"消息,则获取STS协议的操作码
operation_code = get_operation_from_sts(receive->payload);//获取解析出的sts协议的操作码
}
LOGI("Receive message had operation code is %d", operation_code);
return operation_code;
}
//获取解析出的pake协议的操作码
static int32_t get_operation_from_pake(void *payload)
#if !(defined(_CUT_PAKE_) || defined(_CUT_PAKE_SERVER_))
{
int32_t permissible_code[] = { BIND, AUTH_KEY_AGREEMENT };//允许的操作码,目前有:BIND(绑定),AUTH_KEY_AGREEMENT(认证密钥协商)
struct pake_start_request_data *data = payload;//结构体强转,解析出该消息的操作码
for (uint32_t i = 0; i < sizeof(permissible_code) / sizeof(int32_t); i++) {
if (permissible_code[i] == data->operation_code) {//查询该操作码是否属于允许的操作码,是就返回,否则返回无效,即-1
return data->operation_code;
}
}
LOGE("Receive operation code %d is error", data->operation_code);
return INVALID_OPERATION_CODE;
}
//获取解析出的sts协议的操作码
static int32_t get_operation_from_sts(void *payload)
#if !(defined(_CUT_STS_) || defined(_CUT_STS_SERVER_))
{
int32_t permissible_code[] = { AUTHENTICATE, ADD_AUTHINFO, REMOVE_AUTHINFO, UNBIND, SEC_CLONE_OP };//允许的操作码,
struct sts_start_request_data *data = payload;//结构体强转,解析出该消息的操作码
for (uint32_t i = 0; i < sizeof(permissible_code) / sizeof(int32_t); i++) {//查询该操作码是否属于允许的操作码,是就返回,否则返回无效,即-1
if (permissible_code[i] == data->operation_code) {
return data->operation_code;
}
}
LOGE("Receive operation code %d is error", data->operation_code);
return INVALID_OPERATION_CODE;
}
//检查消息是否为非法消息,是非法消息则返回true,否则返回false
static bool is_message_illegal(int32_t operation_code, int32_t modular)
{
//合法消息表
struct check_message_powered table[] = { { BIND, PAKE_MODULAR },
{ BIND, EXCHANGE_MODULAR },
{ AUTH_KEY_AGREEMENT, PAKE_MODULAR },
{ UNBIND, STS_MODULAR },
{ UNBIND, REMOVE_MODULAR },
{ AUTHENTICATE, STS_MODULAR },
{ ADD_AUTHINFO, STS_MODULAR },
{ ADD_AUTHINFO, ADD_MODULAR },
{ REMOVE_AUTHINFO, STS_MODULAR },
{ REMOVE_AUTHINFO, REMOVE_MODULAR },
{ SEC_CLONE_OP, STS_MODULAR },
{ SEC_CLONE_OP, SEC_CLONE_MODULAR } };
for (uint32_t i = 0; i < sizeof(table) / sizeof(table[0]); i++) {//遍历合法消息表,查询对应的消息是否存在
if ((modular == table[i].modular) && (operation_code == table[i].operation_code)) {
return false;//若存在,返回消息合法
}
}
return true;//不存在,返回消息不合法
}
本文主要介绍了导航消息模块和检查消息合法性模块,其余内容将在下一篇博客中介绍。