当前位置:   article > 正文

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

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

一、概述

上一篇博客 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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

三、小结

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

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号