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