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