• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hks_config_parser.h"
17 
18 #include <inttypes.h>
19 #include <securec.h>
20 #include <stdint.h>
21 #include <string.h>
22 #include <unistd.h>
23 
24 #include "hks_at_api_wrap.h"
25 #include "hks_log.h"
26 #include "hks_mem.h"
27 #include "hks_param.h"
28 #include "hks_template.h"
29 #include "hks_type_inner.h"
30 
31 static const struct HksFileTransferSystemAbilityConfig SA_UPGRADE_CFG_LIST[] = HUKS_SA_UPGRADE_CONFIG;
32 static const struct HksFileTransferHapConfig HAP_UPGRADE_CFG_LIST[] = HUKS_HAP_UPGRADE_CONFIG;
33 static const uint32_t SA_SKIP_UPGRADE_CFG_LIST[] = HUKS_SA_SKIP_UPGRADE_CONFIG;
34 static const char * const HAP_SKIP_UPGRADE_CFG_LIST[] = HUKS_HAP_SKIP_UPGRADE_CONFIG;
35 
36 static const char * const RDB_DE_PREFIX = "DistributedDataRdb";
37 static const char * const RDB_ROOT_DE = "distributeddb_client_root_key";
38 
HksIsRdbDeKey(const char * alias)39 bool HksIsRdbDeKey(const char *alias)
40 {
41     uint32_t rdbDePrefixLen = strlen(RDB_DE_PREFIX);
42     uint32_t rdbRootDeLen = strlen(RDB_ROOT_DE);
43     uint32_t aliasSize = strlen(alias);
44     if (aliasSize >= rdbDePrefixLen && HksMemCmp(alias, RDB_DE_PREFIX, rdbDePrefixLen) == EOK) {
45         return true;
46     }
47     if (aliasSize == rdbRootDeLen && HksMemCmp(alias, RDB_ROOT_DE, rdbRootDeLen) == EOK) {
48         return true;
49     }
50     return false;
51 }
52 
ParseOwnerIdFromParamSet(const struct HksParamSet * paramSet,uint32_t * uid,uint64_t * accessTokenId,uint32_t * userId)53 static int32_t ParseOwnerIdFromParamSet(const struct HksParamSet *paramSet, uint32_t *uid, uint64_t *accessTokenId,
54     uint32_t *userId)
55 {
56     bool getUid = false;
57     bool getAccessToken = false;
58     bool getUserId = false;
59     int32_t ret;
60     for (uint32_t i = 0; i < paramSet->paramsCnt; ++i) {
61         if (paramSet->params[i].tag == HKS_TAG_PROCESS_NAME) {
62             // the uid data should be uint32_t
63             if (paramSet->params[i].blob.size != sizeof(uint32_t)) {
64                 HKS_LOG_E("process name blob data is over the size of uint32_t.");
65                 ret = HKS_ERROR_INVALID_KEY_FILE;
66                 break;
67             }
68             *uid = *(uint32_t *)paramSet->params[i].blob.data;
69             getUid = true;
70             continue;
71         }
72         if (paramSet->params[i].tag == HKS_TAG_ACCESS_TOKEN_ID) {
73             *accessTokenId = paramSet->params[i].uint64Param;
74             getAccessToken = true;
75             continue;
76         }
77         if (paramSet->params[i].tag == HKS_TAG_SPECIFIC_USER_ID) {
78             *userId = paramSet->params[i].uint32Param;
79             getUserId = true;
80             continue;
81         }
82         if (paramSet->params[i].tag == HKS_TAG_USER_ID && !getUserId) {
83             *userId = paramSet->params[i].uint32Param;
84             getUserId = true;
85             continue;
86         }
87         if (getUid && getAccessToken && getUserId) {
88             break;
89         }
90     }
91     ret = getUid && getAccessToken && getUserId ? HKS_SUCCESS : HKS_ERROR_INVALID_KEY_FILE;
92     return ret;
93 }
94 
ParseOwnerIdFromFileContent(const struct HksBlob * fileContent,uint32_t * uid,uint64_t * accessTokenId,uint32_t * userId)95 static int32_t ParseOwnerIdFromFileContent(const struct HksBlob *fileContent, uint32_t *uid, uint64_t *accessTokenId,
96     uint32_t *userId)
97 {
98     struct HksParamSet *tmpParamSet = NULL;
99     int32_t ret = HksGetParamSet((const struct HksParamSet *)fileContent->data, fileContent->size, &tmpParamSet);
100     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "fresh paramset failed.")
101 
102     ret = ParseOwnerIdFromParamSet(tmpParamSet, uid, accessTokenId, userId);
103     HKS_FREE(tmpParamSet);
104     return ret;
105 }
106 
InitDefaultStrategy(const char * alias,struct HksUpgradeFileTransferInfo * info)107 static void InitDefaultStrategy(const char *alias, struct HksUpgradeFileTransferInfo *info)
108 {
109     info->skipTransfer = false;
110     info->needDe = false;
111     info->needFrontUser = false;
112     if (HksIsRdbDeKey(alias)) {
113         HKS_LOG_I("Find rdb key file, set default as DE.");
114         // Add default DE for rdb key file.
115         info->needDe = true;
116     }
117 }
118 
MatchSaConfig(const char * alias,uint32_t uid,uint32_t userId,struct HksUpgradeFileTransferInfo * info)119 static int32_t MatchSaConfig(const char *alias, uint32_t uid, uint32_t userId, struct HksUpgradeFileTransferInfo *info)
120 {
121     InitDefaultStrategy(alias, info);
122     for (uint32_t i = 0; i < HKS_ARRAY_SIZE(SA_SKIP_UPGRADE_CFG_LIST); ++i) {
123         if (uid == SA_SKIP_UPGRADE_CFG_LIST[i]) {
124             HKS_LOG_E_IMPORTANT("%" LOG_PUBLIC "u needs skip transfer upgrade.", uid);
125             info->skipTransfer = true;
126             return HKS_SUCCESS;
127         }
128     }
129 
130     for (uint32_t i = 0; i < HKS_ARRAY_SIZE(SA_UPGRADE_CFG_LIST); ++i) {
131         if (SA_UPGRADE_CFG_LIST[i].uid == uid) {
132             info->needDe = SA_UPGRADE_CFG_LIST[i].needDe;
133             info->needFrontUser = SA_UPGRADE_CFG_LIST[i].needFrontUser;
134             HKS_LOG_E_IMPORTANT("match sa config, need de %" LOG_PUBLIC "d, need with withUser %" LOG_PUBLIC "d,"
135                 "need uid %" LOG_PUBLIC "u.", info->needDe, info->needFrontUser, uid);
136             break;
137         }
138     }
139     info->uid = uid;
140     info->userId = userId;
141     return HKS_SUCCESS;
142 }
143 
MatchHapConfig(const char * alias,uint32_t uid,uint32_t userId,uint64_t accessTokenId,struct HksUpgradeFileTransferInfo * info)144 static int32_t MatchHapConfig(const char *alias, uint32_t uid, uint32_t userId, uint64_t accessTokenId,
145     struct HksUpgradeFileTransferInfo *info)
146 {
147     char hapName[HAP_NAME_LEN_MAX] = { 0 };
148     int32_t ret = HksGetHapNameFromAccessToken(accessTokenId, hapName, HAP_NAME_LEN_MAX);
149     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret,
150         "get hap name from accessTokenId failed, accessTokenId is %" LOG_PUBLIC PRIu64, accessTokenId)
151 
152     InitDefaultStrategy(alias, info);
153     for (uint32_t i = 0; i < HKS_ARRAY_SIZE(HAP_SKIP_UPGRADE_CFG_LIST); ++i) {
154         HKS_IF_TRUE_CONTINUE(strlen(HAP_SKIP_UPGRADE_CFG_LIST[i]) != strlen(hapName));
155         if (HksMemCmp(HAP_SKIP_UPGRADE_CFG_LIST[i], hapName, strlen(hapName)) == EOK) {
156             info->skipTransfer = true;
157             HKS_LOG_E_IMPORTANT("%" LOG_PUBLIC "u, %" LOG_PUBLIC "s needs skip transfer upgrade.", uid, hapName);
158             return HKS_SUCCESS;
159         }
160     }
161     for (uint32_t i = 0; i < HKS_ARRAY_SIZE(HAP_UPGRADE_CFG_LIST); ++i) {
162         HKS_IF_TRUE_CONTINUE(strlen(HAP_UPGRADE_CFG_LIST[i].hapName) != strlen(hapName));
163         if (HksMemCmp(HAP_UPGRADE_CFG_LIST[i].hapName, hapName, strlen(hapName)) == EOK) {
164             info->needDe = HAP_UPGRADE_CFG_LIST[i].needDe;
165             info->needFrontUser = HAP_UPGRADE_CFG_LIST[i].needFrontUser;
166             HKS_LOG_E_IMPORTANT("match hap config, need de %" LOG_PUBLIC "d, need with withUser %" LOG_PUBLIC "d,"
167                 "need uid %" LOG_PUBLIC "u.", info->needDe, info->needFrontUser, uid);
168             break;
169         }
170     }
171     info->uid = uid;
172     info->userId = userId;
173     return HKS_SUCCESS;
174 }
175 
HksMatchConfig(const char * alias,uint32_t uid,uint32_t userId,uint64_t accessTokenId,struct HksUpgradeFileTransferInfo * info)176 int32_t HksMatchConfig(const char *alias, uint32_t uid, uint32_t userId, uint64_t accessTokenId,
177     struct HksUpgradeFileTransferInfo *info)
178 {
179     enum HksAtType type;
180     int32_t ret = HksGetAtType(accessTokenId, &type);
181     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get access token type failed.")
182     if (type == HKS_TOKEN_HAP) {
183         return MatchHapConfig(alias, uid, userId, accessTokenId, info);
184     }
185     return MatchSaConfig(alias, uid, userId, info);
186 }
187 
188 // get transfer config info of a key file, which contains the owner info
HksParseConfig(const char * alias,const struct HksBlob * fileContent,struct HksUpgradeFileTransferInfo * info)189 int32_t HksParseConfig(const char *alias, const struct HksBlob *fileContent, struct HksUpgradeFileTransferInfo *info)
190 {
191     uint32_t uid = 0;
192     uint64_t accessTokenId = 0;
193     uint32_t userId = 0;
194     int32_t ret = ParseOwnerIdFromFileContent(fileContent, &uid, &accessTokenId, &userId);
195     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "parse file failed.")
196     return HksMatchConfig(alias, uid, userId, accessTokenId, info);
197 }