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