OpenHarmony解读之设备认证:数据接收管理-消息处理(1)

一、概述

本文将承接上一篇博客 OpenHarmony解读之设备认证:数据接收管理-消息解析 的内容,主要介绍HiChain本端接收数据的处理过程中的消息处理阶段

二、源码分析

这一模块的源码位于:/base/security/deviceauth。

  1. receive_data 函数中,首先执行deserialize_message 函数将消息解析完毕保存在struct message结构中,然后调用navigate_message函数,根据消息码得到消息类型msg_type和消息模块modular,具体分析如下:
ini 复制代码
//导航消息,得到 "消息模块-消息类型(消息码低四位)-是否请求消息" 一一对应
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;
}
  1. 然后执行check_message_support函数检查消息是否可支持,对该函数的分析如下:
rust 复制代码
/*
函数功能:检查消息是否是系统可支持
函数参数:
    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;
}
  1. 在函数check_message_support 中:首先执行check_hichain_state_is_success函数检查hichain实例的状态是否正确,具体函数分析如下:
rust 复制代码
//检查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;//返回错误
}
  1. 然后执行get_operation_code函数获取操作码:
c 复制代码
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;
}

DD一下: 欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。

erlang 复制代码
`欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
  1. 接着执行is_message_illegal函数检查消息是否合法:
c 复制代码
//检查消息是否为非法消息,是非法消息则返回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;//不存在,返回消息不合法
}

三、小结

本文主要介绍了导航消息模块和检查消息合法性模块,其余内容将在下一篇博客中介绍。

相关推荐
早點睡39034 分钟前
高级进阶 React Native 鸿蒙跨平台开发:@react-native-community-slider 滑块组件
react native·react.js·harmonyos
一只大侠的侠1 小时前
Flutter开源鸿蒙跨平台训练营 Day11从零开发商品详情页面
flutter·开源·harmonyos
jl48638211 小时前
变比测试仪显示屏的“标杆“配置!如何兼顾30000小时寿命与六角矢量图精准显示?
人工智能·经验分享·嵌入式硬件·物联网·人机交互
一只大侠的侠1 小时前
React Native开源鸿蒙跨平台训练营 Day18自定义useForm表单管理实战实现
flutter·开源·harmonyos
一只大侠的侠1 小时前
React Native开源鸿蒙跨平台训练营 Day20自定义 useValidator 实现高性能表单验证
flutter·开源·harmonyos
听麟2 小时前
HarmonyOS 6.0+ 跨端智慧政务服务平台开发实战:多端协同办理与电子证照管理落地
笔记·华为·wpf·音视频·harmonyos·政务
前端世界2 小时前
从单设备到多设备协同:鸿蒙分布式计算框架原理与实战解析
华为·harmonyos
一只大侠的侠3 小时前
Flutter开源鸿蒙跨平台训练营 Day12从零开发通用型登录页面
flutter·开源·harmonyos
Hello_Embed4 小时前
libmodbus STM32 主机实验(USB 串口版)
笔记·stm32·学习·嵌入式·freertos·modbus
前端不太难4 小时前
HarmonyOS App 工程深水区:从能跑到可控
华为·状态模式·harmonyos