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