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