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_service.h"
17
18 #include <openssl/x509.h>
19 #include <openssl/x509v3.h>
20 #include <openssl/bio.h>
21 #include <openssl/pem.h>
22
23 #include "securec.h"
24
25 #include "cert_manager.h"
26 #include "cert_manager_app_cert_process.h"
27 #include "cert_manager_auth_mgr.h"
28 #include "cert_manager_check.h"
29 #include "cert_manager_key_operation.h"
30 #include "cert_manager_mem.h"
31 #include "cert_manager_permission_check.h"
32 #include "cert_manager_query.h"
33 #include "cert_manager_status.h"
34 #include "cert_manager_storage.h"
35 #include "cert_manager_uri.h"
36 #include "cm_event_process.h"
37 #include "cm_cert_property_rdb.h"
38 #include "cm_log.h"
39 #include "cm_type.h"
40 #include "cm_x509.h"
41
42 #include "cert_manager_file_operator.h"
43 #include "cert_manager_updateflag.h"
44
CheckPermission(bool needPriPermission,bool needCommonPermission)45 static int32_t CheckPermission(bool needPriPermission, bool needCommonPermission)
46 {
47 if (needPriPermission) {
48 if (!CmHasPrivilegedPermission()) {
49 CM_LOG_E("caller lacks pri permission");
50 return CMR_ERROR_PERMISSION_DENIED;
51 }
52 if (!CmIsSystemApp()) {
53 CM_LOG_E("caller is not system app");
54 return CMR_ERROR_NOT_SYSTEMP_APP;
55 }
56 }
57
58 if (needCommonPermission) {
59 if (!CmHasCommonPermission()) {
60 CM_LOG_E("caller lacks common permission");
61 return CMR_ERROR_PERMISSION_DENIED;
62 }
63 }
64
65 return CM_SUCCESS;
66 }
67
CmServicInstallAppCert(struct CmContext * context,const struct CmAppCertParam * certParam,struct CmBlob * keyUri)68 int32_t CmServicInstallAppCert(struct CmContext *context, const struct CmAppCertParam *certParam, struct CmBlob *keyUri)
69 {
70 int32_t ret = CmServiceInstallAppCertCheck(certParam, context);
71 if (ret != CM_SUCCESS) {
72 CM_LOG_E("service intall app cert check params failed, ret = %d", ret);
73 return ret;
74 }
75
76 ret = CmInstallAppCertPro(context, certParam, keyUri);
77 if (ret != CM_SUCCESS) {
78 CM_LOG_E("CmInstallAppCert fail, ret = %d", ret);
79 return ret;
80 }
81 return ret;
82 }
83
GetPublicAppCert(const struct CmContext * context,uint32_t store,struct CmBlob * keyUri,struct CmBlob * certBlob)84 static int32_t GetPublicAppCert(const struct CmContext *context, uint32_t store,
85 struct CmBlob *keyUri, struct CmBlob *certBlob)
86 {
87 struct CmBlob commonUri = { 0, NULL };
88 int32_t ret = CmCheckAndGetCommonUri(context, store, keyUri, &commonUri);
89 if (ret != CM_SUCCESS) {
90 CM_LOG_E("check and get common uri when get app cert failed, ret = %d", ret);
91 return ret;
92 }
93
94 do {
95 ret = CmStorageGetAppCert(context, store, &commonUri, certBlob);
96 if (ret != CM_SUCCESS) {
97 CM_LOG_E("get app cert from storage failed, ret = %d", ret);
98 break;
99 }
100
101 /* remove authinfo from uri */
102 if (keyUri->size < commonUri.size) {
103 CM_LOG_E("keyUri size[%u] smaller than commonUri size[%u]", keyUri->size, commonUri.size);
104 ret = CMR_ERROR_INVALID_ARGUMENT;
105 break;
106 }
107 if (memcpy_s(keyUri->data, keyUri->size, commonUri.data, commonUri.size) != EOK) {
108 CM_LOG_E("copy keyUri failed");
109 ret = CMR_ERROR_INVALID_OPERATION;
110 break;
111 }
112 keyUri->size = commonUri.size;
113 } while (0);
114
115 CM_FREE_PTR(commonUri.data);
116 return ret;
117 }
118
GetPrivateAppCert(const struct CmContext * context,uint32_t store,const struct CmBlob * keyUri,struct CmBlob * certBlob)119 static int32_t GetPrivateAppCert(const struct CmContext *context, uint32_t store,
120 const struct CmBlob *keyUri, struct CmBlob *certBlob)
121 {
122 int32_t ret = CmCheckCallerIsProducer(context, keyUri);
123 if (ret != CM_SUCCESS) {
124 /* caller is not producer, check wether has ACCESS_CERT_MANAGER_INTERNAL permission */
125 ret = CheckPermission(true, false);
126 if (ret != CM_SUCCESS) {
127 return ret;
128 }
129 }
130
131 ret = CmStorageGetAppCert(context, store, keyUri, certBlob);
132 if (ret != CM_SUCCESS) {
133 CM_LOG_E("get app cert from storage failed, ret = %d", ret);
134 }
135
136 return ret;
137 }
138
CmServiceGetAppCert(const struct CmContext * context,uint32_t store,struct CmBlob * keyUri,struct CmBlob * certBlob)139 int32_t CmServiceGetAppCert(const struct CmContext *context, uint32_t store,
140 struct CmBlob *keyUri, struct CmBlob *certBlob)
141 {
142 if (store == CM_CREDENTIAL_STORE) {
143 return GetPublicAppCert(context, store, keyUri, certBlob);
144 } else if (store == CM_PRI_CREDENTIAL_STORE) {
145 return GetPrivateAppCert(context, store, keyUri, certBlob);
146 } else if (store == CM_SYS_CREDENTIAL_STORE) {
147 return CmStorageGetAppCert(context, store, keyUri, certBlob);
148 }
149 return CMR_ERROR_INVALID_ARGUMENT;
150 }
151
CmServiceGrantAppCertificate(const struct CmContext * context,const struct CmBlob * keyUri,uint32_t appUid,struct CmBlob * authUri)152 int32_t CmServiceGrantAppCertificate(const struct CmContext *context, const struct CmBlob *keyUri,
153 uint32_t appUid, struct CmBlob *authUri)
154 {
155 if (CheckUri(keyUri) != CM_SUCCESS || CmCheckBlob(authUri) != CM_SUCCESS) {
156 CM_LOG_E("invalid input arguments");
157 return CMR_ERROR_INVALID_ARGUMENT;
158 }
159
160 int32_t ret = CheckPermission(true, true);
161 if (ret != CM_SUCCESS) {
162 return ret;
163 }
164
165 return CmAuthGrantAppCertificate(context, keyUri, appUid, authUri);
166 }
167
CmServiceGetAuthorizedAppList(const struct CmContext * context,const struct CmBlob * keyUri,struct CmAppUidList * appUidList)168 int32_t CmServiceGetAuthorizedAppList(const struct CmContext *context, const struct CmBlob *keyUri,
169 struct CmAppUidList *appUidList)
170 {
171 if (CheckUri(keyUri) != CM_SUCCESS) {
172 CM_LOG_E("invalid input arguments");
173 return CMR_ERROR_INVALID_ARGUMENT;
174 }
175
176 int32_t ret = CheckPermission(true, true);
177 if (ret != CM_SUCCESS) {
178 return ret;
179 }
180
181 return CmAuthGetAuthorizedAppList(context, keyUri, appUidList);
182 }
183
CmServiceIsAuthorizedApp(const struct CmContext * context,const struct CmBlob * authUri)184 int32_t CmServiceIsAuthorizedApp(const struct CmContext *context, const struct CmBlob *authUri)
185 {
186 if (CheckUri(authUri) != CM_SUCCESS) {
187 CM_LOG_E("invalid input arguments");
188 return CMR_ERROR_INVALID_ARGUMENT;
189 }
190
191 int32_t ret = CheckPermission(false, true);
192 if (ret != CM_SUCCESS) {
193 return ret;
194 }
195
196 return CmAuthIsAuthorizedApp(context, authUri);
197 }
198
CmServiceRemoveGrantedApp(const struct CmContext * context,const struct CmBlob * keyUri,uint32_t appUid)199 int32_t CmServiceRemoveGrantedApp(const struct CmContext *context, const struct CmBlob *keyUri, uint32_t appUid)
200 {
201 if (CheckUri(keyUri) != CM_SUCCESS) {
202 CM_LOG_E("invalid input arguments");
203 return CMR_ERROR_INVALID_ARGUMENT;
204 }
205
206 int32_t ret = CheckPermission(true, true);
207 if (ret != CM_SUCCESS) {
208 return ret;
209 }
210
211 return CmAuthRemoveGrantedApp(context, keyUri, appUid);
212 }
213
CheckAndGetStore(const struct CmContext * context,const struct CmBlob * authUri,uint32_t * store)214 static int32_t CheckAndGetStore(const struct CmContext *context, const struct CmBlob *authUri, uint32_t *store)
215 {
216 struct CMUri uriObj;
217 int32_t ret = CertManagerUriDecode(&uriObj, (char *)authUri->data);
218 if (ret != CM_SUCCESS) {
219 CM_LOG_E("uri decode failed, ret = %d", ret);
220 return ret;
221 }
222
223 if ((uriObj.object == NULL) || (uriObj.user == NULL) || (uriObj.app == NULL)) {
224 CM_LOG_E("uri format invalid");
225 (void)CertManagerFreeUri(&uriObj);
226 return CMR_ERROR_INVALID_ARGUMENT;
227 }
228
229 uint32_t type = uriObj.type;
230 uint32_t userId = (uint32_t)atoi(uriObj.user);
231 (void)CertManagerFreeUri(&uriObj);
232 if (type == CM_URI_TYPE_SYS_KEY) {
233 if (!CmHasSystemAppPermission()) {
234 CM_LOG_E("caller lacks system app cert permission");
235 return CMR_ERROR_PERMISSION_DENIED;
236 }
237
238 if (context->userId != 0 && context->userId != userId) {
239 CM_LOG_E("uri check userId failed");
240 return CMR_ERROR_INVALID_ARGUMENT;
241 }
242
243 *store = CM_SYS_CREDENTIAL_STORE;
244 }
245
246 return CM_SUCCESS;
247 }
248
CmServiceInit(const struct CmContext * context,const struct CmBlob * authUri,const struct CmSignatureSpec * spec,struct CmBlob * handle)249 int32_t CmServiceInit(const struct CmContext *context, const struct CmBlob *authUri,
250 const struct CmSignatureSpec *spec, struct CmBlob *handle)
251 {
252 if (CheckUri(authUri) != CM_SUCCESS || CmCheckBlob(handle) != CM_SUCCESS) {
253 CM_LOG_E("invalid input arguments");
254 return CMR_ERROR_INVALID_ARGUMENT;
255 }
256
257 int32_t ret = CheckPermission(false, true);
258 if (ret != CM_SUCCESS) {
259 return ret;
260 }
261
262 uint32_t store = CM_CREDENTIAL_STORE;
263 ret = CheckAndGetStore(context, authUri, &store);
264 if (ret != CM_SUCCESS) {
265 CM_LOG_E("check and get store error");
266 return ret;
267 }
268
269 struct CmBlob commonUri = { 0, NULL };
270 ret = CmCheckAndGetCommonUri(context, store, authUri, &commonUri);
271 if (ret != CM_SUCCESS) {
272 CM_LOG_E("check and get common uri failed, ret = %d", ret);
273 return ret;
274 }
275
276 ret = CmKeyOpInit(context, &commonUri, spec, handle);
277 CM_FREE_PTR(commonUri.data);
278 return ret;
279 }
280
CmServiceUpdate(const struct CmContext * context,const struct CmBlob * handle,const struct CmBlob * inData)281 int32_t CmServiceUpdate(const struct CmContext *context, const struct CmBlob *handle,
282 const struct CmBlob *inData)
283 {
284 if (CmCheckBlob(handle) != CM_SUCCESS || CmCheckBlob(inData) != CM_SUCCESS) {
285 CM_LOG_E("invalid input arguments");
286 return CMR_ERROR_INVALID_ARGUMENT;
287 }
288
289 int32_t ret = CheckPermission(false, true);
290 if (ret != CM_SUCCESS) {
291 return ret;
292 }
293
294 return CmKeyOpProcess(SIGN_VERIFY_CMD_UPDATE, context, handle, inData, NULL);
295 }
296
CmServiceFinish(const struct CmContext * context,const struct CmBlob * handle,const struct CmBlob * inData,struct CmBlob * outData)297 int32_t CmServiceFinish(const struct CmContext *context, const struct CmBlob *handle,
298 const struct CmBlob *inData, struct CmBlob *outData)
299 {
300 if (CmCheckBlob(handle) != CM_SUCCESS) { /* inData.data and outData.data can be null */
301 CM_LOG_E("invalid input arguments");
302 return CMR_ERROR_INVALID_ARGUMENT;
303 }
304
305 int32_t ret = CheckPermission(false, true);
306 if (ret != CM_SUCCESS) {
307 return ret;
308 }
309
310 return CmKeyOpProcess(SIGN_VERIFY_CMD_FINISH, context, handle, inData, outData);
311 }
312
CmServiceAbort(const struct CmContext * context,const struct CmBlob * handle)313 int32_t CmServiceAbort(const struct CmContext *context, const struct CmBlob *handle)
314 {
315 if (CmCheckBlob(handle) != CM_SUCCESS) {
316 CM_LOG_E("invalid input arguments");
317 return CMR_ERROR_INVALID_ARGUMENT;
318 }
319
320 int32_t ret = CheckPermission(false, true);
321 if (ret != CM_SUCCESS) {
322 return ret;
323 }
324
325 return CmKeyOpProcess(SIGN_VERIFY_CMD_ABORT, context, handle, NULL, NULL);
326 }
327
DeepCopyPath(const uint8_t * srcData,uint32_t srcLen,struct CmMutableBlob * dest)328 static int32_t DeepCopyPath(const uint8_t *srcData, uint32_t srcLen, struct CmMutableBlob *dest)
329 {
330 uint8_t *data = (uint8_t *)CMMalloc(srcLen);
331 if (data == NULL) {
332 CM_LOG_E("malloc failed");
333 return CMR_ERROR_MALLOC_FAIL;
334 }
335 (void)memcpy_s(data, srcLen, srcData, srcLen);
336
337 dest->data = data;
338 dest->size = srcLen;
339 return CM_SUCCESS;
340 }
341
MergeUserPathList(const struct CmMutableBlob * callerPathList,const struct CmMutableBlob * sysServicePathList,struct CmMutableBlob * pathList)342 static int32_t MergeUserPathList(const struct CmMutableBlob *callerPathList,
343 const struct CmMutableBlob *sysServicePathList, struct CmMutableBlob *pathList)
344 {
345 uint32_t uidCount = callerPathList->size + sysServicePathList->size;
346 if (uidCount == 0) {
347 return CM_SUCCESS;
348 }
349
350 if (uidCount > MAX_COUNT_CERTIFICATE) {
351 CM_LOG_E("uid count beyond MAX");
352 return CM_FAILURE;
353 }
354
355 uint32_t memSize = sizeof(struct CmMutableBlob) * uidCount;
356 struct CmMutableBlob *uidList = (struct CmMutableBlob *)CMMalloc(memSize);
357 if (uidList == NULL) {
358 CM_LOG_E("malloc uidList failed");
359 return CMR_ERROR_MALLOC_FAIL;
360 }
361 (void)memset_s(uidList, memSize, 0, memSize);
362
363 int32_t ret = CM_SUCCESS;
364 struct CmMutableBlob *callerPath = (struct CmMutableBlob *)callerPathList->data;
365 struct CmMutableBlob *sysServicePath = (struct CmMutableBlob *)sysServicePathList->data;
366 for (uint32_t i = 0; i < callerPathList->size; i++) {
367 ret = DeepCopyPath(callerPath[i].data, callerPath[i].size, &uidList[i]);
368 if (ret != CM_SUCCESS) {
369 CmFreePathList(uidList, uidCount);
370 return ret;
371 }
372 }
373 for (uint32_t i = 0; i < sysServicePathList->size; i++) {
374 ret = DeepCopyPath(sysServicePath[i].data, sysServicePath[i].size, &uidList[i + callerPathList->size]);
375 if (ret != CM_SUCCESS) {
376 CmFreePathList(uidList, uidCount);
377 return ret;
378 }
379 }
380
381 pathList->data = (uint8_t *)uidList;
382 pathList->size = uidCount;
383 return CM_SUCCESS;
384 }
385
CmGetUserCertPathList(const struct CmContext * context,uint32_t store,struct CmMutableBlob * pathList)386 static int32_t CmGetUserCertPathList(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathList)
387 {
388 int32_t ret = CM_SUCCESS;
389 struct CmMutableBlob callerPathList = { 0, NULL };
390 struct CmMutableBlob sysServicePathList = { 0, NULL };
391
392 do {
393 /* user: caller */
394 ret = CmGetCertPathList(context, store, &callerPathList);
395 if (ret != CM_SUCCESS) {
396 CM_LOG_E("get caller certPathList fail, ret = %d", ret);
397 break;
398 }
399
400 /* user: system service */
401 uint32_t sysServiceUserId = 0;
402 struct CmContext sysServiceContext = { sysServiceUserId, context->uid, {0} };
403 ret = CmGetCertPathList(&sysServiceContext, store, &sysServicePathList);
404 if (ret != CM_SUCCESS) {
405 CM_LOG_E("get system service certPathList fail, ret = %d", ret);
406 break;
407 }
408
409 /* merge callerPathList and sysServicePathList */
410 ret = MergeUserPathList(&callerPathList, &sysServicePathList, pathList);
411 if (ret != CM_SUCCESS) {
412 CM_LOG_E("merge cert path list failed");
413 break;
414 }
415 } while (0);
416
417 if (callerPathList.data != NULL) {
418 CmFreePathList((struct CmMutableBlob *)callerPathList.data, callerPathList.size);
419 }
420 if (sysServicePathList.data != NULL) {
421 CmFreePathList((struct CmMutableBlob *)sysServicePathList.data, sysServicePathList.size);
422 }
423 return ret;
424 }
425
CmServiceGetCertList(const struct CmContext * context,uint32_t store,struct CmMutableBlob * certFileList)426 int32_t CmServiceGetCertList(const struct CmContext *context, uint32_t store, struct CmMutableBlob *certFileList)
427 {
428 int32_t ret = CM_SUCCESS;
429 struct CmMutableBlob pathList = { 0, NULL }; /* uid path list */
430
431 do {
432 if (store == CM_USER_TRUSTED_STORE) {
433 /* get all uid path for caller and system service */
434 ret = CmGetUserCertPathList(context, store, &pathList);
435 if (ret != CM_SUCCESS) {
436 CM_LOG_E("GetCertPathList fail, ret = %d", ret);
437 break;
438 }
439 } else if (store == CM_SYSTEM_TRUSTED_STORE) {
440 ret = CmGetSysCertPathList(context, &pathList);
441 if (ret != CM_SUCCESS) {
442 CM_LOG_E("GetCertPathList fail, ret = %d", ret);
443 break;
444 }
445 } else {
446 ret = CM_FAILURE;
447 CM_LOG_E("Invalid store");
448 break;
449 }
450
451 /* create certFilelist(path + name) from every uid */
452 ret = CreateCertFileList(&pathList, certFileList);
453 if (ret != CM_SUCCESS) {
454 CM_LOG_E("CreateCertFileList fail, ret = %d", ret);
455 break;
456 }
457 } while (0);
458
459 if (pathList.data != NULL) {
460 CmFreePathList((struct CmMutableBlob *)pathList.data, pathList.size);
461 }
462 return ret;
463 }
464
CmServiceGetCertInfo(const struct CmContext * context,const struct CmBlob * certUri,uint32_t store,struct CmBlob * certificateData,uint32_t * status)465 int32_t CmServiceGetCertInfo(const struct CmContext *context, const struct CmBlob *certUri,
466 uint32_t store, struct CmBlob *certificateData, uint32_t *status)
467 {
468 if (CmCheckBlob(certUri) != CM_SUCCESS || CheckUri(certUri) != CM_SUCCESS) {
469 CM_LOG_E("input params invalid");
470 return CMR_ERROR_INVALID_ARGUMENT;
471 }
472
473 int32_t ret = CM_SUCCESS;
474 struct CmMutableBlob certFileList = { 0, NULL };
475 do {
476 ret = CmServiceGetCertList(context, store, &certFileList);
477 if (ret != CM_SUCCESS) {
478 CM_LOG_E("GetCertList failed, ret = %d", ret);
479 break;
480 }
481
482 uint32_t matchIndex = CmGetMatchedCertIndex(&certFileList, certUri);
483 if ((matchIndex == MAX_COUNT_CERTIFICATE) || (matchIndex == certFileList.size)) {
484 CM_LOG_D("certFile of certUri don't matched");
485 ret = CMR_ERROR_NOT_EXIST;
486 break;
487 }
488
489 struct CertFileInfo *cFileList = (struct CertFileInfo *)certFileList.data;
490 ret = CmGetCertStatus(context, &cFileList[matchIndex], store, status); /* status */
491 if (ret != CM_SUCCESS) {
492 CM_LOG_E("Failed to get cert status");
493 ret = CM_FAILURE;
494 break;
495 }
496
497 ret = CmStorageGetBuf((char *)cFileList[matchIndex].path.data,
498 (char *)cFileList[matchIndex].fileName.data, certificateData); /* cert data */
499 if (ret != CM_SUCCESS) {
500 CM_LOG_E("Failed to get cert data");
501 ret = CM_FAILURE;
502 break;
503 }
504 } while (0);
505
506 if (certFileList.data != NULL) {
507 CmFreeCertFiles((struct CertFileInfo *)certFileList.data, certFileList.size);
508 }
509 return ret;
510 }
511
CmX509ToPEM(const X509 * x509,struct CmBlob * userCertPem)512 int32_t CmX509ToPEM(const X509 *x509, struct CmBlob *userCertPem)
513 {
514 int32_t ret = CM_SUCCESS;
515 char *pemCert = NULL;
516
517 BIO *bio = BIO_new(BIO_s_mem());
518 if (!bio) {
519 CM_LOG_E("BIO_new failed!");
520 return CM_FAILURE;
521 }
522
523 do {
524 if (PEM_write_bio_X509(bio, (X509 *)x509) == 0) {
525 CM_LOG_E("Error writing PEM");
526 ret = CM_FAILURE;
527 break;
528 }
529
530 long pemCertLen = BIO_get_mem_data(bio, &pemCert);
531 if (pemCertLen <= 0) {
532 perror("Error getting PEM data");
533 ret = CM_FAILURE;
534 break;
535 }
536
537 userCertPem->data = (uint8_t *)CMMalloc(pemCertLen);
538 if (userCertPem->data == NULL) {
539 CM_LOG_E("CMMalloc buffer failed!");
540 ret = CMR_ERROR_MALLOC_FAIL;
541 break;
542 }
543 userCertPem->size = (uint32_t)pemCertLen;
544 (void)memcpy_s(userCertPem->data, userCertPem->size, pemCert, pemCertLen);
545 } while (0);
546
547 BIO_free(bio);
548 return ret;
549 }
550
TryBackupUserCert(const struct CmContext * context,const struct CmBlob * userCert,struct CmBlob * certUri,struct CmMutableBlob * pathBlob)551 static int32_t TryBackupUserCert(const struct CmContext *context, const struct CmBlob *userCert,
552 struct CmBlob *certUri, struct CmMutableBlob *pathBlob)
553 {
554 int32_t ret = CmBackupUserCert(context, certUri, userCert);
555 if (ret != CM_SUCCESS) {
556 CM_LOG_E("CmBackupUserCert fail");
557 if (CmRemoveUserCert(pathBlob, certUri) != CM_SUCCESS) {
558 CM_LOG_E("CmBackupUserCert fail and CmRemoveUserCert fail");
559 }
560 return CM_FAILURE;
561 }
562 return ret;
563 }
564
GetUserCertNameAndPath(const struct CmContext * context,const struct CmBlob * certData,const struct CmBlob * certAlias,struct CertName * certName,struct CmMutableBlob * pathBlob)565 static int32_t GetUserCertNameAndPath(const struct CmContext *context, const struct CmBlob *certData,
566 const struct CmBlob *certAlias, struct CertName *certName, struct CmMutableBlob *pathBlob)
567 {
568 int32_t ret = CM_SUCCESS;
569 do {
570 X509 *userCertX509 = InitCertContext(certData->data, certData->size);
571 if (userCertX509 == NULL) {
572 CM_LOG_E("Parse X509 cert fail");
573 ret = CMR_ERROR_INVALID_CERT_FORMAT;
574 break;
575 }
576
577 ret = GetSubjectNameAndAlias(userCertX509, certAlias, certName->subjectName, certName->displayName);
578 FreeCertContext(userCertX509);
579 if (ret != CM_SUCCESS) {
580 CM_LOG_E("Failed to get alias from subject name");
581 break;
582 }
583
584 ret = GetObjNameFromCertData(certData, certAlias, certName->objectName);
585 if (ret != CM_SUCCESS) {
586 CM_LOG_E("Failed to get object name from subject name");
587 break;
588 }
589
590 ret = CmGetCertFilePath(context, CM_USER_TRUSTED_STORE, pathBlob);
591 if (ret != CM_SUCCESS) {
592 CM_LOG_E("Failed obtain path for store:%u", CM_USER_TRUSTED_STORE);
593 break;
594 }
595 } while (0);
596 return ret;
597 }
598
CmInstallUserCert(const struct CmContext * context,const struct CmBlob * userCert,const struct CmBlob * certAlias,const uint32_t status,struct CmBlob * certUri)599 int32_t CmInstallUserCert(const struct CmContext *context, const struct CmBlob *userCert,
600 const struct CmBlob *certAlias, const uint32_t status, struct CmBlob *certUri)
601 {
602 int32_t ret = CM_SUCCESS;
603 uint8_t pathBuf[CERT_MAX_PATH_LEN] = { 0 };
604 struct CmMutableBlob pathBlob = { sizeof(pathBuf), pathBuf };
605 uint8_t subjectBuf[MAX_LEN_SUBJECT_NAME] = { 0 };
606 struct CmBlob subjectName = { sizeof(subjectBuf), subjectBuf };
607 uint8_t objectBuf[MAX_LEN_CERT_ALIAS] = { 0 };
608 struct CmBlob objectName = { sizeof(objectBuf), objectBuf };
609 uint8_t displayBuf[MAX_LEN_CERT_ALIAS] = { 0 };
610 struct CmBlob displayName = { sizeof(displayBuf), displayBuf };
611 struct CertName certName = { &displayName, &objectName, &subjectName };
612
613 do {
614 ret = GetUserCertNameAndPath(context, userCert, certAlias, &certName, &pathBlob);
615 if (ret != CM_SUCCESS) {
616 CM_LOG_E("GetUserCertNameAndPath fail");
617 break;
618 }
619
620 ret = CmWriteUserCert(context, &pathBlob, userCert, &objectName, certUri);
621 if (ret != CM_SUCCESS) {
622 CM_LOG_E("CertManagerWriteUserCert fail");
623 break;
624 }
625
626 ret = RdbInsertCertProperty(context, certUri, &displayName, &subjectName, CM_USER_TRUSTED_STORE);
627 if (ret != CM_SUCCESS) {
628 CM_LOG_E("Failed to RdbInsertCertProperty");
629 break;
630 }
631
632 ret = SetcertStatus(context, certUri, CM_USER_TRUSTED_STORE, status, NULL);
633 if (ret != CM_SUCCESS) {
634 CM_LOG_E("SetcertStatus fail");
635 break;
636 }
637
638 if (status == CERT_STATUS_ENABLED) {
639 ret = TryBackupUserCert(context, userCert, certUri, &pathBlob);
640 if (ret != CM_SUCCESS) {
641 CM_LOG_E("BackupUserCert fail");
642 break;
643 }
644 }
645 } while (0);
646 return ret;
647 }
648
CmComparisonCallerIdWithUri(const struct CmContext * context,const struct CmBlob * certUri)649 static int32_t CmComparisonCallerIdWithUri(const struct CmContext *context,
650 const struct CmBlob *certUri)
651 {
652 struct CMUri uriObj;
653 (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
654 if (CheckUri(certUri) != CM_SUCCESS) {
655 CM_LOG_E("cert uri no end");
656 return CMR_ERROR_INVALID_ARGUMENT;
657 }
658
659 int32_t ret = CertManagerUriDecode(&uriObj, (char *)certUri->data);
660 if (ret != CM_SUCCESS) {
661 CM_LOG_E("uri decode failed, ret = %d", ret);
662 return ret;
663 }
664
665 if (uriObj.user == NULL) {
666 CM_LOG_E("uri user invalid");
667 (void)CertManagerFreeUri(&uriObj);
668 return CMR_ERROR_INVALID_ARGUMENT;
669 }
670 uint32_t userId = (uint32_t)atoi(uriObj.user);
671
672 if (uriObj.app == NULL) {
673 CM_LOG_E("uri app invalid");
674 (void)CertManagerFreeUri(&uriObj);
675 return CMR_ERROR_INVALID_ARGUMENT;
676 }
677 uint32_t uid = (uint32_t)atoi(uriObj.app);
678 if ((context->userId == userId) && (context->uid == uid)) {
679 ret = CM_SUCCESS;
680 } else {
681 ret = CMR_ERROR_INVALID_ARGUMENT;
682 }
683
684 (void)CertManagerFreeUri(&uriObj);
685 return ret;
686 }
687
CmRmUserCert(const char * usrCertConfigFilepath)688 int32_t CmRmUserCert(const char *usrCertConfigFilepath)
689 {
690 int32_t ret = CM_SUCCESS;
691 uint8_t usrCertBackupFilePath[CERT_MAX_PATH_LEN + 1] = { 0 };
692 uint32_t size = 0;
693
694 ret = CmIsFileExist(NULL, usrCertConfigFilepath);
695 if (ret != CMR_OK) {
696 return CM_SUCCESS;
697 }
698 size = CmFileRead(NULL, usrCertConfigFilepath, 0, usrCertBackupFilePath, CERT_MAX_PATH_LEN);
699 if (size == 0) {
700 CM_LOG_E("CmFileRead read size 0 invalid ,fail");
701 return CM_FAILURE;
702 }
703
704 ret = CmFileRemove(NULL, (const char *)usrCertBackupFilePath);
705 if (ret != CM_SUCCESS) {
706 CM_LOG_E("Remove cert backup file fail");
707 }
708 return ret;
709 }
710
CmRmSaConf(const char * usrCertConfigFilepath)711 int32_t CmRmSaConf(const char *usrCertConfigFilepath)
712 {
713 int32_t ret = CM_SUCCESS;
714
715 ret = CmFileRemove(NULL, usrCertConfigFilepath);
716 if (ret != CM_SUCCESS) {
717 CM_LOG_E("CmFileRemove fail");
718 return ret;
719 }
720 return ret;
721 }
722
CmUninstallUserCert(const struct CmContext * context,const struct CmBlob * certUri)723 int32_t CmUninstallUserCert(const struct CmContext *context, const struct CmBlob *certUri)
724 {
725 if (CmCheckBlob(certUri) != CM_SUCCESS || CheckUri(certUri) != CM_SUCCESS) {
726 CM_LOG_E("input params invalid");
727 return CMR_ERROR_INVALID_ARGUMENT;
728 }
729
730 int32_t ret = CM_SUCCESS;
731 ASSERT_ARGS(context && certUri && certUri->data && certUri->size);
732 uint8_t pathBuf[CERT_MAX_PATH_LEN] = {0};
733 struct CmMutableBlob pathBlob = { sizeof(pathBuf), pathBuf };
734 uint32_t store = CM_USER_TRUSTED_STORE;
735
736 do {
737 ret = CmComparisonCallerIdWithUri(context, certUri);
738 if (ret != CM_SUCCESS) {
739 CM_LOG_E("CallerId don't match uri, ret = %d", ret);
740 break;
741 }
742
743 ret = DeleteCertProperty((char *)certUri->data);
744 if (ret != CM_SUCCESS) {
745 CM_LOG_E("Failed delete cert: %s rdbData", (char *)certUri->data);
746 break;
747 }
748
749 ret = CmGetCertFilePath(context, store, &pathBlob);
750 if (ret != CM_SUCCESS) {
751 CM_LOG_E("Failed obtain path for store %d", store);
752 break;
753 }
754
755 ret = CmRemoveUserCert(&pathBlob, certUri);
756 if (ret != CM_SUCCESS) {
757 CM_LOG_E("RemoveUserCertFile fail, ret = %d", ret);
758 break;
759 }
760
761 ret = CmRemoveBackupUserCert(context, certUri, NULL);
762 if (ret != CM_SUCCESS) {
763 CM_LOG_E("CmRemoveBackupUserCert fail");
764 break;
765 }
766 ret = CmSetStatusEnable(context, &pathBlob, certUri, store);
767 if (ret != CM_SUCCESS) {
768 CM_LOG_E("UpdateStatusFile fail, ret = %d", ret);
769 break;
770 }
771 } while (0);
772
773 return ret;
774 }
775
CmUninstallAllUserCert(const struct CmContext * context)776 int32_t CmUninstallAllUserCert(const struct CmContext *context)
777 {
778 uint32_t store = CM_USER_TRUSTED_STORE;
779 struct CmMutableBlob pathList = { 0, NULL };
780
781 int32_t ret = CmGetCertPathList(context, store, &pathList);
782 if (ret != CM_SUCCESS) {
783 CM_LOG_E("GetCertPathList fail, ret = %d", ret);
784 return ret;
785 }
786
787 if (pathList.size == 0) {
788 CM_LOG_D("the user dir is empty");
789 return CM_SUCCESS;
790 }
791
792 ret = CmRemoveAllUserCert(context, store, &pathList);
793 CmFreePathList((struct CmMutableBlob *)pathList.data, pathList.size);
794 if (ret != CM_SUCCESS) {
795 CM_LOG_E("RemoveAllUserCert fail, ret = %d", ret);
796 return ret;
797 }
798
799 return ret;
800 }
801
CmServiceSetCertStatus(const struct CmContext * context,const struct CmBlob * certUri,uint32_t store,uint32_t status)802 int32_t CmServiceSetCertStatus(const struct CmContext *context, const struct CmBlob *certUri,
803 uint32_t store, uint32_t status)
804 {
805 if (CmCheckBlob(certUri) != CM_SUCCESS || CheckUri(certUri) != CM_SUCCESS) {
806 CM_LOG_E("input params invalid");
807 return CMR_ERROR_INVALID_ARGUMENT;
808 }
809 return SetcertStatus(context, certUri, store, status, NULL);
810 }
811
CmSetStatusBackupCert(const struct CmContext * context,const struct CmBlob * certUri,uint32_t store,uint32_t status)812 int32_t CmSetStatusBackupCert(
813 const struct CmContext *context, const struct CmBlob *certUri, uint32_t store, uint32_t status)
814 {
815 int32_t ret = CM_SUCCESS;
816
817 if (status == CERT_STATUS_ENANLED) {
818 bool needUpdate = false;
819 ret = IsCertNeedBackup(context->userId, context->uid, certUri, &needUpdate);
820 if (ret != CM_SUCCESS) {
821 CM_LOG_E("Check cert is need update failed, ret = %d", ret);
822 return CMR_ERROR_INVALID_OPERATION;
823 } else if (needUpdate == false) {
824 /* No need to update */
825 return CM_SUCCESS;
826 }
827
828 struct CmBlob certificateData = { 0, NULL };
829 ret = CmReadCertData(store, context, certUri, &certificateData);
830 if (ret != CM_SUCCESS) {
831 CM_LOG_E("CmReadCertData failed, ret = %d", ret);
832 return CM_FAILURE;
833 }
834
835 ret = CmBackupUserCert(context, certUri, &certificateData);
836 if (ret != CM_SUCCESS) {
837 CM_LOG_E("CmBackupUserCert failed, ret = %d", ret);
838 ret = CM_FAILURE;
839 }
840 CM_FREE_BLOB(certificateData);
841 } else if (status == CERT_STATUS_DISABLED) {
842 ret = CmRemoveBackupUserCert(context, certUri, NULL);
843 if (ret != CM_SUCCESS) {
844 CM_LOG_E("CmRemoveBackupUserCert fail, ret = %d", ret);
845 }
846 }
847
848 return ret;
849 }
850