• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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