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