• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 #include <openssl/safestack.h>
23 
24 #include "securec.h"
25 
26 #include "cert_manager.h"
27 #include "cert_manager_app_cert_process.h"
28 #include "cert_manager_auth_mgr.h"
29 #include "cert_manager_check.h"
30 #include "cert_manager_key_operation.h"
31 #include "cert_manager_mem.h"
32 #include "cert_manager_permission_check.h"
33 #include "cert_manager_query.h"
34 #include "cert_manager_status.h"
35 #include "cert_manager_storage.h"
36 #include "cert_manager_uri.h"
37 #include "cm_event_process.h"
38 #include "cm_cert_property_rdb.h"
39 #include "cm_log.h"
40 #include "cm_type.h"
41 #include "cm_x509.h"
42 #include "cm_util.h"
43 
44 #include "cert_manager_file_operator.h"
45 #include "cert_manager_updateflag.h"
46 #define MAX_PATH_LEN 256
47 
CheckPermission(bool needPriPermission,bool needCommonPermission)48 static int32_t CheckPermission(bool needPriPermission, bool needCommonPermission)
49 {
50     if (needPriPermission) {
51         if (!CmHasPrivilegedPermission()) {
52             CM_LOG_E("caller lacks pri permission");
53             return CMR_ERROR_PERMISSION_DENIED;
54         }
55         if (!CmIsSystemApp()) {
56             CM_LOG_E("caller is not system app");
57             return CMR_ERROR_NOT_SYSTEMP_APP;
58         }
59     }
60 
61     if (needCommonPermission) {
62         if (!CmHasCommonPermission()) {
63             CM_LOG_E("caller lacks common permission");
64             return CMR_ERROR_PERMISSION_DENIED;
65         }
66     }
67 
68     return CM_SUCCESS;
69 }
70 
CmServicInstallAppCert(struct CmContext * context,const struct CmAppCertParam * certParam,struct CmBlob * keyUri)71 int32_t CmServicInstallAppCert(struct CmContext *context, const struct CmAppCertParam *certParam, struct CmBlob *keyUri)
72 {
73     int32_t ret = CmServiceInstallAppCertCheck(certParam, context);
74     if (ret != CM_SUCCESS) {
75         CM_LOG_E("service intall app cert check params failed, ret = %d", ret);
76         return ret;
77     }
78 
79     ret = CmInstallAppCertPro(context, certParam, keyUri);
80     if (ret != CM_SUCCESS) {
81         CM_LOG_E("CmInstallAppCert fail, ret = %d", ret);
82         return ret;
83     }
84     return ret;
85 }
86 
GetPublicAppCert(const struct CmContext * context,uint32_t store,struct CmBlob * keyUri,struct CmBlob * certBlob)87 static int32_t GetPublicAppCert(const struct CmContext *context, uint32_t store,
88     struct CmBlob *keyUri, struct CmBlob *certBlob)
89 {
90     struct CmBlob commonUri = { 0, NULL };
91     int32_t ret = CmCheckAndGetCommonUri(context, store, keyUri, &commonUri);
92     if (ret != CM_SUCCESS) {
93         CM_LOG_E("check and get common uri when get app cert failed, ret = %d", ret);
94         return ret;
95     }
96 
97     do {
98         ret = CmStorageGetAppCert(context, store, &commonUri, certBlob);
99         if (ret != CM_SUCCESS) {
100             CM_LOG_E("get app cert from storage failed, ret = %d", ret);
101             break;
102         }
103 
104         /* remove authinfo from uri */
105         if (keyUri->size < commonUri.size) {
106             CM_LOG_E("keyUri size[%u] smaller than commonUri size[%u]", keyUri->size, commonUri.size);
107             ret = CMR_ERROR_BUFFER_TOO_SMALL;
108             break;
109         }
110         if (memcpy_s(keyUri->data, keyUri->size, commonUri.data, commonUri.size) != EOK) {
111             CM_LOG_E("copy keyUri failed");
112             ret = CMR_ERROR_MEM_OPERATION_COPY;
113             break;
114         }
115         keyUri->size = commonUri.size;
116     } while (0);
117 
118     CM_FREE_PTR(commonUri.data);
119     return ret;
120 }
121 
GetPrivateAppCert(const struct CmContext * context,uint32_t store,const struct CmBlob * keyUri,struct CmBlob * certBlob)122 static int32_t GetPrivateAppCert(const struct CmContext *context, uint32_t store,
123     const struct CmBlob *keyUri, struct CmBlob *certBlob)
124 {
125     int32_t ret = CmCheckCallerIsProducer(context, keyUri);
126     if (ret != CM_SUCCESS) {
127         /* caller is not producer, check wether has ACCESS_CERT_MANAGER_INTERNAL permission */
128         ret = CheckPermission(true, false);
129         if (ret != CM_SUCCESS) {
130             return ret;
131         }
132     }
133 
134     ret = CmStorageGetAppCert(context, store, keyUri, certBlob);
135     if (ret != CM_SUCCESS) {
136         CM_LOG_E("get app cert from storage failed, ret = %d", ret);
137     }
138 
139     return ret;
140 }
141 
CmServiceGetAppCert(const struct CmContext * context,uint32_t store,struct CmBlob * keyUri,struct CmBlob * certBlob)142 int32_t CmServiceGetAppCert(const struct CmContext *context, uint32_t store,
143     struct CmBlob *keyUri, struct CmBlob *certBlob)
144 {
145     if (store == CM_CREDENTIAL_STORE) {
146         return GetPublicAppCert(context, store, keyUri, certBlob);
147     } else if (store == CM_PRI_CREDENTIAL_STORE) {
148         return GetPrivateAppCert(context, store, keyUri, certBlob);
149     } else if (store == CM_SYS_CREDENTIAL_STORE) {
150         return CmStorageGetAppCert(context, store, keyUri, certBlob);
151     }
152     return CMR_ERROR_INVALID_ARGUMENT;
153 }
154 
CmServiceGrantAppCertificate(const struct CmContext * context,const struct CmBlob * keyUri,uint32_t appUid,struct CmBlob * authUri)155 int32_t CmServiceGrantAppCertificate(const struct CmContext *context, const struct CmBlob *keyUri,
156     uint32_t appUid, struct CmBlob *authUri)
157 {
158     if (CheckUri(keyUri) != CM_SUCCESS || CmCheckBlob(authUri) != CM_SUCCESS || context == NULL) {
159         CM_LOG_E("invalid input arguments");
160         return CMR_ERROR_INVALID_ARGUMENT_URI;
161     }
162 
163     int32_t ret = CheckPermission(true, true);
164     if (ret != CM_SUCCESS) {
165         return ret;
166     }
167 
168     return CmAuthGrantAppCertificate(context, keyUri, appUid, authUri);
169 }
170 
CmServiceGetAuthorizedAppList(const struct CmContext * context,const struct CmBlob * keyUri,struct CmAppUidList * appUidList)171 int32_t CmServiceGetAuthorizedAppList(const struct CmContext *context, const struct CmBlob *keyUri,
172     struct CmAppUidList *appUidList)
173 {
174     if (CheckUri(keyUri) != CM_SUCCESS) {
175         CM_LOG_E("invalid input arguments");
176         return CMR_ERROR_INVALID_ARGUMENT_URI;
177     }
178 
179     int32_t ret = CheckPermission(true, true);
180     if (ret != CM_SUCCESS) {
181         return ret;
182     }
183 
184     return CmAuthGetAuthorizedAppList(context, keyUri, appUidList);
185 }
186 
CmServiceIsAuthorizedApp(const struct CmContext * context,const struct CmBlob * authUri)187 int32_t CmServiceIsAuthorizedApp(const struct CmContext *context, const struct CmBlob *authUri)
188 {
189     if (CheckUri(authUri) != CM_SUCCESS) {
190         CM_LOG_E("invalid input arguments");
191         return CMR_ERROR_INVALID_ARGUMENT;
192     }
193 
194     int32_t ret = CheckPermission(false, true);
195     if (ret != CM_SUCCESS) {
196         return ret;
197     }
198 
199     return CmAuthIsAuthorizedApp(context, authUri);
200 }
201 
CmServiceRemoveGrantedApp(const struct CmContext * context,const struct CmBlob * keyUri,uint32_t appUid)202 int32_t CmServiceRemoveGrantedApp(const struct CmContext *context, const struct CmBlob *keyUri, uint32_t appUid)
203 {
204     if (CheckUri(keyUri) != CM_SUCCESS) {
205         CM_LOG_E("invalid input arguments");
206         return CMR_ERROR_INVALID_ARGUMENT_URI;
207     }
208 
209     int32_t ret = CheckPermission(true, true);
210     if (ret != CM_SUCCESS) {
211         return ret;
212     }
213 
214     return CmAuthRemoveGrantedApp(context, keyUri, appUid);
215 }
216 
CheckAndGetStore(const struct CmContext * context,const struct CmBlob * authUri,uint32_t * store)217 static int32_t CheckAndGetStore(const struct CmContext *context, const struct CmBlob *authUri, uint32_t *store)
218 {
219     struct CMUri uriObj;
220     int32_t ret = CertManagerUriDecode(&uriObj, (char *)authUri->data);
221     if (ret != CM_SUCCESS) {
222         CM_LOG_E("uri decode failed, ret = %d", ret);
223         return ret;
224     }
225 
226     if ((uriObj.object == NULL) || (uriObj.user == NULL) || (uriObj.app == NULL)) {
227         CM_LOG_E("uri format invalid");
228         (void)CertManagerFreeUri(&uriObj);
229         return CMR_ERROR_INVALID_ARGUMENT_URI;
230     }
231 
232     uint32_t type = uriObj.type;
233     uint32_t userId = 0;
234     if (CmIsNumeric(uriObj.user, strlen(uriObj.user) + 1, &userId) != CM_SUCCESS) {
235         CM_LOG_E("parse string to uint32 failed.");
236         (void)CertManagerFreeUri(&uriObj);
237         return CMR_ERROR_INVALID_ARGUMENT_URI;
238     }
239 
240     (void)CertManagerFreeUri(&uriObj);
241     if (type == CM_URI_TYPE_SYS_KEY) {
242         if (!CmHasSystemAppPermission()) {
243             CM_LOG_E("caller lacks system app cert permission");
244             return CMR_ERROR_PERMISSION_DENIED;
245         }
246 
247         if (context->userId != 0 && context->userId != userId) {
248             CM_LOG_E("uri check userId failed");
249             return CMR_ERROR_INVALID_ARGUMENT_USER_ID;
250         }
251 
252         *store = CM_SYS_CREDENTIAL_STORE;
253     }
254 
255     return CM_SUCCESS;
256 }
257 
CmServiceInit(const struct CmContext * context,const struct CmBlob * authUri,const struct CmSignatureSpec * spec,struct CmBlob * handle)258 int32_t CmServiceInit(const struct CmContext *context, const struct CmBlob *authUri,
259     const struct CmSignatureSpec *spec, struct CmBlob *handle)
260 {
261     if (CheckUri(authUri) != CM_SUCCESS) {
262         CM_LOG_E("invalid input arguments uri");
263         return CMR_ERROR_INVALID_ARGUMENT_URI;
264     }
265 
266     if (CmCheckBlob(handle) != CM_SUCCESS) {
267         CM_LOG_E("invalid input arguments handle");
268         return CMR_ERROR_INVALID_ARGUMENT_HANDLE;
269     }
270 
271     int32_t ret = CheckPermission(false, true);
272     if (ret != CM_SUCCESS) {
273         return ret;
274     }
275 
276     uint32_t store = CM_CREDENTIAL_STORE;
277     ret = CheckAndGetStore(context, authUri, &store);
278     if (ret != CM_SUCCESS) {
279         CM_LOG_E("check and get store error");
280         return ret;
281     }
282 
283     struct CmBlob commonUri = { 0, NULL };
284     ret = CmCheckAndGetCommonUri(context, store, authUri, &commonUri);
285     if (ret != CM_SUCCESS) {
286         CM_LOG_E("check and get common uri failed, ret = %d", ret);
287         return ret;
288     }
289 
290     enum CmAuthStorageLevel level;
291     ret = GetRdbAuthStorageLevel(&commonUri, &level);
292     if (ret != CM_SUCCESS) {
293         CM_LOG_E("get rdb auth storage level failed, ret = %d", ret);
294         CM_FREE_PTR(commonUri.data);
295         return ret;
296     }
297     if (level == ERROR_LEVEL) {
298         level = CM_AUTH_STORAGE_LEVEL_EL1;
299         CM_LOG_I("Init level is ERROR_LEVEL, change to default level el1");
300     }
301 
302     ret = CmKeyOpInit(context, &commonUri, spec, level, handle);
303     CM_FREE_PTR(commonUri.data);
304     return ret;
305 }
306 
CmServiceUpdate(const struct CmContext * context,const struct CmBlob * handle,const struct CmBlob * inData)307 int32_t CmServiceUpdate(const struct CmContext *context, const struct CmBlob *handle,
308     const struct CmBlob *inData)
309 {
310     if (CmCheckBlob(handle) != CM_SUCCESS) {
311         CM_LOG_E("invalid input arguments");
312         return CMR_ERROR_INVALID_ARGUMENT_HANDLE;
313     }
314 
315     if (CmCheckBlob(inData) != 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_UPDATE, context, handle, inData, NULL);
326 }
327 
CmServiceFinish(const struct CmContext * context,const struct CmBlob * handle,const struct CmBlob * inData,struct CmBlob * outData)328 int32_t CmServiceFinish(const struct CmContext *context, const struct CmBlob *handle,
329     const struct CmBlob *inData, struct CmBlob *outData)
330 {
331     if (CmCheckBlob(handle) != CM_SUCCESS) { /* inData.data and outData.data can be null */
332         CM_LOG_E("invalid input arguments");
333         return CMR_ERROR_INVALID_ARGUMENT_HANDLE;
334     }
335 
336     int32_t ret = CheckPermission(false, true);
337     if (ret != CM_SUCCESS) {
338         return ret;
339     }
340 
341     return CmKeyOpProcess(SIGN_VERIFY_CMD_FINISH, context, handle, inData, outData);
342 }
343 
CmServiceAbort(const struct CmContext * context,const struct CmBlob * handle)344 int32_t CmServiceAbort(const struct CmContext *context, const struct CmBlob *handle)
345 {
346     if (CmCheckBlob(handle) != CM_SUCCESS) {
347         CM_LOG_E("invalid input arguments");
348         return CMR_ERROR_INVALID_ARGUMENT_HANDLE;
349     }
350 
351     int32_t ret = CheckPermission(false, true);
352     if (ret != CM_SUCCESS) {
353         return ret;
354     }
355 
356     return CmKeyOpProcess(SIGN_VERIFY_CMD_ABORT, context, handle, NULL, NULL);
357 }
358 
359 // LCOV_EXCL_START
DeepCopyPath(const uint8_t * srcData,uint32_t srcLen,struct CmMutableBlob * dest)360 static int32_t DeepCopyPath(const uint8_t *srcData, uint32_t srcLen, struct CmMutableBlob *dest)
361 {
362     uint8_t *data = (uint8_t *)CMMalloc(srcLen);
363     if (data == NULL) {
364         CM_LOG_E("malloc failed");
365         return CMR_ERROR_MALLOC_FAIL;
366     }
367     (void)memcpy_s(data, srcLen, srcData, srcLen);
368 
369     dest->data = data;
370     dest->size = srcLen;
371     return CM_SUCCESS;
372 }
373 
MergeUserPathList(const struct CmMutableBlob * callerPathList,const struct CmMutableBlob * targetPathList,struct CmMutableBlob * pathList)374 static int32_t MergeUserPathList(const struct CmMutableBlob *callerPathList,
375     const struct CmMutableBlob *targetPathList, struct CmMutableBlob *pathList)
376 {
377     uint32_t uidCount = callerPathList->size + targetPathList->size;
378     if (uidCount == 0) {
379         return CM_SUCCESS;
380     }
381 
382     if (uidCount > MAX_COUNT_CERTIFICATE_ALL) {
383         CM_LOG_E("uid count beyond MAX");
384         return CMR_ERROR_MAX_CERT_COUNT_REACHED;
385     }
386 
387     uint32_t memSize = sizeof(struct CmMutableBlob) * uidCount;
388     struct CmMutableBlob *uidList = (struct CmMutableBlob *)CMMalloc(memSize);
389     if (uidList == NULL) {
390         CM_LOG_E("malloc uidList failed");
391         return CMR_ERROR_MALLOC_FAIL;
392     }
393     (void)memset_s(uidList, memSize, 0, memSize);
394 
395     int32_t ret = CM_SUCCESS;
396     struct CmMutableBlob *callerPath = (struct CmMutableBlob *)callerPathList->data;
397     struct CmMutableBlob *sysServicePath = (struct CmMutableBlob *)targetPathList->data;
398     for (uint32_t i = 0; i < callerPathList->size; i++) {
399         ret = DeepCopyPath(callerPath[i].data, callerPath[i].size, &uidList[i]);
400         if (ret != CM_SUCCESS) {
401             CmFreePathList(uidList, uidCount);
402             return ret;
403         }
404     }
405     for (uint32_t i = 0; i < targetPathList->size; i++) {
406         ret = DeepCopyPath(sysServicePath[i].data, sysServicePath[i].size, &uidList[i + callerPathList->size]);
407         if (ret != CM_SUCCESS) {
408             CmFreePathList(uidList, uidCount);
409             return ret;
410         }
411     }
412 
413     pathList->data = (uint8_t *)uidList;
414     pathList->size = uidCount;
415     return CM_SUCCESS;
416 }
417 
CmGetUserCertPathList(const struct CmContext * context,const struct UserCAProperty * prop,uint32_t store,struct CmMutableBlob * pathList)418 static int32_t CmGetUserCertPathList(const struct CmContext *context, const struct UserCAProperty *prop,
419     uint32_t store, struct CmMutableBlob *pathList)
420 {
421     int32_t ret = CM_SUCCESS;
422     struct CmMutableBlob callerPathList = { 0, NULL };
423     struct CmMutableBlob targetPathList = { 0, NULL };
424 
425     do {
426         /* user: caller */
427         ret = CmGetCertPathList(context, store, &callerPathList);
428         if (ret != CM_SUCCESS) {
429             CM_LOG_E("get caller certPathList fail, ret = %d", ret);
430             break;
431         }
432 
433         /* avoid obtain duplicate data when both the target userid and the caller's userid are same */
434         if (context->userId != prop->userId) {
435             /* The caller takes the specified userid for sa, otherwise 0 */
436             uint32_t targetUserId = context->userId == 0 ? prop->userId : 0;
437             struct CmContext targetContext = { targetUserId, context->uid, {0} };
438             ret = CmGetCertPathList(&targetContext, store, &targetPathList);
439             if (ret != CM_SUCCESS) {
440                 CM_LOG_E("get system service certPathList fail, ret = %d", ret);
441                 break;
442             }
443         }
444 
445         /* merge callerPathList and targetPathList */
446         ret = MergeUserPathList(&callerPathList, &targetPathList, pathList);
447         if (ret != CM_SUCCESS) {
448             CM_LOG_E("merge cert path list failed");
449             break;
450         }
451     } while (0);
452 
453     if (callerPathList.data != NULL) {
454         CmFreePathList((struct CmMutableBlob *)callerPathList.data, callerPathList.size);
455     }
456     if (targetPathList.data != NULL) {
457         CmFreePathList((struct CmMutableBlob *)targetPathList.data, targetPathList.size);
458     }
459     return ret;
460 }
461 
CmGetSaUserCertList(const struct CmContext * context,const struct UserCAProperty * prop,struct CmMutableBlob * pathList)462 static int32_t CmGetSaUserCertList(const struct CmContext *context, const struct UserCAProperty *prop,
463     struct CmMutableBlob *pathList)
464 {
465     int32_t ret = CM_SUCCESS;
466     struct CmContext cmContext = *context;
467 
468     if (prop->userId == INIT_INVALID_VALUE) {
469         /* if target userid is invalid, obtain the certificate in the userid=0 directory */
470         ret = CmGetCertPathList(&cmContext, CM_USER_TRUSTED_STORE, pathList);
471         if (ret != CM_SUCCESS) {
472             CM_LOG_E("get target invalid cert path list failed");
473         }
474         return ret;
475     }
476 
477     if (prop->scope == CM_ALL_USER) {
478         ret = CmGetUserCertPathList(&cmContext, prop, CM_USER_TRUSTED_STORE, pathList);
479         if (ret != CM_SUCCESS) {
480             CM_LOG_E("get all user cert path list failed");
481             return ret;
482         }
483     } else {
484         if (prop->scope == CM_CURRENT_USER) { /* update target userid */
485             cmContext.userId = prop->userId;
486         }
487         ret = CmGetCertPathList(&cmContext, CM_USER_TRUSTED_STORE, pathList);
488         if (ret != CM_SUCCESS) {
489             CM_LOG_E("get current or global user cert path list failed");
490             return ret;
491         }
492     }
493     return ret;
494 }
495 
CmGetHapUserCertList(const struct CmContext * context,const struct UserCAProperty * prop,struct CmMutableBlob * pathList)496 static int32_t CmGetHapUserCertList(const struct CmContext *context, const struct UserCAProperty *prop,
497     struct CmMutableBlob *pathList)
498 {
499     int32_t ret = CM_SUCCESS;
500     struct CmContext cmContext = *context;
501 
502     if (prop->scope == CM_ALL_USER) {
503         ret = CmGetUserCertPathList(&cmContext, prop, CM_USER_TRUSTED_STORE, pathList);
504         if (ret != CM_SUCCESS) {
505             CM_LOG_E("get all user cert path list failed");
506             return ret;
507         }
508     } else {
509         if (prop->scope == CM_GLOBAL_USER) { /* Obtain only the certificate in the userid=0 directory  */
510             cmContext.userId = 0;
511         }
512         ret = CmGetCertPathList(&cmContext, CM_USER_TRUSTED_STORE, pathList);
513         if (ret != CM_SUCCESS) {
514             CM_LOG_E("get current or global cert path list failed");
515             return ret;
516         }
517     }
518     return ret;
519 }
520 
CmServiceGetUserCACertList(const struct CmContext * context,const struct UserCAProperty * prop,struct CmMutableBlob * pathList)521 static int32_t CmServiceGetUserCACertList(const struct CmContext *context, const struct UserCAProperty *prop,
522     struct CmMutableBlob *pathList)
523 {
524     int32_t ret = CM_SUCCESS;
525 
526     if (context->userId == 0) { /* caller is sa */
527         ret = CmGetSaUserCertList(context, prop, pathList);
528         if (ret != CM_SUCCESS) {
529             CM_LOG_E("get sa user cert list failed");
530             return ret;
531         }
532     } else { /* caller is hap */
533         ret = CmGetHapUserCertList(context, prop, pathList);
534         if (ret != CM_SUCCESS) {
535             CM_LOG_E("get gap user cert list failed");
536             return ret;
537         }
538     }
539     return ret;
540 }
541 // LCOV_EXCL_STOP
542 
CmServiceGetCertList(const struct CmContext * context,const struct UserCAProperty * prop,uint32_t store,struct CmMutableBlob * certFileList)543 int32_t CmServiceGetCertList(const struct CmContext *context, const struct UserCAProperty *prop,
544     uint32_t store, struct CmMutableBlob *certFileList)
545 {
546     uint32_t scope = prop->scope;
547     if (scope != CM_ALL_USER && scope != CM_CURRENT_USER && scope != CM_GLOBAL_USER) {
548         CM_LOG_E("The scope is incorrect");
549         return CMR_ERROR_INVALID_ARGUMENT_SCOPE;
550     }
551 
552     int32_t ret = CM_SUCCESS;
553     struct CmMutableBlob pathList = { 0, NULL };
554 
555     do {
556         if (store == CM_USER_TRUSTED_STORE) {
557             if (context->userId != 0 && prop->userId != INIT_INVALID_VALUE) {
558                 /* if caller is hap, the target userid must be invalid */
559                 CM_LOG_E("The target userid is incorrect");
560                 ret = CMR_ERROR_INVALID_ARGUMENT_USER_ID;
561                 break;
562             }
563             /* get all uid path for caller and system service */
564             ret = CmServiceGetUserCACertList(context, prop, &pathList);
565             if (ret != CM_SUCCESS) {
566                 CM_LOG_E("CmServiceGetUserCACertList fail, ret = %d", ret);
567                 break;
568             }
569         } else if (store == CM_SYSTEM_TRUSTED_STORE) {
570             ret = CmGetSysCertPathList(context, &pathList);
571             if (ret != CM_SUCCESS) {
572                 CM_LOG_E("GetCertPathList fail, ret = %d", ret);
573                 break;
574             }
575         } else {
576             ret = CMR_ERROR_INVALID_ARGUMENT_STORE_TYPE;
577             CM_LOG_E("Invalid store");
578             break;
579         }
580 
581         /* create certFilelist(path + name) from every uid */
582         ret = CreateCertFileList(&pathList, certFileList);
583         if (ret != CM_SUCCESS) {
584             CM_LOG_E("CreateCertFileList fail, ret = %d", ret);
585             break;
586         }
587     } while (0);
588 
589     if (pathList.data != NULL) {
590         CmFreePathList((struct CmMutableBlob *)pathList.data, pathList.size);
591     }
592     return ret;
593 }
594 
CmServiceGetSysCertInfo(const struct CmContext * context,const struct CmBlob * certUri,uint32_t store,struct CmBlob * certificateData,uint32_t * status)595 static int32_t CmServiceGetSysCertInfo(const struct CmContext *context, const struct CmBlob *certUri,
596     uint32_t store, struct CmBlob *certificateData, uint32_t *status)
597 {
598     int32_t ret = CM_SUCCESS;
599     struct CmMutableBlob certFileList = { 0, NULL };
600     do {
601         const struct UserCAProperty prop = { INIT_INVALID_VALUE, CM_ALL_USER };
602         ret = CmServiceGetCertList(context, &prop, store, &certFileList);
603         if (ret != CM_SUCCESS) {
604             CM_LOG_E("GetCertList failed, ret = %d", ret);
605             break;
606         }
607 
608         uint32_t matchIndex = CmGetMatchedCertIndex(&certFileList, certUri);
609         if ((matchIndex == MAX_COUNT_CERTIFICATE) || (matchIndex == certFileList.size)) {
610             CM_LOG_D("certFile of certUri don't matched");
611             ret = CMR_ERROR_NOT_EXIST;
612             break;
613         }
614         *status = CERT_STATUS_ENABLED;
615 
616         struct CertFileInfo *cFileList = (struct CertFileInfo *)certFileList.data;
617         ret = CmStorageGetBuf((char *)cFileList[matchIndex].path.data,
618         (char *)cFileList[matchIndex].fileName.data, certificateData); /* cert data */
619         if (ret != CM_SUCCESS) {
620             CM_LOG_E("Failed to get cert data");
621             break;
622         }
623     } while (0);
624 
625     if (certFileList.data != NULL) {
626         CmFreeCertFiles((struct CertFileInfo *)certFileList.data, certFileList.size);
627     }
628     return ret;
629 }
630 
CmServiceGetUserCertInfo(struct CmContext * context,const struct CmBlob * certUri,uint32_t store,struct CmBlob * certificateData,uint32_t * status)631 static int32_t CmServiceGetUserCertInfo(struct CmContext *context, const struct CmBlob *certUri,
632     uint32_t store, struct CmBlob *certificateData, uint32_t *status)
633 {
634     int32_t ret = CM_SUCCESS;
635     char uidPath[MAX_PATH_LEN] = { 0 };
636     ret = CmServiceGetUserCertInfoCheck(context, certUri, CM_URI_TYPE_CERTIFICATE, false);
637     if (ret != CM_SUCCESS) {
638         CM_LOG_E("Failed to check caller and uri");
639         return ret;
640     }
641 
642     ret = ConstructUidPath(context, store, uidPath, MAX_PATH_LEN);
643     if (ret != CM_SUCCESS) {
644         CM_LOG_E("Failed to construct uidpath");
645         return ret;
646     }
647     struct CmBlob path = {MAX_PATH_LEN, (uint8_t *)uidPath};
648     struct CertFileInfo cFile = {*certUri, path};
649     ret = CmStorageGetBuf(uidPath, (char *)cFile.fileName.data, certificateData); /* cert data */
650     if (ret != CM_SUCCESS) {
651         CM_LOG_E("Failed to get cert data");
652         return ret;
653     }
654 
655     if (store == CM_SYS_CREDENTIAL_STORE) {
656         *status = CERT_STATUS_ENABLED;
657         return ret;
658     }
659     ret = CmGetCertConfigStatus((char *)cFile.fileName.data, status);
660     if (ret != CM_SUCCESS) {
661         CM_LOG_E("Failed to get cert status, ret = %d", ret);
662         CM_FREE_PTR(certificateData->data);
663         certificateData->size = 0;
664         return CMR_ERROR_GET_CERT_STATUS;
665     }
666     return ret;
667 }
668 
CmServiceGetCertInfo(struct CmContext * context,const struct CmBlob * certUri,uint32_t store,struct CmBlob * certificateData,uint32_t * status)669 int32_t CmServiceGetCertInfo(struct CmContext *context, const struct CmBlob *certUri,
670     uint32_t store, struct CmBlob *certificateData, uint32_t *status)
671 {
672     if (CmCheckBlob(certUri) != CM_SUCCESS || CheckUri(certUri) != CM_SUCCESS) {
673         CM_LOG_E("input params invalid");
674         return CMR_ERROR_INVALID_ARGUMENT_URI;
675     }
676 
677     int32_t ret = CM_SUCCESS;
678     if (store == CM_SYSTEM_TRUSTED_STORE) {
679         ret = CmServiceGetSysCertInfo(context, certUri, store, certificateData, status);
680         if (ret != CM_SUCCESS) {
681             CM_LOG_E("Failed to get system cert info");
682             return ret;
683         }
684     } else if (store == CM_USER_TRUSTED_STORE) {
685         ret = CmServiceGetUserCertInfo(context, certUri, store, certificateData, status);
686         if (ret != CM_SUCCESS) {
687             CM_LOG_E("Failed to get user cert info");
688             return ret;
689         }
690     } else {
691         CM_LOG_E("Invalid store");
692         ret = CMR_ERROR_INVALID_ARGUMENT_STORE_TYPE;
693     }
694     return ret;
695 }
696 
697 // LCOV_EXCL_START
CmX509ToPEM(const X509 * x509,struct CmBlob * userCertPem)698 int32_t CmX509ToPEM(const X509 *x509, struct CmBlob *userCertPem)
699 {
700     int32_t ret = CM_SUCCESS;
701     char *pemCert = NULL;
702 
703     BIO *bio = BIO_new(BIO_s_mem());
704     if (!bio) {
705         CM_LOG_E("BIO_new failed!");
706         return CMR_ERROR_OPENSSL_FAIL;
707     }
708 
709     do {
710         if (PEM_write_bio_X509(bio, (X509 *)x509) == 0) {
711             CM_LOG_E("Error writing PEM");
712             ret = CMR_ERROR_OPENSSL_FAIL;
713             break;
714         }
715 
716         long pemCertLen = BIO_get_mem_data(bio, &pemCert);
717         if (pemCertLen <= 0) {
718             perror("Error getting PEM data");
719             ret = CMR_ERROR_OPENSSL_FAIL;
720             break;
721         }
722 
723         userCertPem->data = (uint8_t *)CMMalloc(pemCertLen);
724         if (userCertPem->data == NULL) {
725             CM_LOG_E("CMMalloc buffer failed!");
726             ret = CMR_ERROR_MALLOC_FAIL;
727             break;
728         }
729         userCertPem->size = (uint32_t)pemCertLen;
730         (void)memcpy_s(userCertPem->data, userCertPem->size, pemCert, pemCertLen);
731     } while (0);
732 
733     BIO_free(bio);
734     return ret;
735 }
736 
TryBackupUserCert(const struct CmContext * context,const struct CmBlob * userCert,struct CmBlob * certUri,struct CmMutableBlob * pathBlob)737 static int32_t TryBackupUserCert(const struct CmContext *context, const struct CmBlob *userCert,
738     struct CmBlob *certUri, struct CmMutableBlob *pathBlob)
739 {
740     uint32_t uid = 0;
741     int32_t ret = CertManagerGetUidFromUri(certUri, &uid);
742     if (ret != CM_SUCCESS) {
743         CM_LOG_E("Get uid from uri fail");
744         return ret;
745     }
746     struct CmContext userContext = {
747         .userId = context->userId,
748         .uid = uid
749     };
750     ret = CmBackupUserCert(&userContext, certUri, userCert);
751     if (ret != CM_SUCCESS) {
752         CM_LOG_E("CmBackupUserCert fail");
753         if (CmRemoveUserCert(pathBlob, certUri) != CM_SUCCESS) {
754             CM_LOG_E("CmBackupUserCert fail and CmRemoveUserCert fail");
755         }
756         return ret;
757     }
758     return ret;
759 }
760 
GetUserCertNameAndPath(const struct CmContext * context,const struct CmBlob * certData,const struct CmBlob * certAlias,struct CertName * certName,struct CmMutableBlob * pathBlob)761 static int32_t GetUserCertNameAndPath(const struct CmContext *context, const struct CmBlob *certData,
762     const struct CmBlob *certAlias, struct CertName *certName, struct CmMutableBlob *pathBlob)
763 {
764     int32_t ret = CM_SUCCESS;
765     do {
766         X509 *userCertX509 = InitCertContext(certData->data, certData->size);
767         if (userCertX509 == NULL) {
768             CM_LOG_E("Parse X509 cert fail");
769             ret = CMR_ERROR_INVALID_CERT_FORMAT;
770             break;
771         }
772 
773         ret = GetSubjectNameAndAlias(userCertX509, certAlias, certName->subjectName, certName->displayName);
774         FreeCertContext(userCertX509);
775         if (ret != CM_SUCCESS) {
776             CM_LOG_E("Failed to get alias from subject name");
777             break;
778         }
779 
780         ret = GetObjNameFromCertData(certData, certAlias, certName->objectName);
781         if (ret != CM_SUCCESS) {
782             CM_LOG_E("Failed to get object name from subject name");
783             break;
784         }
785 
786         ret = CmGetCertFilePath(context, CM_USER_TRUSTED_STORE, pathBlob);
787         if (ret != CM_SUCCESS) {
788             CM_LOG_E("Failed obtain path for store:%u", CM_USER_TRUSTED_STORE);
789             break;
790         }
791     } while (0);
792     return ret;
793 }
794 
GetCertFileHash(const struct CmBlob * certFileData,struct CmBlob * certFileHash)795 static int32_t GetCertFileHash(const struct CmBlob *certFileData, struct CmBlob *certFileHash)
796 {
797     uint8_t certAliasData[] = "";
798     struct CmBlob certAlias = { sizeof(certAliasData), certAliasData };
799     // get cert file hash
800     int ret = GetObjNameFromCertData(certFileData, &certAlias, certFileHash);
801     if (ret != CM_SUCCESS) {
802         CM_LOG_E("get objName from certData failed, ret = %d", ret);
803     }
804     return ret;
805 }
806 
CopyCertFileInfo(const struct CertFileInfo * certFile,struct CertFileInfo * dstCertFile)807 static int32_t CopyCertFileInfo(const struct CertFileInfo *certFile, struct CertFileInfo *dstCertFile)
808 {
809     if (certFile == NULL || dstCertFile == NULL) {
810         CM_LOG_E("params null pointer");
811         return CMR_ERROR_NULL_POINTER;
812     }
813     dstCertFile->fileName.data = (uint8_t *)CMMalloc(certFile->fileName.size);
814     if (dstCertFile->fileName.data == NULL) {
815         CM_LOG_E("malloc buffer failed!");
816         return CMR_ERROR_MALLOC_FAIL;
817     }
818     dstCertFile->fileName.size = certFile->fileName.size;
819 
820     dstCertFile->path.data = (uint8_t *)CMMalloc(certFile->path.size);
821     if (dstCertFile->path.data == NULL) {
822         CM_LOG_E("malloc buffer failed!");
823         return CMR_ERROR_MALLOC_FAIL;
824     }
825     dstCertFile->path.size = certFile->path.size;
826 
827     if (memcpy_s(dstCertFile->fileName.data, certFile->fileName.size, certFile->fileName.data,
828         certFile->fileName.size) != EOK) {
829         CM_LOG_E("copy fileName failed!");
830         return CMR_ERROR_MEM_OPERATION_COPY;
831     }
832 
833     if (memcpy_s(dstCertFile->path.data, certFile->path.size, certFile->path.data, certFile->path.size) != EOK) {
834         CM_LOG_E("copy path failed!");
835         return CMR_ERROR_MEM_OPERATION_COPY;
836     }
837     return CM_SUCCESS;
838 }
839 
FreeCertFileInfo(struct CertFileInfo * dstCertFile)840 static void FreeCertFileInfo(struct CertFileInfo *dstCertFile)
841 {
842     if (dstCertFile == NULL) {
843         CM_LOG_E("params null pointer");
844         return;
845     }
846     if (dstCertFile->fileName.data != NULL) {
847         CM_FREE_BLOB(dstCertFile->fileName);
848     }
849     if (dstCertFile->path.data != NULL) {
850         CM_FREE_BLOB(dstCertFile->path);
851     }
852 }
853 
854 // Find duplicate user cert, ouput cert file info if found.
FindDuplicateUserCert(const struct CmContext * context,const char * objectName,struct CertFileInfo * certFileInfo)855 static int32_t FindDuplicateUserCert(const struct CmContext *context, const char *objectName,
856     struct CertFileInfo *certFileInfo)
857 {
858     if (context == NULL || objectName == NULL || certFileInfo == NULL) {
859         CM_LOG_E("params null pointer");
860         return CMR_ERROR_NULL_POINTER;
861     }
862     struct CmMutableBlob certFileList = { 0, NULL };
863     const struct UserCAProperty prop = { INIT_INVALID_VALUE, CM_CURRENT_USER };
864     int32_t ret = CmServiceGetCertList(context, &prop, CM_USER_TRUSTED_STORE, &certFileList);
865     if (ret != CM_SUCCESS) {
866         CM_LOG_E("get cert file list failed");
867         return ret;
868     }
869     struct CertFileInfo *cFileList = (struct CertFileInfo *)certFileList.data;
870     ret = CMR_ERROR_NOT_EXIST;
871     for (uint32_t i = 0; i < certFileList.size; i++) {
872         struct CmBlob certData = { 0, NULL };
873         ret = CmStorageGetBuf((char *)cFileList[i].path.data, (char *)cFileList[i].fileName.data, &certData);
874         if (ret != CM_SUCCESS) {
875             CM_LOG_E("get cert data failed");
876             break;
877         }
878         uint8_t certFileHashData[MAX_LEN_CERT_ALIAS] = { 0 };
879         struct CmBlob certFileHash = { sizeof(certFileHashData), certFileHashData };
880         ret = GetCertFileHash(&certData, &certFileHash);
881         CM_FREE_BLOB(certData);
882         if (ret != CM_SUCCESS) {
883             CM_LOG_E("get certFileHash failed");
884             break;
885         }
886         if (strcmp((char *)certFileHashData, objectName) != 0) {
887             ret = CMR_ERROR_NOT_EXIST;
888             continue;
889         }
890         ret = CopyCertFileInfo(&cFileList[i], certFileInfo);
891         if (ret != CM_SUCCESS) {
892             CM_LOG_E("Copy cert file info failed");
893             break;
894         }
895         ret = CM_SUCCESS;
896         break;
897     }
898     if (certFileList.data != NULL) {
899         CmFreeCertFiles((struct CertFileInfo *)certFileList.data, certFileList.size);
900     }
901     return ret;
902 }
903 
904 // Update rdb table and backup user cert config file.
AfterInstallUserCert(const struct AfterInstallCertProperty * afterPersistProp)905 static int32_t AfterInstallUserCert(const struct AfterInstallCertProperty *afterPersistProp)
906 {
907     int32_t ret = RdbInsertCertProperty(afterPersistProp->propertyOri);
908     if (ret != CM_SUCCESS) {
909         CM_LOG_E("Failed to RdbInsertCertProperty");
910         return ret;
911     }
912 
913     ret = TryBackupUserCert(afterPersistProp->context, afterPersistProp->userCert,
914         afterPersistProp->certUri, afterPersistProp->pathBlob);
915     if (ret != CM_SUCCESS) {
916         CM_LOG_E("BackupUserCert fail");
917         return ret;
918     }
919     return ret;
920 }
921 
922 // Storage user cert file. After that, save to rdb table and backup user cert config file.
PersistUserCert(const struct PersistProperty * persistProp,const struct CertPropertyOri * propertyOri)923 static int32_t PersistUserCert(const struct PersistProperty *persistProp, const struct CertPropertyOri *propertyOri)
924 {
925     int ret = CmWriteUserCert(persistProp->context, persistProp->pathBlob, persistProp->userCert,
926         persistProp->objectName, persistProp->certUri);
927     if (ret != CM_SUCCESS) {
928         CM_LOG_E("CertManagerWriteUserCert fail");
929         return ret;
930     }
931 
932     struct AfterInstallCertProperty afterInstallCertProp = {
933         .propertyOri = propertyOri,
934         .context = persistProp->context,
935         .userCert = persistProp->userCert,
936         .certUri = persistProp->certUri,
937         .pathBlob = persistProp->pathBlob
938     };
939     ret = AfterInstallUserCert(&afterInstallCertProp);
940     if (ret != CM_SUCCESS) {
941         CM_LOG_E("Update rdb table and backup user cert config fail");
942         return ret;
943     }
944     return ret;
945 }
946 
947 // Just update user cert when there are duplicate cert.
UpdateUserCert(const struct UpdateUserCertProperty * updateProp,const struct CertPropertyOri * propertyOri)948 static int32_t UpdateUserCert(const struct UpdateUserCertProperty *updateProp,
949     const struct CertPropertyOri *propertyOri)
950 {
951     // copy uri from certFileInfo
952     if (memcpy_s(updateProp->certUri->data, updateProp->certUri->size, updateProp->certFileInfo->fileName.data,
953         updateProp->certFileInfo->fileName.size) != EOK) {
954         CM_LOG_E("Copy cert uri failed");
955         return CMR_ERROR_MEM_OPERATION_COPY;
956     }
957     updateProp->certUri->size = updateProp->certFileInfo->fileName.size;
958     // set path from certFileInfo
959     struct CmMutableBlob pathBlob = {
960         updateProp->certFileInfo->path.size,
961         updateProp->certFileInfo->path.data,
962     };
963     struct AfterInstallCertProperty afterPersistProp = {
964         .propertyOri = propertyOri,
965         .context = updateProp->context,
966         .userCert = updateProp->userCert,
967         .certUri = updateProp->certUri,
968         .pathBlob = &pathBlob
969     };
970     int32_t ret = AfterInstallUserCert(&afterPersistProp);
971     if (ret != CM_SUCCESS) {
972         CM_LOG_E("Update rdb table and backup user cert config fail");
973         return ret;
974     }
975     return ret;
976 }
977 
CmInstallUserCert(const struct CmContext * context,const struct CmBlob * userCert,const struct CmBlob * certAlias,const uint32_t status,struct CmBlob * certUri)978 int32_t CmInstallUserCert(const struct CmContext *context, const struct CmBlob *userCert,
979     const struct CmBlob *certAlias, const uint32_t status, struct CmBlob *certUri)
980 {
981     int32_t ret = CM_SUCCESS;
982     uint8_t pathBuf[CERT_MAX_PATH_LEN] = { 0 };
983     struct CmMutableBlob pathBlob = { sizeof(pathBuf), pathBuf };
984     uint8_t subjectBuf[MAX_LEN_SUBJECT_NAME] = { 0 };
985     struct CmBlob subjectName = { sizeof(subjectBuf), subjectBuf };
986     uint8_t objectBuf[MAX_LEN_CERT_ALIAS] = { 0 };
987     struct CmBlob objectName = { sizeof(objectBuf), objectBuf };
988     uint8_t displayBuf[MAX_LEN_CERT_ALIAS] = { 0 };
989     struct CmBlob displayName = { sizeof(displayBuf), displayBuf };
990     struct CertName certName = { &displayName, &objectName, &subjectName };
991 
992     ret = GetUserCertNameAndPath(context, userCert, certAlias, &certName, &pathBlob);
993     if (ret != CM_SUCCESS) {
994         CM_LOG_E("GetUserCertNameAndPath fail");
995         return ret;
996     }
997     struct CertPropertyOri propertyOri = { context, certUri, &displayName, &subjectName,
998         CM_USER_TRUSTED_STORE, CM_AUTH_STORAGE_LEVEL_EL1 };
999 
1000     struct CertFileInfo certFileInfo = { 0 };
1001     ret = FindDuplicateUserCert(context, (char *)objectBuf, &certFileInfo);
1002     if (ret != CM_SUCCESS) {
1003         CM_LOG_W("No duplicate files found");   // Should continue install user cert.
1004     }
1005     // If alias is not specified and there are duplicate user cert.
1006     if (strcmp("", (char *)certAlias->data) == 0 && ret == CM_SUCCESS) {
1007         struct UpdateUserCertProperty property = { context, userCert, certUri, &certFileInfo};
1008         ret = UpdateUserCert(&property, &propertyOri);
1009         if (ret != CM_SUCCESS) {
1010             CM_LOG_E("Update user cert failed, ret: %d", ret);
1011         }
1012     } else {  // If alias is specified or there are no duplicate user cert.
1013         struct PersistProperty property = { context, &pathBlob, userCert, &objectName, certUri};
1014         ret = PersistUserCert(&property, &propertyOri);
1015         if (ret != CM_SUCCESS) {
1016             CM_LOG_E("Persist user cert failed, ret: %d", ret);
1017         }
1018     }
1019     // Must free certFileInfo at last.
1020     FreeCertFileInfo(&certFileInfo);
1021     return ret;
1022 }
1023 
CmInstallMultiUserCert(const struct CmContext * context,const struct CmBlob * userCert,const struct CmBlob * certAlias,const uint32_t status,struct CmBlob * certUri)1024 int32_t CmInstallMultiUserCert(const struct CmContext *context, const struct CmBlob *userCert,
1025     const struct CmBlob *certAlias, const uint32_t status, struct CmBlob *certUri)
1026 {
1027     if (context == NULL || userCert == NULL || certAlias == NULL || certUri->data == NULL ||
1028         certUri->size < sizeof(uint32_t)) {
1029         CM_LOG_E("invalid argument");
1030         return CMR_ERROR_INVALID_ARGUMENT;
1031     }
1032 
1033     uint8_t *outData = certUri->data;
1034     uint32_t uriListSize = 0;
1035 
1036     STACK_OF(X509) *certStack = InitCertStackContext(userCert->data, userCert->size);
1037     if (certStack == NULL) {
1038         CM_LOG_E("init certStack failed");
1039         return CMR_ERROR_INVALID_CERT_FORMAT;
1040     }
1041     uriListSize = (uint32_t)sk_X509_num(certStack);
1042     // check buffer size
1043     uint32_t capacity = (certUri->size - sizeof(uint32_t)) / MAX_LEN_URI;
1044     if (uriListSize > capacity) {
1045         CM_LOG_E("too many certs, uriListSize = %u, capacity = %u", uriListSize, capacity);
1046         sk_X509_pop_free(certStack, X509_free);
1047         return CMR_ERROR_MAX_CERT_COUNT_REACHED;
1048     }
1049     int32_t ret = CheckInstallMultiCertCount(context, (uint32_t)uriListSize);
1050     if (ret != CM_SUCCESS) {
1051         CM_LOG_E("check install certs too many, ret = %d", ret);
1052         sk_X509_pop_free(certStack, X509_free);
1053         return ret;
1054     }
1055 
1056     // set uriListSize
1057     *((uint32_t *)outData) = uriListSize;
1058     outData += sizeof(uint32_t);
1059 
1060     for (uint32_t i = 0; i < uriListSize; ++i) {
1061         struct CmBlob certPemData = { 0, NULL };
1062         X509 *cert = sk_X509_value(certStack, i);
1063         ret = CmX509ToPEM(cert, &certPemData);
1064         if (ret != CM_SUCCESS) {
1065             CM_LOG_E("CmX509ToPem failed, ret = %d", ret);
1066             break;
1067         }
1068 
1069         // install an user cert
1070         struct CmBlob outUri = { MAX_LEN_URI, outData };
1071         ret = CmInstallUserCert(context, &certPemData, certAlias, status, &outUri);
1072         if (ret != CM_SUCCESS) {
1073             CM_FREE_BLOB(certPemData);
1074             CM_LOG_E("CmInstallUserCert failed, ret = %d", ret);
1075             break;
1076         }
1077         CM_FREE_BLOB(certPemData);
1078         outData += MAX_LEN_URI;
1079     }
1080 
1081     sk_X509_pop_free(certStack, X509_free);
1082     return ret;
1083 }
1084 
CmComparisonCallerIdWithUri(const struct CmContext * context,const struct CmBlob * certUri)1085 static int32_t CmComparisonCallerIdWithUri(const struct CmContext *context,
1086     const struct CmBlob *certUri)
1087 {
1088     struct CMUri uriObj;
1089     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
1090     if (CheckUri(certUri) != CM_SUCCESS) {
1091         CM_LOG_E("cert uri no end");
1092         return CMR_ERROR_INVALID_ARGUMENT_URI;
1093     }
1094 
1095     int32_t ret = CertManagerUriDecode(&uriObj, (char *)certUri->data);
1096     if (ret != CM_SUCCESS) {
1097         CM_LOG_E("uri decode failed, ret = %d", ret);
1098         return ret;
1099     }
1100 
1101     ret = CMR_ERROR_INVALID_ARGUMENT_URI;
1102     do {
1103         if (uriObj.user == NULL) {
1104             CM_LOG_E("uri user invalid");
1105             break;
1106         }
1107         uint32_t userId = 0;
1108         if (CmIsNumeric(uriObj.user, strlen(uriObj.user) + 1, &userId) != CM_SUCCESS) {
1109             CM_LOG_E("parse string to uint32 failed.");
1110             break;
1111         }
1112 
1113         if (uriObj.app == NULL) {
1114             CM_LOG_E("uri app invalid");
1115             break;
1116         }
1117         uint32_t uid = 0;
1118         if (CmIsNumeric(uriObj.app, strlen(uriObj.app) + 1, &uid) != CM_SUCCESS) {
1119             CM_LOG_E("parse string to uint32 failed.");
1120             break;
1121         }
1122 
1123         if ((context->userId == userId) && (context->uid == uid)) {
1124             ret = CM_SUCCESS;
1125             break;
1126         }
1127 
1128         CM_LOG_E("userid(%u)/uid(%u) mismatch, uri: userid(%u)/uid(%u)", context->userId, context->uid, userId, uid);
1129     } while (0);
1130 
1131     (void)CertManagerFreeUri(&uriObj);
1132     return ret;
1133 }
1134 
CmRmUserCert(const char * usrCertConfigFilepath)1135 int32_t CmRmUserCert(const char *usrCertConfigFilepath)
1136 {
1137     int32_t ret = CM_SUCCESS;
1138     uint8_t usrCertBackupFilePath[CERT_MAX_PATH_LEN + 1] = { 0 };
1139     uint32_t size = 0;
1140 
1141     ret = CmIsFileExist(NULL, usrCertConfigFilepath);
1142     if (ret != CMR_OK) {
1143         return CM_SUCCESS;
1144     }
1145     size = CmFileRead(NULL, usrCertConfigFilepath, 0, usrCertBackupFilePath, CERT_MAX_PATH_LEN);
1146     if (size == 0) {
1147         CM_LOG_E("CmFileRead read size 0 invalid ,fail");
1148         return CMR_ERROR_READ_FILE_ERROR;
1149     }
1150 
1151     ret = CmFileRemove(NULL, (const char *)usrCertBackupFilePath);
1152     if (ret != CM_SUCCESS) {
1153         CM_LOG_E("Remove cert backup file fail");
1154     }
1155     return ret;
1156 }
1157 
CmRmSaConf(const char * usrCertConfigFilepath)1158 int32_t CmRmSaConf(const char *usrCertConfigFilepath)
1159 {
1160     int32_t ret = CM_SUCCESS;
1161 
1162     ret = CmFileRemove(NULL, usrCertConfigFilepath);
1163     if (ret != CM_SUCCESS) {
1164         CM_LOG_E("CmFileRemove fail");
1165         return ret;
1166     }
1167     return ret;
1168 }
1169 
CmUninstallUserCert(const struct CmContext * context,const struct CmBlob * certUri)1170 int32_t CmUninstallUserCert(const struct CmContext *context, const struct CmBlob *certUri)
1171 {
1172     if (CmCheckBlob(certUri) != CM_SUCCESS || CheckUri(certUri) != CM_SUCCESS) {
1173         CM_LOG_E("input params invalid");
1174         return CMR_ERROR_INVALID_ARGUMENT_URI;
1175     }
1176 
1177     int32_t ret = CM_SUCCESS;
1178     ASSERT_ARGS(context && certUri && certUri->data && certUri->size);
1179     uint8_t pathBuf[CERT_MAX_PATH_LEN] = {0};
1180     struct CmMutableBlob pathBlob = { sizeof(pathBuf), pathBuf };
1181     uint32_t store = CM_USER_TRUSTED_STORE;
1182 
1183     do {
1184         ret = CmComparisonCallerIdWithUri(context, certUri);
1185         if (ret != CM_SUCCESS) {
1186             CM_LOG_E("CallerId don't match uri, ret = %d", ret);
1187             break;
1188         }
1189 
1190         ret = DeleteCertProperty((char *)certUri->data);
1191         if (ret != CM_SUCCESS) {
1192             CM_LOG_E("Failed delete cert: %s rdbData", (char *)certUri->data);
1193             break;
1194         }
1195 
1196         ret = CmGetCertFilePath(context, store, &pathBlob);
1197         if (ret != CM_SUCCESS) {
1198             CM_LOG_E("Failed obtain path for store %d", store);
1199             break;
1200         }
1201 
1202         ret = CmRemoveUserCert(&pathBlob, certUri);
1203         if (ret != CM_SUCCESS) {
1204             CM_LOG_E("RemoveUserCertFile fail, ret = %d", ret);
1205             break;
1206         }
1207 
1208         ret = CmRemoveBackupUserCert(context, certUri, NULL);
1209         if (ret != CM_SUCCESS) {
1210             CM_LOG_E("CmRemoveBackupUserCert fail");
1211             break;
1212         }
1213     } while (0);
1214     return ret;
1215 }
1216 
CmUninstallAllUserCert(const struct CmContext * context)1217 int32_t CmUninstallAllUserCert(const struct CmContext *context)
1218 {
1219     uint32_t store = CM_USER_TRUSTED_STORE;
1220     struct CmMutableBlob pathList = { 0, NULL };
1221 
1222     int32_t ret = CmGetCertPathList(context, store, &pathList);
1223     if (ret != CM_SUCCESS) {
1224         CM_LOG_E("GetCertPathList fail, ret = %d", ret);
1225         return ret;
1226     }
1227 
1228     if (pathList.size == 0) {
1229         CM_LOG_D("the user dir is empty");
1230         return CM_SUCCESS;
1231     }
1232 
1233     ret = CmRemoveAllUserCert(context, store, &pathList);
1234     CmFreePathList((struct CmMutableBlob *)pathList.data, pathList.size);
1235     if (ret != CM_SUCCESS) {
1236         CM_LOG_E("RemoveAllUserCert fail, ret = %d", ret);
1237         return ret;
1238     }
1239 
1240     return ret;
1241 }
1242 
CmSetStatusBackupCert(const struct CmContext * context,const struct CmBlob * certUri,uint32_t store,uint32_t status)1243 int32_t CmSetStatusBackupCert(
1244     const struct CmContext *context, const struct CmBlob *certUri, uint32_t store, uint32_t status)
1245 {
1246     int32_t ret = CM_SUCCESS;
1247 
1248     if (status == CERT_STATUS_ENANLED) {
1249         bool needUpdate = false;
1250         ret = IsCertNeedBackup(context->userId, context->uid, certUri, &needUpdate);
1251         if (ret != CM_SUCCESS) {
1252             CM_LOG_E("Check cert is need update failed, ret = %d", ret);
1253             return ret;
1254         } else if (needUpdate == false) {
1255             /* No need to update */
1256             return CM_SUCCESS;
1257         }
1258 
1259         struct CmBlob certificateData = { 0, NULL };
1260         ret = CmReadCertData(store, context, certUri, &certificateData);
1261         if (ret != CM_SUCCESS) {
1262             CM_LOG_E("CmReadCertData failed, ret = %d", ret);
1263             return CM_FAILURE;
1264         }
1265 
1266         ret = CmBackupUserCert(context, certUri, &certificateData);
1267         if (ret != CM_SUCCESS) {
1268             CM_LOG_E("CmBackupUserCert failed, ret = %d", ret);
1269             ret = CM_FAILURE;
1270         }
1271         CM_FREE_BLOB(certificateData);
1272     } else if (status == CERT_STATUS_DISABLED) {
1273         ret = CmRemoveBackupUserCert(context, certUri, NULL);
1274         if (ret != CM_SUCCESS) {
1275             CM_LOG_E("CmRemoveBackupUserCert fail, ret = %d", ret);
1276         }
1277     }
1278 
1279     return ret;
1280 }
1281 // LCOV_EXCL_STOP