• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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 "alg_defs.h"
17 #include "alg_loader.h"
18 #include "das_standard_token_manager.h"
19 #include "hc_dev_info.h"
20 #include "hc_log.h"
21 #include "identity_manager.h"
22 #include "os_account_adapter.h"
23 #include "hisysevent_common.h"
24 #include "string_util.h"
25 
26 typedef struct {
27     int32_t osAccountId;
28     int32_t peerOsAccountId;
29     int32_t acquireType;
30     char *deviceId;
31     int32_t flag;
32     Uint8Buff publicKey;
33     char *serviceType;
34 } CredentialRequestParam;
35 
CombineServiceId(const Uint8Buff * pkgName,const Uint8Buff * serviceType,Uint8Buff * serviceId)36 static int32_t CombineServiceId(const Uint8Buff *pkgName, const Uint8Buff *serviceType, Uint8Buff *serviceId)
37 {
38     int32_t res = HC_SUCCESS;
39     Uint8Buff serviceIdPlain = { NULL, 0 };
40     serviceIdPlain.length = pkgName->length + serviceType->length;
41     serviceIdPlain.val = (uint8_t *)HcMalloc(serviceIdPlain.length, 0);
42     if (serviceIdPlain.val == NULL) {
43         LOGE("malloc serviceIdPlain.val failed.");
44         res = HC_ERR_ALLOC_MEMORY;
45         goto ERR;
46     }
47     if (memcpy_s(serviceIdPlain.val, serviceIdPlain.length, pkgName->val, pkgName->length) != EOK) {
48         LOGE("Copy service id: pkgName failed.");
49         res = HC_ERR_MEMORY_COPY;
50         goto ERR;
51     }
52     if (memcpy_s(serviceIdPlain.val + pkgName->length, serviceIdPlain.length - pkgName->length, serviceType->val,
53         serviceType->length) != EOK) {
54         LOGE("Copy service id: serviceType failed.");
55         res = HC_ERR_MEMORY_COPY;
56         goto ERR;
57     }
58     res = GetLoaderInstance()->sha256(&serviceIdPlain, serviceId);
59     if (res != HC_SUCCESS) {
60         LOGE("Sha256 serviceId  failed.");
61         goto ERR;
62     }
63 ERR:
64     HcFree(serviceIdPlain.val);
65     return res;
66 }
67 
IsPeerDevice(const Uint8Buff * authId)68 static bool IsPeerDevice(const Uint8Buff *authId)
69 {
70     char selfUdid[INPUT_UDID_LEN] = { 0 };
71     int32_t res = HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
72     if (res != HC_SUCCESS) {
73         LOGE("Failed to get local udid! res: %" LOG_PUB "d.", res);
74         return false;
75     }
76     char *authIdStr = (char *)HcMalloc(authId->length + 1, 0);
77     if (authIdStr == NULL) {
78         LOGE("Failed to alloc memory for authIdStr!");
79         return false;
80     }
81     if (memcpy_s(authIdStr, authId->length + 1, authId->val, authId->length) != EOK) {
82         LOGE("Failed to copy authId!");
83         HcFree(authIdStr);
84         return false;
85     }
86     bool isPeerDevice = !IsStrEqual(selfUdid, authIdStr);
87     HcFree(authIdStr);
88     return isPeerDevice;
89 }
90 
FillKeyAlias(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * keyAliasBuff)91 static int32_t FillKeyAlias(const Uint8Buff *serviceId, const Uint8Buff *keyType, const Uint8Buff *authId,
92     Uint8Buff *keyAliasBuff)
93 {
94     uint32_t totalLen = keyAliasBuff->length;
95     uint32_t usedLen = 0;
96     if (memcpy_s(keyAliasBuff->val, totalLen, serviceId->val, serviceId->length) != EOK) {
97         LOGE("Error occurs, Copy serviceId failed.");
98         return HC_ERR_MEMORY_COPY;
99     }
100     usedLen = usedLen + serviceId->length;
101     if (memcpy_s(keyAliasBuff->val + usedLen, totalLen - usedLen, keyType->val, keyType->length) != EOK) {
102         LOGE("Error occurs, Copy keyType failed.");
103         return HC_ERR_MEMORY_COPY;
104     }
105     usedLen = usedLen + keyType->length;
106     if (memcpy_s(keyAliasBuff->val + usedLen, totalLen - usedLen, authId->val, authId->length) != EOK) {
107         LOGE("Error occurs, Copy authId failed.");
108         return HC_ERR_MEMORY_COPY;
109     }
110     return HC_SUCCESS;
111 }
112 
FillKeyAliasWithPeerOsAccId(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,int32_t peerOsAccountId,Uint8Buff * keyAliasBuff)113 static int32_t FillKeyAliasWithPeerOsAccId(const Uint8Buff *serviceId, const Uint8Buff *keyType,
114     const Uint8Buff *authId, int32_t peerOsAccountId, Uint8Buff *keyAliasBuff)
115 {
116     uint32_t totalLen = keyAliasBuff->length;
117     uint32_t usedLen = 0;
118     if (memcpy_s(keyAliasBuff->val, totalLen, serviceId->val, serviceId->length) != EOK) {
119         LOGE("Copy serviceId failed.");
120         return HC_ERR_MEMORY_COPY;
121     }
122     usedLen = usedLen + serviceId->length;
123     if (memcpy_s(keyAliasBuff->val + usedLen, totalLen - usedLen, keyType->val, keyType->length) != EOK) {
124         LOGE("Copy keyType failed.");
125         return HC_ERR_MEMORY_COPY;
126     }
127     usedLen = usedLen + keyType->length;
128     if (memcpy_s(keyAliasBuff->val + usedLen, totalLen - usedLen, authId->val, authId->length) != EOK) {
129         LOGE("Copy authId failed.");
130         return HC_ERR_MEMORY_COPY;
131     }
132     usedLen = usedLen + authId->length;
133     Uint8Buff peerOsAccIdBuff = { (uint8_t *)&peerOsAccountId, sizeof(peerOsAccountId) };
134     if (memcpy_s(keyAliasBuff->val + usedLen, totalLen - usedLen, peerOsAccIdBuff.val,
135         peerOsAccIdBuff.length) != EOK) {
136         LOGE("Copy peerOsAccountId failed.");
137         return HC_ERR_MEMORY_COPY;
138     }
139     return HC_SUCCESS;
140 }
141 
CombineKeyAlias(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,int32_t peerOsAccountId,Uint8Buff * keyAliasHash)142 static int32_t CombineKeyAlias(const Uint8Buff *serviceId, const Uint8Buff *keyType, const Uint8Buff *authId,
143     int32_t peerOsAccountId, Uint8Buff *keyAliasHash)
144 {
145     Uint8Buff keyAliasBuff = { NULL, 0 };
146     bool isPeerDevice = IsPeerDevice(authId);
147     if (isPeerDevice) {
148         keyAliasBuff.length = serviceId->length + authId->length + keyType->length + sizeof(peerOsAccountId);
149     } else {
150         keyAliasBuff.length = serviceId->length + authId->length + keyType->length;
151     }
152     keyAliasBuff.val = (uint8_t *)HcMalloc(keyAliasBuff.length, 0);
153     if (keyAliasBuff.val == NULL) {
154         LOGE("Failed to alloc memory for key alias!");
155         return HC_ERR_ALLOC_MEMORY;
156     }
157     int32_t res = HC_SUCCESS;
158     if (isPeerDevice) {
159         res = FillKeyAliasWithPeerOsAccId(serviceId, keyType, authId, peerOsAccountId, &keyAliasBuff);
160     } else {
161         res = FillKeyAlias(serviceId, keyType, authId, &keyAliasBuff);
162     }
163     if (res != HC_SUCCESS) {
164         LOGE("Failed to fill key alias!");
165         HcFree(keyAliasBuff.val);
166         return res;
167     }
168     res = GetLoaderInstance()->sha256(&keyAliasBuff, keyAliasHash);
169     HcFree(keyAliasBuff.val);
170     if (res != HC_SUCCESS) {
171         LOGE("Sha256 failed!");
172     }
173     return res;
174 }
175 
CombineKeyAliasForPake(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,int32_t peerOsAccountId,Uint8Buff * outKeyAlias)176 static int32_t CombineKeyAliasForPake(const Uint8Buff *serviceId, const Uint8Buff *keyType, const Uint8Buff *authId,
177     int32_t peerOsAccountId, Uint8Buff *outKeyAlias)
178 {
179     if (outKeyAlias->length != SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH) {
180         LOGE("Invalid key alias len!");
181         return HC_ERR_INVALID_LEN;
182     }
183     uint8_t keyAliasHashVal[SHA256_LEN] = { 0 };
184     Uint8Buff keyAliasHash = { keyAliasHashVal, SHA256_LEN };
185     int32_t res = CombineKeyAlias(serviceId, keyType, authId, peerOsAccountId, &keyAliasHash);
186     if (res != HC_SUCCESS) {
187         LOGE("Failed to combine key alias!");
188         return res;
189     }
190 
191     char outKeyAliasHex[SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1] = { 0 };
192     res = ByteToHexString(keyAliasHash.val, keyAliasHash.length, outKeyAliasHex, sizeof(outKeyAliasHex));
193     if (res != HC_SUCCESS) {
194         LOGE("Failed to convert key alias hash to hex!");
195         return res;
196     }
197     if (memcpy_s(outKeyAlias->val, outKeyAlias->length, outKeyAliasHex, HcStrlen(outKeyAliasHex)) != EOK) {
198         LOGE("Failed to copy out key alias hex!");
199         return HC_ERR_MEMORY_COPY;
200     }
201     return HC_SUCCESS;
202 }
203 
GenerateKeyAliasInner(const char * serviceType,const char * authId,int keyAliasType,int32_t peerOsAccountId,Uint8Buff * outKeyAlias)204 static int32_t GenerateKeyAliasInner(const char *serviceType, const char *authId, int keyAliasType,
205     int32_t peerOsAccountId, Uint8Buff *outKeyAlias)
206 {
207     if (HcStrlen(serviceType) == 0 || HcStrlen(authId) == 0) {
208         LOGE("Invalid param len!");
209         return HC_ERR_INVALID_LEN;
210     }
211     if (keyAliasType >= KEY_ALIAS_TYPE_END) {
212         LOGE("Invalid key type!");
213         return HC_ERR_INVALID_PARAMS;
214     }
215     Uint8Buff pkgNameBuff = { (uint8_t *)DEFAULT_PACKAGE_NAME, HcStrlen(DEFAULT_PACKAGE_NAME) };
216     Uint8Buff serviceTypeBuff = { (uint8_t *)serviceType, HcStrlen(serviceType) };
217     Uint8Buff authIdBuff = { (uint8_t *)authId, HcStrlen(authId) };
218     if (pkgNameBuff.length > PACKAGE_NAME_MAX_LEN || serviceTypeBuff.length > SERVICE_TYPE_MAX_LEN ||
219         authIdBuff.length > AUTH_ID_MAX_LEN) {
220         LOGE("Param len over max!");
221         return HC_ERR_INVALID_LEN;
222     }
223 
224     uint8_t serviceId[SHA256_LEN] = { 0 };
225     Uint8Buff serviceIdBuff = { serviceId, SHA256_LEN };
226     int32_t res = CombineServiceId(&pkgNameBuff, &serviceTypeBuff, &serviceIdBuff);
227     if (res != HC_SUCCESS) {
228         LOGE("CombineServiceId failed, res: %" LOG_PUB "d.", res);
229         return res;
230     }
231 
232     Uint8Buff keyTypeBuff = { GetKeyTypePair(keyAliasType), KEY_TYPE_PAIR_LEN };
233     res = CombineKeyAliasForPake(&serviceIdBuff, &keyTypeBuff, &authIdBuff, peerOsAccountId, outKeyAlias);
234     if (res != HC_SUCCESS) {
235         LOGE("CombineKeyAlias failed, keyType: %" LOG_PUB "d, res: %" LOG_PUB "d", keyAliasType, res);
236     }
237     return res;
238 }
239 
ClearCredParam(CredentialRequestParam * param)240 static void ClearCredParam(CredentialRequestParam *param)
241 {
242     if (param == NULL) {
243         return;
244     }
245     if (param->deviceId != NULL) {
246         HcFree(param->deviceId);
247         param->deviceId = NULL;
248     }
249     if (param->serviceType != NULL) {
250         HcFree(param->serviceType);
251         param->serviceType = NULL;
252     }
253     if (param->publicKey.val != NULL) {
254         HcFree(param->publicKey.val);
255         param->publicKey.val = NULL;
256     }
257 }
258 
GetServTypeAndPubKey(const CJson * reqJson,bool isPubKeyNeeded,CredentialRequestParam * param)259 static int32_t GetServTypeAndPubKey(const CJson *reqJson, bool isPubKeyNeeded, CredentialRequestParam *param)
260 {
261     const char *serviceType = GetStringFromJson(reqJson, FIELD_SERVICE_TYPE);
262     int32_t res = HC_SUCCESS;
263     if (serviceType == NULL) {
264         LOGI("serviceType not found, use default value.");
265         res = DeepCopyString(DEFAULT_SERVICE_TYPE, &param->serviceType);
266     } else {
267         res = DeepCopyString(serviceType, &param->serviceType);
268     }
269     if (res != HC_SUCCESS) {
270         LOGE("Failed to copy serviceType!");
271         return res;
272     }
273 
274     if (!isPubKeyNeeded) {
275         return HC_SUCCESS;
276     }
277 
278     const char *publicKeyStr = GetStringFromJson(reqJson, FIELD_PUBLIC_KEY);
279     if (publicKeyStr == NULL) {
280         LOGE("Failed to get public key!");
281         return HC_ERR_JSON_GET;
282     }
283     if (HcStrlen(publicKeyStr) == 0 || HcStrlen(publicKeyStr) > PAKE_ED25519_KEY_STR_LEN) {
284         LOGE("Invalid public key len!");
285         return HC_ERR_INVALID_LEN;
286     }
287     if (InitUint8Buff(&param->publicKey, PAKE_ED25519_KEY_PAIR_LEN) != HC_SUCCESS) {
288         LOGE("Failed to alloc memory for publicKey!");
289         return HC_ERR_ALLOC_MEMORY;
290     }
291     if (GetByteFromJson(reqJson, FIELD_PUBLIC_KEY, param->publicKey.val, param->publicKey.length) !=
292         HC_SUCCESS) {
293         LOGE("Failed to get public key bytes!");
294         return HC_ERR_JSON_GET;
295     }
296     return HC_SUCCESS;
297 }
298 
GetAndCheckOsAccountId(const CJson * reqJson,CredentialRequestParam * param)299 static int32_t GetAndCheckOsAccountId(const CJson *reqJson, CredentialRequestParam *param)
300 {
301     int32_t osAccountId = INVALID_OS_ACCOUNT;
302     if (GetIntFromJson(reqJson, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
303         LOGE("Failed to get osAccountId!");
304         return HC_ERR_JSON_GET;
305     }
306     param->osAccountId = DevAuthGetRealOsAccountLocalId(osAccountId);
307     if (param->osAccountId == INVALID_OS_ACCOUNT) {
308         LOGE("Invalid osAccountId!");
309         return HC_ERR_INVALID_PARAMS;
310     }
311     return HC_SUCCESS;
312 }
313 
GetAndCheckAcquireType(const CJson * reqJson,CredentialRequestParam * param)314 static int32_t GetAndCheckAcquireType(const CJson *reqJson, CredentialRequestParam *param)
315 {
316     if (GetIntFromJson(reqJson, FIELD_ACQURIED_TYPE, &param->acquireType) != HC_SUCCESS) {
317         LOGE("Failed to get acquireType!");
318         return HC_ERR_JSON_GET;
319     }
320     if (param->acquireType != P2P_BIND) {
321         LOGE("acquireType invalid! only P2P_BIND is allowed now!");
322         return HC_ERR_INVALID_PARAMS;
323     }
324     return HC_SUCCESS;
325 }
326 
GetPeerOsAccountId(const CJson * reqJson,const char * deviceId,int32_t * peerOsAccountId)327 static int32_t GetPeerOsAccountId(const CJson *reqJson, const char *deviceId, int32_t *peerOsAccountId)
328 {
329     Uint8Buff authIdBuff = { (uint8_t *)deviceId, HcStrlen(deviceId) };
330     if (!IsPeerDevice(&authIdBuff)) {
331         LOGI("Not peer device operation, peer osAccountId is not needed.");
332         return HC_SUCCESS;
333     }
334     if (GetIntFromJson(reqJson, FIELD_PEER_OS_ACCOUNT_ID, peerOsAccountId) != HC_SUCCESS) {
335         LOGE("Failed to get peer osAccountId!");
336         return HC_ERR_JSON_GET;
337     }
338     return HC_SUCCESS;
339 }
340 
GenerateRequestParamFromJson(const char * reqJsonStr,bool isPubKeyNeeded,CredentialRequestParam * param)341 static int32_t GenerateRequestParamFromJson(const char *reqJsonStr, bool isPubKeyNeeded,
342     CredentialRequestParam *param)
343 {
344     CJson *reqJson = CreateJsonFromString(reqJsonStr);
345     if (reqJson == NULL) {
346         LOGE("Failed to create request json!");
347         return HC_ERR_JSON_CREATE;
348     }
349     int32_t res = HC_SUCCESS;
350     do {
351         res = GetAndCheckOsAccountId(reqJson, param);
352         if (res != HC_SUCCESS) {
353             break;
354         }
355         res = GetAndCheckAcquireType(reqJson, param);
356         if (res != HC_SUCCESS) {
357             break;
358         }
359         if (GetIntFromJson(reqJson, FIELD_CRED_OP_FLAG, &param->flag) != HC_SUCCESS) {
360             LOGI("reqJsonStr not contains flag!");
361         }
362         const char *deviceId = GetStringFromJson(reqJson, FIELD_DEVICE_ID);
363         if (deviceId == NULL) {
364             LOGE("Failed to get deviceId!");
365             res = HC_ERR_JSON_GET;
366             break;
367         }
368         if (DeepCopyString(deviceId, &param->deviceId) != HC_SUCCESS) {
369             LOGE("Failed to copy deviceId!");
370             res = HC_ERR_MEMORY_COPY;
371             break;
372         }
373         res = GetPeerOsAccountId(reqJson, deviceId, &param->peerOsAccountId);
374         if (res != HC_SUCCESS) {
375             break;
376         }
377         res = GetServTypeAndPubKey(reqJson, isPubKeyNeeded, param);
378     } while (0);
379     FreeJson(reqJson);
380     if (res != HC_SUCCESS) {
381         ClearCredParam(param);
382     }
383     return res;
384 }
385 
CheckKeyExistByParam(const CredentialRequestParam * param)386 static int32_t CheckKeyExistByParam(const CredentialRequestParam *param)
387 {
388     uint8_t keyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
389     Uint8Buff keyAliasBuff = { keyAliasVal, PAKE_KEY_ALIAS_LEN };
390     int32_t res = GenerateKeyAliasInner(param->serviceType, param->deviceId,
391         KEY_ALIAS_P2P_AUTH, param->peerOsAccountId, &keyAliasBuff);
392     if (res != HC_SUCCESS) {
393         LOGE("Failed to generate identity key alias!");
394         return res;
395     }
396     LOGI("Key alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.", keyAliasVal[DEV_AUTH_ZERO],
397         keyAliasVal[DEV_AUTH_ONE], keyAliasVal[DEV_AUTH_TWO], keyAliasVal[DEV_AUTH_THREE]);
398 
399     res = GetLoaderInstance()->checkKeyExist(&keyAliasBuff, false, param->osAccountId);
400     if (res != HC_SUCCESS) {
401         LOGE("Identity key not exists!");
402         return HC_ERR_LOCAL_IDENTITY_NOT_EXIST;
403     }
404     return HC_SUCCESS;
405 }
406 
AddPubKeyToReturnData(const CredentialRequestParam * param,CJson * returnDataJson)407 static int32_t AddPubKeyToReturnData(const CredentialRequestParam *param, CJson *returnDataJson)
408 {
409     TokenManagerParams params = {
410         .osAccountId = param->osAccountId,
411         .peerOsAccountId = param->peerOsAccountId,
412         .pkgName = { (uint8_t *)DEFAULT_PACKAGE_NAME, HcStrlen(DEFAULT_PACKAGE_NAME) },
413         .serviceType = { (uint8_t *)param->serviceType, HcStrlen(param->serviceType) },
414         .authId = { (uint8_t *)param->deviceId, HcStrlen(param->deviceId) },
415         .userType = KEY_ALIAS_P2P_AUTH,
416         .isDirectAuthToken = true
417     };
418     uint8_t returnPkBytes[PUBLIC_KEY_MAX_LENGTH] = { 0 };
419     Uint8Buff returnPkBuff = { returnPkBytes, PUBLIC_KEY_MAX_LENGTH };
420     if (GetStandardTokenManagerInstance()->getPublicKey(&params, &returnPkBuff) != HC_SUCCESS) {
421         LOGE("Failed to get public key!");
422         return HC_ERR_LOCAL_IDENTITY_NOT_EXIST;
423     }
424 
425     uint32_t pkHexLen = returnPkBuff.length * BYTE_TO_HEX_OPER_LENGTH + 1;
426     char *pkHexStr = (char *)HcMalloc(pkHexLen, 0);
427     if (pkHexStr == NULL) {
428         LOGE("Failed to alloc memory for pkHexStr!");
429         return HC_ERR_ALLOC_MEMORY;
430     }
431     int32_t res = ByteToHexString(returnPkBuff.val, returnPkBuff.length, pkHexStr, pkHexLen);
432     if (res != HC_SUCCESS) {
433         LOGE("Failed to convert pk bytes to hex string!");
434         HcFree(pkHexStr);
435         return res;
436     }
437     if (AddStringToJson(returnDataJson, FIELD_PUBLIC_KEY, pkHexStr) != HC_SUCCESS) {
438         LOGE("Failed to add pubKey to returnData!");
439         HcFree(pkHexStr);
440         return HC_ERR_JSON_ADD;
441     }
442     HcFree(pkHexStr);
443     return HC_SUCCESS;
444 }
445 
GenerateReturnData(const CredentialRequestParam * param,char ** returnData)446 static int32_t GenerateReturnData(const CredentialRequestParam *param, char **returnData)
447 {
448     if (param->flag != RETURN_FLAG_PUBLIC_KEY) {
449         LOGI("No need to return public key.");
450         return HC_SUCCESS;
451     }
452     CJson *returnDataJson = CreateJson();
453     if (returnDataJson == NULL) {
454         LOGE("Failed to create return data json!");
455         return HC_ERR_JSON_CREATE;
456     }
457 
458     int32_t res = AddPubKeyToReturnData(param, returnDataJson);
459     if (res != HC_SUCCESS) {
460         LOGE("Failed to add public key to return data!");
461         FreeJson(returnDataJson);
462         return res;
463     }
464 
465     char *jsonStr = PackJsonToString(returnDataJson);
466     FreeJson(returnDataJson);
467     if (jsonStr == NULL) {
468         LOGE("Failed to convert return data json to string!");
469         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
470     }
471 
472     if (DeepCopyString(jsonStr, returnData) != HC_SUCCESS) {
473         LOGE("Failed to copy return json string!");
474         FreeJsonString(jsonStr);
475         return HC_ERR_MEMORY_COPY;
476     }
477     FreeJsonString(jsonStr);
478     return HC_SUCCESS;
479 }
480 
QueryCredential(const char * reqJsonStr,char ** returnData)481 static int32_t QueryCredential(const char *reqJsonStr, char **returnData)
482 {
483     CredentialRequestParam param = { 0 };
484     int32_t res = GenerateRequestParamFromJson(reqJsonStr, false, &param);
485     if (res != HC_SUCCESS) {
486         LOGE("Failed to generate request param!");
487         return res;
488     }
489     res = CheckKeyExistByParam(&param);
490     if (res != HC_SUCCESS) {
491         LOGW("Query key not exists!");
492         ClearCredParam(&param);
493         return res;
494     }
495     if (returnData != NULL) {
496         res = GenerateReturnData(&param, returnData);
497     }
498     ClearCredParam(&param);
499     return res;
500 }
501 
RegisterIdentity(const CredentialRequestParam * param,int32_t keyType)502 static int32_t RegisterIdentity(const CredentialRequestParam *param, int32_t keyType)
503 {
504     TokenManagerParams params = {
505         .peerOsAccountId = param->peerOsAccountId,
506         .osAccountId = param->osAccountId,
507         .pkgName = { (uint8_t *)DEFAULT_PACKAGE_NAME, HcStrlen(DEFAULT_PACKAGE_NAME) },
508         .serviceType = { (uint8_t *)param->serviceType, HcStrlen(param->serviceType) },
509         .authId = { (uint8_t *)param->deviceId, HcStrlen(param->deviceId) },
510         .userType = keyType,
511         .isDirectAuthToken = true
512     };
513     return GetStandardTokenManagerInstance()->registerLocalIdentity(&params);
514 }
515 
GenarateCredential(const char * reqJsonStr,char ** returnData)516 static int32_t GenarateCredential(const char *reqJsonStr, char **returnData)
517 {
518     CredentialRequestParam param = { 0 };
519     int32_t res = GenerateRequestParamFromJson(reqJsonStr, false, &param);
520     if (res != HC_SUCCESS) {
521         LOGE("Generate request param from Json occurred error!");
522         return res;
523     }
524     if (CheckKeyExistByParam(&param) == HC_SUCCESS) {
525         LOGE("Key already exists!");
526         ClearCredParam(&param);
527         return HC_ERR_IDENTITY_DUPLICATED;
528     }
529     res = RegisterIdentity(&param, KEY_ALIAS_P2P_AUTH);
530     if (res != HC_SUCCESS) {
531         LOGE("Failed to registerLocalIdentity!");
532         ClearCredParam(&param);
533         return res;
534     }
535     if (returnData != NULL) {
536         res = GenerateReturnData(&param, returnData);
537     }
538     ClearCredParam(&param);
539     return res;
540 }
541 
ComputeAndSavePsk(int32_t osAccountId,const char * peerServiceType,const char * peerAuthId,int32_t peerOsAccountId)542 static int32_t ComputeAndSavePsk(int32_t osAccountId, const char *peerServiceType, const char *peerAuthId,
543     int32_t peerOsAccountId)
544 {
545     uint8_t selfKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
546     Uint8Buff selfKeyAlias = { selfKeyAliasVal, PAKE_KEY_ALIAS_LEN };
547     uint8_t peerKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
548     Uint8Buff peerKeyAlias = { peerKeyAliasVal, PAKE_KEY_ALIAS_LEN };
549 
550     char selfAuthId[INPUT_UDID_LEN] = { 0 };
551     int32_t res = HcGetUdid((uint8_t *)selfAuthId, INPUT_UDID_LEN);
552     if (res != HC_SUCCESS) {
553         LOGE("Failed to get local udid! res: %" LOG_PUB "d", res);
554         return HC_ERR_DB;
555     }
556 
557     res = GenerateKeyAliasInner(DEFAULT_SERVICE_TYPE, selfAuthId, KEY_ALIAS_P2P_AUTH, peerOsAccountId, &selfKeyAlias);
558     if (res != HC_SUCCESS) {
559         LOGE("Failed to generate self key alias!");
560         return res;
561     }
562     LOGI("selfKeyAlias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****", selfKeyAliasVal[DEV_AUTH_ZERO],
563         selfKeyAliasVal[DEV_AUTH_ONE], selfKeyAliasVal[DEV_AUTH_TWO], selfKeyAliasVal[DEV_AUTH_THREE]);
564 
565     res = GenerateKeyAliasInner(peerServiceType, peerAuthId, KEY_ALIAS_P2P_AUTH, peerOsAccountId, &peerKeyAlias);
566     if (res != HC_SUCCESS) {
567         LOGE("Failed to generate peer key alias!");
568         return res;
569     }
570     LOGI("peerKeyAlias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****", peerKeyAliasVal[DEV_AUTH_ZERO],
571         peerKeyAliasVal[DEV_AUTH_ONE], peerKeyAliasVal[DEV_AUTH_TWO], peerKeyAliasVal[DEV_AUTH_THREE]);
572     res = GetLoaderInstance()->checkKeyExist(&selfKeyAlias, false, osAccountId);
573     if (res != HC_SUCCESS) {
574         LOGE("self auth keyPair not exists!");
575         return res;
576     }
577     res = GetLoaderInstance()->checkKeyExist(&peerKeyAlias, false, osAccountId);
578     if (res != HC_SUCCESS) {
579         LOGE("peer auth pubKey not exists!");
580         return res;
581     }
582 
583     uint8_t sharedKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
584     Uint8Buff sharedKeyAlias = { sharedKeyAliasVal, PAKE_KEY_ALIAS_LEN };
585     res = GenerateKeyAliasInner(peerServiceType, peerAuthId, KEY_ALIAS_PSK, peerOsAccountId, &sharedKeyAlias);
586     if (res != HC_SUCCESS) {
587         LOGE("Failed to generate psk alias!");
588         return res;
589     }
590     LOGI("psk alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****", sharedKeyAliasVal[DEV_AUTH_ZERO],
591         sharedKeyAliasVal[DEV_AUTH_ONE], sharedKeyAliasVal[DEV_AUTH_TWO], sharedKeyAliasVal[DEV_AUTH_THREE]);
592 
593     KeyParams selfKeyParams = { { selfKeyAlias.val, selfKeyAlias.length, true }, false, osAccountId };
594     KeyBuff peerKeyBuff = { peerKeyAlias.val, peerKeyAlias.length, true };
595     return GetLoaderInstance()->agreeSharedSecretWithStorage(
596         &selfKeyParams, &peerKeyBuff, ED25519, PAKE_PSK_LEN, &sharedKeyAlias);
597 }
598 
IsSelfKeyPairExist(int32_t osAccountId)599 static int32_t IsSelfKeyPairExist(int32_t osAccountId)
600 {
601     char selfAuthId[INPUT_UDID_LEN] = { 0 };
602     int32_t res = HcGetUdid((uint8_t *)selfAuthId, INPUT_UDID_LEN);
603     if (res != HC_SUCCESS) {
604         LOGE("Failed to get local udid! res: %" LOG_PUB "d", res);
605         return HC_ERR_DB;
606     }
607 
608     uint8_t selfKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
609     Uint8Buff selfKeyAlias = { selfKeyAliasVal, PAKE_KEY_ALIAS_LEN };
610     res = GenerateKeyAliasInner(DEFAULT_SERVICE_TYPE, selfAuthId, KEY_ALIAS_P2P_AUTH, DEFAULT_OS_ACCOUNT,
611         &selfKeyAlias);
612     if (res != HC_SUCCESS) {
613         LOGE("Failed to generate self keypair alias!");
614         return res;
615     }
616     LOGI("selfKeyAlias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****", selfKeyAliasVal[DEV_AUTH_ZERO],
617         selfKeyAliasVal[DEV_AUTH_ONE], selfKeyAliasVal[DEV_AUTH_TWO], selfKeyAliasVal[DEV_AUTH_THREE]);
618 
619     return GetLoaderInstance()->checkKeyExist(&selfKeyAlias, false, osAccountId);
620 }
621 
UnregisterIdentity(const CredentialRequestParam * param,int32_t keyType)622 static int32_t UnregisterIdentity(const CredentialRequestParam *param, int32_t keyType)
623 {
624     TokenManagerParams params = {
625         .osAccountId = param->osAccountId,
626         .peerOsAccountId = param->peerOsAccountId,
627         .pkgName = { (uint8_t *)DEFAULT_PACKAGE_NAME, HcStrlen(DEFAULT_PACKAGE_NAME) },
628         .serviceType = { (uint8_t *)param->serviceType, HcStrlen(param->serviceType) },
629         .authId = { (uint8_t *)param->deviceId, HcStrlen(param->deviceId) },
630         .userType = keyType,
631         .isDirectAuthToken = true
632     };
633     return GetStandardTokenManagerInstance()->unregisterLocalIdentity(&params);
634 }
635 
ImportCredential(const char * reqJsonStr,char ** returnData)636 static int32_t ImportCredential(const char *reqJsonStr, char **returnData)
637 {
638     (void)returnData;
639     CredentialRequestParam param = { 0 };
640     int32_t res = GenerateRequestParamFromJson(reqJsonStr, true, &param);
641     if (res != HC_SUCCESS) {
642         LOGE("Failed to generate request param!");
643         return res;
644     }
645     if (IsSelfKeyPairExist(param.osAccountId) != HC_SUCCESS) {
646         LOGE("Self key pair not exists!");
647         ClearCredParam(&param);
648         return HC_ERR_LOCAL_IDENTITY_NOT_EXIST;
649     }
650     uint8_t keyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
651     Uint8Buff keyAliasBuff = { keyAliasVal, PAKE_KEY_ALIAS_LEN };
652     res = GenerateKeyAliasInner(param.serviceType, param.deviceId, KEY_ALIAS_P2P_AUTH,
653         param.peerOsAccountId, &keyAliasBuff);
654     if (res != HC_SUCCESS) {
655         LOGE("Failed to generate key alias!");
656         ClearCredParam(&param);
657         return res;
658     }
659     ExtraInfo exInfo = {
660         .authId = { (uint8_t *)param.deviceId, HcStrlen(param.deviceId) },
661         .userType = KEY_ALIAS_P2P_AUTH,
662         .pairType = PAIR_TYPE_BIND
663     };
664     KeyParams keyParams = { { keyAliasBuff.val, keyAliasBuff.length, true }, false, param.osAccountId };
665     res = GetLoaderInstance()->importPublicKey(&keyParams, &param.publicKey, ED25519, &exInfo);
666     if (res != HC_SUCCESS) {
667         LOGE("Failed to importPublicKey!");
668         ClearCredParam(&param);
669         return res;
670     }
671     res = ComputeAndSavePsk(param.osAccountId, param.serviceType, param.deviceId, param.peerOsAccountId);
672     if (res != HC_SUCCESS) {
673         LOGE("Failed to ComputeAndSavePsk, delete imported key!");
674         ReportRadarEvent(res);
675         if (UnregisterIdentity(&param, KEY_ALIAS_P2P_AUTH) != HC_SUCCESS) {
676             LOGW("Failed to delete imported public key!");
677         }
678     }
679     ClearCredParam(&param);
680     return res;
681 }
682 
DeleteCredential(const char * reqJsonStr,char ** returnData)683 static int32_t DeleteCredential(const char *reqJsonStr, char **returnData)
684 {
685     (void)returnData;
686     CredentialRequestParam param = { 0 };
687     int32_t res = GenerateRequestParamFromJson(reqJsonStr, false, &param);
688     if (res != HC_SUCCESS) {
689         LOGE("Failed to generate request param!");
690         return res;
691     }
692     res = UnregisterIdentity(&param, KEY_ALIAS_PSK);
693     if (res != HC_SUCCESS) {
694         LOGE("Failed to delete psk!");
695         ClearCredParam(&param);
696         return res;
697     }
698     res = UnregisterIdentity(&param, KEY_ALIAS_P2P_AUTH);
699     ClearCredParam(&param);
700     if (res != HC_SUCCESS) {
701         LOGE("Failed to delete identity key!");
702     }
703     return res;
704 }
705 
706 static const CredentialOperator g_credentialOperator = {
707     .queryCredential = QueryCredential,
708     .genarateCredential = GenarateCredential,
709     .importCredential = ImportCredential,
710     .deleteCredential = DeleteCredential,
711 };
712 
GetCredentialOperator(void)713 const CredentialOperator *GetCredentialOperator(void)
714 {
715     return &g_credentialOperator;
716 }