1 /*
2  * Copyright (c) 2022-2024 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 "cert_manager_auth_mgr.h"
17 
18 #include <pthread.h>
19 
20 #include "securec.h"
21 
22 #include "cert_manager_auth_list_mgr.h"
23 #include "cert_manager_key_operation.h"
24 #include "cert_manager_mem.h"
25 #include "cert_manager_session_mgr.h"
26 #include "cert_manager_crypto_operation.h"
27 #include "cert_manager_uri.h"
28 #include "cm_log.h"
29 
30 #define MAC_SHA256_LEN 32
31 
32 #define NUMBER_9_IN_DECIMAL 9
33 #define BYTE_TO_HEX_OPER_LENGTH 2
34 #define OUT_OF_HEX 16
35 #define DEC 10
36 
37 static pthread_mutex_t g_authMgrLock = PTHREAD_MUTEX_INITIALIZER;
38 
HexToChar(uint8_t hex)39 static char HexToChar(uint8_t hex)
40 {
41     return (hex > NUMBER_9_IN_DECIMAL) ? (hex + 0x37) : (hex + 0x30); /* Convert to the corresponding character */
42 }
43 
CharToHex(char c)44 static uint8_t CharToHex(char c)
45 {
46     if ((c >= 'A') && (c <= 'F')) {
47         return (c - 'A' + DEC);
48     } else if ((c >= 'a') && (c <= 'f')) {
49         return (c - 'a' + DEC);
50     } else if ((c >= '0') && (c <= '9')) {
51         return (c - '0');
52     } else {
53         return OUT_OF_HEX;
54     }
55 }
56 
ByteToHexString(const uint8_t * byte,uint32_t byteLen,char * hexStr,uint32_t hexLen)57 static int32_t ByteToHexString(const uint8_t *byte, uint32_t byteLen, char *hexStr, uint32_t hexLen)
58 {
59     if (hexLen < (byteLen * BYTE_TO_HEX_OPER_LENGTH + 1)) { /* The terminator('\0') needs 1 bit */
60         return CMR_ERROR_BUFFER_TOO_SMALL;
61     }
62 
63     for (uint32_t i = 0; i < byteLen; ++i) {
64         hexStr[i * BYTE_TO_HEX_OPER_LENGTH] = HexToChar((byte[i] & 0xF0) >> 4); /* 4: shift right for filling */
65         hexStr[i * BYTE_TO_HEX_OPER_LENGTH + 1] = HexToChar(byte[i] & 0x0F); /* get low four bits */
66     }
67     hexStr[byteLen * BYTE_TO_HEX_OPER_LENGTH] = '\0';
68 
69     return CM_SUCCESS;
70 }
71 
HexStringToByte(const char * hexStr,uint8_t * byte,uint32_t byteLen)72 static int32_t HexStringToByte(const char *hexStr, uint8_t *byte, uint32_t byteLen)
73 {
74     uint32_t realHexLen = strlen(hexStr);
75     /* odd number or len too small */
76     if ((realHexLen % BYTE_TO_HEX_OPER_LENGTH != 0) || (byteLen < realHexLen / BYTE_TO_HEX_OPER_LENGTH)) {
77         return CMR_ERROR_INVALID_ARGUMENT;
78     }
79 
80     for (uint32_t i = 0; i < realHexLen / BYTE_TO_HEX_OPER_LENGTH; ++i) {
81         uint8_t high = CharToHex(hexStr[i * BYTE_TO_HEX_OPER_LENGTH]);
82         uint8_t low = CharToHex(hexStr[i * BYTE_TO_HEX_OPER_LENGTH + 1]);
83         if ((high == OUT_OF_HEX) || (low == OUT_OF_HEX)) {
84             return CMR_ERROR_INVALID_ARGUMENT;
85         }
86         byte[i] = high << 4; /* 4: Set the high nibble */
87         byte[i] |= low; /* Set the low nibble */
88     }
89     return CM_SUCCESS;
90 }
91 
GetAndCheckUriObj(struct CMUri * uriObj,const struct CmBlob * uri,uint32_t type)92 static int32_t GetAndCheckUriObj(struct CMUri *uriObj, const struct CmBlob *uri, uint32_t type)
93 {
94     int32_t ret = CertManagerUriDecode(uriObj, (char *)uri->data);
95     if (ret != CM_SUCCESS) {
96         CM_LOG_E("uri decode failed, ret = %d", ret);
97         return ret;
98     }
99 
100     if ((uriObj->object == NULL) || (uriObj->user == NULL) || (uriObj->app == NULL) || (uriObj->type != type)) {
101         CM_LOG_E("uri format invalid");
102         (void)CertManagerFreeUri(uriObj);
103         return CMR_ERROR_INVALID_ARGUMENT;
104     }
105 
106     return CM_SUCCESS;
107 }
108 
CheckCallerIsProducer(const struct CmContext * context,const struct CMUri * uriObj)109 static int32_t CheckCallerIsProducer(const struct CmContext *context, const struct CMUri *uriObj)
110 {
111     /* check caller is Producer: user and app has been checked not null */
112     uint32_t userId = (uint32_t)atoi(uriObj->user);
113     uint32_t uid = (uint32_t)atoi(uriObj->app);
114     if ((userId == context->userId) && (uid == context->uid)) {
115         CM_LOG_D("caller is producer.");
116         return CM_SUCCESS;
117     }
118 
119     return CMR_ERROR_PERMISSION_DENIED;
120 }
121 
UintToString(uint32_t input,char * out,uint32_t outLen)122 static int32_t UintToString(uint32_t input, char *out, uint32_t outLen)
123 {
124     if (snprintf_s(out, outLen, outLen - 1, "%u", input) < 0) {
125         return CMR_ERROR_INVALID_OPERATION;
126     }
127     return CM_SUCCESS;
128 }
129 
ConstructToBeAuthedUri(const struct CMUri * uriObj,uint32_t clientUid,struct CmBlob * toBeAuthedUri)130 static int32_t ConstructToBeAuthedUri(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *toBeAuthedUri)
131 {
132     struct CMUri uri;
133     (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri));
134 
135     char uidStr[MAX_UINT32_LEN] = { 0 };
136     int32_t ret = UintToString(clientUid, uidStr, MAX_UINT32_LEN);
137     if (ret != CM_SUCCESS) {
138         CM_LOG_E("construct client uid to string failed");
139         return ret;
140     }
141 
142     uri.clientApp = uidStr;
143     uri.clientUser = NULL;
144     uri.mac = NULL;
145 
146     return CmConstructUri(&uri, toBeAuthedUri);
147 }
148 
ConstructMacKeyUri(const struct CMUri * uriObj,uint32_t clientUid,struct CmBlob * macKeyUri)149 static int32_t ConstructMacKeyUri(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *macKeyUri)
150 {
151     struct CMUri uri;
152     (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri));
153 
154     char uidStr[MAX_UINT32_LEN] = { 0 };
155     int32_t ret = UintToString(clientUid, uidStr, MAX_UINT32_LEN);
156     if (ret != CM_SUCCESS) {
157         CM_LOG_E("construct client uid to string failed");
158         return ret;
159     }
160 
161     uri.type = CM_URI_TYPE_MAC_KEY; /* type is 'm' */
162     uri.clientApp = uidStr;
163     uri.clientUser = NULL;
164     uri.mac = NULL;
165 
166     return CmConstructUri(&uri, macKeyUri);
167 }
168 
ConstructCommonUri(const struct CMUri * uriObj,struct CmBlob * commonUri,uint32_t store)169 static int32_t ConstructCommonUri(const struct CMUri *uriObj, struct CmBlob *commonUri, uint32_t store)
170 {
171     struct CMUri uri;
172     (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri));
173 
174     if (store != CM_SYS_CREDENTIAL_STORE) {
175         uri.type = CM_URI_TYPE_APP_KEY; /* type is 'ak' */
176     } else {
177         uri.type = CM_URI_TYPE_SYS_KEY; /* type is 'sk' */
178     }
179 
180     uri.clientApp = NULL;
181     uri.clientUser = NULL;
182     uri.mac = NULL;
183 
184     return CmConstructUri(&uri, commonUri);
185 }
CalcUriMac(const struct CMUri * uriObj,uint32_t clientUid,struct CmBlob * mac,bool isNeedGenKey)186 static int32_t CalcUriMac(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *mac, bool isNeedGenKey)
187 {
188     struct CmBlob toBeAuthedUri = { 0, NULL };
189     struct CmBlob macKeyUri = { 0, NULL };
190     int32_t ret;
191 
192     do {
193         /* construct to be authed URI */
194         ret = ConstructToBeAuthedUri(uriObj, clientUid, &toBeAuthedUri);
195         if (ret != CM_SUCCESS) {
196             CM_LOG_E("construct to be authed uri failed, ret = %d", ret);
197             break;
198         }
199 
200         /* construct mac key URI */
201         ret = ConstructMacKeyUri(uriObj, clientUid, &macKeyUri);
202         if (ret != CM_SUCCESS) {
203             CM_LOG_E("construct mac key uri, ret = %d", ret);
204             break;
205         }
206 
207         if (isNeedGenKey) {
208             ret = CmKeyOpGenMacKey(&macKeyUri);
209             if (ret != CM_SUCCESS) {
210                 CM_LOG_E("generate mac key failed, ret = %d", ret);
211                 break;
212             }
213         }
214 
215         ret = CmKeyOpCalcMac(&macKeyUri, &toBeAuthedUri, mac);
216         if (ret != CM_SUCCESS) {
217             CM_LOG_E("calc mac failed, ret = %d", ret);
218             break;
219         }
220     } while (0);
221 
222     CM_FREE_PTR(toBeAuthedUri.data);
223     CM_FREE_PTR(macKeyUri.data);
224     return ret;
225 }
226 
DeleteMacKey(const struct CMUri * uriObj,uint32_t clientUid)227 static int32_t DeleteMacKey(const struct CMUri *uriObj, uint32_t clientUid)
228 {
229     struct CmBlob macKeyUri = { 0, NULL };
230     int32_t ret;
231 
232     do {
233         /* construct mac key URI */
234         ret = ConstructMacKeyUri(uriObj, clientUid, &macKeyUri);
235         if (ret != CM_SUCCESS) {
236             CM_LOG_E("construct mac key uri, ret = %d", ret);
237             break;
238         }
239 
240         ret = CmKeyOpDeleteKey(&macKeyUri);
241         if (ret != CM_SUCCESS) {
242             CM_LOG_E("delete mac key failed, ret = %d", ret);
243             break;
244         }
245 
246         ret = CM_SUCCESS; /* ret is success if key not exist */
247     } while (0);
248 
249     CM_FREE_PTR(macKeyUri.data);
250     return ret;
251 }
252 
253 
ConstructAuthUri(const struct CMUri * uriObj,uint32_t clientUid,const struct CmBlob * mac,struct CmBlob * authUri)254 static int32_t ConstructAuthUri(const struct CMUri *uriObj, uint32_t clientUid, const struct CmBlob *mac,
255     struct CmBlob *authUri)
256 {
257     struct CMUri uri;
258     (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri));
259 
260     char uidStr[MAX_UINT32_LEN] = { 0 };
261     int32_t ret = UintToString(clientUid, uidStr, MAX_UINT32_LEN);
262     if (ret != CM_SUCCESS) {
263         CM_LOG_E("construct client uid to string failed");
264         return ret;
265     }
266 
267     uint32_t macHexLen = mac->size * BYTE_TO_HEX_OPER_LENGTH + 1;
268     char *macHex = (char *)CMMalloc(macHexLen);
269     if (macHex == NULL) {
270         CM_LOG_E("malloc mac hex buffer failed");
271         return CMR_ERROR_MALLOC_FAIL;
272     }
273 
274     ret = ByteToHexString(mac->data, mac->size, macHex, macHexLen);
275     if (ret != CM_SUCCESS) {
276         CM_LOG_E("byte to hex string failed, ret = %d", ret);
277         CMFree(macHex);
278         return ret;
279     }
280 
281     uri.clientApp = uidStr;
282     uri.clientUser = NULL;
283     uri.mac = macHex;
284 
285     ret = CmConstructUri(&uri, authUri);
286     CMFree(macHex);
287     return ret;
288 }
289 
GenerateAuthUri(const struct CMUri * uriObj,uint32_t clientUid,struct CmBlob * authUri)290 static int32_t GenerateAuthUri(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *authUri)
291 {
292     struct CmBlob tempAuthUri = { 0, NULL };
293     int32_t ret;
294     do {
295         /* calc uri mac */
296         uint8_t macData[MAC_SHA256_LEN] = {0};
297         struct CmBlob mac = { sizeof(macData), macData };
298         ret = CalcUriMac(uriObj, clientUid, &mac, true);
299         if (ret != CM_SUCCESS) {
300             CM_LOG_E("calc uri mac failed, ret = %d", ret);
301             break;
302         }
303 
304         /* construct auth URI */
305         ret = ConstructAuthUri(uriObj, clientUid, &mac, &tempAuthUri);
306         if (ret != CM_SUCCESS) {
307             CM_LOG_E("construct auth uri failed, ret = %d", ret);
308             break;
309         }
310 
311         if (authUri->size < tempAuthUri.size) {
312             CM_LOG_E("auth uri out size too small");
313             ret = CMR_ERROR_BUFFER_TOO_SMALL;
314             break;
315         }
316         if (memcpy_s(authUri->data, authUri->size, tempAuthUri.data, tempAuthUri.size) != EOK) {
317             CM_LOG_E("copy auth uri failed");
318             ret = CMR_ERROR_INVALID_OPERATION;
319             break;
320         }
321         authUri->size = tempAuthUri.size;
322         ret = CM_SUCCESS;
323     } while (0);
324 
325     CM_FREE_PTR(tempAuthUri.data);
326     return ret;
327 }
328 
CmAuthGrantAppCertificate(const struct CmContext * context,const struct CmBlob * keyUri,uint32_t appUid,struct CmBlob * authUri)329 int32_t CmAuthGrantAppCertificate(const struct CmContext *context, const struct CmBlob *keyUri,
330     uint32_t appUid, struct CmBlob *authUri)
331 {
332     pthread_mutex_lock(&g_authMgrLock);
333     int32_t ret = CmCheckCredentialExist(context, keyUri);
334     if (ret != CM_SUCCESS) {
335         CM_LOG_E("credential not exist when grant auth, ret = %d", ret);
336         pthread_mutex_unlock(&g_authMgrLock);
337         return ret;
338     }
339 
340     struct CMUri uriObj;
341     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
342     ret = GetAndCheckUriObj(&uriObj, keyUri, CM_URI_TYPE_APP_KEY);
343     if (ret != CM_SUCCESS) {
344         CM_LOG_E("uri decode failed, ret = %d", ret);
345         pthread_mutex_unlock(&g_authMgrLock);
346         return ret;
347     }
348 
349     do {
350         ret = CheckCallerIsProducer(context, &uriObj);
351         if (ret != CM_SUCCESS) {
352             CM_LOG_E("check caller userId/uid failed when grant, ret = %d", ret);
353             break;
354         }
355 
356         /* auth URI */
357         ret = GenerateAuthUri(&uriObj, appUid, authUri);
358         if (ret != CM_SUCCESS) {
359             CM_LOG_E("construct auth URI failed, ret = %d", ret);
360             break;
361         }
362 
363         /* add auth uid */
364         ret = CmAddAuthUid(context, keyUri, appUid);
365         if (ret != CM_SUCCESS) {
366             CM_LOG_E("add auth uid to auth list failed, ret = %d", ret);
367             break;
368         }
369     } while (0);
370 
371     pthread_mutex_unlock(&g_authMgrLock);
372     if (ret != CM_SUCCESS) {
373         (void)CmAuthRemoveGrantedApp(context, keyUri, appUid); /* clear auth info */
374     }
375     (void)CertManagerFreeUri(&uriObj);
376     return ret;
377 }
378 
CmAuthGetAuthorizedAppList(const struct CmContext * context,const struct CmBlob * keyUri,struct CmAppUidList * appUidList)379 int32_t CmAuthGetAuthorizedAppList(const struct CmContext *context, const struct CmBlob *keyUri,
380     struct CmAppUidList *appUidList)
381 {
382     pthread_mutex_lock(&g_authMgrLock);
383     struct CMUri uriObj;
384     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
385     int32_t ret = GetAndCheckUriObj(&uriObj, keyUri, CM_URI_TYPE_APP_KEY);
386     if (ret != CM_SUCCESS) {
387         CM_LOG_E("uri decode failed, ret = %d", ret);
388         pthread_mutex_unlock(&g_authMgrLock);
389         return ret;
390     }
391 
392     struct CmAppUidList tempAppUidList = { 0, NULL };
393     do {
394         ret = CheckCallerIsProducer(context, &uriObj);
395         if (ret != CM_SUCCESS) {
396             CM_LOG_E("check caller userId/uid failed, ret = %d", ret);
397             break;
398         }
399 
400         ret = CmGetAuthList(context, keyUri, &tempAppUidList);
401         if (ret != CM_SUCCESS) {
402             CM_LOG_E("get auth list failed, ret = %d", ret);
403             break;
404         }
405 
406         if (tempAppUidList.appUidCount != 0) {
407             if (appUidList->appUidCount < tempAppUidList.appUidCount) {
408                 CM_LOG_E("out auth list buffer too small, input[%u] < expect[%u]",
409                     appUidList->appUidCount, tempAppUidList.appUidCount);
410                 ret = CMR_ERROR_BUFFER_TOO_SMALL;
411                 break;
412             }
413             if (memcpy_s(appUidList->appUid, appUidList->appUidCount * sizeof(uint32_t),
414                 tempAppUidList.appUid, tempAppUidList.appUidCount * sizeof(uint32_t)) != EOK) {
415                 ret = CMR_ERROR_INVALID_OPERATION;
416                 break;
417             }
418         }
419         appUidList->appUidCount = tempAppUidList.appUidCount;
420         ret = CM_SUCCESS;
421     } while (0);
422 
423     CM_FREE_PTR(tempAppUidList.appUid);
424     (void)CertManagerFreeUri(&uriObj);
425     pthread_mutex_unlock(&g_authMgrLock);
426     return ret;
427 }
428 
GetMacByteFromString(const char * macString,struct CmBlob * macByte)429 static int32_t GetMacByteFromString(const char *macString, struct CmBlob *macByte)
430 {
431     uint32_t size = strlen(macString) / BYTE_TO_HEX_OPER_LENGTH;
432     if ((size == 0) || (size > MAX_OUT_BLOB_SIZE)) {
433         return CMR_ERROR_INVALID_ARGUMENT;
434     }
435 
436     uint8_t *data = (uint8_t *)CMMalloc(size);
437     if (data  == NULL) {
438         CM_LOG_E("malloc mac in byte failed");
439         return CMR_ERROR_MALLOC_FAIL;
440     }
441 
442     int32_t ret = HexStringToByte(macString, data, size);
443     if (ret != CM_SUCCESS) {
444         CM_LOG_E("mac hex string to byte failed, ret = %d", ret);
445         CM_FREE_PTR(data);
446         return ret;
447     }
448 
449     macByte->data = data;
450     macByte->size = size;
451     return CM_SUCCESS;
452 }
453 
CheckIsAuthorizedApp(const struct CMUri * uriObj)454 static int32_t CheckIsAuthorizedApp(const struct CMUri *uriObj)
455 {
456     if ((uriObj->clientApp == NULL) || (uriObj->mac == NULL)) {
457         CM_LOG_E("invalid input auth uri");
458         return CMR_ERROR_INVALID_ARGUMENT;
459     }
460 
461     struct CmBlob macByte = { 0, NULL };
462     int32_t ret = GetMacByteFromString(uriObj->mac, &macByte);
463     if (ret != CM_SUCCESS) {
464         CM_LOG_E("get mac byte from string failed, ret = %d", ret);
465         return ret;
466     }
467 
468     /* calc uri mac */
469     uint8_t macData[MAC_SHA256_LEN] = {0};
470     struct CmBlob mac = { sizeof(macData), macData };
471     uint32_t clientUid = (uint32_t)atoi(uriObj->clientApp);
472     ret = CalcUriMac(uriObj, clientUid, &mac, false);
473     if (ret != CM_SUCCESS) {
474         CM_LOG_E("calc uri mac failed, ret = %d", ret);
475         CM_FREE_PTR(macByte.data);
476         return CMR_ERROR_AUTH_CHECK_FAILED;
477     }
478 
479     if ((macByte.size != mac.size) || (memcmp(macByte.data, mac.data, macByte.size) != 0)) {
480         CM_LOG_E("mac size[%u] invalid or mac check failed", macByte.size);
481         CM_FREE_PTR(macByte.data);
482         return CMR_ERROR_AUTH_CHECK_FAILED;
483     }
484 
485     CM_FREE_PTR(macByte.data);
486     return CM_SUCCESS;
487 }
488 
CmAuthIsAuthorizedApp(const struct CmContext * context,const struct CmBlob * authUri)489 int32_t CmAuthIsAuthorizedApp(const struct CmContext *context, const struct CmBlob *authUri)
490 {
491     struct CMUri uriObj;
492     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
493     int32_t ret = GetAndCheckUriObj(&uriObj, authUri, CM_URI_TYPE_APP_KEY);
494     if (ret != CM_SUCCESS) {
495         CM_LOG_E("uri decode failed, ret = %d", ret);
496         return ret;
497     }
498 
499     ret = CheckIsAuthorizedApp(&uriObj);
500     if (ret != CM_SUCCESS) {
501         CM_LOG_E("check is authed app failed, ret = %d", ret);
502     }
503     (void)CertManagerFreeUri(&uriObj);
504     return ret;
505 }
506 
CmAuthRemoveGrantedApp(const struct CmContext * context,const struct CmBlob * keyUri,uint32_t appUid)507 int32_t CmAuthRemoveGrantedApp(const struct CmContext *context, const struct CmBlob *keyUri, uint32_t appUid)
508 {
509     pthread_mutex_lock(&g_authMgrLock);
510     struct CMUri uriObj;
511     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
512     int32_t ret = GetAndCheckUriObj(&uriObj, keyUri, CM_URI_TYPE_APP_KEY);
513     if (ret != CM_SUCCESS) {
514         CM_LOG_E("uri decode failed, ret = %d", ret);
515         pthread_mutex_unlock(&g_authMgrLock);
516         return ret;
517     }
518 
519     do {
520         ret = CheckCallerIsProducer(context, &uriObj);
521         if (ret != CM_SUCCESS) {
522             CM_LOG_E("check caller userId/uid failed when remove grant, ret = %d", ret);
523             break;
524         }
525 
526         /* delete mac key */
527         ret = DeleteMacKey(&uriObj, appUid);
528         if (ret != CM_SUCCESS) {
529             CM_LOG_E("delete mac key failed, ret = %d", ret);
530             break;
531         }
532 
533         /* remove auth uid */
534         ret = CmRemoveAuthUid(context, keyUri, appUid);
535         if (ret != CM_SUCCESS) {
536             CM_LOG_E("remove auth uid from auth list failed, ret = %d", ret);
537             break;
538         }
539 
540         /* remove session node */
541         struct CmSessionNodeInfo info = { context->userId, context->uid, *keyUri };
542         CmDeleteSessionByNodeInfo(DELETE_SESSION_BY_ALL, &info);
543     } while (0);
544 
545     (void)CertManagerFreeUri(&uriObj);
546     pthread_mutex_unlock(&g_authMgrLock);
547     return ret;
548 }
549 
DeleteAuthInfo(uint32_t userId,const struct CmBlob * uri,const struct CmAppUidList * appUidList)550 static int32_t DeleteAuthInfo(uint32_t userId, const struct CmBlob *uri, const struct CmAppUidList *appUidList)
551 {
552     struct CMUri uriObj;
553     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
554     int32_t ret = GetAndCheckUriObj(&uriObj, uri, CM_URI_TYPE_APP_KEY);
555     if (ret != CM_SUCCESS) {
556         CM_LOG_E("uri decode failed, ret = %d", ret);
557         return ret;
558     }
559 
560     do {
561         for (uint32_t i = 0; i < appUidList->appUidCount; ++i) {
562             ret = DeleteMacKey(&uriObj, appUidList->appUid[i]);
563             if (ret != CM_SUCCESS) {
564                 CM_LOG_E("delete mac key failed, ret = %d", ret);
565                 break;
566             }
567         }
568     } while (0);
569 
570     (void)CertManagerFreeUri(&uriObj);
571     return ret;
572 }
573 
574 /* clear auth info when delete public credential */
CmAuthDeleteAuthInfo(const struct CmContext * context,const struct CmBlob * uri)575 int32_t CmAuthDeleteAuthInfo(const struct CmContext *context, const struct CmBlob *uri)
576 {
577     pthread_mutex_lock(&g_authMgrLock);
578     struct CmAppUidList appUidList = { 0, NULL };
579     int32_t ret;
580     do {
581         ret = CmGetAuthList(context, uri, &appUidList);
582         if (ret != CM_SUCCESS) {
583             CM_LOG_E("get auth list failed, ret = %d", ret);
584             break;
585         }
586 
587         ret = DeleteAuthInfo(context->userId, uri, &appUidList);
588         if (ret != CM_SUCCESS) {
589             CM_LOG_E("delete auth failed, ret = %d", ret);
590             break;
591         }
592 
593         ret = CmDeleteAuthListFile(context, uri);
594         if (ret != CM_SUCCESS) {
595             CM_LOG_E("delete auth list file failed, ret = %d", ret);
596             break;
597         }
598 
599         /* remove session node by uri */
600         struct CmSessionNodeInfo info = { context->userId, 0, *uri };
601         CmDeleteSessionByNodeInfo(DELETE_SESSION_BY_URI, &info);
602     } while (0);
603 
604     CM_FREE_PTR(appUidList.appUid);
605     pthread_mutex_unlock(&g_authMgrLock);
606     return ret;
607 }
608 
609 /* clear auth info when delete user */
CmAuthDeleteAuthInfoByUserId(uint32_t userId,const struct CmBlob * uri)610 int32_t CmAuthDeleteAuthInfoByUserId(uint32_t userId, const struct CmBlob *uri)
611 {
612     pthread_mutex_lock(&g_authMgrLock);
613     struct CmAppUidList appUidList = { 0, NULL };
614     int32_t ret;
615     do {
616         ret = CmGetAuthListByUserId(userId, uri, &appUidList);
617         if (ret != CM_SUCCESS) {
618             CM_LOG_E("get auth list by user id failed, ret = %d", ret);
619             break;
620         }
621 
622         ret = DeleteAuthInfo(userId, uri, &appUidList);
623         if (ret != CM_SUCCESS) {
624             CM_LOG_E("delete auth failed, ret = %d", ret);
625             break;
626         }
627 
628         ret = CmDeleteAuthListFileByUserId(userId, uri);
629         if (ret != CM_SUCCESS) {
630             CM_LOG_E("delete auth list file failed, ret = %d", ret);
631             break;
632         }
633     } while (0);
634 
635     CM_FREE_PTR(appUidList.appUid);
636     pthread_mutex_unlock(&g_authMgrLock);
637     return ret;
638 }
639 
640 /* clear auth info when delete application */
CmAuthDeleteAuthInfoByUid(uint32_t userId,uint32_t targetUid,const struct CmBlob * uri)641 int32_t CmAuthDeleteAuthInfoByUid(uint32_t userId, uint32_t targetUid, const struct CmBlob *uri)
642 {
643     pthread_mutex_lock(&g_authMgrLock);
644     bool isInAuthList = false;
645     int32_t ret = CmCheckIsAuthUidExistByUserId(userId, targetUid, uri, &isInAuthList);
646     if (ret != CM_SUCCESS) {
647         CM_LOG_E("check is in auth list failed, ret = %d", ret);
648         pthread_mutex_unlock(&g_authMgrLock);
649         return ret;
650     }
651 
652     if (!isInAuthList) {
653         pthread_mutex_unlock(&g_authMgrLock);
654         return CM_SUCCESS;
655     }
656 
657     uint32_t appUid[] = { targetUid };
658     struct CmAppUidList appUidList = { sizeof(appUid) / sizeof(uint32_t), appUid };
659     ret = DeleteAuthInfo(userId, uri, &appUidList);
660     if (ret != CM_SUCCESS) {
661         CM_LOG_E("delete mac key info failed, ret = %d", ret);
662         pthread_mutex_unlock(&g_authMgrLock);
663         return ret;
664     }
665 
666     ret = CmRemoveAuthUidByUserId(userId, targetUid, uri);
667     if (ret != CM_SUCCESS) {
668         CM_LOG_E("remove auth uid by user id failed, ret = %d", ret);
669     }
670     pthread_mutex_unlock(&g_authMgrLock);
671     return ret;
672 }
673 
CheckCommonPermission(const struct CmContext * context,const struct CMUri * uriObj)674 static int32_t CheckCommonPermission(const struct CmContext *context, const struct CMUri *uriObj)
675 {
676     int32_t ret = CheckCallerIsProducer(context, uriObj);
677     if (ret == CM_SUCCESS) {
678         return ret;
679     }
680 
681     if (uriObj->clientApp == NULL) {
682         CM_LOG_E("invalid uri client app");
683         return CMR_ERROR_PERMISSION_DENIED;
684     }
685 
686     uint32_t clientUid = (uint32_t)atoi(uriObj->clientApp);
687     if (clientUid != context->uid) {
688         CM_LOG_E("caller uid not match client uid");
689         return CMR_ERROR_PERMISSION_DENIED;
690     }
691 
692     CM_LOG_D("caller may be authed app, need check");
693     return CheckIsAuthorizedApp(uriObj);
694 }
695 
CmCheckAndGetCommonUri(const struct CmContext * context,uint32_t store,const struct CmBlob * uri,struct CmBlob * commonUri)696 int32_t CmCheckAndGetCommonUri(const struct CmContext *context, uint32_t store, const struct CmBlob *uri,
697     struct CmBlob *commonUri)
698 {
699     struct CMUri uriObj;
700     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
701     int32_t ret = CM_SUCCESS;
702     uint32_t type = (store == CM_SYS_CREDENTIAL_STORE) ? CM_URI_TYPE_SYS_KEY : CM_URI_TYPE_APP_KEY;
703     ret = GetAndCheckUriObj(&uriObj, uri, type);
704     if (ret != CM_SUCCESS) {
705         CM_LOG_E("uri decode failed, ret = %d", ret);
706         return ret;
707     }
708 
709     do {
710         if (store != CM_SYS_CREDENTIAL_STORE) {
711             ret = CheckCommonPermission(context, &uriObj);
712             if (ret != CM_SUCCESS) {
713                 break;
714             }
715         }
716 
717         ret = ConstructCommonUri(&uriObj, commonUri, store);
718         if (ret != CM_SUCCESS) {
719             CM_LOG_E("construct common uri failed, ret = %d", ret);
720             break;
721         }
722     } while (0);
723 
724     (void)CertManagerFreeUri(&uriObj);
725     return ret;
726 }
727 
CmCheckCallerIsProducer(const struct CmContext * context,const struct CmBlob * uri)728 int32_t CmCheckCallerIsProducer(const struct CmContext *context, const struct CmBlob *uri)
729 {
730     struct CMUri uriObj;
731     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
732     int32_t ret = GetAndCheckUriObj(&uriObj, uri, CM_URI_TYPE_APP_KEY);
733     if (ret != CM_SUCCESS) {
734         CM_LOG_E("uri decode failed, ret = %d", ret);
735         return ret;
736     }
737 
738     ret = CheckCallerIsProducer(context, &uriObj);
739     (void)CertManagerFreeUri(&uriObj);
740     return ret;
741 }
742 
743