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