• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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.h"
17 
18 #include <unistd.h>
19 #include <libgen.h>
20 
21 #include "cert_manager_auth_mgr.h"
22 #include "cert_manager_file.h"
23 #include "cert_manager_file_operator.h"
24 #include "cert_manager_key_operation.h"
25 #include "cert_manager_mem.h"
26 #include "cert_manager_permission_check.h"
27 #include "cert_manager_status.h"
28 #include "cert_manager_storage.h"
29 #include "cert_manager_uri.h"
30 #include "cert_manager_query.h"
31 #include "cm_cert_property_rdb.h"
32 #include "cert_manager_crypto_operation.h"
33 #include "cm_log.h"
34 #include "cm_type.h"
35 #include "cm_x509.h"
36 #include "cm_util.h"
37 
38 #include "securec.h"
39 
40 #include "hks_api.h"
41 
42 // LCOV_EXCL_START
43 #define MAX_PATH_LEN                        256
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
49 static bool g_hksInitialized = false;
50 
CertManagerInitialize(void)51 int32_t CertManagerInitialize(void)
52 {
53     int32_t ret;
54     if (!g_hksInitialized) {
55         ret = HksInitialize();
56         if (ret != HKS_SUCCESS) {
57             CM_LOG_E("HUKS init failed, ret = %d", ret);
58             return CMR_ERROR_SA_START_HUKS_INIT_FAILED;
59         }
60         g_hksInitialized = true;
61     }
62 
63     if (CmMakeDir(CERT_DIR) == CMR_ERROR_MAKE_DIR_FAIL) {
64         CM_LOG_E("Failed to create folder\n");
65         return CMR_ERROR_MAKE_DIR_FAIL;
66     }
67 
68     ret = CreateCertPropertyRdb();
69     if (ret != CM_SUCCESS) {
70         return ret;
71     }
72 
73     ret = CertManagerStatusInit();
74     if (ret != CM_SUCCESS) {
75         return (ret == CM_FAILURE) ? CMR_ERROR_SA_START_STATUS_INIT_FAILED : ret;
76     }
77 
78     return CM_SUCCESS;
79 }
80 
GetFilePath(const struct CmContext * context,uint32_t store,char * pathPtr,char * suffix,uint32_t * suffixLen)81 static int32_t GetFilePath(const struct CmContext *context, uint32_t store, char *pathPtr,
82     char *suffix, uint32_t *suffixLen)
83 {
84     int32_t ret;
85 
86     if (context == NULL) {
87         CM_LOG_E("Null pointer failture");
88         return CMR_ERROR_NULL_POINTER;
89     }
90 
91     if (suffix == NULL || suffixLen == NULL) {
92         CM_LOG_E("NULL pointer failure");
93         return CMR_ERROR_NULL_POINTER;
94     }
95 
96     switch (store) {
97         case CM_CREDENTIAL_STORE:
98             ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s%u", CREDNTIAL_STORE, context->userId);
99             break;
100         case CM_USER_TRUSTED_STORE:
101             ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s%u", USER_CA_STORE, context->userId);
102             break;
103         case CM_PRI_CREDENTIAL_STORE:
104             ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s%u", PRI_CREDNTIAL_STORE, context->userId);
105             break;
106         case CM_SYS_CREDENTIAL_STORE:
107             ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s%u", SYS_CREDNTIAL_STORE, context->userId);
108             break;
109         case CM_SYSTEM_TRUSTED_STORE:
110             ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s", SYSTEM_CA_STORE);
111             break;
112         default:
113             return CMR_ERROR_INVALID_ARGUMENT_STORE_TYPE;
114     }
115 
116     if (ret < 0) {
117         CM_LOG_E("Construct file Path failed ret: %d", ret);
118         return CMR_ERROR_MEM_OPERATION_PRINT;
119     }
120 
121     // construct file suffix
122     if (store != CM_SYSTEM_TRUSTED_STORE) {
123         ret = sprintf_s(suffix, MAX_SUFFIX_LEN, "%u", context->uid);
124         if (ret < 0) {
125             CM_LOG_E("Construct file suffix failed ret: %d", ret);
126             return CMR_ERROR_MEM_OPERATION_PRINT;
127         }
128     }
129 
130     *suffixLen = (uint32_t)strlen(suffix);
131     return CMR_OK;
132 }
133 
CmGetFilePath(const struct CmContext * context,uint32_t store,struct CmMutableBlob * pathBlob)134 static int32_t CmGetFilePath(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathBlob)
135 {
136     char pathPtr[MAX_PATH_LEN] = {0};
137     uint32_t suffixLen = 0;
138     char suffixBuf[MAX_SUFFIX_LEN] = {0};
139 
140     if ((pathBlob == NULL) || (pathBlob->data == NULL) || (pathBlob->size == 0)) {
141         CM_LOG_E("Null pointer failure");
142         return CMR_ERROR_NULL_POINTER;
143     }
144     int32_t ret = GetFilePath(context, store, pathPtr, suffixBuf, &suffixLen);
145     if (ret != CMR_OK) {
146         CM_LOG_E("Get file path faild");
147         return ret;
148     }
149 
150     /* Create folder if it does not exist */
151     if (CmMakeDir(pathPtr) == CMR_ERROR_MAKE_DIR_FAIL) {
152         CM_LOG_E("Failed to create path folder");
153         return CMR_ERROR_MAKE_DIR_FAIL;
154     }
155 
156     if (pathBlob->size - 1 < strlen(pathPtr) + suffixLen) {
157         CM_LOG_E("Failed to copy path");
158         return CMR_ERROR_BUFFER_TOO_SMALL;
159     }
160 
161     char *path = (char *)pathBlob->data;
162     if (suffixLen == 0) {
163         if (sprintf_s(path, MAX_PATH_LEN, "%s", pathPtr) < 0) {
164             return CMR_ERROR_MEM_OPERATION_PRINT;
165         }
166     } else {
167         if (sprintf_s(path, MAX_PATH_LEN, "%s/%s", pathPtr, suffixBuf) < 0) {
168             return CMR_ERROR_MEM_OPERATION_PRINT;
169         }
170     }
171 
172     pathBlob->size = strlen(path) + 1;
173     if (CmMakeDir(path) == CMR_ERROR_MAKE_DIR_FAIL) {
174         CM_LOG_E("Failed to create folder");
175         return CMR_ERROR_MAKE_DIR_FAIL;
176     }
177     return CMR_OK;
178 }
179 
FindObjectCert(const struct CmBlob * certUri,const struct CmMutableBlob * fNames,uint32_t certCount)180 static int32_t FindObjectCert(const struct CmBlob *certUri, const struct CmMutableBlob *fNames, uint32_t certCount)
181 {
182     for (uint32_t i = 0; i < certCount; i++) {
183         if (fNames[i].data == NULL) {
184             CM_LOG_E("Corrupted file name at index: %u", i);
185             return CMR_ERROR_STORAGE;
186         }
187         /* Check if url is matching with the cert filename */
188         if ((certUri->size <= fNames[i].size) && (memcmp(certUri->data, fNames[i].data, certUri->size) == 0)) {
189             return CM_SUCCESS;
190         }
191     }
192     return CMR_ERROR_NOT_FOUND;
193 }
194 
GetGmSystemCaCertPath(struct CmMutableBlob * path)195 static int32_t GetGmSystemCaCertPath(struct CmMutableBlob *path)
196 {
197     if ((path == NULL) || (path->data == NULL) || (path->size == 0)) {
198         CM_LOG_E("Null pointer failure");
199         return CMR_ERROR_NULL_POINTER;
200     }
201 
202     /* get gm system ca cert path */
203     char *pathStr = (char *)path->data;
204     if (sprintf_s(pathStr, path->size, "%s", SYSTEM_CA_STORE_GM) < 0) {
205         CM_LOG_E("sprintf gm system ca path failed");
206         return CMR_ERROR_MEM_OPERATION_PRINT;
207     }
208 
209     path->size = strlen(pathStr) + 1;
210     return CM_SUCCESS;
211 }
212 
CertManagerFindCertFileNameByUri(const struct CmContext * context,const struct CmBlob * certUri,uint32_t store,bool isGmSysCert,struct CmMutableBlob * path)213 int32_t CertManagerFindCertFileNameByUri(const struct CmContext *context, const struct CmBlob *certUri,
214     uint32_t store, bool isGmSysCert, struct CmMutableBlob *path)
215 {
216     ASSERT_ARGS(context && certUri && certUri->data);
217 
218     int32_t ret;
219     if (!isGmSysCert) {
220         ret = CmGetFilePath(context, store, path);
221     } else {
222         if (CmIsDirExist(SYSTEM_CA_STORE_GM) != CM_SUCCESS) {
223             return CMR_ERROR_NOT_FOUND;
224         }
225         ret = GetGmSystemCaCertPath(path);
226     }
227     if (ret != CM_SUCCESS) {
228         CM_LOG_E("Failed obtain path for store %x\n", store);
229         return ret;
230     }
231 
232     struct CmMutableBlob fileNames = { 0, NULL };
233     ret = CertManagerGetFilenames(&fileNames, (char *)path->data);
234     if (ret != CM_SUCCESS) {
235         CM_LOG_E("Failed obtain filenames from path");
236         return ret;
237     }
238 
239     struct CmMutableBlob *fNames = (struct CmMutableBlob *)fileNames.data;
240     ret = FindObjectCert(certUri, fNames, fileNames.size);
241     FreeFileNames(fNames, fileNames.size);
242     if (ret != CM_SUCCESS) {
243         CM_LOG_E("No cert matched, err: %d", ret);
244     }
245     return ret;
246 }
247 
CmRemoveAppCert(const struct CmContext * context,const struct CmBlob * keyUri,const uint32_t store)248 int32_t CmRemoveAppCert(const struct CmContext *context, const struct CmBlob *keyUri,
249     const uint32_t store)
250 {
251     ASSERT_ARGS(context && keyUri && keyUri->data && keyUri->size);
252 
253     enum CmAuthStorageLevel level;
254     int32_t ret = GetRdbAuthStorageLevel(keyUri, &level);
255     if (ret != CM_SUCCESS) {
256         CM_LOG_E("get rdb auth storage level failed, ret = %d", ret);
257         return ret;
258     }
259     if (level == ERROR_LEVEL) {
260         level = CM_AUTH_STORAGE_LEVEL_EL1;
261         CM_LOG_I("Remove cred level is ERROR_LEVEL, change to default level el1");
262     }
263 
264     if (store == CM_CREDENTIAL_STORE) {
265         ret = CmAuthDeleteAuthInfo(context, keyUri, level);
266         if (ret != CM_SUCCESS) {
267             CM_LOG_E("delete auth info failed when remove app certificate."); /* ignore ret code, only record log */
268         }
269     }
270 
271     ret = DeleteCertProperty((char *)keyUri->data);
272     if (ret != CM_SUCCESS) {
273         CM_LOG_E("Failed delete cert: %s rdbData", (char *)keyUri->data);
274         return ret;
275     }
276 
277     char pathBuf[CERT_MAX_PATH_LEN] = {0};
278     struct CmMutableBlob path = { sizeof(pathBuf), (uint8_t*) pathBuf };
279 
280     ret = CmGetFilePath(context, store, &path);
281     if (ret != CMR_OK) {
282         CM_LOG_E("Failed obtain path for store %u", store);
283         return ret;
284     }
285     ret = CertManagerFileRemove(pathBuf, (char *)keyUri->data);
286     if (ret != CMR_OK) {
287         CM_LOG_E("CertManagerFileRemove failed ret: %d", ret);
288         return ret;
289     }
290     ret = CmKeyOpDeleteKey(keyUri, level);
291     if (ret != CM_SUCCESS) { /* ignore the return of deleteKey */
292         CM_LOG_E("CertManagerKeyRemove failed, ret: %d", ret);
293     }
294 
295     return CMR_OK;
296 }
297 
ClearAuthInfo(const struct CmContext * context,const struct CmBlob * keyUri,const uint32_t store,enum CmAuthStorageLevel level)298 static void ClearAuthInfo(const struct CmContext *context, const struct CmBlob *keyUri, const uint32_t store,
299     enum CmAuthStorageLevel level)
300 {
301     if (store != CM_CREDENTIAL_STORE) {
302         return;
303     }
304 
305     int32_t ret = CmAuthDeleteAuthInfo(context, keyUri, level);
306     if (ret != CM_SUCCESS) {
307         CM_LOG_E("delete auth info failed."); /* ignore ret code, only record log */
308     }
309 }
310 
CmAppCertGetFilePath(const struct CmContext * context,const uint32_t store,struct CmBlob * path)311 static int32_t CmAppCertGetFilePath(const struct CmContext *context, const uint32_t store, struct CmBlob *path)
312 {
313     int32_t ret = CM_FAILURE;
314 
315     switch (store) {
316         case CM_CREDENTIAL_STORE :
317             ret = sprintf_s((char*)path->data, MAX_PATH_LEN, "%s%u/%u", CREDNTIAL_STORE, context->userId, context->uid);
318             break;
319         case CM_PRI_CREDENTIAL_STORE :
320             ret = sprintf_s((char*)path->data, MAX_PATH_LEN, "%s%u", PRI_CREDNTIAL_STORE, context->userId);
321             break;
322         case CM_SYS_CREDENTIAL_STORE:
323             ret = sprintf_s((char *)path->data, MAX_PATH_LEN, "%s%u", SYS_CREDNTIAL_STORE, context->userId);
324             break;
325         case CM_USER_TRUSTED_STORE:
326             ret = sprintf_s((char *)path->data, MAX_PATH_LEN, "%s%u", USER_CA_STORE, context->userId);
327             break;
328         default:
329             return CMR_ERROR_INVALID_ARGUMENT_STORE_TYPE;
330     }
331     if (ret < 0) {
332         return CMR_ERROR_MEM_OPERATION_PRINT;
333     }
334     return CM_SUCCESS;
335 }
336 
CmCallingAppCertGetFilePath(const struct CmContext * context,const uint32_t store,struct CmBlob * path)337 static int32_t CmCallingAppCertGetFilePath(const struct CmContext *context, const uint32_t store, struct CmBlob *path)
338 {
339     int32_t ret = CM_FAILURE;
340 
341     switch (store) {
342         case CM_CREDENTIAL_STORE :
343             ret = sprintf_s((char*)path->data, MAX_PATH_LEN, "%s%u/%u",
344                 CREDNTIAL_STORE, context->userId, context->uid);
345             break;
346         case CM_PRI_CREDENTIAL_STORE :
347             ret = sprintf_s((char*)path->data, MAX_PATH_LEN, "%s%u/%u",
348                 PRI_CREDNTIAL_STORE, context->userId, context->uid);
349             break;
350         case CM_SYS_CREDENTIAL_STORE:
351             ret = sprintf_s((char *)path->data, MAX_PATH_LEN, "%s%u/%u",
352                 SYS_CREDNTIAL_STORE, context->userId, context->uid);
353             break;
354         case CM_USER_TRUSTED_STORE:
355             ret = sprintf_s((char *)path->data, MAX_PATH_LEN, "%s%u/%u",
356                 USER_CA_STORE, context->userId, context->uid);
357             break;
358         default:
359             return CMR_ERROR_INVALID_ARGUMENT_STORE_TYPE;
360     }
361     if (ret < 0) {
362         return CMR_ERROR_MEM_OPERATION_PRINT;
363     }
364     return CM_SUCCESS;
365 }
366 
CmFreeFileNames(struct CmBlob * fileNames,const uint32_t fileSize)367 void CmFreeFileNames(struct CmBlob *fileNames, const uint32_t fileSize)
368 {
369     if (fileNames == NULL) {
370         CM_LOG_E("CmFreeFileNames fileNames is null");
371         return;
372     }
373 
374     for (uint32_t i = 0; i < fileSize; i++) {
375         if (fileNames[i].data != NULL) {
376             CMFree(fileNames[i].data);
377             fileNames[i].size = 0;
378         }
379     }
380 }
381 
CmGetUri(const char * filePath,struct CmBlob * uriBlob)382 int32_t CmGetUri(const char *filePath, struct CmBlob *uriBlob)
383 {
384     if ((filePath == NULL) || (uriBlob == NULL) || (uriBlob->data == NULL)) {
385         CM_LOG_E("CmGetUri param is null");
386         return CM_FAILURE;
387     }
388 
389     uint32_t filePathLen = strlen(filePath);
390     if ((filePathLen == 0) || (filePathLen > CM_MAX_FILE_NAME_LEN)) {
391         return CMR_ERROR_INVALID_ARGUMENT;
392     }
393 
394     int32_t i = (int32_t)(filePathLen - 1);
395     for (; i >= 0; i--) {
396         if (filePath[i] == '/') {
397             break;
398         }
399     }
400 
401     int32_t index = i + 1; /* index range: 0 to filePathLen */
402     uint32_t uriLen = filePathLen - (uint32_t)index + 1; /* include '\0' at end, range: 1 to filePathLen + 1 */
403     if (memcpy_s(uriBlob->data, uriBlob->size, &filePath[index], uriLen) != EOK) {
404         return CMR_ERROR_BUFFER_TOO_SMALL;
405     }
406     uriBlob->size = uriLen;
407 
408     return CM_SUCCESS;
409 }
410 
GetUriAndDeleteRdbData(const char * filePath,struct CmBlob * uriBlob,enum CmAuthStorageLevel * level)411 static int32_t GetUriAndDeleteRdbData(const char *filePath, struct CmBlob *uriBlob, enum CmAuthStorageLevel *level)
412 {
413     int32_t ret = CmGetUri(filePath, uriBlob);
414     if (ret != CM_SUCCESS) {
415         CM_LOG_E("Get uri failed");
416         return ret;
417     }
418 
419     ret = GetRdbAuthStorageLevel(uriBlob, level);
420     if (ret != CM_SUCCESS) {
421         CM_LOG_E("get rdb auth storage level failed, ret = %d", ret);
422         return ret;
423     }
424     if (*level == ERROR_LEVEL) {
425         *level = CM_AUTH_STORAGE_LEVEL_EL1;
426         CM_LOG_I("Delete rdb level is ERROR_LEVEL, change to default level el1");
427     }
428 
429     ret = DeleteCertProperty((char *)uriBlob->data);
430     if (ret != CM_SUCCESS) {
431         CM_LOG_E("Failed delete cert: %s rdbData", (char *)uriBlob->data);
432         return ret;
433     }
434     return CM_SUCCESS;
435 }
436 
CmRemoveSpecifiedAppCert(const struct CmContext * context,const uint32_t store)437 static int32_t CmRemoveSpecifiedAppCert(const struct CmContext *context, const uint32_t store)
438 {
439     uint32_t fileCount = 0;
440     int32_t ret = CM_SUCCESS;
441     char pathBuf[CERT_MAX_PATH_LEN] = {0};
442     char uriBuf[MAX_LEN_URI] = {0};
443     struct CmBlob fileNames[MAX_COUNT_CERTIFICATE];
444     struct CmBlob path = { sizeof(pathBuf), (uint8_t*)pathBuf };
445     struct CmBlob uriBlob = { sizeof(uriBuf), (uint8_t*)uriBuf };
446     uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob);
447     (void)memset_s(fileNames, len, 0, len);
448 
449     do {
450         ret = CmAppCertGetFilePath(context, store, &path);
451         if (ret != CM_SUCCESS) {
452             CM_LOG_E("Get file path for store:%u faild", store);
453             break;
454         }
455 
456         if (store == CM_CREDENTIAL_STORE) {
457             ret = CmUidLayerGetFileCountAndNames(pathBuf, fileNames, MAX_COUNT_CERTIFICATE, &fileCount);
458         } else {
459             ret = CmUserIdLayerGetFileCountAndNames(pathBuf, fileNames, MAX_COUNT_CERTIFICATE, &fileCount);
460         }
461         if (ret != CM_SUCCESS) {
462             CM_LOG_E("Get file count and names from path faild");
463             break;
464         }
465 
466         for (uint32_t i = 0; i < fileCount; i++) {
467             if (CertManagerFileRemove(NULL, (char *)fileNames[i].data) != CM_SUCCESS) {
468                 CM_LOG_E("App cert %u remove faild", i);
469                 continue;
470             }
471 
472             uriBlob.size = sizeof(uriBuf);
473             (void)memset_s(uriBuf, uriBlob.size, 0, uriBlob.size);
474             enum CmAuthStorageLevel level;
475             if (GetUriAndDeleteRdbData((char *)fileNames[i].data, &uriBlob, &level) != CM_SUCCESS) {
476                 CM_LOG_E("Get uri failed");
477                 continue;
478             }
479 
480             int32_t retCode = CmKeyOpDeleteKey(&uriBlob, level);
481             if (retCode != CM_SUCCESS) { /* ignore the return of deleteKey */
482                 CM_LOG_E("App key %u remove failed ret: %d", i, retCode);
483             }
484             ClearAuthInfo(context, &uriBlob, store, level);
485         }
486     } while (0);
487     CmFreeFileNames(fileNames, MAX_COUNT_CERTIFICATE);
488     return ret;
489 }
490 
CmRemoveAllAppCert(const struct CmContext * context)491 int32_t CmRemoveAllAppCert(const struct CmContext *context)
492 {
493     if (!CmHasPrivilegedPermission() || !CmHasCommonPermission() || !CmHasSystemAppPermission()) {
494         CM_LOG_E("permission check failed");
495         return CMR_ERROR_PERMISSION_DENIED;
496     }
497     if (!CmIsSystemApp()) {
498         CM_LOG_E("remove app cert: caller is not system app");
499         return CMR_ERROR_NOT_SYSTEMP_APP;
500     }
501 
502     /* Only public and private credential removed can be returned */
503     /* remove pubic credential app cert */
504     int32_t ret = CmRemoveSpecifiedAppCert(context, CM_CREDENTIAL_STORE);
505     if (ret != CM_SUCCESS) {
506         CM_LOG_E("remove pubic credential app cert faild");
507     }
508 
509     /* remove private credential app cert */
510     ret = CmRemoveSpecifiedAppCert(context, CM_PRI_CREDENTIAL_STORE);
511     if (ret != CM_SUCCESS) {
512         CM_LOG_E("remove private credential app cert faild");
513     }
514 
515     /* remove system credential app cert */
516     ret = CmRemoveSpecifiedAppCert(context, CM_SYS_CREDENTIAL_STORE);
517     if (ret != CM_SUCCESS) {
518         CM_LOG_E("remove system credential app cert faild");
519     }
520 
521     return ret;
522 }
523 
CmServiceGetAppCertList(const struct CmContext * context,uint32_t store,struct CmBlob * fileNames,const uint32_t fileSize,uint32_t * fileCount)524 int32_t CmServiceGetAppCertList(const struct CmContext *context, uint32_t store, struct CmBlob *fileNames,
525     const uint32_t fileSize, uint32_t *fileCount)
526 {
527     char pathBuf[CERT_MAX_PATH_LEN] = {0};
528     struct CmBlob path = { sizeof(pathBuf), (uint8_t*)pathBuf };
529 
530     int32_t ret = CmAppCertGetFilePath(context, store, &path);
531     if (ret != CM_SUCCESS) {
532         CM_LOG_E("Get file path for store:%u faild", store);
533         return CM_FAILURE;
534     }
535 
536     if (store == CM_CREDENTIAL_STORE) {
537         ret = CmUidLayerGetFileCountAndNames(pathBuf, fileNames, fileSize, fileCount);
538     } else {
539         ret = CmUserIdLayerGetFileCountAndNames(pathBuf, fileNames, fileSize, fileCount);
540     }
541     if (ret != CM_SUCCESS) {
542         CM_LOG_E("Get file count and names from path faild ret:%d", ret);
543         return ret;
544     }
545 
546     return CM_SUCCESS;
547 }
548 
CmServiceGetCallingAppCertList(const struct CmContext * context,uint32_t store,struct CmBlob * fileNames,const uint32_t fileSize,uint32_t * fileCount)549 int32_t CmServiceGetCallingAppCertList(const struct CmContext *context, uint32_t store, struct CmBlob *fileNames,
550     const uint32_t fileSize, uint32_t *fileCount)
551 {
552     char pathBuf[CERT_MAX_PATH_LEN] = {0};
553     struct CmBlob path = { sizeof(pathBuf), (uint8_t*)pathBuf };
554 
555     int32_t ret = CmCallingAppCertGetFilePath(context, store, &path);
556     if (ret != CM_SUCCESS) {
557         CM_LOG_E("Get file path for store:%u faild", store);
558         return CM_FAILURE;
559     }
560 
561     ret = CmUidLayerGetFileCountAndNames(pathBuf, fileNames, fileSize, fileCount);
562     if (ret != CM_SUCCESS) {
563         CM_LOG_E("Get file count and names from path faild ret:%d", ret);
564         return ret;
565     }
566 
567     return CM_SUCCESS;
568 }
569 
GetCertOrCredCount(const struct CmContext * context,const uint32_t store,uint32_t * certCount)570 int32_t GetCertOrCredCount(const struct CmContext *context, const uint32_t store, uint32_t *certCount)
571 {
572     if (context == NULL || certCount == NULL) {
573         CM_LOG_E("null pointer");
574         return CMR_ERROR_NULL_POINTER;
575     }
576     uint32_t fileCount = 0;
577     struct CmBlob fileNames[MAX_COUNT_CERTIFICATE];
578     uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob);
579     (void)memset_s(fileNames, len, 0, len);
580 
581     int32_t ret = CmServiceGetAppCertList(context, store, fileNames, MAX_COUNT_CERTIFICATE, &fileCount);
582     CmFreeFileNames(fileNames, MAX_COUNT_CERTIFICATE);
583     if (ret != CM_SUCCESS) {
584         CM_LOG_E("Failed to get app cert list");
585         return ret;
586     }
587 
588     *certCount = fileCount;
589     return CM_SUCCESS;
590 }
591 
CmCheckCertCount(const struct CmContext * context,const uint32_t store,const char * fileName)592 int32_t CmCheckCertCount(const struct CmContext *context, const uint32_t store, const char *fileName)
593 {
594     if (context == NULL || fileName == NULL) {
595         return CMR_ERROR_INVALID_ARGUMENT;
596     }
597 
598     int32_t ret = CM_FAILURE;
599     do {
600         uint32_t certCount = 0;
601         int32_t retVal = GetCertOrCredCount(context, store, &certCount);
602         if (retVal != CM_SUCCESS) {
603             CM_LOG_E("Failed obtain cert count for store:%u", store);
604             break;
605         }
606         if (certCount < MAX_COUNT_CERTIFICATE) {
607             ret = CM_SUCCESS;
608             break;
609         }
610 
611         char pathBuf[CERT_MAX_PATH_LEN] = {0};
612         retVal = ConstructUidPath(context, store, pathBuf, sizeof(pathBuf));
613         if (retVal != CM_SUCCESS) {
614             CM_LOG_E("Failed obtain path for store:%u", store);
615             break;
616         }
617 
618         char fullFileName[CM_MAX_FILE_NAME_LEN] = {0};
619         if (snprintf_s(fullFileName, CM_MAX_FILE_NAME_LEN, CM_MAX_FILE_NAME_LEN - 1, "%s/%s", pathBuf, fileName) < 0) {
620             CM_LOG_E("mkdir full name failed");
621             ret = CMR_ERROR_MEM_OPERATION_PRINT;
622             break;
623         }
624 
625         if (access(fullFileName, F_OK) == 0) {
626             ret = CM_SUCCESS;
627             break;
628         }
629     } while (0);
630     return ret;
631 }
632 
ConstructCertUri(const struct CmContext * context,const struct CmBlob * certAlias,struct CmBlob * certUri)633 static int32_t ConstructCertUri(const struct CmContext *context, const struct CmBlob *certAlias,
634     struct CmBlob *certUri)
635 {
636     struct CmBlob commonUri = { 0, NULL };
637     int32_t ret;
638     do {
639         ret = CmConstructCommonUri(context, CM_URI_TYPE_CERTIFICATE, certAlias, &commonUri);
640         if (ret != CM_SUCCESS) {
641             CM_LOG_E("construct cert uri get common uri failed");
642             break;
643         }
644 
645         if (certUri->size < commonUri.size) {
646             CM_LOG_E("out cert uri size[%u] too small", certUri->size);
647             ret = CMR_ERROR_BUFFER_TOO_SMALL;
648             break;
649         }
650 
651         if (memcpy_s(certUri->data, certUri->size, commonUri.data, commonUri.size) != EOK) {
652             CM_LOG_E("copy cert uri failed");
653             ret = CMR_ERROR_MEM_OPERATION_COPY;
654             break;
655         }
656 
657         certUri->size = commonUri.size;
658     } while (0);
659 
660     CM_FREE_PTR(commonUri.data);
661     return ret;
662 }
663 
CmWriteUserCert(const struct CmContext * context,struct CmMutableBlob * pathBlob,const struct CmBlob * userCert,const struct CmBlob * certAlias,struct CmBlob * certUri)664 int32_t CmWriteUserCert(const struct CmContext *context, struct CmMutableBlob *pathBlob,
665     const struct CmBlob *userCert, const struct CmBlob *certAlias, struct CmBlob *certUri)
666 {
667     if (certAlias->size > MAX_LEN_CERT_ALIAS) {
668         CM_LOG_E("alias size[%u] is too large", certAlias->size);
669         return CMR_ERROR_ALIAS_LENGTH_REACHED_LIMIT;
670     }
671 
672     int32_t ret;
673     do {
674         ret = ConstructCertUri(context, certAlias, certUri);
675         if (ret != CM_SUCCESS) {
676             CM_LOG_E("get cert uri failed");
677             break;
678         }
679 
680         if (certUri->size > MAX_LEN_URI) {
681             CM_LOG_E("uri size is too large");
682             ret = CMR_ERROR_INVALID_ARGUMENT;
683             break;
684         }
685 
686         ret = CmCheckCertCount(context, CM_USER_TRUSTED_STORE, (char *)certUri->data);
687         if (ret != CM_SUCCESS) {
688             CM_LOG_E("cert count beyond maxcount, can't install");
689             ret = CMR_ERROR_MAX_CERT_COUNT_REACHED;
690             break;
691         }
692 
693         if (CmFileWrite((char*)pathBlob->data, (char *)certUri->data, 0, userCert->data, userCert->size) != CMR_OK) {
694             CM_LOG_E("Failed to write certificate");
695             ret = CMR_ERROR_WRITE_FILE_FAIL;
696             break;
697         }
698     } while (0);
699     return ret;
700 }
701 
CmGetDisplayNameByURI(const struct CmBlob * uri,const char * object,struct CmBlob * displayName)702 int32_t CmGetDisplayNameByURI(const struct CmBlob *uri, const char *object, struct CmBlob *displayName)
703 {
704     if ((CmCheckBlob(uri) != CM_SUCCESS) || (object == NULL) ||
705         (CmCheckBlob(displayName) != CM_SUCCESS)) {
706         CM_LOG_E("input param is invalid");
707         return CMR_ERROR_INVALID_ARGUMENT;
708     }
709     int32_t ret = CM_SUCCESS;
710     struct CertProperty certProperty;
711     (void)memset_s(&certProperty, sizeof(struct CertProperty), 0, sizeof(struct CertProperty));
712     ret = QueryCertProperty((char *)uri->data, &certProperty);
713     if (ret != CM_SUCCESS) {
714         CM_LOG_E("Failed to query certProperty, ret=%d", ret);
715         return ret;
716     }
717     const char *temp = NULL;
718     if (strlen(certProperty.uri) != 0) {
719         temp = (const char *)certProperty.alias;
720     } else {
721         temp = object;
722     }
723     if (memcpy_s(displayName->data, displayName->size, temp, strlen(temp) + 1) != CM_SUCCESS) {
724         CM_LOG_E("Failed to copy displayName->data");
725         ret = CMR_ERROR_MEM_OPERATION_COPY;
726     }
727     displayName->size = strlen(temp) + 1;
728     return ret;
729 }
730 
GetCertType(uint32_t store)731 static const char* GetCertType(uint32_t store)
732 {
733     switch (store) {
734         case CM_USER_TRUSTED_STORE:
735             return "c";
736 
737         case CM_CREDENTIAL_STORE:
738             return "ak";
739 
740         case CM_PRI_CREDENTIAL_STORE:
741             return "ak";
742 
743         case CM_SYS_CREDENTIAL_STORE:
744             return "sk";
745 
746         default:
747             return NULL;
748     }
749     return NULL;
750 }
751 
RdbInsertCertProperty(const struct CertPropertyOri * propertyOri)752 int32_t RdbInsertCertProperty(const struct CertPropertyOri *propertyOri)
753 {
754     struct CertProperty certProp;
755     (void)memset_s(&certProp, sizeof(struct CertProperty), 0, sizeof(struct CertProperty));
756     certProp.userId = (int32_t)propertyOri->context->userId;
757     certProp.uid = (int32_t)propertyOri->context->uid;
758     certProp.level = propertyOri->level;
759 
760     const char *certType = GetCertType(propertyOri->store);
761     if (certType == NULL) {
762         CM_LOG_E("Type does not support installation");
763         return CMR_ERROR_INVALID_ARGUMENT;
764     }
765     certProp.certStore = (int32_t)propertyOri->store;
766     if (memcpy_s(certProp.certType, MAX_LEN_CERT_TYPE, certType, strlen(certType)) != EOK) {
767         CM_LOG_E("memcpy certType fail");
768         return CMR_ERROR_MEM_OPERATION_COPY;
769     }
770 
771     if (memcpy_s(certProp.uri, MAX_LEN_URI, (char *)propertyOri->uri->data, propertyOri->uri->size) != EOK) {
772         CM_LOG_E("memcpy uri fail");
773         return CMR_ERROR_MEM_OPERATION_COPY;
774     }
775     if (memcpy_s(certProp.alias, MAX_LEN_CERT_ALIAS, (char *)propertyOri->alias->data, propertyOri->alias->size)
776         != EOK) {
777         CM_LOG_E("memcpy subjectName fail");
778         return CMR_ERROR_MEM_OPERATION_COPY;
779     }
780     if (memcpy_s(certProp.subjectName, MAX_LEN_SUBJECT_NAME, (char *)propertyOri->subjectName->data,
781         propertyOri->subjectName->size) != EOK) {
782         CM_LOG_E("memcpy subjectName fail");
783         return CMR_ERROR_MEM_OPERATION_COPY;
784     }
785 
786     int32_t ret = InsertCertProperty(&certProp);
787     if (ret != CM_SUCCESS) {
788         CM_LOG_E("Failed to InsertCertProperty");
789         return ret;
790     }
791     return CM_SUCCESS;
792 }
793 
CmStoreUserCert(const char * path,const struct CmBlob * userCert,const char * userCertName)794 int32_t CmStoreUserCert(const char *path, const struct CmBlob *userCert, const char *userCertName)
795 {
796     int32_t ret = CM_SUCCESS;
797     if (CmUserBackupFileWrite(path, userCertName, 0, userCert->data, userCert->size) != CMR_OK) {
798         CM_LOG_E("Failed to write certificate");
799         ret = CMR_ERROR_WRITE_FILE_FAIL;
800     }
801     return ret;
802 }
803 
CmGenerateSaConf(const char * userCertConfigPath,const char * userCertBakupDirPath,const char * userCertName)804 int32_t CmGenerateSaConf(const char *userCertConfigPath, const char *userCertBakupDirPath, const char *userCertName)
805 {
806     int32_t ret = CM_SUCCESS;
807     char userCertBackupFilePath[CERT_MAX_PATH_LEN] = { 0 };
808 
809     if (userCertBakupDirPath == NULL) {
810         if (snprintf_s(userCertBackupFilePath, CERT_MAX_PATH_LEN, CERT_MAX_PATH_LEN - 1, "%s", userCertName) < 0) {
811             CM_LOG_E("construct userCertBackupFilePath failed");
812             return CMR_ERROR_MEM_OPERATION_PRINT;
813         }
814     } else {
815         if (snprintf_s(userCertBackupFilePath, CERT_MAX_PATH_LEN, CERT_MAX_PATH_LEN - 1, "%s/%s", userCertBakupDirPath,
816                        userCertName) < 0) {
817             CM_LOG_E("construct userCertBackupFilePath failed");
818             return CMR_ERROR_MEM_OPERATION_PRINT;
819         }
820     }
821 
822     if (CmFileWrite(NULL, userCertConfigPath, 0, (const uint8_t *)userCertBackupFilePath,
823                     strlen(userCertBackupFilePath)) != CMR_OK) {
824         CM_LOG_E("Failed to write saconf file content");
825         ret = CMR_ERROR_WRITE_FILE_FAIL;
826     }
827     return ret;
828 }
829 
CmRemoveUserCert(struct CmMutableBlob * pathBlob,const struct CmBlob * certUri)830 int32_t CmRemoveUserCert(struct CmMutableBlob *pathBlob, const struct CmBlob *certUri)
831 {
832     return CertManagerFileRemove((char *)pathBlob->data, (char *)certUri->data);
833 }
834 
CmBackupRemove(uint32_t userId,const char * path,const struct CmBlob * certUri)835 int32_t CmBackupRemove(uint32_t userId, const char *path, const struct CmBlob *certUri)
836 {
837     if (path == NULL) {
838         CM_LOG_E("input params is invaild");
839         return CMR_ERROR_INVALID_ARGUMENT;
840     }
841 
842     uint32_t uid = 0;
843     char *uidStr = basename((char *)path);
844     if (CmIsNumeric(uidStr, strlen(uidStr) + 1, &uid) != CM_SUCCESS) {
845         CM_LOG_E("parse string to uint32 failed.");
846         return CMR_ERROR_INVALID_ARGUMENT;
847     }
848 
849     char userCertConfigFilePath[CERT_MAX_PATH_LEN] = { 0 };
850     int32_t ret = CmGetCertConfPath(userId, uid, certUri, userCertConfigFilePath, CERT_MAX_PATH_LEN);
851     if (ret != CM_SUCCESS) {
852         CM_LOG_E("Get user cert config path failed ret = %d", ret);
853         return CM_FAILURE;
854     }
855 
856     ret = CmRemoveBackupUserCert(NULL, NULL, userCertConfigFilePath);
857     if (ret != CMR_OK) {
858         CM_LOG_E("User Cert remove config and backup file failed, ret: %d", ret);
859     }
860     return ret;
861 }
862 
RemoveAllUserCert(const struct CmContext * context,uint32_t store,const char * path)863 static int32_t RemoveAllUserCert(const struct CmContext *context, uint32_t store, const char* path)
864 {
865     ASSERT_ARGS(path);
866     struct CmMutableBlob fileNames = { 0, NULL };
867     struct CmBlob certUri = { 0, NULL };
868     int32_t ret = CertManagerGetFilenames(&fileNames, path);
869     if (ret != CM_SUCCESS) {
870         CM_LOG_E("Failed obtain filenames from path");
871         return ret;
872     }
873 
874     struct CmMutableBlob *fNames = (struct CmMutableBlob *)fileNames.data;
875     for (uint32_t i = 0; i < fileNames.size; i++) {
876         certUri.data = (uint8_t *)fNames[i].data;
877         certUri.size = fNames[i].size - 1;
878         ret = CertManagerFileRemove(path, (char *)fNames[i].data);
879         if (ret != CMR_OK) {
880             CM_LOG_E("User Cert %u remove failed, ret: %d", i, ret);
881             continue;
882         }
883         ret = CmBackupRemove(context->userId, path, &certUri);
884         if (ret != CMR_OK) {
885             CM_LOG_E("User Cert %u remove config and backup file failed, ret: %d", i, ret);
886         }
887         ret = DeleteCertProperty((char *)certUri.data);
888         if (ret != CM_SUCCESS) {
889             CM_LOG_E("Failed delete cert: %s rdbData", (char *)certUri.data);
890         }
891     }
892 
893     FreeFileNames(fNames, fileNames.size);
894     return ret;
895 }
896 
RemoveAllUidDir(const char * path)897 static int32_t RemoveAllUidDir(const char* path)
898 {
899     return CM_ERROR(CmDirRemove(path));
900 }
901 
RemoveAllConfUidDir(uint32_t userId,const char * uidPath)902 static int32_t RemoveAllConfUidDir(uint32_t userId, const char *uidPath)
903 {
904     if (uidPath == NULL) {
905         CM_LOG_E("input params is invaild");
906         return CMR_ERROR_INVALID_ARGUMENT;
907     }
908     char configUidDirPath[CERT_MAX_PATH_LEN] = { 0 };
909     uint32_t uid = 0;
910     char *uidStr = basename((char *)uidPath);
911     if (CmIsNumeric(uidStr, strlen(uidStr) + 1, &uid) != CM_SUCCESS) {
912         CM_LOG_E("parse string to uint32 failed.");
913         return CMR_ERROR_INVALID_ARGUMENT;
914     }
915 
916     int32_t ret = CmGetCertConfUidDir(userId, uid, configUidDirPath, CERT_MAX_PATH_LEN);
917     if (ret != CM_SUCCESS) {
918         CM_LOG_E("Get user cert config file UidDirPath failed, ret = %d", ret);
919         return ret;
920     }
921 
922     ret = CmDirRemove(configUidDirPath);
923     if (ret != CM_SUCCESS) {
924         CM_LOG_E("Remove user cert config file configUidDirPath fail, ret = %d", ret);
925     }
926     return ret;
927 }
928 
CmRemoveAllUserCert(const struct CmContext * context,uint32_t store,const struct CmMutableBlob * pathList)929 int32_t CmRemoveAllUserCert(const struct CmContext *context, uint32_t store, const struct CmMutableBlob *pathList)
930 {
931     ASSERT_ARGS(pathList && pathList->data && pathList->size);
932     int32_t ret = CM_SUCCESS;
933     struct CmMutableBlob *path = (struct CmMutableBlob *)pathList->data;
934 
935     for (uint32_t i = 0; i < pathList->size; i++) {
936         ret = RemoveAllUserCert(context, store, (char *)path[i].data);
937         if (ret != CM_SUCCESS) {
938             CM_LOG_E("Failed remove usercert at %u_th dir", i);
939             continue;
940         }
941         ret = RemoveAllUidDir((char *)path[i].data);
942         if (ret != CM_SUCCESS) {
943             CM_LOG_E("Remove UidPath fail, ret = %d", ret);
944             continue;
945         }
946         ret = RemoveAllConfUidDir(context->userId, (char *)path[i].data);
947         if (ret != CM_SUCCESS) {
948             CM_LOG_E("Remove all config UidPath fail, ret = %d", ret);
949             continue;
950         }
951     }
952     return ret;
953 }
954 
CmRemoveBackupUserCert(const struct CmContext * context,const struct CmBlob * certUri,const char * userCertConfigFilePath)955 int32_t CmRemoveBackupUserCert(const struct CmContext *context, const struct CmBlob *certUri,
956                                const char *userCertConfigFilePath)
957 {
958     int32_t ret = CM_SUCCESS;
959     char userConfigFilePath[CERT_MAX_PATH_LEN] = { 0 };
960     char *userConfFilePath = NULL;
961 
962     if (userCertConfigFilePath == NULL) {
963         if ((context == NULL) || (CmCheckBlob(certUri) != CM_SUCCESS)) {
964             CM_LOG_E("Invalid input arguments");
965             return CMR_ERROR_INVALID_ARGUMENT;
966         }
967 
968         ret = CmGetCertConfPath(context->userId, context->uid, certUri, userConfigFilePath, CERT_MAX_PATH_LEN);
969         if (ret != CM_SUCCESS) {
970             CM_LOG_E("CmGetCertConfPath failed, ret = %d", ret);
971             return ret;
972         }
973         userConfFilePath = userConfigFilePath;
974     } else {
975         userConfFilePath = (char *)userCertConfigFilePath;
976     }
977 
978     ret = CmRmUserCert(userConfFilePath);
979     if (ret != CM_SUCCESS) {
980         CM_LOG_E("RmUserCertFile failed, ret = %d", ret);
981         return ret;
982     }
983 
984     ret = CmRmSaConf(userConfFilePath);
985     if (ret != CM_SUCCESS) {
986         CM_LOG_E("RmSaConfFile fail, ret = %d", ret);
987         return ret;
988     }
989 
990     return CM_SUCCESS;
991 }
992 
GetObjNameFromCertData(const struct CmBlob * certData,const struct CmBlob * certAlias,struct CmBlob * objectName)993 int32_t GetObjNameFromCertData(const struct CmBlob *certData, const struct CmBlob *certAlias,
994     struct CmBlob *objectName)
995 {
996     if ((CmCheckBlob(certData) != CM_SUCCESS) || (CmCheckBlob(certAlias) != CM_SUCCESS) || (objectName == NULL)) {
997         CM_LOG_E("input param is invalid");
998         return CMR_ERROR_INVALID_ARGUMENT;
999     }
1000     struct CmBlob object = { certAlias->size, certAlias->data };
1001     uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
1002     struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
1003     if (strcmp("", (char *)certAlias->data) == 0) {
1004         int32_t ret = GetNameEncode(certData, &encodeTarget);
1005         if (ret != CM_SUCCESS) {
1006             CM_LOG_E("base64urlsha256 failed");
1007             return ret;
1008         }
1009         object.data = encodeTarget.data;
1010         object.size = encodeTarget.size;
1011     }
1012 
1013     if (memcpy_s(objectName->data, objectName->size, object.data, object.size) != CM_SUCCESS) {
1014         CM_LOG_E("memcpy object name failed");
1015         return CMR_ERROR_MEM_OPERATION_COPY;
1016     }
1017     return CM_SUCCESS;
1018 }
1019 #ifdef __cplusplus
1020 }
1021 #endif
1022 // LCOV_EXCL_STOP