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