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