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