📌往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)
📃 鸿蒙(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。
- 首先总体分析函数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(¶, sizeof(para), 0, sizeof(para));//清空操作参数空间
hichain->cb.get_protocol_params(&hichain->identity, GENERATE_KEY_PAIR, &pin, ¶);//设备可信认证过程:获取协议参数,主要获取认证会话密钥长度、对端认证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, ¶.self_auth_id, KEY_ALIAS_LT_KEY_PAIR);
#else
struct hc_key_alias alias = generate_key_alias(&service_id, ¶.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, ¶.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");
}
}
}
- 然后,对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;
}
- 在函数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进行了详细的分析,但是由于篇幅有限,其余内容将在下一篇博客中进行介绍。


642

被折叠的 条评论
为什么被折叠?



