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 "hc_log.h"
19 #include "identity_manager.h"
20 #include "hisysevent_common.h"
21
SetProtocolsToIdentityInfo(IdentityInfo * info)22 static int32_t SetProtocolsToIdentityInfo(IdentityInfo *info)
23 {
24 ProtocolEntity *ecSpekeEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
25 if (ecSpekeEntity == NULL) {
26 LOGE("Failed to alloc memory for ec speke entity!");
27 return HC_ERR_ALLOC_MEMORY;
28 }
29 ecSpekeEntity->protocolType = ALG_EC_SPEKE;
30 ecSpekeEntity->expandProcessCmds = 0;
31 if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&ecSpekeEntity) == NULL) {
32 LOGE("Failed to push ecSpeke entity!");
33 HcFree(ecSpekeEntity);
34 return HC_ERR_ALLOC_MEMORY;
35 }
36
37 return HC_SUCCESS;
38 }
39
AddServiceTypeToQueryParams(const CJson * in,CJson * out)40 static int32_t AddServiceTypeToQueryParams(const CJson *in, CJson *out)
41 {
42 const char *serviceType = GetStringFromJson(in, FIELD_SERVICE_TYPE);
43 if (serviceType == NULL) {
44 LOGI("get serviceType from json failed, replace by default.");
45 serviceType = DEFAULT_SERVICE_TYPE;
46 }
47 if (AddStringToJson(out, FIELD_SERVICE_TYPE, serviceType) != HC_SUCCESS) {
48 LOGE("Failed to add serviceType!");
49 return HC_ERR_JSON_ADD;
50 }
51 return HC_SUCCESS;
52 }
53
CombineQueryCredentialParams(const CJson * in,CJson * out)54 static int32_t CombineQueryCredentialParams(const CJson *in, CJson *out)
55 {
56 int32_t osAccountId = INVALID_OS_ACCOUNT;
57 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
58 LOGE("Failed to get osAccountId from context!");
59 return HC_ERR_JSON_GET;
60 }
61 const char *peerConnDeviceId = GetStringFromJson(in, FIELD_PEER_CONN_DEVICE_ID);
62 if (peerConnDeviceId == NULL) {
63 LOGE("Failed to get peerConnDeviceId from context, need peerConnDeviceId!");
64 return HC_ERR_JSON_GET;
65 }
66 int32_t acquireType = ACQUIRE_TYPE_INVALID;
67 if (GetIntFromJson(in, FIELD_ACQURIED_TYPE, &acquireType) != HC_SUCCESS) {
68 LOGE("Failed to get acquireType from context!");
69 return HC_ERR_JSON_GET;
70 }
71 if (acquireType != P2P_BIND) {
72 LOGE("acquireType invalid! only P2P_BIND is allowed now!");
73 return HC_ERR_INVALID_PARAMS;
74 }
75 int32_t peerOsAccountId = INVALID_OS_ACCOUNT;
76 if (GetIntFromJson(in, FIELD_PEER_OS_ACCOUNT_ID, &peerOsAccountId) != HC_SUCCESS) {
77 LOGE("Failed to get peer osAccountId!");
78 return HC_ERR_JSON_GET;
79 }
80 if (AddIntToJson(out, FIELD_PEER_OS_ACCOUNT_ID, peerOsAccountId) != HC_SUCCESS) {
81 LOGE("Failed to add peer osAccountId!");
82 return HC_ERR_JSON_ADD;
83 }
84 if (AddIntToJson(out, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
85 LOGE("add osAccountId to json error!");
86 return HC_ERR_JSON_ADD;
87 }
88 if (AddIntToJson(out, FIELD_ACQURIED_TYPE, acquireType) != HC_SUCCESS) {
89 LOGE("add acquireType to json error!");
90 return HC_ERR_JSON_ADD;
91 }
92 if (AddIntToJson(out, FIELD_CRED_OP_FLAG, RETURN_FLAG_DEFAULT) != HC_SUCCESS) {
93 LOGE("add flag to json error!");
94 return HC_ERR_JSON_ADD;
95 }
96 if (AddStringToJson(out, FIELD_DEVICE_ID, peerConnDeviceId) != HC_SUCCESS) {
97 LOGE("add device id to json error!");
98 return HC_ERR_JSON_ADD;
99 }
100 return AddServiceTypeToQueryParams(in, out);
101 }
102
IsPeerDevicePublicKeyExist(const CJson * in)103 static int32_t IsPeerDevicePublicKeyExist(const CJson *in)
104 {
105 CJson *paramsJson = CreateJson();
106 if (paramsJson == NULL) {
107 LOGE("alloc memory error!");
108 return HC_ERR_ALLOC_MEMORY;
109 }
110 int32_t ret = CombineQueryCredentialParams(in, paramsJson);
111 if (ret != HC_SUCCESS) {
112 LOGE("Prepare query credential parmaters return error!");
113 FreeJson(paramsJson);
114 return ret;
115 }
116 const CredentialOperator *credOperator = GetCredentialOperator();
117 if (credOperator == NULL) {
118 LOGE("credOperator is null!");
119 FreeJson(paramsJson);
120 return HC_ERR_NOT_SUPPORT;
121 }
122 char *requestParams = PackJsonToString(paramsJson);
123 FreeJson(paramsJson);
124 if (requestParams == NULL) {
125 LOGE("Failed to pack query credentail params json to string!");
126 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
127 }
128 ret = credOperator->queryCredential(requestParams, NULL);
129 FreeJsonString(requestParams);
130 return ret;
131 }
132
CreateUrlStr(int32_t keyType,char ** urlStr)133 static int32_t CreateUrlStr(int32_t keyType, char **urlStr)
134 {
135 CJson *urlJson = CreateCredUrlJson(PRE_SHARED, keyType, TRUST_TYPE_P2P);
136 if (!urlJson) {
137 LOGE("Failed to create CredUrlJson info!");
138 return HC_ERR_ALLOC_MEMORY;
139 }
140 if (AddBoolToJson(urlJson, FIELD_IS_DIRECT_AUTH, true) != HC_SUCCESS) {
141 LOGE("Failed to add isDirectAuth to preshared url json!");
142 FreeJson(urlJson);
143 return HC_ERR_JSON_ADD;
144 } else {
145 LOGI("add isDirectAuth:true into urlJson!");
146 }
147 char *str = PackJsonToString(urlJson);
148 FreeJson(urlJson);
149 if (str == NULL) {
150 LOGE("Failed to pack url json to string!");
151 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
152 }
153 *urlStr = str;
154 return HC_SUCCESS;
155 }
156
GetCredInfosByPeerIdentity(const CJson * in,IdentityInfoVec * vec)157 static int32_t GetCredInfosByPeerIdentity(const CJson *in, IdentityInfoVec *vec)
158 {
159 int32_t keyType = KEY_TYPE_ASYM;
160 (void)GetIntFromJson(in, FIELD_KEY_TYPE, &keyType);
161
162 int32_t ret = IsPeerDevicePublicKeyExist(in);
163 if (ret != HC_SUCCESS) {
164 LOGE("Failed to get peer device public key!");
165 return ret;
166 }
167
168 char *urlStr = NULL;
169 ret = CreateUrlStr(keyType, &urlStr);
170 if (ret != HC_SUCCESS) {
171 LOGE("Create url string with keyType failed!");
172 return ret;
173 }
174 IdentityInfo *info = CreateIdentityInfo();
175 if (info == NULL) {
176 LOGE("Create identityInfo failed!");
177 FreeJsonString(urlStr);
178 return HC_ERR_ALLOC_MEMORY;
179 }
180 ret = SetPreSharedUrlForProof(urlStr, &info->proof.preSharedUrl);
181 FreeJsonString(urlStr);
182 if (ret != HC_SUCCESS) {
183 LOGE("Failed to set preSharedUrl of proof!");
184 DestroyIdentityInfo(info);
185 return ret;
186 }
187 ret = SetProtocolsToIdentityInfo(info);
188 if (ret != HC_SUCCESS) {
189 LOGE("Error occurs, Failed to set protocols!");
190 DestroyIdentityInfo(info);
191 return ret;
192 }
193 info->proofType = PRE_SHARED;
194 info->IdInfoType = P2P_DIRECT_AUTH;
195 if (vec->pushBack(vec, (const IdentityInfo **)&info) == NULL) {
196 LOGE("Failed to push info!");
197 DestroyIdentityInfo(info);
198 return HC_ERR_ALLOC_MEMORY;
199 }
200 return HC_SUCCESS;
201 }
202
GetCredInfoByPeerUrl(const CJson * in,const Uint8Buff * presharedUrl,IdentityInfo ** returnInfo)203 static int32_t GetCredInfoByPeerUrl(const CJson *in, const Uint8Buff *presharedUrl, IdentityInfo **returnInfo)
204 {
205 if (in == NULL || presharedUrl == NULL || returnInfo == NULL) {
206 LOGE("Invalid input params!");
207 return HC_ERR_INVALID_PARAMS;
208 }
209 IdentityInfo *info = CreateIdentityInfo();
210 if (info == NULL) {
211 LOGE("Failed to create identity info!");
212 return HC_ERR_ALLOC_MEMORY;
213 }
214 int32_t ret = SetPreSharedUrlForProof((const char *)presharedUrl->val, &info->proof.preSharedUrl);
215 if (ret != HC_SUCCESS) {
216 LOGE("Failed to set preSharedUrl of proof!");
217 DestroyIdentityInfo(info);
218 return ret;
219 }
220 ret = SetProtocolsToIdentityInfo(info);
221 if (ret != HC_SUCCESS) {
222 LOGE("Failed to set protocols!");
223 DestroyIdentityInfo(info);
224 return ret;
225 }
226 info->proofType = PRE_SHARED;
227 info->IdInfoType = P2P_DIRECT_AUTH;
228 *returnInfo = info;
229 return HC_SUCCESS;
230 }
231
GenerateSelfKeyAlias(const char * selfAuthId,Uint8Buff * selfKeyAlias)232 static int32_t GenerateSelfKeyAlias(const char *selfAuthId, Uint8Buff *selfKeyAlias)
233 {
234 TokenManagerParams tokenParams = { 0 };
235 tokenParams.pkgName.val = (uint8_t *)DEFAULT_PACKAGE_NAME;
236 tokenParams.pkgName.length = HcStrlen(DEFAULT_PACKAGE_NAME);
237 tokenParams.serviceType.val = (uint8_t *)DEFAULT_SERVICE_TYPE;
238 tokenParams.serviceType.length = HcStrlen(DEFAULT_SERVICE_TYPE);
239 tokenParams.userType = KEY_ALIAS_P2P_AUTH;
240 tokenParams.authId.val = (uint8_t *)selfAuthId;
241 tokenParams.authId.length = HcStrlen(selfAuthId);
242 return GenerateKeyAlias(&tokenParams, selfKeyAlias);
243 }
244
GeneratePeerKeyAlias(const char * peerServiceType,const char * peerAuthId,int32_t peerOsAccountId,Uint8Buff * peerKeyAlias)245 static int32_t GeneratePeerKeyAlias(const char *peerServiceType, const char *peerAuthId, int32_t peerOsAccountId,
246 Uint8Buff *peerKeyAlias)
247 {
248 TokenManagerParams tokenParams = { 0 };
249 tokenParams.pkgName.val = (uint8_t *)DEFAULT_PACKAGE_NAME;
250 tokenParams.pkgName.length = HcStrlen(DEFAULT_PACKAGE_NAME);
251 tokenParams.serviceType.val = (uint8_t *)peerServiceType;
252 tokenParams.serviceType.length = HcStrlen(peerServiceType);
253 tokenParams.userType = KEY_ALIAS_P2P_AUTH;
254 tokenParams.authId.val = (uint8_t *)peerAuthId;
255 tokenParams.authId.length = HcStrlen(peerAuthId);
256 tokenParams.isDirectAuthToken = true;
257 tokenParams.peerOsAccountId = peerOsAccountId;
258 return GenerateKeyAlias(&tokenParams, peerKeyAlias);
259 }
260
261 /**
262 * @brief compute shared key alias
263 *
264 * @param osAccountId
265 * @param selfAuthId self device udid
266 * @param peerAuthId peer device udid
267 * @param sharedKeyAlias
268 * @return int32_t
269 */
ComputeAndSaveDirectAuthPsk(const CJson * in,const char * selfAuthId,const char * peerAuthId,const char * peerServiceType,const Uint8Buff * sharedKeyAlias)270 static int32_t ComputeAndSaveDirectAuthPsk(const CJson *in, const char *selfAuthId, const char *peerAuthId,
271 const char *peerServiceType, const Uint8Buff *sharedKeyAlias)
272 {
273 int32_t osAccountId = INVALID_OS_ACCOUNT;
274 (void)GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId);
275 int32_t peerOsAccountId = INVALID_OS_ACCOUNT;
276 (void)GetIntFromJson(in, FIELD_PEER_OS_ACCOUNT_ID, &peerOsAccountId);
277 uint8_t selfKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
278 Uint8Buff selfKeyAlias = { selfKeyAliasVal, PAKE_KEY_ALIAS_LEN };
279 int32_t ret = GenerateSelfKeyAlias(selfAuthId, &selfKeyAlias);
280 if (ret != HC_SUCCESS) {
281 LOGE("Failed to generate self key alias!");
282 return ret;
283 }
284 LOGI("selfKeyAlias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.", selfKeyAlias.val[DEV_AUTH_ZERO],
285 selfKeyAlias.val[DEV_AUTH_ONE], selfKeyAlias.val[DEV_AUTH_TWO], selfKeyAlias.val[DEV_AUTH_THREE]);
286
287 uint8_t peerKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
288 Uint8Buff peerKeyAlias = { peerKeyAliasVal, PAKE_KEY_ALIAS_LEN };
289 ret = GeneratePeerKeyAlias(peerServiceType, peerAuthId, peerOsAccountId, &peerKeyAlias);
290 if (ret != HC_SUCCESS) {
291 LOGE("Failed to generate peer key alias!");
292 return ret;
293 }
294 LOGI("peerKeyAlias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.", peerKeyAlias.val[DEV_AUTH_ZERO],
295 peerKeyAlias.val[DEV_AUTH_ONE], peerKeyAlias.val[DEV_AUTH_TWO], peerKeyAlias.val[DEV_AUTH_THREE]);
296
297 ret = GetLoaderInstance()->checkKeyExist(&selfKeyAlias, false, osAccountId);
298 if (ret != HC_SUCCESS) {
299 LOGE("self auth keyPair not exist!");
300 return ret;
301 }
302 ret = GetLoaderInstance()->checkKeyExist(&peerKeyAlias, false, osAccountId);
303 if (ret != HC_SUCCESS) {
304 LOGE("peer auth pubKey not exist!");
305 return ret;
306 }
307
308 KeyParams selfKeyParams = { { selfKeyAlias.val, selfKeyAlias.length, true }, false, osAccountId };
309 KeyBuff peerKeyBuff = { peerKeyAlias.val, peerKeyAlias.length, true };
310 return GetLoaderInstance()->agreeSharedSecretWithStorage(
311 &selfKeyParams, &peerKeyBuff, ED25519, PAKE_PSK_LEN, sharedKeyAlias);
312 }
313
GetDirectAuthPskAliasInner(const char * peerServiceType,const char * peerAuthId,int32_t peerOsAccountId,Uint8Buff * pskKeyAlias)314 static int32_t GetDirectAuthPskAliasInner(const char *peerServiceType, const char *peerAuthId, int32_t peerOsAccountId,
315 Uint8Buff *pskKeyAlias)
316 {
317 TokenManagerParams tokenParams = { 0 };
318 tokenParams.pkgName.val = (uint8_t *)DEFAULT_PACKAGE_NAME;
319 tokenParams.pkgName.length = HcStrlen(DEFAULT_PACKAGE_NAME);
320 tokenParams.serviceType.val = (uint8_t *)peerServiceType;
321 tokenParams.serviceType.length = HcStrlen(peerServiceType);
322 tokenParams.userType = KEY_ALIAS_PSK;
323 tokenParams.authId.val = (uint8_t *)peerAuthId;
324 tokenParams.authId.length = HcStrlen(peerAuthId);
325 tokenParams.isDirectAuthToken = true;
326 tokenParams.peerOsAccountId = peerOsAccountId;
327 return GenerateKeyAlias(&tokenParams, pskKeyAlias);
328 }
329
GetDirectAuthPskAliasCreateIfNeeded(const CJson * in,Uint8Buff * pskKeyAlias)330 static int32_t GetDirectAuthPskAliasCreateIfNeeded(const CJson *in, Uint8Buff *pskKeyAlias)
331 {
332 int32_t osAccountId = INVALID_OS_ACCOUNT;
333 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
334 LOGE("Failed to get osAccountId!");
335 return HC_ERR_JSON_GET;
336 }
337 int32_t peerOsAccountId = INVALID_OS_ACCOUNT;
338 if (GetIntFromJson(in, FIELD_PEER_OS_ACCOUNT_ID, &peerOsAccountId) != HC_SUCCESS) {
339 LOGE("Failed to get peer osAccountId!");
340 return HC_ERR_JSON_GET;
341 }
342 const char *selfAuthId = GetStringFromJson(in, FIELD_AUTH_ID);
343 if (selfAuthId == NULL) {
344 LOGE("get authId from context fail.");
345 return HC_ERR_JSON_GET;
346 }
347 const char *peerAuthId = GetStringFromJson(in, FIELD_PEER_CONN_DEVICE_ID);
348 if (peerAuthId == NULL) {
349 LOGE("get peerConnDeviceId from json fail.");
350 return HC_ERR_JSON_GET;
351 }
352 const char *peerServiceType = GetStringFromJson(in, FIELD_SERVICE_TYPE);
353 if (peerServiceType == NULL) {
354 LOGI("get serviceType from json fail, replace by default");
355 peerServiceType = DEFAULT_SERVICE_TYPE;
356 }
357 int32_t ret = GetDirectAuthPskAliasInner(peerServiceType, peerAuthId, peerOsAccountId, pskKeyAlias);
358 if (ret != HC_SUCCESS) {
359 LOGE("Failed to generate psk key alias!");
360 return ret;
361 }
362 LOGI("psk alias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.", pskKeyAlias->val[DEV_AUTH_ZERO],
363 pskKeyAlias->val[DEV_AUTH_ONE], pskKeyAlias->val[DEV_AUTH_TWO], pskKeyAlias->val[DEV_AUTH_THREE]);
364 ret = GetLoaderInstance()->checkKeyExist(pskKeyAlias, false, osAccountId);
365 if (ret != HC_SUCCESS) {
366 ret = ComputeAndSaveDirectAuthPsk(in, selfAuthId, peerAuthId, peerServiceType, pskKeyAlias);
367 ReportRadarEvent(ret);
368 }
369 return ret;
370 }
371
GetSharedSecretByUrl(const CJson * in,const Uint8Buff * presharedUrl,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)372 static int32_t GetSharedSecretByUrl(
373 const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
374 {
375 (void)protocolType;
376 if (in == NULL || presharedUrl == NULL || sharedSecret == NULL) {
377 LOGE("Invalid input params!");
378 return HC_ERR_INVALID_PARAMS;
379 }
380 int32_t osAccountId;
381 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
382 LOGE("Failed to get osAccountId!");
383 return HC_ERR_JSON_GET;
384 }
385 uint8_t pskKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
386 Uint8Buff pskKeyAlias = { pskKeyAliasVal, PAKE_KEY_ALIAS_LEN };
387 int32_t ret = GetDirectAuthPskAliasCreateIfNeeded(in, &pskKeyAlias);
388 if (ret != HC_SUCCESS) {
389 LOGE("Failed to generate key alias for psk!");
390 return ret;
391 }
392 uint8_t nonceVal[PAKE_NONCE_LEN] = { 0 };
393 Uint8Buff nonceBuff = { nonceVal, PAKE_NONCE_LEN };
394 if (GetByteFromJson(in, FIELD_NONCE, nonceBuff.val, nonceBuff.length) != HC_SUCCESS) {
395 LOGE("Failed to get nonce!");
396 return HC_ERR_JSON_GET;
397 }
398 uint8_t pskVal[PAKE_PSK_LEN] = { 0 };
399 Uint8Buff pskBuff = { pskVal, PAKE_PSK_LEN };
400 Uint8Buff keyInfo = { (uint8_t *)TMP_AUTH_KEY_FACTOR, HcStrlen(TMP_AUTH_KEY_FACTOR) };
401 KeyParams keyAliasParams = { { pskKeyAlias.val, pskKeyAlias.length, true }, false, osAccountId };
402 ret = GetLoaderInstance()->computeHkdf(&keyAliasParams, &nonceBuff, &keyInfo, &pskBuff);
403 if (ret != HC_SUCCESS) {
404 LOGE("Failed to compute hkdf for psk!");
405 return ret;
406 }
407 ret = ConvertPsk(&pskBuff, sharedSecret);
408 if (ret != HC_SUCCESS) {
409 LOGE("Failed to convert sharedSecret to psk!");
410 }
411 return ret;
412 }
413
GetCredInfoByPeerCert(const CJson * in,const CertInfo * certInfo,IdentityInfo ** returnInfo)414 static int32_t GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)
415 {
416 // NOT SUPPORT FOR P2P AUTH
417 (void)certInfo;
418 (void)returnInfo;
419 (void)in;
420 return HC_ERR_ALG_FAIL;
421 }
422
GetSharedSecretByPeerCert(const CJson * in,const CertInfo * peerCertInfo,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)423 static int32_t GetSharedSecretByPeerCert(
424 const CJson *in, const CertInfo *peerCertInfo, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
425 {
426 // NOT SUPPORT P2P AUTH
427 (void)in;
428 (void)peerCertInfo;
429 (void)protocolType;
430 (void)sharedSecret;
431 return HC_ERR_ALG_FAIL;
432 }
433
434 static const AuthIdentity g_authIdentity = {
435 .getCredInfosByPeerIdentity = GetCredInfosByPeerIdentity,
436 .getCredInfoByPeerUrl = GetCredInfoByPeerUrl,
437 .getSharedSecretByUrl = GetSharedSecretByUrl,
438 .getCredInfoByPeerCert = GetCredInfoByPeerCert,
439 .getSharedSecretByPeerCert = GetSharedSecretByPeerCert,
440 };
441
GetP2pAuthIdentity(void)442 const AuthIdentity *GetP2pAuthIdentity(void)
443 {
444 return &g_authIdentity;
445 }