鸿蒙设备开发OpenHarmony解读之设备认证:数据接收管理-获取HiChain实例(2)

📌往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

📃 鸿蒙(HarmonyOS)北向开发知识点记录~

📃 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

📃 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

📃 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

📃 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

📃 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

📃 记录一场鸿蒙开发岗位面试经历~

📃 持续更新中……


一、概述

上一篇博客 OpenHarmony解读之设备认证:数据接收管理-获取HiChain实例(1) 介绍了hichain实例获取的部分内容,本文将继续进行分析。

在上一篇博客介绍的get_instance函数中,在进行完密钥等信息的初始化之后,调用build_self_lt_key_pair函数创建属于本端的长期保存的密钥对,这个密钥对初步分析是用于设备之间的身份可信认证。

创建密钥对部分可分为四个阶段:
1、获取协议参数
2、生成服务id
3、生成密钥别名
4、生成长期保存的密钥对

下面将对build_self_lt_key_pair函数及其涉及到的相关函数进行详细分析,重点分析第一个阶段的内容。

二、源码分析

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

  1. 首先总体分析函数build_self_lt_key_pair,具体如下:
/*
函数功能:构建自己的long term store密钥对
函数参数:
    hichain:HiChain实例对象,传入传出参数
函数返回值:无
*/
static void build_self_lt_key_pair(const struct hichain *hichain)
{
    struct hc_pin pin = { 0, {0} };
    struct operation_parameter para;//定义操作参数
    (void)memset_s(&para, sizeof(para), 0, sizeof(para));//清空操作参数空间
    hichain->cb.get_protocol_params(&hichain->identity, GENERATE_KEY_PAIR, &pin, &para);//设备可信认证过程:获取协议参数,主要获取认证会话密钥长度、对端认证id和本端认证id
    if (para.self_auth_id.length > 0) {//获取成功
        struct service_id service_id = generate_service_id(&hichain->identity);//生成服务id(HC包名称和服务类型进行哈希之后的值)
        if (service_id.length == 0) {//生成服务id失败则直接返回
            LOGE("Generate service id failed");//日志信息
            return;
        }
#if (defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))//如果支持这两种机制
        struct hc_key_alias alias = generate_key_alias(&service_id, &para.self_auth_id, KEY_ALIAS_LT_KEY_PAIR);
#else
        struct hc_key_alias alias = generate_key_alias(&service_id, &para.self_auth_id, KEY_ALIAS_ACCESSOR_PK);//通过服务id和认证id(service id and auth id)生成密钥别名
                                                                                                                //类型为KEY_ALIAS_ACCESSOR_PK
#endif
        if (alias.length == 0) {//生成密钥别名失败则直接返回
            LOGE("Generate key alias failed");
            return;
        }//成功生成密钥别名
        int32_t ret = check_lt_public_key_exist(&alias);//根据别名判断long term公钥是否存在
        if (ret != HC_OK) {//如果不存在
            ret = generate_lt_key_pair(&alias, &para.self_auth_id);//生成自己本端的长期存储有效的密钥对Generate a long-lived key pair ED25519
            if (ret != HC_OK) {
                LOGE("Generate self ltpk return value is %d", ret);
                return;
            }
            DBG_OUT("Generate self ltpk ok");
        }
    }
}
  1. 然后,对build_self_lt_key_pair函数进行逐阶段分析,在此函数中,首先是调用回调函数get_protocol_params获取协议参数,此函数的实现位于分布式软总线模块的auth_interface.c文件中,函数名为AuthGetProtocolParams,具体分析如下:
/*
函数功能:设备可信认证过程:获取协议参数,主要获取认证会话密钥长度、对端认证id和本端认证id
函数参数:
    identity:认证会话标识
    operationCode:操作码
    hcPin:HC PIN码
    para:操作参数
函数返回值:无
详细:
    操作参数结构如下:
//操作参数
struct operation_parameter {
    struct hc_auth_id self_auth_id;//本端认证id
    struct hc_auth_id peer_auth_id;//对端认证id
    uint32_t key_length;//密钥长度
};
*/
static void AuthGetProtocolParams(const struct session_identity *identity, int32_t operationCode,
    struct hc_pin *hcPin, struct operation_parameter *para)
{
    (void)operationCode;//此处未使用到这个参数,但为了避免编译器发出警告,做此处理
    (void)hcPin;//此处未使用到这个参数,但为了避免编译器发出警告,做此处理
    if (identity == NULL || para == NULL) {//参数有效性检查
        return;
    }
    para->key_length = AUTH_SESSION_KEY_LEN;//赋值认证会话密钥长度
    AuthSession *authSes = AuthGetAuthSessionBySessionId(identity->session_id);//根据会话id获取认证会话
    if (authSes == NULL || authSes->conn == NULL) {//若认证会话为空或者该会话维护的连接为空,则返回错误
        SOFTBUS_PRINT("[AUTH] AuthGetProtocolParams get session fail\n");
        return;
    }
    para->peer_auth_id.length = strlen(authSes->conn->authId);//赋值对端认证id长度
    int ret = memcpy_s(para->peer_auth_id.auth_id, sizeof(para->peer_auth_id.auth_id),
                       authSes->conn->authId, strlen(authSes->conn->authId));//将该认证会话维护的认证连接的认证id赋给操作参数中的对端认证id
    if (ret != EOK) {//若拷贝失败,则返回
        return;
    }
    DeviceInfo *info = BusGetLocalDeviceInfo();//获取本地设备信息
    if (info == NULL) {//获取失败则返回
        return;
    }
    para->self_auth_id.length = strlen(info->deviceId);//赋值本端认证id长度为设备id长度
    ret = memcpy_s(para->self_auth_id.auth_id, sizeof(para->self_auth_id.auth_id),
                   info->deviceId, strlen(info->deviceId));//将本地设备id赋给操作参数中的本端认证id
    if (ret != EOK) {//若拷贝失败,则返回
        return;
    }
    SOFTBUS_PRINT("[AUTH] AuthGetProtocolParams ok\n");//打印日志信息
    return;
}
  1. 在函数AuthGetProtocolParams中调用了AuthGetAuthSessionBySessionId函数获取认证会话信息,具体分析如下:
*
函数功能:根据会话id查询全局认证会话表,获取认证会话
函数参数:
    sessionId:会话id
函数返回值:
    成功:返回指向认证会话结构体的指针
    失败:返回NULL
详细:
*/
static AuthSession *AuthGetAuthSessionBySessionId(uint32_t sessionId)
{
    if (g_authSessionMap == NULL) {//检查全局认证会话表是否为空
        return NULL;
    }
    for (int i = 0; i < AUTH_SESSION_MAX_NUM; i++) {//遍历全局认证会话表
        if (g_authSessionMap[i].isUsed == 0) {
            continue;
        }
        if (g_authSessionMap[i].sessionId == sessionId) {//根据会话id定位到对应的认证会话
            return &g_authSessionMap[i];//返回该会话指针
        }
    }
    return NULL;
}

三、小结

本文重点分析了hichain实例获取阶段的本端密钥对生成函数build_self_lt_key_pair的部分内容,对该函数进行了总体的分析,也对该函数中调用的分布式软总线模块的回调函数AuthGetProtocolParams进行了详细的分析,但是由于篇幅有限,其余内容将在下一篇博客中进行介绍。

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值