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