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