1 /*
2 * Copyright (C) 2025 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 "cred_session_util.h"
17
18 #include "hc_log.h"
19 #include "identity_service.h"
20 #include "device_auth.h"
21 #include "common_defs.h"
22 #include "device_auth_common.h"
23 #include "hc_types.h"
24 #include "hc_dev_info.h"
25 #include "json_utils.h"
26 #include "alg_defs.h"
27 #include "alg_loader.h"
28 #include "string_util.h"
29 #include "os_account_adapter.h"
30 #include "identity_service_defines.h"
31
AddCredIdToContextIfNeeded(CJson * context)32 static int32_t AddCredIdToContextIfNeeded(CJson *context)
33 {
34 CJson *credJson = GetObjFromJson(context, FIELD_CREDENTIAL_OBJ);
35 if (credJson == NULL) {
36 LOGE("Get self credential fail.");
37 return HC_ERR_JSON_GET;
38 }
39 uint8_t credType = ACCOUNT_RELATED;
40 if (GetUint8FromJson(context, FIELD_CRED_TYPE, &credType) != HC_SUCCESS) {
41 LOGE("Get credential type fail.");
42 return HC_ERR_JSON_GET;
43 }
44 if (credType != ACCOUNT_SHARED) {
45 LOGI("No need to add across account credential id to context");
46 return HC_SUCCESS;
47 }
48 const char *credId = GetStringFromJson(context, FIELD_CRED_ID);
49 if (AddStringToJson(context, FIELD_ACROSS_ACCOUNT_CRED_ID, credId) != HC_SUCCESS) {
50 LOGE("add across account credential id to context fail.");
51 return HC_ERR_JSON_ADD;
52 }
53 return HC_SUCCESS;
54 }
55
GetAppIdByContext(const CJson * context)56 static const char *GetAppIdByContext(const CJson *context)
57 {
58 const char *pinCode = GetStringFromJson(context, FIELD_PIN_CODE);
59 if (pinCode == NULL) {
60 const CJson *json = GetObjFromJson(context, FIELD_CREDENTIAL_OBJ);
61 if (json == NULL) {
62 LOGE("get self credential info from json fail.");
63 return NULL;
64 }
65 const char *appId = GetStringFromJson(json, FIELD_CRED_OWNER);
66 if (appId == NULL) {
67 LOGE("get appId from json fail.");
68 return NULL;
69 }
70 return appId;
71 }
72 const char *appId = GetStringFromJson(context, FIELD_SERVICE_PKG_NAME);
73 if (appId == NULL) {
74 LOGE("get servicePkgName from json fail.");
75 return NULL;
76 }
77 return appId;
78 }
79
AddUserIdHashHexStringToContext(CJson * context,CJson * credAuthInfo)80 static int32_t AddUserIdHashHexStringToContext(CJson *context, CJson *credAuthInfo)
81 {
82 uint8_t credType = ACCOUNT_UNRELATED;
83 if (GetUint8FromJson(credAuthInfo, FIELD_CRED_TYPE, &credType) != HC_SUCCESS) {
84 LOGE("get int from json failed!");
85 return HC_ERR_JSON_GET;
86 }
87 if (credType == ACCOUNT_UNRELATED) {
88 return HC_SUCCESS;
89 }
90 const char *userId = GetStringFromJson(credAuthInfo, FIELD_USER_ID);
91 if (userId == NULL) {
92 LOGE("Failed to get user ID!");
93 return HC_ERR_JSON_GET;
94 }
95 Uint8Buff userIdBuf = { (uint8_t *)userId, (uint32_t)HcStrlen(userId) };
96 uint8_t userIdHashByte[SHA256_LEN] = { 0 };
97 Uint8Buff userIdHashBuf = { userIdHashByte, sizeof(userIdHashByte) };
98 int32_t res = GetLoaderInstance()->sha256(&userIdBuf, &userIdHashBuf);
99 if (res != HC_SUCCESS) {
100 LOGE("sha256 failed, res:%" LOG_PUB "d", res);
101 return res;
102 }
103 uint32_t userIdHashLen = SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1;
104 char *userIdHash = (char *)HcMalloc(userIdHashLen, 0);
105 if (userIdHash == NULL) {
106 LOGE("malloc userIdHash string failed");
107 return HC_ERR_ALLOC_MEMORY;
108 }
109 res = ByteToHexString(userIdHashByte, SHA256_LEN, userIdHash, userIdHashLen);
110 if (res != HC_SUCCESS) {
111 LOGE("Byte to hexString failed, res:%" LOG_PUB "d", res);
112 HcFree(userIdHash);
113 return res;
114 }
115 //replace userId plain to hash hex string
116 if (AddStringToJson(context, FIELD_USER_ID, userIdHash) != HC_SUCCESS) {
117 LOGE("Failed to add userIdHash");
118 HcFree(userIdHash);
119 return HC_ERR_JSON_ADD;
120 }
121 HcFree(userIdHash);
122 return res;
123 }
124
QueryAndAddSelfCredToContext(int32_t osAccountId,CJson * context)125 static int32_t QueryAndAddSelfCredToContext(int32_t osAccountId, CJson *context)
126 {
127 const char *credId = GetStringFromJson(context, FIELD_CRED_ID);
128 if (credId == NULL) {
129 LOGE("get self credential id from json fail.");
130 return HC_ERR_JSON_GET;
131 }
132 PRINT_SENSITIVE_DATA("credId", credId);
133 char *credDataStr = NULL;
134 int32_t ret = QueryCredInfoByCredId(osAccountId, credId, &credDataStr);
135 if (ret != HC_SUCCESS) {
136 LOGE("No credential found.");
137 return ret;
138 }
139 CJson *credDataJson = CreateJsonFromString(credDataStr);
140 FreeJsonString(credDataStr);
141 if (credDataJson == NULL) {
142 LOGE("Faild to create json from string");
143 return HC_ERR_JSON_FAIL;
144 }
145 int32_t res = AddUserIdHashHexStringToContext(context, credDataJson);
146 if (res != HC_SUCCESS) {
147 FreeJson(credDataJson);
148 LOGE("Failed to replace userId plain to hash hex string!");
149 return res;
150 }
151 if (AddObjToJson(context, FIELD_CREDENTIAL_OBJ, credDataJson) != HC_SUCCESS) {
152 LOGE("add local credential object to context fail.");
153 FreeJson(credDataJson);
154 return HC_ERR_JSON_ADD;
155 }
156 FreeJson(credDataJson);
157 return HC_SUCCESS;
158 }
159
CheckIsCredBind(CJson * context)160 static bool CheckIsCredBind(CJson *context)
161 {
162 const char *pinCode = GetStringFromJson(context, FIELD_PIN_CODE);
163 bool isBind = true;
164 if (pinCode == NULL || HcStrlen(pinCode) == 0) {
165 isBind = false;
166 }
167 return isBind;
168 }
169
AddAuthIdToCredContext(CJson * context)170 static int32_t AddAuthIdToCredContext(CJson *context)
171 {
172 const char *authId = GetStringFromJson(context, FIELD_DEVICE_ID);
173 char udid[INPUT_UDID_LEN] = { 0 };
174 if (authId == NULL) {
175 LOGD("No authId is found. The default value is udid!");
176 int32_t res = HcGetUdid((uint8_t *)udid, INPUT_UDID_LEN);
177 if (res != HC_SUCCESS) {
178 LOGE("Failed to get local udid! res: %" LOG_PUB "d", res);
179 return HC_ERR_DB;
180 }
181 authId = udid;
182 }
183 if (AddStringToJson(context, FIELD_AUTH_ID, authId) != HC_SUCCESS) {
184 LOGE("Failed to add authId to params!");
185 return HC_ERR_JSON_FAIL;
186 }
187 return HC_SUCCESS;
188 }
189
BuildClientCredBindContext(int32_t osAccountId,int64_t requestId,CJson * context,const char ** returnAppId)190 static int32_t BuildClientCredBindContext(int32_t osAccountId, int64_t requestId,
191 CJson *context, const char **returnAppId)
192 {
193 const char *appId = GetAppIdByContext(context);
194 if (appId == NULL) {
195 LOGE("get appId fail.");
196 return HC_ERR_JSON_GET;
197 }
198 if (AddStringToJson(context, FIELD_APP_ID, appId) != HC_SUCCESS) {
199 LOGE("add appId to context fail.");
200 return HC_ERR_JSON_ADD;
201 }
202 if (AddBoolToJson(context, FIELD_IS_BIND, true) != HC_SUCCESS) {
203 LOGE("add isBind to context fail.");
204 return HC_ERR_JSON_ADD;
205 }
206 if (AddBoolToJson(context, FIELD_IS_CLIENT, true) != HC_SUCCESS) {
207 LOGE("add isClient to context fail.");
208 return HC_ERR_JSON_ADD;
209 }
210 if (AddBoolToJson(context, FIELD_IS_CRED_AUTH, true) != HC_SUCCESS) {
211 LOGE("add isCredAuth to context fail.");
212 return HC_ERR_JSON_ADD;
213 }
214 if (AddIntToJson(context, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
215 LOGE("add osAccountId to context fail.");
216 return HC_ERR_JSON_ADD;
217 }
218 if (AddInt64StringToJson(context, FIELD_REQUEST_ID, requestId) != HC_SUCCESS) {
219 LOGE("add requestId to context fail.");
220 return HC_ERR_JSON_ADD;
221 }
222 if (AddIntToJson(context, FIELD_OPERATION_CODE, AUTH_FORM_ACCOUNT_UNRELATED) != HC_SUCCESS) {
223 LOGE("add opCode to context fail.");
224 return HC_ERR_JSON_ADD;
225 }
226 if (AddAuthIdToCredContext(context)) {
227 return HC_ERR_JSON_ADD;
228 }
229 *returnAppId = appId;
230 return AddChannelInfoToContext(SERVICE_CHANNEL, DEFAULT_CHANNEL_ID, context);
231 }
232
SetContextOpCode(CJson * context)233 static int32_t SetContextOpCode(CJson *context)
234 {
235 uint8_t credType = ACCOUNT_UNRELATED;
236 if (GetUint8FromJson(context, FIELD_CRED_TYPE, &credType) != HC_SUCCESS) {
237 LOGE("get int from json failed!");
238 return HC_ERR_JSON_GET;
239 }
240 switch (credType) {
241 case ACCOUNT_RELATED:
242 if (AddIntToJson(context, FIELD_OPERATION_CODE, AUTH_FORM_IDENTICAL_ACCOUNT) != HC_SUCCESS) {
243 LOGE("add identical account code to context fail.");
244 return HC_ERR_JSON_ADD;
245 }
246 break;
247 case ACCOUNT_UNRELATED:
248 if (AddIntToJson(context, FIELD_OPERATION_CODE, AUTH_FORM_ACCOUNT_UNRELATED) != HC_SUCCESS) {
249 LOGE("add account unrelated code to context fail.");
250 return HC_ERR_JSON_ADD;
251 }
252 break;
253 case ACCOUNT_SHARED:
254 if (AddIntToJson(context, FIELD_OPERATION_CODE, AUTH_FORM_ACROSS_ACCOUNT) != HC_SUCCESS) {
255 LOGE("add across account code to context fail.");
256 return HC_ERR_JSON_ADD;
257 }
258 break;
259 default:
260 LOGE("unsupport cred type.");
261 return HC_ERR_UNSUPPORTED_OPCODE;
262 }
263 return HC_SUCCESS;
264 }
265
BuildClientCredAuthContext(int32_t osAccountId,int64_t requestId,CJson * context,const char ** returnAppId)266 static int32_t BuildClientCredAuthContext(int32_t osAccountId, int64_t requestId,
267 CJson *context, const char **returnAppId)
268 {
269 int32_t res = QueryAndAddSelfCredToContext(osAccountId, context);
270 if (res != HC_SUCCESS) {
271 return res;
272 }
273 const char *appId = GetAppIdByContext(context);
274 if (appId == NULL) {
275 LOGE("get appId fail.");
276 return HC_ERR_JSON_GET;
277 }
278 if (AddStringToJson(context, FIELD_APP_ID, appId) != HC_SUCCESS) {
279 LOGE("add appId to context fail.");
280 return HC_ERR_JSON_ADD;
281 }
282 if (AddBoolToJson(context, FIELD_IS_BIND, false) != HC_SUCCESS) {
283 LOGE("add isBind to context fail.");
284 return HC_ERR_JSON_ADD;
285 }
286 if (AddBoolToJson(context, FIELD_IS_CLIENT, true) != HC_SUCCESS) {
287 LOGE("add isClient to context fail.");
288 return HC_ERR_JSON_ADD;
289 }
290 if (AddBoolToJson(context, FIELD_IS_CRED_AUTH, true) != HC_SUCCESS) {
291 LOGE("add isCredAuth to context fail.");
292 return HC_ERR_JSON_ADD;
293 }
294 if (AddIntToJson(context, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
295 LOGE("add osAccountId to context fail.");
296 return HC_ERR_JSON_ADD;
297 }
298 if (AddInt64StringToJson(context, FIELD_REQUEST_ID, requestId) != HC_SUCCESS) {
299 LOGE("add requestId to context fail.");
300 return HC_ERR_JSON_ADD;
301 }
302 if (SetContextOpCode(context) != HC_SUCCESS) {
303 LOGE("add opCode to context fail.");
304 return HC_ERR_JSON_ADD;
305 }
306 if (AddCredIdToContextIfNeeded(context) != HC_SUCCESS) {
307 LOGE("add across account credential id to context fail.");
308 return HC_ERR_JSON_ADD;
309 }
310 *returnAppId = appId;
311 return AddChannelInfoToContext(SERVICE_CHANNEL, DEFAULT_CHANNEL_ID, context);
312 }
313
BuildClientCredContext(int32_t osAccountId,int64_t requestId,CJson * context,const char ** returnAppId)314 int32_t BuildClientCredContext(int32_t osAccountId, int64_t requestId, CJson *context, const char **returnAppId)
315 {
316 if (context == NULL) {
317 LOGE("input context is null ptr!");
318 return HC_ERR_INVALID_PARAMS;
319 }
320 if (CheckIsCredBind(context)) {
321 return BuildClientCredBindContext(osAccountId, requestId, context, returnAppId);
322 }
323 return BuildClientCredAuthContext(osAccountId, requestId, context, returnAppId);
324 }
325
BuildServerCredBindContext(int64_t requestId,CJson * context,char ** returnPeerUdid,const char ** returnAppId)326 static int32_t BuildServerCredBindContext(int64_t requestId, CJson *context,
327 char **returnPeerUdid, const char **returnAppId)
328 {
329 int32_t res = CheckConfirmationExist(context);
330 if (res != HC_SUCCESS) {
331 return res;
332 }
333 res = AddOsAccountIdToContextIfValid(context);
334 if (res != HC_SUCCESS) {
335 return res;
336 }
337 if (AddBoolToJson(context, FIELD_IS_BIND, true) != HC_SUCCESS) {
338 LOGE("add isBind to context fail.");
339 return HC_ERR_JSON_ADD;
340 }
341 if (AddBoolToJson(context, FIELD_IS_CLIENT, false) != HC_SUCCESS) {
342 LOGE("add isClient to context fail.");
343 return HC_ERR_JSON_ADD;
344 }
345 const char *appId = GetAppIdByContext(context);
346 if (appId == NULL) {
347 LOGE("get appId Fail.");
348 return HC_ERR_JSON_GET;
349 }
350 if (AddStringToJson(context, FIELD_APP_ID, appId) != HC_SUCCESS) {
351 LOGE("add appId to context fail.");
352 return HC_ERR_JSON_ADD;
353 }
354 if (AddBoolToJson(context, FIELD_IS_CRED_AUTH, true) != HC_SUCCESS) {
355 LOGE("add isCredAuth to context fail.");
356 return HC_ERR_JSON_ADD;
357 }
358 if (AddInt64StringToJson(context, FIELD_REQUEST_ID, requestId) != HC_SUCCESS) {
359 LOGE("add requestId to context fail.");
360 return HC_ERR_JSON_ADD;
361 }
362 if (AddAuthIdToCredContext(context)) {
363 return HC_ERR_JSON_ADD;
364 }
365 *returnAppId = appId;
366 return AddChannelInfoToContext(SERVICE_CHANNEL, DEFAULT_CHANNEL_ID, context);
367 }
368
BuildServerCredAuthContext(int64_t requestId,CJson * context,char ** returnPeerUdid,const char ** returnAppId)369 static int32_t BuildServerCredAuthContext(int64_t requestId, CJson *context,
370 char **returnPeerUdid, const char **returnAppId)
371 {
372 int32_t res = CheckConfirmationExist(context);
373 if (res != HC_SUCCESS) {
374 return res;
375 }
376 res = AddOsAccountIdToContextIfValid(context);
377 if (res != HC_SUCCESS) {
378 return res;
379 }
380 int32_t osAccountId = ANY_OS_ACCOUNT;
381 (void)GetIntFromJson(context, FIELD_OS_ACCOUNT_ID, &osAccountId);
382 if (AddBoolToJson(context, FIELD_IS_BIND, false) != HC_SUCCESS) {
383 LOGE("add isBind to context fail.");
384 return HC_ERR_JSON_ADD;
385 }
386 if (AddBoolToJson(context, FIELD_IS_CLIENT, false) != HC_SUCCESS) {
387 LOGE("add isClient to context fail.");
388 return HC_ERR_JSON_ADD;
389 }
390 if ((res = QueryAndAddSelfCredToContext(osAccountId, context)) != HC_SUCCESS ||
391 ((res = AddCredIdToContextIfNeeded(context)) != HC_SUCCESS)) {
392 return res;
393 }
394 const char *appId = GetAppIdByContext(context);
395 if (appId == NULL) {
396 LOGE("get appId Fail.");
397 return HC_ERR_JSON_GET;
398 }
399 if (AddBoolToJson(context, FIELD_IS_CRED_AUTH, true) != HC_SUCCESS) {
400 LOGE("add isCredAuth to context fail.");
401 return HC_ERR_JSON_ADD;
402 }
403 if (AddStringToJson(context, FIELD_APP_ID, appId) != HC_SUCCESS) {
404 LOGE("add appId to context fail.");
405 return HC_ERR_JSON_ADD;
406 }
407 if (AddInt64StringToJson(context, FIELD_REQUEST_ID, requestId) != HC_SUCCESS) {
408 LOGE("add requestId to context fail.");
409 return HC_ERR_JSON_ADD;
410 }
411 *returnAppId = appId;
412 return AddChannelInfoToContext(SERVICE_CHANNEL, DEFAULT_CHANNEL_ID, context);
413 }
414
BuildServerCredContext(int64_t requestId,CJson * context,char ** returnPeerUdid,const char ** returnAppId)415 int32_t BuildServerCredContext(int64_t requestId, CJson *context, char **returnPeerUdid, const char **returnAppId)
416 {
417 if (context == NULL) {
418 LOGE("input context is null ptr!");
419 return HC_ERR_INVALID_PARAMS;
420 }
421 if (CheckIsCredBind(context)) {
422 return BuildServerCredBindContext(requestId, context, returnPeerUdid, returnAppId);
423 }
424 return BuildServerCredAuthContext(requestId, context, returnPeerUdid, returnAppId);
425 }
426