1 /*
2 * Copyright (c) 2023 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_bms_api_wrap.h"
17
18 #include <cJSON.h>
19 #include <cstring>
20 #include <unistd.h>
21 #include "securec.h"
22
23 #include "accesstoken_kit.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27 #include "hap_token_info.h"
28 #include "bundle_mgr_client.h"
29 #include "bundle_info.h"
30
31 #include "hks_log.h"
32 #include "hks_mem.h"
33 #include "hks_template.h"
34
35 #ifdef HKS_CONFIG_FILE
36 #include HKS_CONFIG_FILE
37 #else
38 #include "hks_config.h"
39 #endif
40
41 #define SYSTEM_BASIC "system_basic"
42 #define SYSTEM_CORE "system_core"
43
44 using namespace OHOS;
45 using namespace Security::AccessToken;
46
ConvertCallerInfoToJson(const std::string & idStr,const std::string & extendStr,HksBlob * outInfo,bool isHap)47 static int32_t ConvertCallerInfoToJson(const std::string &idStr, const std::string &extendStr, HksBlob *outInfo,
48 bool isHap)
49 {
50 cJSON *jsonObj = cJSON_CreateObject();
51 HKS_IF_NULL_LOGE_RETURN(jsonObj, HKS_ERROR_NULL_POINTER, "create cjson object failed.")
52
53 const char *jsonKeyId;
54 const char *jsonKeyExtend;
55 if (isHap) {
56 jsonKeyId = "appId";
57 jsonKeyExtend = "bundleName";
58 } else {
59 jsonKeyId = "processName";
60 jsonKeyExtend = "APL";
61 }
62 if ((cJSON_AddStringToObject(jsonObj, jsonKeyId, idStr.c_str()) == nullptr) ||
63 (cJSON_AddStringToObject(jsonObj, jsonKeyExtend, extendStr.c_str()) == nullptr)) {
64 HKS_LOG_E("add string to json object is failed.");
65 cJSON_Delete(jsonObj);
66 return HKS_ERROR_NULL_POINTER;
67 }
68
69 char *jsonStr = cJSON_PrintUnformatted(jsonObj);
70 if (jsonStr == nullptr) {
71 HKS_LOG_E("cJSON_PrintUnformatted failed.");
72 cJSON_Delete(jsonObj);
73 return HKS_ERROR_NULL_POINTER;
74 }
75
76 outInfo->size = strlen(jsonStr);
77 outInfo->data = (uint8_t *)jsonStr;
78 cJSON_Delete(jsonObj);
79 return HKS_SUCCESS;
80 }
81
HksGetCallerType(void)82 enum HksCallerType HksGetCallerType(void)
83 {
84 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
85 switch (AccessTokenKit::GetTokenTypeFlag(callingTokenId)) {
86 case ATokenTypeEnum::TOKEN_HAP:
87 return HKS_HAP_TYPE;
88 case ATokenTypeEnum::TOKEN_NATIVE:
89 case ATokenTypeEnum::TOKEN_SHELL:
90 return HKS_SA_TYPE;
91 default:
92 return HKS_UNIFIED_TYPE;
93 }
94 }
95
HksGetHapInfo(const struct HksProcessInfo * processInfo,struct HksBlob * hapInfo)96 int32_t HksGetHapInfo(const struct HksProcessInfo *processInfo, struct HksBlob *hapInfo)
97 {
98 HKS_IF_NULL_LOGE_RETURN(processInfo, HKS_ERROR_NULL_POINTER, "processInfo is nullptr.")
99 HKS_IF_NULL_LOGE_RETURN(hapInfo, HKS_ERROR_NULL_POINTER, "hapInfo is nullptr.")
100
101 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
102 if (AccessTokenKit::GetTokenType(callingTokenId) != ATokenTypeEnum::TOKEN_HAP) {
103 HKS_LOG_E("caller is not from hap, not support to get hap info.");
104 return HKS_ERROR_NOT_SUPPORTED;
105 }
106
107 HapTokenInfo hapTokenInfo;
108 int32_t callingResult = AccessTokenKit::GetHapTokenInfo(callingTokenId, hapTokenInfo);
109 if (callingResult != HKS_SUCCESS) {
110 HKS_LOG_E("Get hap info failed from access token kit.");
111 return HKS_ERROR_BAD_STATE;
112 }
113
114 AppExecFwk::BundleInfo bundleInfo;
115 AppExecFwk::BundleMgrClient client;
116 bool isGetInfoSuccess = client.GetBundleInfo(hapTokenInfo.bundleName,
117 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_HASH_VALUE, bundleInfo, processInfo->userIdInt);
118 if (!isGetInfoSuccess) {
119 HKS_LOG_E("GetBundleInfo failed.");
120 return HKS_ERROR_BAD_STATE;
121 }
122
123 // The appid is concatenated from the bundle name and the developer's public key certificate.
124 int32_t ret = ConvertCallerInfoToJson(bundleInfo.appId, hapTokenInfo.bundleName, hapInfo, true);
125 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ConvertHapInfoToJson failed.")
126
127 return HKS_SUCCESS;
128 }
129
HksGetHapPkgName(const struct HksProcessInfo * processInfo,struct HksBlob * hapPkgName)130 static int32_t HksGetHapPkgName(const struct HksProcessInfo *processInfo, struct HksBlob *hapPkgName)
131 {
132 HKS_IF_NULL_LOGE_RETURN(processInfo, HKS_ERROR_NULL_POINTER, "processInfo is nullptr.")
133 HKS_IF_NULL_LOGE_RETURN(hapPkgName, HKS_ERROR_NULL_POINTER, "hapPkgName is nullptr.")
134
135 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
136 if (AccessTokenKit::GetTokenType(callingTokenId) != ATokenTypeEnum::TOKEN_HAP) {
137 HKS_LOG_E("caller is not from hap, not support to get hap info.");
138 return HKS_ERROR_NOT_SUPPORTED;
139 }
140
141 HapTokenInfo hapTokenInfo;
142 int32_t callingResult = AccessTokenKit::GetHapTokenInfo(callingTokenId, hapTokenInfo);
143 if (callingResult != HKS_SUCCESS) {
144 HKS_LOG_E("Get hap info failed from access token kit.");
145 return HKS_ERROR_BAD_STATE;
146 }
147
148 uint32_t size = strlen(hapTokenInfo.bundleName.c_str());
149 uint8_t *pkgName = (uint8_t *)HksMalloc(size);
150 HKS_IF_NULL_LOGE_RETURN(pkgName, HKS_ERROR_MALLOC_FAIL, "malloc for pkgName failed.")
151
152 (void)memcpy_s(pkgName, size, hapTokenInfo.bundleName.c_str(), size);
153
154 hapPkgName->size = size;
155 hapPkgName->data = pkgName;
156 return HKS_SUCCESS;
157 }
158
HksGetSaInfo(const struct HksProcessInfo * processInfo,struct HksBlob * saInfo)159 int32_t HksGetSaInfo(const struct HksProcessInfo *processInfo, struct HksBlob *saInfo)
160 {
161 HKS_IF_NULL_LOGE_RETURN(processInfo, HKS_ERROR_NULL_POINTER, "processInfo is nullptr.")
162 HKS_IF_NULL_LOGE_RETURN(saInfo, HKS_ERROR_NULL_POINTER, "saInfo is nullptr.")
163
164 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
165 if (AccessTokenKit::GetTokenType(callingTokenId) == ATokenTypeEnum::TOKEN_HAP) {
166 HKS_LOG_E("Error caller Type, cannot get SaInfo");
167 return HKS_ERROR_NOT_SUPPORTED;
168 }
169 NativeTokenInfo saTokenInfo;
170 int32_t ret = AccessTokenKit::GetNativeTokenInfo(callingTokenId, saTokenInfo);
171 if (ret != AccessTokenKitRet::RET_SUCCESS) {
172 HKS_LOG_E("Get sa info failed from access token kit.");
173 return HKS_ERROR_BAD_STATE;
174 }
175
176 if (saTokenInfo.apl == ATokenAplEnum::APL_SYSTEM_BASIC) {
177 ret = ConvertCallerInfoToJson(saTokenInfo.processName, SYSTEM_BASIC, saInfo, false);
178 } else if (saTokenInfo.apl == ATokenAplEnum::APL_SYSTEM_CORE) {
179 ret = ConvertCallerInfoToJson(saTokenInfo.processName, SYSTEM_CORE, saInfo, false);
180 } else {
181 HKS_LOG_E("The normal process, hide the caller information.");
182 ret = ConvertCallerInfoToJson("", "", saInfo, false);
183 }
184 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ConvertSaInfoToJson failed.")
185 return HKS_SUCCESS;
186 }
187
HksGetSaProcessName(const struct HksProcessInfo * processInfo,struct HksBlob * saProcessName)188 static int32_t HksGetSaProcessName(const struct HksProcessInfo *processInfo, struct HksBlob *saProcessName)
189 {
190 HKS_IF_NULL_LOGE_RETURN(processInfo, HKS_ERROR_NULL_POINTER, "processInfo is nullptr.")
191 HKS_IF_NULL_LOGE_RETURN(saProcessName, HKS_ERROR_NULL_POINTER, "saProcessName is nullptr.")
192
193 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
194 if (AccessTokenKit::GetTokenType(callingTokenId) == ATokenTypeEnum::TOKEN_HAP) {
195 HKS_LOG_E("Error caller Type, cannot get SaInfo");
196 return HKS_ERROR_NOT_SUPPORTED;
197 }
198 NativeTokenInfo saTokenInfo;
199 int32_t ret = AccessTokenKit::GetNativeTokenInfo(callingTokenId, saTokenInfo);
200 if (ret != AccessTokenKitRet::RET_SUCCESS) {
201 HKS_LOG_E("Get sa info failed from access token kit.");
202 return HKS_ERROR_BAD_STATE;
203 }
204
205 uint32_t size = strlen(saTokenInfo.processName.c_str());
206 uint8_t *processName = (uint8_t *)HksMalloc(size);
207 HKS_IF_NULL_LOGE_RETURN(processName, HKS_ERROR_MALLOC_FAIL, "malloc for processName failed.")
208
209 (void)memcpy_s(processName, size, saTokenInfo.processName.c_str(), size);
210
211 saProcessName->size = size;
212 saProcessName->data = processName;
213 return HKS_SUCCESS;
214 }
215
GetCallerName(const struct HksProcessInfo * processInfo,struct HksBlob * appInfo)216 int32_t GetCallerName(const struct HksProcessInfo *processInfo, struct HksBlob *appInfo)
217 {
218 int32_t ret;
219 enum HksCallerType appidType = HksGetCallerType();
220 if (appidType == HKS_HAP_TYPE) {
221 ret = HksGetHapPkgName(processInfo, appInfo);
222 HKS_IF_NOT_SUCC_LOGE(ret, "HksGetHapPkgName failed")
223 } else if (appidType == HKS_SA_TYPE) {
224 ret = HksGetSaProcessName(processInfo, appInfo);
225 HKS_IF_NOT_SUCC_LOGE(ret, "HksGetSaProcessName failed")
226 } else {
227 HKS_LOG_E("invalid appidType!");
228 return HKS_ERROR_BAD_STATE;
229 }
230 return ret;
231 }