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