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 }