From c3aea314a61eef237fb052987f9d588ba4a23a82 Mon Sep 17 00:00:00 2001 From: zhanzeyi Date: Tue, 20 Sep 2022 17:43:19 +0800 Subject: [PATCH] init code Signed-off-by: zhanzeyi --- BUILD.gn | 214 +++ LICENSE | 177 +++ OAT.xml | 73 + README.md | 54 +- build/config.gni | 39 + bundle.json | 69 + cert_manager.gni | 22 + config/BUILD.gn | 916 +++++++++++++ config/systemCertificates/01419da9.0 | Bin 0 -> 605 bytes config/systemCertificates/04f60c28.0 | Bin 0 -> 659 bytes config/systemCertificates/0d69c7e1.0 | Bin 0 -> 485 bytes config/systemCertificates/10531352.0 | Bin 0 -> 1011 bytes config/systemCertificates/111e6273.0 | Bin 0 -> 958 bytes config/systemCertificates/12d55845.0 | Bin 0 -> 846 bytes config/systemCertificates/1ae85e5e.0 | Bin 0 -> 612 bytes config/systemCertificates/1df5a75f.0 | Bin 0 -> 1079 bytes config/systemCertificates/1e1eab7c.0 | Bin 0 -> 967 bytes config/systemCertificates/1e8e7201.0 | Bin 0 -> 867 bytes config/systemCertificates/1eb37bdf.0 | Bin 0 -> 1875 bytes config/systemCertificates/1f58a078.0 | Bin 0 -> 1380 bytes config/systemCertificates/219d9499.0 | Bin 0 -> 1028 bytes config/systemCertificates/23f4c490.0 | Bin 0 -> 1043 bytes config/systemCertificates/27af790d.0 | Bin 0 -> 690 bytes config/systemCertificates/2add47b6.0 | Bin 0 -> 546 bytes config/systemCertificates/2d9dafe4.0 | Bin 0 -> 1373 bytes config/systemCertificates/2fa87019.0 | Bin 0 -> 1002 bytes config/systemCertificates/302904dd.0 | Bin 0 -> 1631 bytes config/systemCertificates/304d27c3.0 | Bin 0 -> 1354 bytes config/systemCertificates/31188b5e.0 | Bin 0 -> 1127 bytes config/systemCertificates/33ee480d.0 | Bin 0 -> 1505 bytes config/systemCertificates/343eb6cb.0 | Bin 0 -> 933 bytes config/systemCertificates/35105088.0 | Bin 0 -> 1506 bytes config/systemCertificates/399e7759.0 | Bin 0 -> 947 bytes config/systemCertificates/3ad48a91.0 | Bin 0 -> 891 bytes config/systemCertificates/3c6676aa.0 | Bin 0 -> 1396 bytes config/systemCertificates/3c860d51.0 | Bin 0 -> 1470 bytes config/systemCertificates/3c899c73.0 | Bin 0 -> 621 bytes config/systemCertificates/3c9a4d3b.0 | Bin 0 -> 2007 bytes config/systemCertificates/3e7271e8.0 | Bin 0 -> 1070 bytes config/systemCertificates/40dc992e.0 | Bin 0 -> 1077 bytes config/systemCertificates/455f1b52.0 | Bin 0 -> 1090 bytes config/systemCertificates/48a195d8.0 | Bin 0 -> 1525 bytes config/systemCertificates/4be590e0.0 | Bin 0 -> 1386 bytes config/systemCertificates/5046c355.0 | Bin 0 -> 1473 bytes config/systemCertificates/524d9b43.0 | Bin 0 -> 1213 bytes config/systemCertificates/52b525c7.0 | Bin 0 -> 1380 bytes config/systemCertificates/583d0756.0 | Bin 0 -> 1519 bytes config/systemCertificates/5a250ea7.0 | Bin 0 -> 1400 bytes config/systemCertificates/5a3f0ff8.0 | Bin 0 -> 1057 bytes config/systemCertificates/5acf816d.0 | Bin 0 -> 526 bytes config/systemCertificates/5cf9d536.0 | Bin 0 -> 1492 bytes config/systemCertificates/5f47b495.0 | Bin 0 -> 1471 bytes config/systemCertificates/60afe812.0 | Bin 0 -> 1049 bytes config/systemCertificates/6187b673.0 | Bin 0 -> 1391 bytes config/systemCertificates/63a2c897.0 | Bin 0 -> 1340 bytes config/systemCertificates/69105f4f.0 | Bin 0 -> 955 bytes config/systemCertificates/6b03dec0.0 | Bin 0 -> 528 bytes config/systemCertificates/75680d2e.0 | Bin 0 -> 1078 bytes config/systemCertificates/76579174.0 | Bin 0 -> 1076 bytes config/systemCertificates/7892ad52.0 | Bin 0 -> 664 bytes config/systemCertificates/7a7c655d.0 | Bin 0 -> 442 bytes config/systemCertificates/7a819ef2.0 | Bin 0 -> 1467 bytes config/systemCertificates/7c302982.0 | Bin 0 -> 1076 bytes config/systemCertificates/81b9768f.0 | Bin 0 -> 969 bytes config/systemCertificates/82223c44.0 | Bin 0 -> 1373 bytes config/systemCertificates/83e9984f.0 | Bin 0 -> 580 bytes config/systemCertificates/85cde254.0 | Bin 0 -> 993 bytes config/systemCertificates/86212b19.0 | Bin 0 -> 848 bytes config/systemCertificates/869fbf79.0 | Bin 0 -> 559 bytes config/systemCertificates/882de061.0 | Bin 0 -> 828 bytes config/systemCertificates/88950faa.0 | Bin 0 -> 657 bytes config/systemCertificates/89c02a45.0 | Bin 0 -> 653 bytes config/systemCertificates/8d6437c3.0 | Bin 0 -> 922 bytes config/systemCertificates/9282e51c.0 | Bin 0 -> 1425 bytes config/systemCertificates/9339512a.0 | Bin 0 -> 1697 bytes config/systemCertificates/9479c8c3.0 | Bin 0 -> 711 bytes config/systemCertificates/9576d26b.0 | Bin 0 -> 1389 bytes config/systemCertificates/9591a472.0 | Bin 0 -> 1452 bytes config/systemCertificates/95aff9e3.0 | Bin 0 -> 959 bytes config/systemCertificates/9685a493.0 | Bin 0 -> 820 bytes config/systemCertificates/985c1f52.0 | Bin 0 -> 1415 bytes config/systemCertificates/9aef356c.0 | Bin 0 -> 673 bytes config/systemCertificates/9d6523ce.0 | Bin 0 -> 1460 bytes config/systemCertificates/9f533518.0 | Bin 0 -> 1869 bytes config/systemCertificates/a2c66da8.0 | Bin 0 -> 1428 bytes config/systemCertificates/a3896b44.0 | Bin 0 -> 862 bytes config/systemCertificates/a7605362.0 | Bin 0 -> 804 bytes config/systemCertificates/a81e292b.0 | Bin 0 -> 886 bytes config/systemCertificates/a9d40e02.0 | Bin 0 -> 1355 bytes config/systemCertificates/ab5346f4.0 | Bin 0 -> 881 bytes config/systemCertificates/ab59055e.0 | Bin 0 -> 1420 bytes config/systemCertificates/aeb67534.0 | Bin 0 -> 1370 bytes config/systemCertificates/b0ed035a.0 | Bin 0 -> 1349 bytes config/systemCertificates/b0f3e76e.0 | Bin 0 -> 889 bytes config/systemCertificates/b3fb433b.0 | Bin 0 -> 765 bytes config/systemCertificates/b74d2bd5.0 | Bin 0 -> 594 bytes config/systemCertificates/b7db1890.0 | Bin 0 -> 895 bytes config/systemCertificates/b872f2b4.0 | Bin 0 -> 891 bytes config/systemCertificates/b936d1c6.0 | Bin 0 -> 1415 bytes config/systemCertificates/bc3f2570.0 | Bin 0 -> 969 bytes config/systemCertificates/bd43e1dd.0 | Bin 0 -> 1491 bytes config/systemCertificates/bdacca6f.0 | Bin 0 -> 960 bytes config/systemCertificates/bf64f35b.0 | Bin 0 -> 1173 bytes config/systemCertificates/c2c1704e.0 | Bin 0 -> 1060 bytes config/systemCertificates/c491639e.0 | Bin 0 -> 586 bytes config/systemCertificates/c51c224c.0 | Bin 0 -> 875 bytes config/systemCertificates/c559d742.0 | Bin 0 -> 1374 bytes config/systemCertificates/c90bc37d.0 | Bin 0 -> 914 bytes config/systemCertificates/cb156124.0 | Bin 0 -> 1615 bytes config/systemCertificates/cb1c3204.0 | Bin 0 -> 1494 bytes config/systemCertificates/ccc52f49.0 | Bin 0 -> 514 bytes config/systemCertificates/cf701eeb.0 | Bin 0 -> 956 bytes config/systemCertificates/d06393bb.0 | Bin 0 -> 967 bytes config/systemCertificates/d0cddf45.0 | Bin 0 -> 1587 bytes config/systemCertificates/d16a5865.0 | Bin 0 -> 1560 bytes config/systemCertificates/d18e9066.0 | Bin 0 -> 1380 bytes config/systemCertificates/d39b0a2c.0 | Bin 0 -> 1446 bytes config/systemCertificates/d41b5e2a.0 | Bin 0 -> 502 bytes config/systemCertificates/d4c339cb.0 | Bin 0 -> 1500 bytes config/systemCertificates/d59297b8.0 | Bin 0 -> 891 bytes config/systemCertificates/d7746a63.0 | Bin 0 -> 1095 bytes config/systemCertificates/da7377f6.0 | Bin 0 -> 1374 bytes config/systemCertificates/dbc54cab.0 | Bin 0 -> 1354 bytes config/systemCertificates/dbff3a01.0 | Bin 0 -> 887 bytes config/systemCertificates/dc99f41e.0 | Bin 0 -> 1551 bytes config/systemCertificates/dfc0fe80.0 | Bin 0 -> 953 bytes config/systemCertificates/e442e424.0 | Bin 0 -> 1380 bytes config/systemCertificates/e48193cf.0 | Bin 0 -> 848 bytes config/systemCertificates/e8651083.0 | Bin 0 -> 1038 bytes config/systemCertificates/ed39abd0.0 | Bin 0 -> 579 bytes config/systemCertificates/edcbddb5.0 | Bin 0 -> 1502 bytes config/systemCertificates/f013ecaf.0 | Bin 0 -> 1374 bytes config/systemCertificates/f0cd152c.0 | Bin 0 -> 1615 bytes config/systemCertificates/f459871d.0 | Bin 0 -> 920 bytes config/systemCertificates/fb5fa911.0 | Bin 0 -> 1349 bytes config/systemCertificates/fd08c599.0 | Bin 0 -> 837 bytes config/systemCertificates/fde84897.0 | Bin 0 -> 940 bytes .../cert_manager_standard/main/BUILD.gn | 23 + .../main/auth_manager/auth_manager_api.c | 124 ++ .../main/auth_manager/auth_manager_api.h | 75 ++ .../main/auth_manager/auth_manager_ipc.c | 281 ++++ .../main/auth_manager/auth_manager_ipc.h | 48 + .../auth_manager/auth_manager_ipc_service.c | 335 +++++ .../auth_manager/auth_manager_ipc_service.h | 53 + .../auth_manager/cert_manager_auth_list_mgr.c | 646 +++++++++ .../auth_manager/cert_manager_auth_list_mgr.h | 52 + .../main/auth_manager/cert_manager_auth_mgr.c | 733 +++++++++++ .../main/auth_manager/cert_manager_auth_mgr.h | 48 + .../auth_manager/cert_manager_double_list.c | 81 ++ .../auth_manager/cert_manager_double_list.h | 58 + .../auth_manager/cert_manager_key_operation.c | 356 +++++ .../auth_manager/cert_manager_key_operation.h | 46 + .../cert_manager_permission_check.cpp | 44 + .../cert_manager_permission_check.h | 31 + .../main/auth_manager/cert_manager_service.c | 173 +++ .../main/auth_manager/cert_manager_service.h | 50 + .../auth_manager/cert_manager_session_mgr.c | 264 ++++ .../auth_manager/cert_manager_session_mgr.h | 61 + .../main/auth_manager/test/cm_abort_test.cpp | 135 ++ .../main/auth_manager/test/cm_finish_test.cpp | 345 +++++ .../test/cm_get_auth_list_test.cpp | 387 ++++++ .../main/auth_manager/test/cm_grant_test.cpp | 361 +++++ .../main/auth_manager/test/cm_init_test.cpp | 381 ++++++ .../auth_manager/test/cm_is_authed_test.cpp | 329 +++++ .../test/cm_remove_grant_test.cpp | 254 ++++ .../main/auth_manager/test/cm_update_test.cpp | 147 +++ .../main/common/BUILD.gn | 52 + .../main/common/include/cm_config.h | 171 +++ .../main/common/include/cm_log.h | 57 + .../main/common/include/cm_mem.h | 59 + .../main/common/include/cm_param.h | 48 + .../main/common/include/cm_pfx.h | 31 + .../main/common/include/cm_type.h | 359 +++++ .../main/common/include/cm_type_inner.h | 22 + .../main/common/include/cm_x509.h | 79 ++ .../main/common/src/cm_param.c | 277 ++++ .../main/common/src/cm_pfx.c | 135 ++ .../main/common/src/cm_x509.c | 296 +++++ .../main/os_dependency/BUILD.gn | 61 + .../cm_ipc/include/cm_client_ipc.h | 51 + .../cm_ipc/include/cm_ipc_check.h | 43 + .../cm_ipc/include/cm_ipc_serialization.h | 49 + .../os_dependency/cm_ipc/include/cm_load_sa.h | 31 + .../os_dependency/cm_ipc/include/cm_request.h | 59 + .../os_dependency/cm_ipc/src/cm_ipc_check.c | 39 + .../os_dependency/cm_ipc/src/cm_ipc_client.c | 660 ++++++++++ .../cm_ipc/src/cm_ipc_serialization.c | 344 +++++ .../os_dependency/cm_ipc/src/cm_load_sa.cpp | 23 + .../os_dependency/cm_ipc/src/cm_request.cpp | 163 +++ .../main/os_dependency/log/cm_log.c | 68 + .../main/os_dependency/posix/cm_mem.c | 42 + .../cert_manager_api_user_trusted_cert.c | 101 ++ .../cert_manager_api_user_trusted_cert.h | 44 + .../cert_manager_user_trusted_cert.c | 622 +++++++++ .../cert_manager_user_trusted_cert.h | 55 + .../cm_ipc_client_user_trusted_cert.c | 401 ++++++ .../cm_ipc_client_user_trusted_cert.h | 45 + .../cm_ipc_service_user_trusted_cert.c | 589 +++++++++ .../cm_ipc_service_user_trusted_cert.h | 47 + .../cm_sa_user_trusted_cert.cpp | 32 + .../cert_manager_standard/main/BUILD.gn | 50 + .../main/include/cert_manager_api.h | 49 + .../main/src/cert_manager_api.c | 134 ++ .../kits/js/@ohos.security.certManager.d.ts | 437 ++++++ interfaces/kits/napi/BUILD.gn | 56 + interfaces/kits/napi/include/cm_napi_common.h | 204 +++ .../napi/include/cm_napi_get_app_cert_info.h | 26 + .../napi/include/cm_napi_get_app_cert_list.h | 26 + .../include/cm_napi_get_system_cert_info.h | 26 + .../include/cm_napi_get_system_cert_list.h | 26 + .../napi/include/cm_napi_install_app_cert.h | 26 + .../napi/include/cm_napi_set_cert_status.h | 26 + .../include/cm_napi_uninstall_all_app_cert.h | 26 + .../napi/include/cm_napi_uninstall_app_cert.h | 26 + interfaces/kits/napi/src/cm_napi.cpp | 111 ++ interfaces/kits/napi/src/cm_napi_common.cpp | 557 ++++++++ .../napi/src/cm_napi_get_app_cert_info.cpp | 205 +++ .../napi/src/cm_napi_get_app_cert_list.cpp | 192 +++ .../napi/src/cm_napi_get_system_cert_info.cpp | 204 +++ .../napi/src/cm_napi_get_system_cert_list.cpp | 192 +++ .../napi/src/cm_napi_install_app_cert.cpp | 224 ++++ .../kits/napi/src/cm_napi_set_cert_status.cpp | 198 +++ .../src/cm_napi_uninstall_all_app_cert.cpp | 157 +++ .../napi/src/cm_napi_uninstall_app_cert.cpp | 170 +++ services/cert_manager_standard/BUILD.gn | 40 + .../cert_manager_engine/main/core/BUILD.gn | 63 + .../main/core/include/cert_manager.h | 153 +++ .../main/core/include/cert_manager_file.h | 40 + .../core/include/cert_manager_file_operator.h | 79 ++ .../main/core/include/cert_manager_mem.h | 51 + .../main/core/include/cert_manager_status.h | 102 ++ .../main/core/include/cert_manager_type.h | 59 + .../main/core/include/cert_manager_uri.h | 80 ++ .../main/core/include/cert_manager_util.h | 42 + .../main/core/include/cm_asn1.h | 123 ++ .../main/core/include/cm_event_process.h | 35 + .../main/core/include/cm_openssl_curve25519.h | 45 + .../main/core/include/cm_openssl_ecc.h | 45 + .../main/core/include/cm_openssl_engine.h | 49 + .../main/core/include/cm_openssl_rsa.h | 43 + .../main/core/include/rbtree.h | 68 + .../main/core/src/cert_manager.c | 1170 ++++++++++++++++ .../main/core/src/cert_manager_auth.c | 161 +++ .../main/core/src/cert_manager_file.c | 169 +++ .../core/src/cert_manager_file_operator.c | 447 +++++++ .../main/core/src/cert_manager_mem.c | 28 + .../main/core/src/cert_manager_status.c | 745 +++++++++++ .../main/core/src/cert_manager_uri.c | 442 +++++++ .../main/core/src/cert_manager_util.c | 128 ++ .../main/core/src/cm_asn1.c | 88 ++ .../main/core/src/cm_event_process.c | 267 ++++ .../main/core/src/cm_openssl_curve25519.c | 62 + .../main/core/src/cm_openssl_ecc.c | 121 ++ .../main/core/src/cm_openssl_rsa.c | 72 + .../main/core/src/rbtree.c | 564 ++++++++ .../cert_manager_service.cfg | 24 + .../cert_manager_service.rc | 21 + .../cert_manager_service/main/BUILD.gn | 28 + .../main/os_dependency/BUILD.gn | 70 + .../main/os_dependency/idl/BUILD.gn | 71 + .../idl/cm_ipc/cm_ipc_serialization.c | 188 +++ .../idl/cm_ipc/cm_ipc_serialization.h | 39 + .../os_dependency/idl/cm_ipc/cm_ipc_service.c | 1171 +++++++++++++++++ .../os_dependency/idl/cm_ipc/cm_ipc_service.h | 55 + .../os_dependency/idl/cm_ipc/cm_response.cpp | 88 ++ .../os_dependency/idl/cm_ipc/cm_response.h | 35 + .../os_dependency/sa/cm_event_observer.cpp | 93 ++ .../main/os_dependency/sa/cm_event_observer.h | 47 + .../main/os_dependency/sa/cm_sa.cpp | 246 ++++ .../main/os_dependency/sa/cm_sa.h | 73 + .../main/os_dependency/sa/sa_profile/BUILD.gn | 20 + .../sa/sa_profile/cert_manager_service.xml | 24 + test/BUILD.gn | 52 + .../certificate_manager/ohos_test.xml | 23 + test/unittest/include/cm_test_common.h | 45 + test/unittest/include/cm_test_log.h | 52 + test/unittest/src/cm_app_cert_test.cpp | 931 +++++++++++++ test/unittest/src/cm_get_certinfo_test.cpp | 253 ++++ test/unittest/src/cm_get_certlist_test.cpp | 200 +++ test/unittest/src/cm_set_status_test.cpp | 184 +++ test/unittest/src/cm_test_common.cpp | 243 ++++ 281 files changed, 25817 insertions(+), 28 deletions(-) create mode 100644 BUILD.gn create mode 100644 LICENSE create mode 100644 OAT.xml create mode 100644 build/config.gni create mode 100644 bundle.json create mode 100644 cert_manager.gni create mode 100644 config/BUILD.gn create mode 100644 config/systemCertificates/01419da9.0 create mode 100644 config/systemCertificates/04f60c28.0 create mode 100644 config/systemCertificates/0d69c7e1.0 create mode 100644 config/systemCertificates/10531352.0 create mode 100644 config/systemCertificates/111e6273.0 create mode 100644 config/systemCertificates/12d55845.0 create mode 100644 config/systemCertificates/1ae85e5e.0 create mode 100644 config/systemCertificates/1df5a75f.0 create mode 100644 config/systemCertificates/1e1eab7c.0 create mode 100644 config/systemCertificates/1e8e7201.0 create mode 100644 config/systemCertificates/1eb37bdf.0 create mode 100644 config/systemCertificates/1f58a078.0 create mode 100644 config/systemCertificates/219d9499.0 create mode 100644 config/systemCertificates/23f4c490.0 create mode 100644 config/systemCertificates/27af790d.0 create mode 100644 config/systemCertificates/2add47b6.0 create mode 100644 config/systemCertificates/2d9dafe4.0 create mode 100644 config/systemCertificates/2fa87019.0 create mode 100644 config/systemCertificates/302904dd.0 create mode 100644 config/systemCertificates/304d27c3.0 create mode 100644 config/systemCertificates/31188b5e.0 create mode 100644 config/systemCertificates/33ee480d.0 create mode 100644 config/systemCertificates/343eb6cb.0 create mode 100644 config/systemCertificates/35105088.0 create mode 100644 config/systemCertificates/399e7759.0 create mode 100644 config/systemCertificates/3ad48a91.0 create mode 100644 config/systemCertificates/3c6676aa.0 create mode 100644 config/systemCertificates/3c860d51.0 create mode 100644 config/systemCertificates/3c899c73.0 create mode 100644 config/systemCertificates/3c9a4d3b.0 create mode 100644 config/systemCertificates/3e7271e8.0 create mode 100644 config/systemCertificates/40dc992e.0 create mode 100644 config/systemCertificates/455f1b52.0 create mode 100644 config/systemCertificates/48a195d8.0 create mode 100644 config/systemCertificates/4be590e0.0 create mode 100644 config/systemCertificates/5046c355.0 create mode 100644 config/systemCertificates/524d9b43.0 create mode 100644 config/systemCertificates/52b525c7.0 create mode 100644 config/systemCertificates/583d0756.0 create mode 100644 config/systemCertificates/5a250ea7.0 create mode 100644 config/systemCertificates/5a3f0ff8.0 create mode 100644 config/systemCertificates/5acf816d.0 create mode 100644 config/systemCertificates/5cf9d536.0 create mode 100644 config/systemCertificates/5f47b495.0 create mode 100644 config/systemCertificates/60afe812.0 create mode 100644 config/systemCertificates/6187b673.0 create mode 100644 config/systemCertificates/63a2c897.0 create mode 100644 config/systemCertificates/69105f4f.0 create mode 100644 config/systemCertificates/6b03dec0.0 create mode 100644 config/systemCertificates/75680d2e.0 create mode 100644 config/systemCertificates/76579174.0 create mode 100644 config/systemCertificates/7892ad52.0 create mode 100644 config/systemCertificates/7a7c655d.0 create mode 100644 config/systemCertificates/7a819ef2.0 create mode 100644 config/systemCertificates/7c302982.0 create mode 100644 config/systemCertificates/81b9768f.0 create mode 100644 config/systemCertificates/82223c44.0 create mode 100644 config/systemCertificates/83e9984f.0 create mode 100644 config/systemCertificates/85cde254.0 create mode 100644 config/systemCertificates/86212b19.0 create mode 100644 config/systemCertificates/869fbf79.0 create mode 100644 config/systemCertificates/882de061.0 create mode 100644 config/systemCertificates/88950faa.0 create mode 100644 config/systemCertificates/89c02a45.0 create mode 100644 config/systemCertificates/8d6437c3.0 create mode 100644 config/systemCertificates/9282e51c.0 create mode 100644 config/systemCertificates/9339512a.0 create mode 100644 config/systemCertificates/9479c8c3.0 create mode 100644 config/systemCertificates/9576d26b.0 create mode 100644 config/systemCertificates/9591a472.0 create mode 100644 config/systemCertificates/95aff9e3.0 create mode 100644 config/systemCertificates/9685a493.0 create mode 100644 config/systemCertificates/985c1f52.0 create mode 100644 config/systemCertificates/9aef356c.0 create mode 100644 config/systemCertificates/9d6523ce.0 create mode 100644 config/systemCertificates/9f533518.0 create mode 100644 config/systemCertificates/a2c66da8.0 create mode 100644 config/systemCertificates/a3896b44.0 create mode 100644 config/systemCertificates/a7605362.0 create mode 100644 config/systemCertificates/a81e292b.0 create mode 100644 config/systemCertificates/a9d40e02.0 create mode 100644 config/systemCertificates/ab5346f4.0 create mode 100644 config/systemCertificates/ab59055e.0 create mode 100644 config/systemCertificates/aeb67534.0 create mode 100644 config/systemCertificates/b0ed035a.0 create mode 100644 config/systemCertificates/b0f3e76e.0 create mode 100644 config/systemCertificates/b3fb433b.0 create mode 100644 config/systemCertificates/b74d2bd5.0 create mode 100644 config/systemCertificates/b7db1890.0 create mode 100644 config/systemCertificates/b872f2b4.0 create mode 100644 config/systemCertificates/b936d1c6.0 create mode 100644 config/systemCertificates/bc3f2570.0 create mode 100644 config/systemCertificates/bd43e1dd.0 create mode 100644 config/systemCertificates/bdacca6f.0 create mode 100644 config/systemCertificates/bf64f35b.0 create mode 100644 config/systemCertificates/c2c1704e.0 create mode 100644 config/systemCertificates/c491639e.0 create mode 100644 config/systemCertificates/c51c224c.0 create mode 100644 config/systemCertificates/c559d742.0 create mode 100644 config/systemCertificates/c90bc37d.0 create mode 100644 config/systemCertificates/cb156124.0 create mode 100644 config/systemCertificates/cb1c3204.0 create mode 100644 config/systemCertificates/ccc52f49.0 create mode 100644 config/systemCertificates/cf701eeb.0 create mode 100644 config/systemCertificates/d06393bb.0 create mode 100644 config/systemCertificates/d0cddf45.0 create mode 100644 config/systemCertificates/d16a5865.0 create mode 100644 config/systemCertificates/d18e9066.0 create mode 100644 config/systemCertificates/d39b0a2c.0 create mode 100644 config/systemCertificates/d41b5e2a.0 create mode 100644 config/systemCertificates/d4c339cb.0 create mode 100644 config/systemCertificates/d59297b8.0 create mode 100644 config/systemCertificates/d7746a63.0 create mode 100644 config/systemCertificates/da7377f6.0 create mode 100644 config/systemCertificates/dbc54cab.0 create mode 100644 config/systemCertificates/dbff3a01.0 create mode 100644 config/systemCertificates/dc99f41e.0 create mode 100644 config/systemCertificates/dfc0fe80.0 create mode 100644 config/systemCertificates/e442e424.0 create mode 100644 config/systemCertificates/e48193cf.0 create mode 100644 config/systemCertificates/e8651083.0 create mode 100644 config/systemCertificates/ed39abd0.0 create mode 100644 config/systemCertificates/edcbddb5.0 create mode 100644 config/systemCertificates/f013ecaf.0 create mode 100644 config/systemCertificates/f0cd152c.0 create mode 100644 config/systemCertificates/f459871d.0 create mode 100644 config/systemCertificates/fb5fa911.0 create mode 100644 config/systemCertificates/fd08c599.0 create mode 100644 config/systemCertificates/fde84897.0 create mode 100644 frameworks/cert_manager_standard/main/BUILD.gn create mode 100644 frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.c create mode 100644 frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.h create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_abort_test.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_finish_test.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_get_auth_list_test.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_grant_test.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_init_test.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_is_authed_test.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_remove_grant_test.cpp create mode 100644 frameworks/cert_manager_standard/main/auth_manager/test/cm_update_test.cpp create mode 100644 frameworks/cert_manager_standard/main/common/BUILD.gn create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_config.h create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_log.h create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_mem.h create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_param.h create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_pfx.h create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_type.h create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_type_inner.h create mode 100644 frameworks/cert_manager_standard/main/common/include/cm_x509.h create mode 100644 frameworks/cert_manager_standard/main/common/src/cm_param.c create mode 100644 frameworks/cert_manager_standard/main/common/src/cm_pfx.c create mode 100644 frameworks/cert_manager_standard/main/common/src/cm_x509.c create mode 100644 frameworks/cert_manager_standard/main/os_dependency/BUILD.gn create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_client_ipc.h create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_check.h create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_serialization.h create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_load_sa.h create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_request.h create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_check.c create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_client.c create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_serialization.c create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_load_sa.cpp create mode 100644 frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_request.cpp create mode 100644 frameworks/cert_manager_standard/main/os_dependency/log/cm_log.c create mode 100644 frameworks/cert_manager_standard/main/os_dependency/posix/cm_mem.c create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.c create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.h create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.c create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.h create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.c create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.h create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.c create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.h create mode 100644 frameworks/cert_manager_standard/main/user_trusted_cert/cm_sa_user_trusted_cert.cpp create mode 100644 interfaces/innerkits/cert_manager_standard/main/BUILD.gn create mode 100644 interfaces/innerkits/cert_manager_standard/main/include/cert_manager_api.h create mode 100644 interfaces/innerkits/cert_manager_standard/main/src/cert_manager_api.c create mode 100644 interfaces/kits/js/@ohos.security.certManager.d.ts create mode 100644 interfaces/kits/napi/BUILD.gn create mode 100644 interfaces/kits/napi/include/cm_napi_common.h create mode 100644 interfaces/kits/napi/include/cm_napi_get_app_cert_info.h create mode 100644 interfaces/kits/napi/include/cm_napi_get_app_cert_list.h create mode 100644 interfaces/kits/napi/include/cm_napi_get_system_cert_info.h create mode 100644 interfaces/kits/napi/include/cm_napi_get_system_cert_list.h create mode 100644 interfaces/kits/napi/include/cm_napi_install_app_cert.h create mode 100644 interfaces/kits/napi/include/cm_napi_set_cert_status.h create mode 100644 interfaces/kits/napi/include/cm_napi_uninstall_all_app_cert.h create mode 100644 interfaces/kits/napi/include/cm_napi_uninstall_app_cert.h create mode 100644 interfaces/kits/napi/src/cm_napi.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_common.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_get_app_cert_info.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_get_app_cert_list.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_get_system_cert_info.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_get_system_cert_list.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_install_app_cert.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_set_cert_status.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_uninstall_all_app_cert.cpp create mode 100644 interfaces/kits/napi/src/cm_napi_uninstall_app_cert.cpp create mode 100644 services/cert_manager_standard/BUILD.gn create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/BUILD.gn create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file_operator.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_mem.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_status.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_type.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_uri.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_util.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cm_asn1.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cm_event_process.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_curve25519.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_ecc.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_engine.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_rsa.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/include/rbtree.h create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_auth.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file_operator.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_mem.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_status.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_uri.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_util.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cm_asn1.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cm_event_process.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_curve25519.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_ecc.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_rsa.c create mode 100644 services/cert_manager_standard/cert_manager_engine/main/core/src/rbtree.c create mode 100644 services/cert_manager_standard/cert_manager_service.cfg create mode 100644 services/cert_manager_standard/cert_manager_service.rc create mode 100644 services/cert_manager_standard/cert_manager_service/main/BUILD.gn create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/BUILD.gn create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.c create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.h create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.c create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.h create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.cpp create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.h create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.cpp create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.h create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.h create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/BUILD.gn create mode 100644 services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.xml create mode 100644 test/BUILD.gn create mode 100644 test/resource/certificate_manager/ohos_test.xml create mode 100644 test/unittest/include/cm_test_common.h create mode 100644 test/unittest/include/cm_test_log.h create mode 100644 test/unittest/src/cm_app_cert_test.cpp create mode 100644 test/unittest/src/cm_get_certinfo_test.cpp create mode 100644 test/unittest/src/cm_get_certlist_test.cpp create mode 100644 test/unittest/src/cm_set_status_test.cpp create mode 100644 test/unittest/src/cm_test_common.cpp diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 0000000..bf16666 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,214 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +group("cert_manager_sdk_test") { + testonly = true + if (os_level == "standard") { + deps = [ "//base/security/certificate_manager/test:unittest" ] + } else { + } +} + +group("cert_manager_napi") { + if (os_level == "standard") { + if (support_jsapi) { + deps = [ + "//base/security/certificate_manager/interfaces/kits/napi:certmanager", + ] + } + } +} + +group("cipher_napi") { + if (os_level == "standard") { + if (support_jsapi) { + deps = [] + # [ "//base/security/huks/frameworks/crypto_lite/js/napi:cipher_napi" ] + } + } +} + +group("cert_manager_type_base") { + if (os_level == "standard") { + deps = [ + "//base/security/certificate_manager:cert_manager_napi", + "//base/security/certificate_manager/config:trusted_system_certificate0", + "//base/security/certificate_manager/config:trusted_system_certificate1", + "//base/security/certificate_manager/config:trusted_system_certificate10", + "//base/security/certificate_manager/config:trusted_system_certificate100", + "//base/security/certificate_manager/config:trusted_system_certificate101", + "//base/security/certificate_manager/config:trusted_system_certificate102", + "//base/security/certificate_manager/config:trusted_system_certificate103", + "//base/security/certificate_manager/config:trusted_system_certificate104", + "//base/security/certificate_manager/config:trusted_system_certificate105", + "//base/security/certificate_manager/config:trusted_system_certificate106", + "//base/security/certificate_manager/config:trusted_system_certificate107", + "//base/security/certificate_manager/config:trusted_system_certificate108", + "//base/security/certificate_manager/config:trusted_system_certificate109", + "//base/security/certificate_manager/config:trusted_system_certificate11", + "//base/security/certificate_manager/config:trusted_system_certificate110", + "//base/security/certificate_manager/config:trusted_system_certificate111", + "//base/security/certificate_manager/config:trusted_system_certificate112", + "//base/security/certificate_manager/config:trusted_system_certificate113", + "//base/security/certificate_manager/config:trusted_system_certificate114", + "//base/security/certificate_manager/config:trusted_system_certificate115", + "//base/security/certificate_manager/config:trusted_system_certificate116", + "//base/security/certificate_manager/config:trusted_system_certificate117", + "//base/security/certificate_manager/config:trusted_system_certificate118", + "//base/security/certificate_manager/config:trusted_system_certificate119", + "//base/security/certificate_manager/config:trusted_system_certificate12", + "//base/security/certificate_manager/config:trusted_system_certificate120", + "//base/security/certificate_manager/config:trusted_system_certificate121", + "//base/security/certificate_manager/config:trusted_system_certificate122", + "//base/security/certificate_manager/config:trusted_system_certificate123", + "//base/security/certificate_manager/config:trusted_system_certificate124", + "//base/security/certificate_manager/config:trusted_system_certificate125", + "//base/security/certificate_manager/config:trusted_system_certificate126", + "//base/security/certificate_manager/config:trusted_system_certificate127", + "//base/security/certificate_manager/config:trusted_system_certificate128", + "//base/security/certificate_manager/config:trusted_system_certificate13", + "//base/security/certificate_manager/config:trusted_system_certificate14", + "//base/security/certificate_manager/config:trusted_system_certificate15", + "//base/security/certificate_manager/config:trusted_system_certificate16", + "//base/security/certificate_manager/config:trusted_system_certificate17", + "//base/security/certificate_manager/config:trusted_system_certificate18", + "//base/security/certificate_manager/config:trusted_system_certificate19", + "//base/security/certificate_manager/config:trusted_system_certificate2", + "//base/security/certificate_manager/config:trusted_system_certificate20", + "//base/security/certificate_manager/config:trusted_system_certificate21", + "//base/security/certificate_manager/config:trusted_system_certificate22", + "//base/security/certificate_manager/config:trusted_system_certificate23", + "//base/security/certificate_manager/config:trusted_system_certificate24", + "//base/security/certificate_manager/config:trusted_system_certificate25", + "//base/security/certificate_manager/config:trusted_system_certificate26", + "//base/security/certificate_manager/config:trusted_system_certificate27", + "//base/security/certificate_manager/config:trusted_system_certificate28", + "//base/security/certificate_manager/config:trusted_system_certificate29", + "//base/security/certificate_manager/config:trusted_system_certificate3", + "//base/security/certificate_manager/config:trusted_system_certificate30", + "//base/security/certificate_manager/config:trusted_system_certificate31", + "//base/security/certificate_manager/config:trusted_system_certificate32", + "//base/security/certificate_manager/config:trusted_system_certificate33", + "//base/security/certificate_manager/config:trusted_system_certificate34", + "//base/security/certificate_manager/config:trusted_system_certificate35", + "//base/security/certificate_manager/config:trusted_system_certificate36", + "//base/security/certificate_manager/config:trusted_system_certificate37", + "//base/security/certificate_manager/config:trusted_system_certificate38", + "//base/security/certificate_manager/config:trusted_system_certificate39", + "//base/security/certificate_manager/config:trusted_system_certificate4", + "//base/security/certificate_manager/config:trusted_system_certificate40", + "//base/security/certificate_manager/config:trusted_system_certificate41", + "//base/security/certificate_manager/config:trusted_system_certificate42", + "//base/security/certificate_manager/config:trusted_system_certificate43", + "//base/security/certificate_manager/config:trusted_system_certificate44", + "//base/security/certificate_manager/config:trusted_system_certificate45", + "//base/security/certificate_manager/config:trusted_system_certificate46", + "//base/security/certificate_manager/config:trusted_system_certificate47", + "//base/security/certificate_manager/config:trusted_system_certificate48", + "//base/security/certificate_manager/config:trusted_system_certificate49", + "//base/security/certificate_manager/config:trusted_system_certificate5", + "//base/security/certificate_manager/config:trusted_system_certificate50", + "//base/security/certificate_manager/config:trusted_system_certificate51", + "//base/security/certificate_manager/config:trusted_system_certificate52", + "//base/security/certificate_manager/config:trusted_system_certificate53", + "//base/security/certificate_manager/config:trusted_system_certificate54", + "//base/security/certificate_manager/config:trusted_system_certificate55", + "//base/security/certificate_manager/config:trusted_system_certificate56", + "//base/security/certificate_manager/config:trusted_system_certificate57", + "//base/security/certificate_manager/config:trusted_system_certificate58", + "//base/security/certificate_manager/config:trusted_system_certificate59", + "//base/security/certificate_manager/config:trusted_system_certificate6", + "//base/security/certificate_manager/config:trusted_system_certificate60", + "//base/security/certificate_manager/config:trusted_system_certificate61", + "//base/security/certificate_manager/config:trusted_system_certificate62", + "//base/security/certificate_manager/config:trusted_system_certificate63", + "//base/security/certificate_manager/config:trusted_system_certificate64", + "//base/security/certificate_manager/config:trusted_system_certificate65", + "//base/security/certificate_manager/config:trusted_system_certificate66", + "//base/security/certificate_manager/config:trusted_system_certificate67", + "//base/security/certificate_manager/config:trusted_system_certificate68", + "//base/security/certificate_manager/config:trusted_system_certificate69", + "//base/security/certificate_manager/config:trusted_system_certificate7", + "//base/security/certificate_manager/config:trusted_system_certificate70", + "//base/security/certificate_manager/config:trusted_system_certificate71", + "//base/security/certificate_manager/config:trusted_system_certificate72", + "//base/security/certificate_manager/config:trusted_system_certificate73", + "//base/security/certificate_manager/config:trusted_system_certificate74", + "//base/security/certificate_manager/config:trusted_system_certificate75", + "//base/security/certificate_manager/config:trusted_system_certificate76", + "//base/security/certificate_manager/config:trusted_system_certificate77", + "//base/security/certificate_manager/config:trusted_system_certificate78", + "//base/security/certificate_manager/config:trusted_system_certificate79", + "//base/security/certificate_manager/config:trusted_system_certificate8", + "//base/security/certificate_manager/config:trusted_system_certificate80", + "//base/security/certificate_manager/config:trusted_system_certificate81", + "//base/security/certificate_manager/config:trusted_system_certificate82", + "//base/security/certificate_manager/config:trusted_system_certificate83", + "//base/security/certificate_manager/config:trusted_system_certificate84", + "//base/security/certificate_manager/config:trusted_system_certificate85", + "//base/security/certificate_manager/config:trusted_system_certificate86", + "//base/security/certificate_manager/config:trusted_system_certificate87", + "//base/security/certificate_manager/config:trusted_system_certificate88", + "//base/security/certificate_manager/config:trusted_system_certificate89", + "//base/security/certificate_manager/config:trusted_system_certificate9", + "//base/security/certificate_manager/config:trusted_system_certificate90", + "//base/security/certificate_manager/config:trusted_system_certificate91", + "//base/security/certificate_manager/config:trusted_system_certificate92", + "//base/security/certificate_manager/config:trusted_system_certificate93", + "//base/security/certificate_manager/config:trusted_system_certificate94", + "//base/security/certificate_manager/config:trusted_system_certificate95", + "//base/security/certificate_manager/config:trusted_system_certificate96", + "//base/security/certificate_manager/config:trusted_system_certificate97", + "//base/security/certificate_manager/config:trusted_system_certificate98", + "//base/security/certificate_manager/config:trusted_system_certificate99", + ] + } else if (os_level == "small") { + deps = [] + } else { + deps = [] + } +} + +group("cert_manager_type_fwk") { + if (os_level == "standard") { + deps = [ + "//base/security/certificate_manager/interfaces/innerkits/cert_manager_standard/main:cert_manager_sdk" + ] + } else if (os_level == "small") { + deps = [] + } else { + deps = [] + } +} + +group("cert_manager_typer_services") { + if (os_level == "standard") { + deps = [ + "//base/security/certificate_manager/frameworks/cert_manager_standard/main:cert_manager_standard_frameworks", + "//base/security/certificate_manager/services/cert_manager_standard:cert_manager_service", + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_engine/main/core:cert_manager_engine_core_standard", + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile:cert_manager_sa_profile", + ] + } else if (os_level == "small") { + deps = [] + } else { + deps = [] + } +} + +group("cert_manager_components") { + deps = [ + "//base/security/certificate_manager:cert_manager_type_base", + "//base/security/certificate_manager:cert_manager_typer_services", + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4947287 --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 0000000..3ae5bf2 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 90deffd..95338de 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,37 @@ -# security_certificate_manager +# 证书管理 -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} +- [简介](#section11660541593) +- [目录](#section161941989596) +- [相关仓](#section1371113476307) -#### 软件架构 -软件架构说明 +## 简介 +证书管理主要提供系统级的证书管理能力,实现证书全生命周期(生成,存储,使用,销毁)的管理和安全使用 ,满足生态应用和上层业务的诉求。 -#### 安装教程 +证书管理模块可以分为如下三大部分: -1. xxxx -2. xxxx -3. xxxx +- SDK层:提供证书管理 API,供应用调用。 +- Service层:实现证书全生命周期管理。 +- Engine层:证书管理核心模块,负责证书的生成、存储、授权、使用、销毁等工作。其中密钥相关操作依赖于当前设备中的HUKS能力,证书管理通过HUKS组件提供对业务证书以及其关联密钥的生成,导入,存储,读取和删除等能力。 -#### 使用说明 +## 目录 -1. xxxx -2. xxxx -3. xxxx +``` +base/security/certificate_manager/ +├── build # 编译配置文件 +├── config # 系统根证书文件 +├── frameworks # 框架代码, 作为基础功能目录, 被interfaces和services使用. +├── interfaces # 接口API代码 +│ └── innerkits +│ └── kits +├── services +│ └── cert_manager_standard # 证书管理核心功能代码 +├── test # 测试资源存放目录 +``` -#### 参与贡献 +## 相关仓 -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +**安全子系统** +**security_huks** -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/build/config.gni b/build/config.gni new file mode 100644 index 0000000..e65619f --- /dev/null +++ b/build/config.gni @@ -0,0 +1,39 @@ +# +# Copyright (c) 2020 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # for HUKS can compile on liteos_m + disable_huks_binary = false + + # cut abilities for authentication + disable_authenticate = false + + # if HUKS use mbedtls engine + huks_use_mbedtls = true + + # whether use lite storeage + huks_use_lite_storage = false + + # whether use hardware root key + huks_use_hardware_root_key = false + + # whether use hks config file + huks_config_file = "" + + # whether use hks key store path + huks_key_store_path = "/storage/" + + # whether huks enable log + huks_enable_log = false +} diff --git a/bundle.json b/bundle.json new file mode 100644 index 0000000..2f4702d --- /dev/null +++ b/bundle.json @@ -0,0 +1,69 @@ +{ + "name": "@ohos/cert_manager", + "description": "The provider of certificate manangement capbility, which belongs to security subsystem", + "version": "3.1", + "license": "Apache License 2.0", + "publishAs": "code-segment", + "segment": { + "destPath": "base/security/certificate_manager" + }, + "dirs":{}, + "scripts": { + "install": "DEST_PATH=${DEP_BUNDLE_BASE}/base/security/certificate_manager && mkdir -p $DEST_PATH && cp -r ./* $DEST_PATH" + }, + "author": {}, + "repository": "", + "component": { + "name": "certificate_manager", + "subsystem": "security", + "syscap": [ "SystemCapability.Security.CertificateManager" ], + "features": [], + "adapted_system_type": [ + "standard", + "small", + "mini" + ], + "rom": "5000KB", + "ram": "500kB", + "deps": { + "components": [ + "libhilog", + "ipc_core", + "system_ability_fwk", + "samgr_proxy", + "c_utils" + ], + "third_party": [ + "openssl", + "bounds_checking_function" + ] + }, + "build": { + "group_type": { + "base_group": [ + "//base/security/certificate_manager:cert_manager_type_base" + ], + "fwk_group": [ + "//base/security/certificate_manager:cert_manager_type_fwk" + ], + "service_group": [ + "//base/security/certificate_manager:cert_manager_typer_services" + ] + }, + "inner_kits": [ + { + "name": "//base/security/certificate_manager/interfaces/innerkits/cert_manager_standard/main:cert_manager_sdk", + "header": { + "header_files": [ + "cert_manager_api.h" + ], + "header_base": "//base/security/certificate_manager/interfaces/innerkits/cert_manager_standard/main/include" + } + } + ], + "test": [ + "//base/security/certificate_manager/test:unittest" + ] + } + } + } diff --git a/cert_manager.gni b/cert_manager.gni new file mode 100644 index 0000000..c7c04a2 --- /dev/null +++ b/cert_manager.gni @@ -0,0 +1,22 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use_crypto_lib = "openssl" +non_rwlock_support = false + +if (!defined(global_parts_info) || + defined(global_parts_info.account_os_account)) { + has_os_account_part = true +} else { + has_os_account_part = false +} diff --git a/config/BUILD.gn b/config/BUILD.gn new file mode 100644 index 0000000..4daa2f7 --- /dev/null +++ b/config/BUILD.gn @@ -0,0 +1,916 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_prebuilt_etc("trusted_system_certificate0") { + source = "systemCertificates/85cde254.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate1") { + source = "systemCertificates/869fbf79.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate2") { + source = "systemCertificates/b0f3e76e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate3") { + source = "systemCertificates/2add47b6.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate4") { + source = "systemCertificates/3c860d51.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate5") { + source = "systemCertificates/0d69c7e1.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate6") { + source = "systemCertificates/1ae85e5e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate7") { + source = "systemCertificates/1df5a75f.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate8") { + source = "systemCertificates/1e1eab7c.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate9") { + source = "systemCertificates/1e8e7201.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate10") { + source = "systemCertificates/1eb37bdf.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate11") { + source = "systemCertificates/1f58a078.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate12") { + source = "systemCertificates/2d9dafe4.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate13") { + source = "systemCertificates/2fa87019.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate14") { + source = "systemCertificates/3ad48a91.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate15") { + source = "systemCertificates/3c9a4d3b.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate16") { + source = "systemCertificates/3c899c73.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate17") { + source = "systemCertificates/3c6676aa.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate18") { + source = "systemCertificates/3e7271e8.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate19") { + source = "systemCertificates/4be590e0.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate20") { + source = "systemCertificates/04f60c28.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate21") { + source = "systemCertificates/5a3f0ff8.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate22") { + source = "systemCertificates/5a250ea7.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate23") { + source = "systemCertificates/5acf816d.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate24") { + source = "systemCertificates/5cf9d536.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate25") { + source = "systemCertificates/5f47b495.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate26") { + source = "systemCertificates/6b03dec0.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate27") { + source = "systemCertificates/7a7c655d.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate28") { + source = "systemCertificates/7a819ef2.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate29") { + source = "systemCertificates/7c302982.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate30") { + source = "systemCertificates/8d6437c3.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate31") { + source = "systemCertificates/9aef356c.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate32") { + source = "systemCertificates/9d6523ce.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate33") { + source = "systemCertificates/9f533518.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate34") { + source = "systemCertificates/12d55845.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate35") { + source = "systemCertificates/23f4c490.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate36") { + source = "systemCertificates/27af790d.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate37") { + source = "systemCertificates/33ee480d.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate38") { + source = "systemCertificates/40dc992e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate39") { + source = "systemCertificates/48a195d8.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate40") { + source = "systemCertificates/52b525c7.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate41") { + source = "systemCertificates/60afe812.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate42") { + source = "systemCertificates/63a2c897.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate43") { + source = "systemCertificates/81b9768f.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate44") { + source = "systemCertificates/83e9984f.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate45") { + source = "systemCertificates/89c02a45.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate46") { + source = "systemCertificates/95aff9e3.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate47") { + source = "systemCertificates/111e6273.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate48") { + source = "systemCertificates/219d9499.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate49") { + source = "systemCertificates/304d27c3.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate50") { + source = "systemCertificates/343eb6cb.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate51") { + source = "systemCertificates/399e7759.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate52") { + source = "systemCertificates/455f1b52.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate53") { + source = "systemCertificates/524d9b43.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate54") { + source = "systemCertificates/583d0756.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate55") { + source = "systemCertificates/882de061.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate56") { + source = "systemCertificates/985c1f52.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate57") { + source = "systemCertificates/01419da9.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate58") { + source = "systemCertificates/5046c355.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate59") { + source = "systemCertificates/6187b673.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate60") { + source = "systemCertificates/7892ad52.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate61") { + source = "systemCertificates/9282e51c.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate62") { + source = "systemCertificates/9479c8c3.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate63") { + source = "systemCertificates/9576d26b.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate64") { + source = "systemCertificates/9591a472.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate65") { + source = "systemCertificates/9685a493.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate66") { + source = "systemCertificates/31188b5e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate67") { + source = "systemCertificates/69105f4f.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate68") { + source = "systemCertificates/75680d2e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate69") { + source = "systemCertificates/82223c44.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate70") { + source = "systemCertificates/86212b19.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate71") { + source = "systemCertificates/88950faa.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate72") { + source = "systemCertificates/302904dd.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate73") { + source = "systemCertificates/9339512a.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate74") { + source = "systemCertificates/10531352.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate75") { + source = "systemCertificates/35105088.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate76") { + source = "systemCertificates/76579174.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate77") { + source = "systemCertificates/a2c66da8.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate78") { + source = "systemCertificates/a9d40e02.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate79") { + source = "systemCertificates/a81e292b.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate80") { + source = "systemCertificates/a3896b44.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate81") { + source = "systemCertificates/a7605362.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate82") { + source = "systemCertificates/ab5346f4.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate83") { + source = "systemCertificates/ab59055e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate84") { + source = "systemCertificates/aeb67534.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate85") { + source = "systemCertificates/b0ed035a.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate86") { + source = "systemCertificates/b3fb433b.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate87") { + source = "systemCertificates/b7db1890.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate88") { + source = "systemCertificates/b74d2bd5.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} +ohos_prebuilt_etc("trusted_system_certificate89") { + source = "systemCertificates/b872f2b4.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate90") { + source = "systemCertificates/b936d1c6.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate91") { + source = "systemCertificates/bc3f2570.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate92") { + source = "systemCertificates/bd43e1dd.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate93") { + source = "systemCertificates/bdacca6f.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate94") { + source = "systemCertificates/bf64f35b.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate95") { + source = "systemCertificates/c2c1704e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate96") { + source = "systemCertificates/c51c224c.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate97") { + source = "systemCertificates/c90bc37d.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate98") { + source = "systemCertificates/c559d742.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate99") { + source = "systemCertificates/c491639e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate100") { + source = "systemCertificates/cb1c3204.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate101") { + source = "systemCertificates/cb156124.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate102") { + source = "systemCertificates/ccc52f49.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate103") { + source = "systemCertificates/cf701eeb.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate104") { + source = "systemCertificates/d0cddf45.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate105") { + source = "systemCertificates/d4c339cb.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate106") { + source = "systemCertificates/d16a5865.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate107") { + source = "systemCertificates/d18e9066.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate108") { + source = "systemCertificates/d39b0a2c.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate109") { + source = "systemCertificates/d41b5e2a.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate110") { + source = "systemCertificates/d06393bb.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate111") { + source = "systemCertificates/d7746a63.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate112") { + source = "systemCertificates/d59297b8.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate113") { + source = "systemCertificates/da7377f6.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate114") { + source = "systemCertificates/dbc54cab.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate115") { + source = "systemCertificates/dbff3a01.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate116") { + source = "systemCertificates/dc99f41e.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate117") { + source = "systemCertificates/dfc0fe80.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate118") { + source = "systemCertificates/e442e424.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate119") { + source = "systemCertificates/e48193cf.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate120") { + source = "systemCertificates/e8651083.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate121") { + source = "systemCertificates/ed39abd0.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate122") { + source = "systemCertificates/edcbddb5.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate123") { + source = "systemCertificates/f0cd152c.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate124") { + source = "systemCertificates/f013ecaf.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate125") { + source = "systemCertificates/f459871d.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate126") { + source = "systemCertificates/fb5fa911.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate127") { + source = "systemCertificates/fd08c599.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} + +ohos_prebuilt_etc("trusted_system_certificate128") { + source = "systemCertificates/fde84897.0" + part_name = "certificate_manager" + subsystem_name = "security" + relative_install_dir = "security/certificates" +} \ No newline at end of file diff --git a/config/systemCertificates/01419da9.0 b/config/systemCertificates/01419da9.0 new file mode 100644 index 0000000000000000000000000000000000000000..86658aeb9a6ecb5ec69dbcb8e2b06e3651bf574b GIT binary patch literal 605 zcmXqLVv00qV!XeAnTe5!Ng(Z$?fUk6-5b4L@q`;P9(rTI#m1r4=5fxJg_+qP)sWkO zlZ`o)g-w_#G}utiKnBF&5*GE%OfJeV&QB{*aLz9($S+DP$;{6)G&3*($ukSUiEDTD_NenDk_SiBxl{yM5pKV}iV+z#ITG5!q zoqFcmskw6bUTJ}gm~YOV_-mWk#-6-;HD_;EF4I4^`&^;^)1|95-Xyc6&HVA}(_{hG zhm9IekB?=1c_!VG;MKYQZ6&|;xsTsmzA{!ESR7&yWWWauI9Yy1#{VoVz<6mh;0N)A zL3~yNW*}uC3liXC5n~ZKae8J^K@iW6XZtp>gllS@cM^DO3UoQAHX9=gW0SckBgg~> zd?~ht?^l?|l_dsZ6Dw|q^rSL&Jr77bWVqdO*A6KqcE3N_Az}*u OwYNU^;qhJOUkm_{_{g6C literal 0 HcmV?d00001 diff --git a/config/systemCertificates/04f60c28.0 b/config/systemCertificates/04f60c28.0 new file mode 100644 index 0000000000000000000000000000000000000000..9c534960432c5290bc86f2a16a7eeb6037355494 GIT binary patch literal 659 zcmXqLV(K?&ViH}z%*4pVBoNa*^JvtRqn8T9?w##yIHP93#m1r4=5fxJg_+r)vBQwt zfRl|ml!Z;0DKywn*gz1(;SlEXOD$LMN-Zi*tuz!d5CRFZ3v)vR6r3|lDh=ffWI&=^ z!lEG=sS2UNu0bI|p}`>veyJtp`9;}=dImZmd1hf%uv}4TafyPfv$KM8YEemMT4r)$ zNoIbYf@5h(Mt%{{JOep#UPA)|BLg4-0#V|;#uf&Kh89M~rk19bQG>~;Wd;Il?BFnD zVq|00Ze(FlVoqXUky;ZHwen|%^7E>zD*3_3qHcJvK6Z86#b?EZ>+a6E#*_H>_JU64 z9jqd6!q2^nwST0z`P}y_U6l_OH`nP-zmRz3%|0b zjNe>qRNrOtxUzDwlYxVQEHF@I`B=nQM64ciwp}?dd1zW$iD%iJ2d2l8lV=(5fu#8v z8UM4e0HdGHfFHyc2Ju-9n1K{>>@#OD7^E^8n58ci*jOVRaISHmL zm^;OiNw6}eTJ~4U&Ua!?oA-Ae;ym)^$wpr$Lxz`HiS9i?UfzBZ1>df@T+92~yel_i gugc9Zk5})HEOKk?$g*;~xN^4d$;4Y1W5cr~08TI3xBvhE literal 0 HcmV?d00001 diff --git a/config/systemCertificates/0d69c7e1.0 b/config/systemCertificates/0d69c7e1.0 new file mode 100644 index 0000000000000000000000000000000000000000..160d545fc28b8cebba1b65d475f09a4544933af4 GIT binary patch literal 485 zcmXqLVti=O#Mr)onTe5!Nl?pTiOe)EmU~W{G?sF|Fqy$*z{SR))#h=|mW7$gAiz+? zK#7exl!aSZ+C3*fDKRHFGd)ki)!A7gC_leM!P!wkS0Tv6P}o2aq>4+J3!w@o$c!v# zAScdiXk=(;XlwumQR2MD76yifmIlU#CI;qFG_Wz!K$wjk>?0;dsMnYo*_oXfSauw% zyxgCo$~RxnQc{L_$+}rjE!jE6P9<;L+4iF={9yPwr(eYjzo$C=mpjO?DX*CC|8d2q z5=&OyEVN&7W#_pb*~Lx<4hDQckIV8iGX7@)1{foo0Y8W@4C1pIFas$AS&#r9ix`VY z$cE~*t~(w%)c@wn`@PTjq|M@%tH{C4?7?8*%B09}XVSt2!pqJxZ+Lb@ar%T`BH_Bs zZ{FEl&O5atr)I#U`uuza;ap9t6a2L{-?Pgs zl5d(Nte71a!_crvKeGN?`%hKpw&$7BL9-@2EPQ-Jm)9@<+X>H`+dfN$t<&CCBJ%qD zZ?(r#yJV;7Wm!i|>2weKuexAzL2&b}mJ*S}>GN1JtnT+YM9F&jop+vS{XFa%L&52w zch$A)te)>N{OS7bP{MiPNG9!uGbZl$cix+jn#*)vXX3JD&+oNLc-Ex(Ew;*Cx%Hii z-Y#C|9meeDD+ZAek_f&-n9TI)D_j}ew*jYqV9Z;Uo_wC|NGvNvHXns%A{7~Pv#u&3(uFc z-8&&E+u?A&)=l=m-0_F!{wv=;_NzD4Zza=ncR@G1FMsz|YpU&DnV4j*u}xR&n?PI2 z$%5sV)^67!V7OH{5j|q J(7RD%7XbdRdH(zmHFpYDPz}E}G_kLH`6?d!&>ZtZw zcFJ>E+=}HrQG$D_nqKegdAWJbG*$NLUNg1W^|#2C@9*N@%2XpgZO74_RyupG3GI9x zS^MY$TU&gbXVzBBxDJyydn$N1X0+t2IP1M-K`l?E?}r__rxj0K&55pkxInXI;m^xc zJWs16O;p%(m;36?Ge2Lcb7>b(JT_N)&56@59xV8xKcUx3U|cJ ze=wOVaC%qNx%I2BeqY78Dq-)PoALLHRwf9?F)*I=`enc56+5#cQ(x05=0mglnV1xMeab8n24W4^4Mt6mzzAeynAsTIE|W36ZQ`2;UOQa4S2wOv_rG>< zhm3Q@W}aDpUg_B6B})5xYkr;2Dyw#I$IE7hB-d>#IVSI1Y3waA>(Gz(4!_%X3r(aB zhTL+qe{flAb#92#SF5D63i-Px$JdDU|DrA7C*cV9Tr zASvT|K)2_`58WjtVV*}>xB83T%X6u)Y+q5g`*Wql#NA)==N|mfW7-qT`1^3~&i5|4 zm2QT0T>n-!9sK`(b)LeJfRpiaeP@gJ@H}Naxxg{2IQZAnfGv5d{J(u9zWfck*_XNT rg&_aEjvK#aJ-@HIH}$+i#i0bD+o}#dS%2!BEF4mVzRzoXI9U$>x7>1) literal 0 HcmV?d00001 diff --git a/config/systemCertificates/12d55845.0 b/config/systemCertificates/12d55845.0 new file mode 100644 index 0000000000000000000000000000000000000000..95500f6bd1373c2dce681e3779ac7647a84ef251 GIT binary patch literal 846 zcmXqLV)imbp7(EZg*cIAj~}vT2q`KpE>UpK*E1A15Cy4X7Upva4p9io z&j$)SDnu9?$cghB7#LU@8yFcH8W~zfiSrs6g1Ckz28M>FQIuQI#HfVqXhv2B<|amd z27@L>E~X|%Muz+AUrrC;Xb#_UCMosXgr+ygFY9C*oQi&P^Kk8Phl3I#-49+Emw9SE zwpa9=yvC1jy`9JD)OUX_EAppa(zNRcy4j_*@^4P z-Bq|BeN3xswcg%>wMV(7R40@a9j(q&NgLp&$0Xa zPdXO75i7c?_QoRA()q%lzY;MHAE&>*I%{^X?5ss6 zTx-sJA~0K0Ynx{H=YL>|WnyMzU|j5E;9$THj3HTJM#ldvtOm?L%770fzz-5& z0j35v16dHCk420{Az=xANbwf&S15*z;pelr>~hlUS#T)JUzuK&f|!LT!du298=T>o{t;X zuDlc3)}8lq;@7rQzjme>uZoO5_h`9TvHNN5Gcz}sdz^n9=Kb|NKTnZS`>_u$yMv2z zoxiGi%nC~19kT+H`dpb@E zJ-bvpvHPd3QE%#&mo*#1%U&JbreV2XG*#xrxAJLOT)pMoHzsnk^s(R8+{X28Zj-60 F004`~O?LnQ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/1ae85e5e.0 b/config/systemCertificates/1ae85e5e.0 new file mode 100644 index 0000000000000000000000000000000000000000..45a8215e1312759b1a2813c9f229b95e1845f55e GIT binary patch literal 612 zcmXqLVoES*Vq#yw%*4pV#KW5v&tb0-V;4B}eyjl(8;4e#$2nUTW+sEiiH6(;oNUaY zENsF|p}~fN2K*onhcJg{PEKZCerBG$hKxe?nSTHrAxg8W^UfNu-of9a-1`}GZ?rqDX>2axy832YSTKw z`Rzxy{m;Coy6?w=?Hr$7&S~A}P~ L_2|r;hb7ejGE}&$ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/1df5a75f.0 b/config/systemCertificates/1df5a75f.0 new file mode 100644 index 0000000000000000000000000000000000000000..1449f866336129f369b7dad1050d28facc41f037 GIT binary patch literal 1079 zcmXqLVlg&oVwPUO%*4pV#LU_J*?^agQ>)FR?K>|cBR4C9fv+LA0Vf-CC<~h~lZ&gN zsDUtu!^Oknq8n0FT3n*wo}1)hsBWMN5@zO+0}2O)28SpF<>!|uIOil57b_SmI6EpB zDHs_TSQ^NQ^BPzh8XA}ySQwj{T11KS8XtyH| z{>xjW-nyGcdA*%e%%XT<)m|RqtqiBsa*ky4Oo^I0EqzA2@D*wRE?#7bCr=pG;HoWkdHGfLxKgqi{ifbBAO}p3kcC!&{YKzIUXMe*5 zw#Jw3*WVz(dz6Wpk%4h>6QdL`M8pjEfpI7+%*gnkh1Gx=NEyh21o&9QSVaEb5;-#8 z;GW`MIVa0MtCN*IAAD>v-~&nXgVeJC(+`_L<7JS5JWJzggT@mEjSUOx7Syy=<)kDQ zSn2DhWEQ0+m*f{!>ZRzGfKrZLUTTTHv!5+A#i$w?fYJ<*0;d`vZ46>N0tq7!2Bsbz ze~@C3UZ4Od-RU^ny13dWrxulDre!84mZTP?mgNKK%>2BZ%;FLQ=LL=n?AvTJN=iU3 zC@(KZu{*gaM<42z_#&Xy@yVd%8gCq*oEUEu53*1Xs02Cv05b$I{V+1rPrq$&;{K93 zwTe{@1?NPBGCM@3Cb%%J+4R!De|Es3v>SE323rdZUp~q_{<+|`f@s?X-VgiMFqXEQ ztDEn;e|v)UoX@9ZAH`+dSUh+7Q-_30W{UqVY}p}xt7LKgmHQiJFs;eY⪙?DO#BN zPBrT3Go$C9?yvUz^?5?3@@q=W?IUYry9JM*yF;hsG zeQA?8+s)2)&(^j37I-D#N~Ff#=1*rds)O5dZ>V(?Tz@t3tliF22PWi29g8bTy&m&# G@go3thmqj` literal 0 HcmV?d00001 diff --git a/config/systemCertificates/1e1eab7c.0 b/config/systemCertificates/1e1eab7c.0 new file mode 100644 index 0000000000000000000000000000000000000000..f81b63aa1e1b222d41e2b079e2088f3680dbd977 GIT binary patch literal 967 zcmXqLVm@rp#I$+=GZP~d6CHzYMDH8?d{!96EGDKRG~KOd+nC$YF#!Pr1foY%m@ z(7?dZ(7?#j)GSJz*Vq`uH8M7}G_{Nx9FA;aR6-6sMpg#qCPsb+gC<5UrY1&4hP|be zKO`yTtE_uaRko&f?@g7fJGTEh`@!kK>xz!BxY@HpWPN$MzFj_F@Fi&Ljma#J-P#Hr zy|h1Q>4Y+0^Emv#(&Fu>7#n++J(Fz{SNomi-SGf$MW)m)WRxd35 zEtOro@yEH9oI0O^uO1e0+0nN2Ter65t;NP6H-8mLeOD5d>6n;ZpZ4@{R>KCB&-dG0 zJN`=6m$u8xZH4B5b`MwX97j74NC z^Y=3A#HK8vRT9CknH8t(|99>bawr3nC@_>68NzJePr17HR`I5Yed{KyouNMcALGUi zK@2;5pGYf~NY@>B7niA}x<2Nb?5#_cCqGZue9+c@k0p}-W8{^TR_~eXRaxXtx~-gk zuW6HX!TdSj))yMyt!7=Sb9v_}_iv{@eS5xkr-%I>vF!(Qzr5mH|K{`7=dAOV$#n$> zUYp!_reyNBowt^$vX)dv)j8NTd8-K;2kY?x)Y3XEdC2Q{u7GK2A9)yQoc1vUx(PYMuRdbS|yFzQ}f3+nG;lCc0UZ=FXD3 sVDKo`k7YxAw?bX{LEEWK7u{xA+f?kxUwDBxWl@Ekrr+elOF~4V0eot3SpWb4 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/1e8e7201.0 b/config/systemCertificates/1e8e7201.0 new file mode 100644 index 0000000000000000000000000000000000000000..232c4b6121f7236eb429572c591127e8aa60166f GIT binary patch literal 867 zcmXqLVvaXxVsc-=%*4pV#LdD01dNIi!5oVWc-c6$+C196^D;7WvoaX?7%CXZu`!3T za0`pO=j10P<^*S^=P3l`=a(orJ1XcZ1Q{C&8wi3_a0zoERKNt8kp&Ip#CZ)Y4U7#f z3=KdaN}SgSnM-Bcni!Rky~D`Lz}&>h&tTBR$i>ve$jER;wQNEqTZNL?*8|PlT25)q z`^#D;cyw(?(H}P^=i{5Y=CZ`AoYwPxn9$_*FlaSTqkBQl-IR;3zv?XJZ?fglUN`;v zHjy@g%H7t&4dp!?4?QnsCF#q@{hF3>zf*mx#eBBwb|+7(Me-Kk+i>Eg8eg;MvG>v4 zmsk=`c`noVmTCR%^a+iLPv>?ehMTV`5xG?_`;jk@3_*EunPN{PO=3Mc%Jd@cgsZLDb_S zlVPG{+>Yt**OqTjnN_tv{-E&t*-5{7a~_0bimhb6mG`oFa$(uA%+@AxCT2zk#>Gws z4hDR{_><*lWc<&<0!$HX2K*qtFo@4;zzn1eWI+OaEMhDo{U5yRSLnH_tn&@{l{~Ba z-lMzHdyqpJm}r2Z%*f#FaQi^Os(&YV-hZDK;_A738Uv@}n$5y(Z5r&xr?Q`w?A*nm zyKV{B<*y$<@^|eoPWNg)?owUxV0~UrKC@<@v8C(bz9&1wb5{Kkn)W96nC=smoSjpW zf8PntNDs4X-f`Yk@$kuvf9Gx;3SM<)Lf6X=v2Hz6?^Z=gm=bbRTvM6jq*l?z>U;6vh=ZpX(UQTUo1KYI8Vetr=}_-mlhSJ=9MTUrlb_578ffdmMD~$m+K`b z=B5^Lusr>O*BU4TTH@K!&gib2?fWnVT3JS(qD28%To0xP*lqofVwn8Wn=| z9Q6z}4b(xB%)$!J8Hu?`sYS&K`DqHy`ME&zlT#If^7Bg+bQO#Y3@i-f#Cd_Fg@K`= zk&&gTL6kVJv4w%TF^oI(Jk-Rbgd8c1tPIReO#BQ6O-x)&O-zgo>lscLm}@sgd0FLD zOsQR5FD3uY^y=Q*r+Hn9?9?_*2-=lwtr3yGbaU>MWuNb+@PvN*_WYBQQbXLsq+{DO zA2#NE+W)lHC@W-vk!0jQ`R?ns32m(^`HuxRm)j{!GgZvq%yF|oFXem7q~L3O8zyvh zJ#O!1yS#S--=moerQ7&!&Ene4ofyCt^l@H&*_+e+7vy-)&or==IpQi1vF6(47uTP@ zI?Bjiel74BbA6Y`Qs0cyoiF#y^OG$6YUDj9H$js7_nEn+clN8D?Vns>Sy>#X%6BT} zb-57x=@duzqRFcR4!`CsOEI}*xxGw~lef(E$jWuLS?jmfrs_|L5O@<)v%c=pHi?@T zX8T2X-d~xRO+_<_f9xK-~-`|o|qIPdHw&8zdpCAsqV^GvwR8GrL}m+6_x zC|^nQN!yPcT)X~DrOK>LjNBX7$4vX&VDvl2cE-mA_Fnh)t)HTIGjx`CUc%huoE^z0 z*EPmSm_C@Wd!LQJxzf(M*XQSzD=xFOX#DMQ%g|Q)ap%_yTldyI2sk3txmkIZfMM(H zb@}ftj3vqhnV1B}@vT+*QNF-TsSrSY~wZovWH8V&&|u@xW&@Uc>`aVeG8rW$1y=g{1^GFd$(3kj z8FG#U7L&jn$;dE4XuXo@p~aRT^zOaf`m&!i4sw>C=t5wn@UB|2?h*7L(V zV>@2(uRX8Ke^1pa?u`G^gIjgis9cI*zqjaoW=n$c3jto?mC6@dpY~NRn`c`jTx9%p zRqe54d5$mt80%HeYwLt?-g~5-JL#CEzt}6Ax+=FTu32s?UY9n7EnmH$CPUcx+gyVW z`RbM`%32ftPS7;{H2J>C(qrF$yzk*p@~T;P`D@6J-fgqO+Qpizj8{h~aeQyu^-Ax7 z`>ZWnT^F-j-@K#e>R|oqPW=n(*B9TY-7sBZaMWr|_`JW8Zw(?J zF6!)T{d!~Z#uG~wpUMbNf5*4?zUIpJCc)8{pJWNQux&G9Iuf)_>C&A|icV6u96o5C ze8a^P^XS5^Gai@Cxy}f2byaS#WvMbpLfbvyT6;2(?xk%c6`u1$Qfv} zDM$3fQswK-B~PB}o%}aL-RaosWAip#h_+ZdJK$cO#Eh-3*54|(y!b9v&DQ+;LierR z$M;IC=E%2c$ab)ol-!lt^=#kOn9F9@-#Y}UBv_=g7{2NM+;r^T&d|@+h7+UiY~>JL jTc*mzTdmjrh-Vqw9yNhn^SN*CR`k>~9Q|;!+~WcO<#gK$ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/1f58a078.0 b/config/systemCertificates/1f58a078.0 new file mode 100644 index 0000000000000000000000000000000000000000..3e49eba74782a8bcac1c87f76f3809872b98ddd0 GIT binary patch literal 1380 zcmXqLVofk;V)j_T%*4pVB;pcoq7vQMIotHpxgFZp(aY67lxi68vT19KA-KZ8LN z6Bknx6C=aIb*h^fCGLcG*t@;{x&F~><-$j^E+(ca#;;nh9{4m*TI`B$ZNP@$^1T&S z36D~kX4kaMz9!YT_P@Mn{ne>*LZ_dJw6Gk!Z?;)%e%IrZw`Z7~yJ0M@;r3_w$q$#d zT=nHF^8ER!{qf3MwF_&rH(9B!%nfo`^J8D$?>oziCr(IQ#w?=n>3RF&jEn)AMhC83rT-&ocbpMgx(TsPM6&FS@^c}vCCHz+Sv5~;EZPmkJCes&(2#TxgvC#E87KStJ|+r zW3>bYKUn*p%Kc(;r0~gqhNy2b>y#5(i$6XQ*r>Yh>ZIMm2YDV?-r8arzICpeb2ZWH@t!#jcLSb-knS{u>pOw5c7jEkKN91Qq@DOOgPk?}tZs{u2R zGT;LV@Phey9JPd()N{$kVR`FGO|>vl1&I-ccd zJ>d#R%%+5_2_H_JV@~?n{q}dB)*Uuq8%_RBv91Uo5B?V|iLY#mmX$woTGz4IIij*| z-KnL)yen-B_9{pwF3GX@<81Wsp!@$HZ$1ht8BLpW=v#E=v}y$&XUAF5-y$VD?uB-k z2Xa@$aLFxp`g?qC2mgUj6-+82lh=2)cbxQUkbQL_&n{8VY_}<&`n11kCf12X#UI6D z+}T1r8LA?LHgLUf{kw68acS0M8KGwharv_KC*_q-w3=If!j*)Sx4ih2Y)hR;xt$s@qw4|YSFQcHJR0iznZz8Nz9A$ znQ}C4-3z|B?)~4-K6ty3Pulohh{Qkseedg9vYj6n%(xv}x`{WEy;W4%^4iDyE7ka~ zc^u!oOzEq!dDK+*`PI85MDzb&6G>_Iyu_8Rc$?oeIYC3|@y4mmXIq!u)#rbn9+bCR zzqRJ8SMl?sb_ez<3bES%+0N|A6n#SV*`pAPua)gRvca4DTC3SCj_dsRv7x9}^=Wy~ z7iJlcWdZRW3I=(fnw(eLPH%Z0{9Ey$KfltfwjGgL-`s5_J9J;PKAiWal_P6oj>$>c UHy+y76>rmy^i^gy->dHd0ROW{V*mgE literal 0 HcmV?d00001 diff --git a/config/systemCertificates/219d9499.0 b/config/systemCertificates/219d9499.0 new file mode 100644 index 0000000000000000000000000000000000000000..3cd289bdff9d0a2185b4271ebd7d1e278714a542 GIT binary patch literal 1028 zcmXqLVqq|7VtTQFnTe5!iIKs8myJ`a&7D}zC@A-4f18*?ZNn=n&ou%V)X zJcz?3ED@5Cs^Ffl;F6eIwpbt{QEvx~TcFsvGE>kPAtjH&r@(LEy>6)$}FigkQ3)MFflMQvNSXYk_J)YyvE2}`Z%JAQ32WWjI0dI zO^m$2z+vQIYGPz$xHtFut8fX=h0(9C$9uHB+IRQ=llSQ|Us5wRhZio0E8qQgw&%-& z2HP-+WRCn>pUzycuV)HT3K6)msqxBzQd{r(6#DppG|Z&k?F&(hv_w4?6GZn+Hy zZ@8-GuQHGL-mZ52hVHkO;@jnm%>0&#+o#T$bXzMgcG16%2i*7SpZ1DAe0|#L>LZ~= z!n!y5*2fFkF5qD0*cP)i)q=%!rrhF$gp#9rVyq zO5gg1!@pKX{aNU+xmt?Ed~^>0rNBbXPRIhS;Mifi%K{jMifwq9*wTB}@{*}G$#@453n zr;L?f$aJil+wGVqc2ePK=e)Dlw+g=3%~Vqm2~l00SKRt+w&Gl_oF={%KMwKy5|GQ8 z_P(9>2!CSt+IP*`Q-AbLYALdOt?;V(ZS&dbc^rFQ`>Aa!)_!vNo6kSB!bgdMC0_r- zrP}#RJ@n28W{NLh5=xwU^`gTj0iSnA)(AK+TRM;H>eQrJyyrWbjvDbi(Vp-6jCa1q UoQ*rRqQcjj^RJh!zrA-p0Q?z-P5=M^ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/23f4c490.0 b/config/systemCertificates/23f4c490.0 new file mode 100644 index 0000000000000000000000000000000000000000..53a86ac2a010c22a604a8955755060c9c2b7cb1e GIT binary patch literal 1043 zcmXqLV&OMvV*0*-nTe5!iIKs8myJ`a&7D}zCXA-4f18*?ZNn=n&ou%W7f zGKj+^EE8OkSd^BTnvIsU;t9aEv$)9=A4sQT&!TE z;G9}il9`s7oLG{XpQqqhT9T1plvz?~AScdiU}9iqWNBz_Y-wl~CC+P%%%!7Cniv(3 zgMpEifw_s1m%*Tkk%Os;k&$7$(TRUA3zxC9uH_L-xqr_0{Rw7?cKd~^f7>jZ|Kae$ zTUT!6X$MdEt+K?f<-@!e@o%20yL{DHW?y~pf!2o;>x1>@onmF2EZ3hVW4YY-SJbv* z7S*)Z<@L`ak9o~h6$yE*cKma_ z+08VYjXQQW{hecFCvd|0JzHv8)oe)#+y8}uHU@g}`)tdLH^s8$999mSrQNDFNoG0I z<|p>N>p3c$c9_||nseE7^PbF8U(d{a@i(Pcyummx&MS82NxAkdbEOVk%@a0Nj=MiQ z-uC^q?`4Nx+3l|2m2pbXX1Vd>+O7QVPc91>S2Hm(FK#?)(0Ir|78uL2d@N!tBKzaF zUp#kLzU@nN=$bp%1rG78?09a_I0+=L%+lCp(AeI9Rn5YjC0X=~+9qHE=K;A%n1$7V znUV27ay$c*J20LZ8Cd7qcg($bQYv)en#|9iBX7-SY?ty6U%9Z7Q|tD3{Y`Rbj>l!) zXl`FP{k^BDT{)X$MAH7gh#g$%_HQ=dRZNpV8S<;>jIEEujmGum^O~!6FFO9!M7-~& zpu?9xI$FM>^~;lD^;9o2a4Sg3X8aW2@nvuKTaC!OzGB_t%_lac9@ni}x@u2wTkhTP zC8vHUIC5uv`0~4CUs!Ba<=3CGt&er5?)zFe!TC(D{455pcFmWeN)ZgouO16IYeu_s z-0gA9N@ZK|RB@H#mZ^$Uch+7sSuK2R?VdZ2Y%S03wJR-HC=tngQfW*7oU3tK*OzX) b!j=1DyMv(HEcr^lr2YKU-#pNl7oP$Erje6H literal 0 HcmV?d00001 diff --git a/config/systemCertificates/27af790d.0 b/config/systemCertificates/27af790d.0 new file mode 100644 index 0000000000000000000000000000000000000000..75dfaf39fddbbd46f687e0324a3a5811372b0e3f GIT binary patch literal 690 zcmXqLVp?a=#ALdFnTe5!Nx){)7Y{CmNB>@{SjQ#U9nLo3V&l+i^EhYA!pv;YIKzRh;S%O`Pt6Z0DlINi@XSlrGqf}?2Z?hF8)zhJDi|3Um@A+t zP|#Iy%P&$$EG@~%FUqV+O;IQj)^y%uOt+RB%o$D#=XC zOinDx%+FJBglI0Q1RCaUWFRNbYhZ3@Xkcmp22tX?#uf&Kh89M~rk19bQG?m(Wd;Il z?BFnFVq|00Ze(FlVoqXU5#9LWFSDrg(>1T#%>|R*UurfBs&x(L_Uf$;v9`*K7iBsS zu1~eA{MUD#I~Un_ zdrXuKc%ydzT7uqQ#l=nr4hHFV8?faItY{wRxPgWnpGE2ryJJ zP-0^aW#JZGeqAijbzXF! zJ=KIuzUuC48{>sX=lU+mcbsZbe^RdH^~HIfliH`W^H{ZdrOlrkIoWr5B3ql+VkZL! z13qA=$nrBX{%2tU1~;1lKZq|3;kJQGfj`#uh>s1x_GJG%e!}} z`NI52lP)}vaXlW%KME}v#q?GC%S;CWoE zA9wSd=rYX(oN9_$NlXTXm$vrDys~~+!P&Z^bdvRnn7Ur)s&z|Lp SnIFGfKh!$?Q~Pt;1akl<_O(j@ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/2d9dafe4.0 b/config/systemCertificates/2d9dafe4.0 new file mode 100644 index 0000000000000000000000000000000000000000..24e5adbb0d859d830f2c27e62342850b2b35399a GIT binary patch literal 1373 zcmXqLVvRItVs>1>%*4n9L*4Ezka4LI4DLs{5_nf&|>Weuc3 z94;Oar_#!T#NuKF$6#Gc3u8kwV`C$8Lj?mlkTf%oI853(2c*bYAt*n;M8Vn7Ku(<3 z(7@2Z$jrdP$imbjN}SgOnM-y1nwXT3y~N1Mz}&>d&tTBR#KqLa#K^Gp7S~j775ue>tg;F2s6Ci_|>?|`&#G^)?V+-4PQ5Fn8k=32`u)_=Kg5H zep}q~`W=nx?631b>mBqL*An=A=G2SVf3sKX&6=;l>a@=X;-<|xeB}M%n(S_?%KFWo=WQQ#&R<~Q-MVwm z6qU;U+U%9C8T{H8KHic!ow?(bXHxEo3&}}$6Zj)m^)KARx-@OkdFirEEh!s)EQ1ah z?E28-&9q_Lb|z*<2FArs1`Y=Nz?3U1%*gnkh1Gx=NEyh21o&9QSVY`+oc;ea|J{#G zZ}k26eyVQhv&lYezz34%2dQTP<{dWVR0hmAz*NS_z@VV)Xv#9-kV8_!`$wie*X`Fl zGMTVrVSd>!F|j2c<~lDY9QtJQgKPec#;3cZZ>j1mSsq%bV)X3<_oqEsKPIo)#C|A# z{_Qg-x>oJW%75r7aK`X@!|vTDZY<(U34gWd>!Fo~qL&o1-uzKw)HvU^qd{)v8NsDC zpTsu1&;4_$LGj4x3+@Gu3r{sma_HoKiY=ehB_e#qOlH!Dr)=hTmOYy=+oC@vTiUJ7 z*(u(Rkv%vhHnsM9SMkDGAyM+0&LZlETKTtjR7+V;*)E%~eCwR&nwjBIvnN+M8%Q%> zPdeeSY}KEXCtlYl1~aZu=*XKB@3QlBLZiu>{L8hsJmOz(nXpH9r408PnX8L36dG8r z{n^;BzuU`@*Q-tD^&>M)wXe5s9Qjn5c)o63S+ZA^L+a%AA94*nZBN^-_4EA+)=79F zmMFEz&bj)mWkN{S*H4{lj2X=yi;Q2KWSO{0&_vMg)dgosdFIIzc>V|4hJSI)dw6=m zzSk#{&*q+a^22OZ#@x4iW2YCm@NVNXz4MSKcK3q7DW~hiUJL3kp5%JMr|{;UlQV%%ZK)2w-M7YFQ+6NTy+5_$Qd{MJPiv`Wo)7mb-kkX4>mzlqN%P0S zs9SH}JyVZ+;d)`NOyG)))h>@ObZ0&OVZHl~@AZ^Vf%~4VS{?P$@EzNp;{C!&T=S3b GoDKkgi$p^J literal 0 HcmV?d00001 diff --git a/config/systemCertificates/2fa87019.0 b/config/systemCertificates/2fa87019.0 new file mode 100644 index 0000000000000000000000000000000000000000..13ce65e936bc95eed9275bde0a2ed38cce235f2d GIT binary patch literal 1002 zcmXqLVt!`O#B^=}GZP~dlR)@sn1imhek0DbFv;RtV0|DJ{v&&ns5&(eu%B)-yCP&;u!9 z7FNep;+$Gkl9`s7oLG{o;8Zl`k>Sanx=9AP$8Pj#bMJ9G_dtExy?Z}@30<}^ zF5b+dzo)S0>HKX<33lI*D*FB_!05-J$(J)1DW7xPc;?Afd9#aMRzG@@ABjX}zU94KpZ#J7^Hcw zJy`eY{WsqBa(ZOuk95g(lM|=8h+Zz*V817;_Kin<@8Q*}3blhX9fM7_ZrFL0jqAt; z*RPJTd7ZA+w$^GrC5N6~x>&nO@XGH9Bc)jlC-3~_d08LFJpG(CgGjr2fyK(cyv^!m zGXfv5K2}^Ub+uK=Msw>dv7-$uzUA__tW=00a#f{Sq8mAb@0^?Vf zk420{MA6{nZ-(oBGj6r7(z>u*Z=-|ZavuXekTgFd<9`+wU>ajH;0N)AL3~yNW*}t{ z1QL*E@iy=@a9`lMz`4yaqokz3N?$*@C`T_ZwWK&dr?@yrFF8L~ADV>Vi3}+L!PAc( zP#bdG0h28-?id+%uk(JsJ^Xe3D&6hH?yXq|pDdMq^4#X-m&nxetyR%cy{cvps;28% z90*Tnp25~Ue`i@$UciH09Xfwp&q!>TIW>^)jqHw&|Lp-XO@|&oFlyMpfZP4VVZ-+` z(~TPZ#T6@gGGp$=nXF^ls`e`2e!WDh&dE>74_C7Pt0|PvHde`!WBtyWaUe_Rv|e1| z>2(^H>ke&6o2V9Vqo)#oI)eYT#+&tm(>~v+&Oflc<5O_?=7hL)>ojhe>g1caURHZ} z?@hG7dbU{2UKbXLrp=v|;sS-XRg1*@zA~O&l9QUT(6cPY`Q(i~X6ZRgr)<4)X6N24 Z(=f$*Hx9r4eR@fP&xX(i3#!960RX_ofnWdt literal 0 HcmV?d00001 diff --git a/config/systemCertificates/302904dd.0 b/config/systemCertificates/302904dd.0 new file mode 100644 index 0000000000000000000000000000000000000000..72e48c301e6035cbc5fe075b21fd5faf21eda1c4 GIT binary patch literal 1631 zcmXqLVv9CtVsT!;%*4pVB*<{;rF7@VP-fo6&m41)JYM$DfR~L^tIebBJ1-+6H!Fid zlp(hPCmVAp3!5;LTaclUfdGiZ#lz{6k(pbWUy@mDC}SW66659(HZU+SQZTVFG%+(a zurLJjjLi%s4a7mR%sc|lsYNB3>3N9?LHYS53eJuOa^k#(#z19;1{TIfM&?oCyvE2} zn%dpOq=f8MMpg#qCMJFcgC-^}rY0svhO-iusZx;}U!{og^-NKjTGM>_sHNH+p7&zm zz1MH7S?pBbbn5Nd=-YhTb>F&jh;O>N`SdmMpdyXieSY)0wsHTQ*D}ku?4FWl%%#nj z*z61}SC%ZE6ehDU--k;fcfNAfmSeYcp2+Il*{pFv_>+$xljp(^hk4JQvM$hVIq`o+ z&V|=qQY{>E+cT8kDPJu(mm8QV@NQw%p^Hj}hniY1eF`lLs8Ovt*%HIO=B|^U_VcDi zDxIe%Y`XAHc~_dx?xZC@gQHTaYi9gf>@kmj>bm6;U$WllF}tq+Q1V0TY*p;VeJ*N7 znjb%Y%{f!Yq{ux#e~JCRxxtUl*RIs5iIAH9(AL~sB2D9x!_mO5p2NE5f;&_qQVhh7 zu6l5dYnj9Sif><8YBGge_FTNUob5d0_lyH8!gpIGu4U<&{CMr354T-%Bky=du3Ix} zrkR0bb(yhJ`{F~B+VXxDyj$1aK2`ci)n3ETS1vuB`G23so6@fpVzSE$4%XX9FP!xI z{0W_w+)bJb3UUOj)fGKhn7 zCcBDmifZ;U#mw1RcT0S;r&l@dT`m4|g1AS&*-zc8M{mDd)#~c_>#UXQ#*AlXKC>r; zzfs=V&T;4n=f~-7S{lBON)FsQ(sTR%qlMy;=Tss~3~$x{HORer=V8{vKk-b=j0}v6 zn;4}Gni$0l_<>1SR+y3TKMSh?GmtXi0}1eh1XzF>iOoP3#OGrXV-b;P4||YT{!Ycz z#;Oq0h#l&Bn;e%Fe_n zrkqhyQc!HAuU`%XddbkNq?cBtpIBOwUzAyrTC8u73o=EXCCwnkK!1Vm0_`?UkS?I6 zQdhmm2*j(Pqc9#7>^ zdVV&;@w-gu)f$FJx>lXB85a71O59$(r(f=lwc8zIyHVrcli*O{^9v_PGs(uMxp5k6 zJmgiGUT|4J{#8o&wB50{o*(J)_epV+jcI=zdC%$M>=kv(I`8(&oHS^9Ydz=eftQjG zvTiVyny>zDqMEi@7#$Oi%dwvRLy<2a4IN)-Bym6&X+lpe>2|Wtiii*XR z_pzrwt(e5Si}Aqg9+|ZLYud^gr|`~s_R_Lfepz78OdiYfhg)X7Up(i242k%eu>O|B z5`7KVJ5>uh+G0OjKmV_3+VCgEdCIfLGWq+~@@XZ{)IM3)`mOK<8}rnE_xe3#qOMGO zq5bZ;;q6^4S?x2PAB}%syIkoz;|<@Rofr6Ku|_VLH{)i$_Njt>DThKAe|fq7@FdMU z9bzgoZF<#aY>VE0=G=C3_P=U3XSAyPk5p!!^>*&u6;I+U&Rq}U&A()yyOA~9^IX?N zx8g6~^gpa9F6T>Kv#>WUD6`HxgXg%Mxq9=`p5shUM9z9LZYbXT_t*rh{7X4+t>3+w zxNnhjY&U~fnyO2|JqP|DHKN}aowK!^nOUv$gA NE73A;ovl~TUI3Z=my-Yh literal 0 HcmV?d00001 diff --git a/config/systemCertificates/304d27c3.0 b/config/systemCertificates/304d27c3.0 new file mode 100644 index 0000000000000000000000000000000000000000..507b8428b59681a113d25ccc2e355636521b74a9 GIT binary patch literal 1354 zcmXqLVs$fUV%A&0%*4pVBoKRlNOD7YIb z1m)+K7|4n98k!jx8yXsbL6kVJiGiV!F^o&8@l8xh$PQ*?WngY%;%6{uV&Y(&&&(hrbq}h)8tkgc3F0Lf2{r0D3=j25d zdnaWtSj@Yq?$qSX%P#hqUM>A8{_VW$(Wg~!$|o=AS6;^_#azGd%7wRj)vMi6-VG0Xe;Fxn%ir!X zm1CoeUu%yQQ;358{r%zo)>ab~uOC!14N-V=+}{1o`>6fiRR`BviwDFc-Qf53x}*Io zZ%^^0vu}|ceM&$YY@cH%M<#Ix0Q{jSpAFDN6yr(4Y2zu>9qf~ZG6rLu(& zEiHm89L_XPzRopoZghXwlcx_no_K6>KkKJes#X0->D$SDoD-*oS9Nr(c~`LJ=N-+* zJTlfoelFLR`)yD=@%g6I^obd--uJq(T?%uJm}SGm-@JoW^|0l6>m??g+bf0i-H$$B zIX&~wvhwt;_p3ivrHVdD3`=EVW@KPo>}23zzz0mDviyvU|5;do37-v|jAeyEd{zTy zAY~v6QozR|#v;;qr02}nCkFqQ@^HlWh^8x+Fy6n9oXUXN0+`Ae8H7`nzV>Oab$N37 z|IUnOhZ{U>S*m|2>sP%syS3?D?zd<2p2kP?pEfsIcp`P%ItyDXUf(y`mx0OHQ47>%VJPO4)tvq}8ec6m&2EMb>znHi8HAL{K+XwxgvglM?>d9*@w|1HqepWl+ zU;eC7{ZhI0ERp=mFW)XaygX&sh48?=>a4s6|DF&sc$eQRsLe6=%9Z^Mt|GHKTy7b> z+OqudyZ6yeSM9E?t(bH>#^&>lwZC>`*B>#{*v2H<6{0g|gLrY@1@pxsHZ!I&@My9| z&-3)$7=Qfn>GSHTeWv2u!%rC8bd269vhBqo{wapbr_4B$^?K_=^{)ae7+>@WCB5i4 zv$fuB`hnR3X%HkEnl7^z@AAyl$n3xVG=42h zTS~sv0-mEBN#`0CU-;b#AC>({t1 zv@$;NGs4=%f8!~pPL^pJ8ArW$sCDkXW~?7@_1~<{T@prsC%f_kI=F#?@mywa1mBFC#k|DPNCmVAp3!5-gNRXj~ zff$IxF3j(qnpBmlpsV1WpPZPQlWFK=-~f{061EH}Ey~WUOjU5o%*o6xPR&s$OH~L- z&Cbiu$gIid|I}s=moLW?p znU1$|aU;RgAbr6g`xFcf zkyJa{u|?TYf^1eMOa+PCR({+2&TkC(kh1 z?cuwZKi~L^GchwVFfInBVgp%VqLSrf5n~ZawLjj~cFg9kO-PLC539F9JnrEq4ER9O z{EUqMSy+IXhRuK<#1{tfSq+$h6mlp7vk)+p85y+fAAU6ITla8AjCb7mY`HAXOG+z+ zj>m=97Kf!Yv{X%g!nsr6?0hZthYaQWJWiOdXq^9KhtA1*z73bW&0}BfyviMCviD1| z=Ha($qI2pvg1aJmFL-O*Ke+k6!snllA6wl&GiS;TKmWto;@iI$y;z%Oyj3-L^@ATi zE9d_G#Jg+V&YP=_W&fPKd)?|C(`}fgb~zuLw$ru9V)OEa(`+YJ*Bwv{_Gy3ni92L! z;N+`HOL@CKPUf=<;oETIq~D!ShDKqpQhvVLI#(>sspxb4<&B2Uf0p!#f6P^0JtghO v+TZ*fd1|`#;_RH8dVU8Sm_M!e{I3m*dj5fQ47 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/33ee480d.0 b/config/systemCertificates/33ee480d.0 new file mode 100644 index 0000000000000000000000000000000000000000..1dd645cc4cdb3e5b9559e20346922dc459a2eac8 GIT binary patch literal 1505 zcmc&zSyYk<7-e%sCC5UPP{dFZbAG_BCQ{1MmZ1_UEz^j>JyC>QGDRoIYNk{)_2j;e zX=7??B9pllsnar^(rWN%S|(_=Xl_U&^VGw<&(nAAz280OJKwn%NYj!7Y0%yhC`BK8O^M@&Q9_J$sS2Xu%K+hHHUg{dLY1t1YgL|5`w^44RfhEBw9;QxGG8U*+4 zyTDo?Xc`0o0@5J*kTeJww1kkC6VCNNu~$!r2&*O?(UQ2a@%j3S>E(SVGJB4CMWEs$ z&U{)GPf!qD$Rc=f_mS)()1QTpj?8{Su7Xa@oC+g`FP!)M)&O2j=_v?v{KlxGra2^iSd%6%}`DPaYfu=@Hr!zszEVqfTk#@_~8 z`%1;>%FbNrFH4vgxbvHM4`7t=n$6+?<(=bW>LC0LCqG%IwQnIh&$!#IAekbHtVDQ- zk|1*dkb`#pzsD3Kw#mq9W4yCMCFwm$d69&A)>t#hkB4$`ecQS%XC2-+)+`q}v>e{E zS`U4$I2o!CB3&YcQx^A{KafB_) z?6GRfX0b2kdWu->6mp)HuT(X~>ye`+!BuBw(6LJMO2ZzU2{!wPKFuML*0B1xKu=Oe zp1A;lf` zEm^OMOGUUAwyn{0OYzQ=6CqvAFRAdJ!OKjvblEbKFyyHdDA`>1qIYVR?tM%t_-N;6 V_2(^Z#)_>wJtMjXW^vTE?H>b?c2xiX literal 0 HcmV?d00001 diff --git a/config/systemCertificates/343eb6cb.0 b/config/systemCertificates/343eb6cb.0 new file mode 100644 index 0000000000000000000000000000000000000000..da61112c93babb53080276db8b0ebddc4b3a247c GIT binary patch literal 933 zcmXqLVqR#_#MHTfnTe5!iJOH12pIWWSLu2f@Un4gwRyCC=VfGMWo0n1Hk2?BV`C0w z;S%O|u1rcTDk&;0F40l&%u6qnvDWs<7|ZqHeiS`t-m7g!ti?T+%cD{tc?Hk$ih_2kR@n$>>oQqLvzV~_ru z&7YCFK-lk?R?6(F6NJu-uzj(9d_`m53%(z#{XC}R_DwYuh>q57W7Kf1da6$WHrQ@4~P@O;tquu7H6o`!svsZ`nKgw^#ElwRnBc z{r1&Z%Re2`S>Dgk@ft5UCVl0O%Da6PQ8=d^#1Pta^E>gCzFfCE@<+5uJrh@ zdDZruqst8}9b(rVc@(P_{NbF8GDqTyDU!Qbk{sU1TNIQFu@x>ikcd@PU&_SH$iTR` zaj8M$A_G2PJjwDiGX7^_0me9+0Y8W@4C1pIFas%YM9T89h_Q%lr!CAV z?)>V!R^5Vd1ACBqc@_%;GXs+aMhgtu^fF3H3as??%gf7+^a@Ioax#;3!6`#8IX_oF zxhO|Jxde!cfT=(a$TN@!8KBGpOiK;eZ9q+Sz?fuY2z$?^ydcDH>hzO8I&Zliyt0@< z^^3gl>g|hLBQg&eti2)HrTh5g*~X|J#mZ63Ygj-3RkG&0$adtmnNKlG-_s3BPmX@p zTY6LZ@eV&Ph2?onD)W^R(yO~=i#U%O#=NYY-{5Y$b|E*rh^_m7=1eIbZkOlDs>|y) zo!n8@@>cmDob8x2Jxv^hsVYv2t<{f5_eD-SaQ@FApw0 zeEPq^n;MoKH(cZ=#}{%cZO^lNCBy7DS4tuAccb~6xIbL3tFJ#7552J9Rl@9L-yZiw vYaU`t5Sgnx-Dl-w(Yc977~?&zMeGeT6!H^1q4;34;KbD1Tb6ZLoC^g2kq>3m literal 0 HcmV?d00001 diff --git a/config/systemCertificates/35105088.0 b/config/systemCertificates/35105088.0 new file mode 100644 index 0000000000000000000000000000000000000000..2fa45b280e22a9fe641b25ffb3f7d866bebec657 GIT binary patch literal 1506 zcmXqLV!db3#C&W4GZP~dlK|u2T!TN0PX(@!-jl*-%B*X^%f_kI=F#?@mywZ&mBFB~ z!;ss6lZ`o)g-w_#G}utsKoG>?5a#krEm!bLEhlW?@yZTv2Ipi9%4Yqk?m4QAuW6 zW^!UlW`3T6V`)i7ei6_-137VCLjwaN10VqcQR2MD76yif7DmRVmZp|bgUP8)OiIWB z$;isU+{DDsV9>24f>r`tqA z?DrV|tIL`5Uu>?#-oQT7Wy{k}6s6x*Oxt*6b_Mf+0IL^gKHS+e&*$HI)@i2l;ZfWF zpZjUMU1!_3kh>?I3t9QD^Xb|iGi%Fs1=~~gN+#>-tTWOWU7j=gxdqQQPWV1$U$FUv zV&~6BhlAhWUiGiUFY|bIPr~GTM~?H{e`vJs%w+4pimB<{?`*^V@m$E{m*)Shs+Mh> z`#sP7SF!WcI=-c88#QZ;T9QLMkMJIx9AY3TyykMP`SRDXRyn3Iw;itw-CF6%eg8&7 z7w6=pzO8BJRXfhM?AU0(#FGCe)4bP0K2vKxXS1%16Kg)RBmL0};kjp`n=booejEM& z-qYeW%GSCJ`%ObjI6ZH8Mo869GJ6&{iSM&ot&Feuo|A8!)h_IJjCWY+;__wY^YHe0 z0rKG?EA0N3BV7E?r~I6|>Cbb>GTyIJ(92db)!TkcA+&naiHzi{X3 z8`~?tcH5t6y_R3UQuqE&rte>;&)RBw>u~ypcCVEh^OXDk$EasN+~EJ2{T+kemB{wf zL5@>jeR043F2ymlrZfNNdhjzY;(kN+JI(z$s<2>y5zjm6H7+upixM2hLgE>Bj zWv=~soVnHAtxTH9Z}wV-32o#c53jT?VXOxPVeQ|W8avxuYe g9fr>DI%KaO>$7prl3gxwuhv%VW75x46IT2M0J!OJYGZP~dlK_YHgRlusZW|YtW}S?jc-+f?myJ`a&7D}zCz zA-4f18*?ZNn=n&ou%W1dFo?q?%;S=op6Q%gRHERSmux6$APy4d78WQkFV{-}N+koO z^pf*)4HXRJKvK-Y;&2`AIr&M6ISN7f`6UX@js|k#yar~5hK2?Z5GBrQ4CKMN^l(BG zqY|>m8Ce;an;7{S44N3Zn3@dd`IJs!)JE3#aq8T|A z&M;11?q{$)_`CCwOos5ek9w8vwzD}fG;*FhC*8dN{#olnw@25~jV;t*_#-WJ|60ik06Z{$usNcN*7A>Z>YdMz&_;#V8wj@Ao_KA}aTB!TxfA z{eKw0wccFeA`oG;vQ*;g#YOwvAE{@3nPvRLlOv(~O8ge9mi-G?dHK}Zo%fH=DT`a+ zZ9Z|{9i?Zv=R~CXvQGayyICYf{CKqHJfr=e-u=4F?Q~`Jc1NRIJXhZTXuP_+H^P3a z^b1doMFqDES?+${B=*UN%a47$hjQ?3! zfC;G0fFHyc2Ju-9n1PgmEJ%QlMT|v+`Cfo&*hQb+X&)9pl9oO^eUt6QPy>08v@(l? zfmj1}1*qu{7!8aJr{|cj@(>o{`gPZ3j(^aGFZb86e66hHSga!P$6LGQfbPz#$Nzmf zC?9cpNA8@elIJrtR|{@^T(Dr_S)Y!XlY1r>JX*~!vv2as|H)UMuqRwzynk*q=f|sk zkAuJTCI7NtetS#W{iL*O7xNr@Kk06LRqi!^Zp0()$O8__Z*?`AT67HFks3>ujWo?Cxj#WeU z^4IG{MPAb-4oIsket75QefOHJTU0n$4c_SP<=*eQKVav| c&#z}N3avfSacqW3d@q;Hv6ok;PR+ds0Q5R@5qwPB{BO@y-gF%!bw*e;`b0`a&Fq5aN zp^$+9h{Gk!>6DmLl9`)dlxiq!AP5rU7UpuUOiC>ZDJm^4F;p^800}Y+OTrZ@Afy$7 z^7Bg!!|F<^IChw;MQFb8lbttNLc@n^wolb5B&#(PO+Vy_3-8?#l#`0j4ZA-VJ!F6KYLwB<*Txh2chm4;Ok`xj_^5t{jZv1`*~o4BuY=WRVPuSW00l6ig{BHp=w z3v#oilJ}-Oliz;s!>9RryQQ~(3g{@Fbm-AzvEErmOso4O?!FWdd{<|>dct};gDF)P zjBS^v@_+r)H!tbDyNeEE>~7huMwi?#S?FE(*LcS$OK$5so2!4GH_A#LR&jcjY`GEu Dq-#{f literal 0 HcmV?d00001 diff --git a/config/systemCertificates/3c6676aa.0 b/config/systemCertificates/3c6676aa.0 new file mode 100644 index 0000000000000000000000000000000000000000..d189e90bf84570e394fafe9e8553d8401ee84f92 GIT binary patch literal 1396 zcmXqLVl6OeVvbnA%*4pV#KJIRTCV{w8>d#AN85K^Mn-N{27?GgZUas>=1>+kVJ1Hx zLpcK(5QmFLG`J)&u|y#ywMfA)6-eeJ=B1?O8EP7+gXEcc6tK!GxP~bN<>!|uI6E51 ziSrs77#bN^7#bQ{8d*k(^BNgJxduiSQ8cu@wU2T+-$0o`Q{GilE;B7RJAL2aM(VWxT~f0SnHBg&ra$EFFC0q_ct`HFjnVi zLI%tBn}>qbEIO84vvyc^=&b$O8Iw1Mh(t^ay&CYZZS9ie`k3}_eb3Yf8>qcseMw$m!Ox@hVwsK1?r-HXdW#nNZc;n8D7${hdh6;Zp#s;?$M=il%)ct;Oz1O>I(b?7_2mQmD%Ln@ zM5HZs%PnBKF7VSkQ(7v{}BKh_GDF#X@X@aZpxN||M8jvX-x;mhz8>-=(ghr_$i zL~(_BTU(R`?nv%#nIiTq>@yQHBLm}NCj$oqeqdsj6=r1o&%$cJ45SSBKmzoYHLd)_lXx@PU64yIbR?WRlz6He|w@?y%pE05EQ4bq?c z_Q^Ud-f7lv*CZts*YPUgN93bsH%;!xE-??MZp)l7OC*2#y2kSv?`O{1xApnM`X9f9 z-Nk&)rh}>*{+%!+n;x9emI%$K&HG@6RUr=;w+rR!s{xRXSH*Tbo~{K7o13E0uQpn|p7* O{1hMHDf8~lbv*zZq*{Ui literal 0 HcmV?d00001 diff --git a/config/systemCertificates/3c860d51.0 b/config/systemCertificates/3c860d51.0 new file mode 100644 index 0000000000000000000000000000000000000000..4f228c2e26cc126a09cb156d66403d1594a98033 GIT binary patch literal 1470 zcmXqLV%=rX#Jp$$GZP~d6DPxN2N~zDasC?&c-c6$+C196^D;8BvN9OB8gd(OvN4CU zun99cdl-ru2!l9W!aTv{nZ?Dyndx~7j_!u?2C^VwW??aeuzP+^ih{GFg06zQk%62z zuYsANfsv_!g|UILX_PpxF*280)-*9GA$x$4m4Ug5iJ!rsiHVD;iHVV6{gZcf-70)S zc`E~S#ayf>O^P|SBerFdld#sF)bJ(;yKt4W0o|%v+w=dtUv%MsJd=u-@U(tq;b$5V z42#{5vn_8?*518$ns$BYneKz(@_b3D{C91`x{7bDtIOThC{yRuqhNZ|*|+6a%k3bY z&wT3T+}ZmD^@}Rz>)o(>CSe|>RrK>#(u7G)?lIcu`92M3JH2K7 zTNj6;r=ogpUDB>u@owL;r(CP}mfmL#+8%mbDb^@!`t)Ss+b3^VnpL-2c^wVv{HgMM zZu!cl|DiHV3p2GZGO2vptac^)7E9>UgIvdR4a_HKJ((wB9496odNg|LX_L-LALpv| zFJ!-RY*R(RZ5|%(8txv)>pNfG?dkZw*mslBnH%D_&Tc=KHuuWkxc_^n+i8|QuUnoJ zv0l|=spE0mJ-h*@n3?%GqU5I*S0wFUUnG*rxAZA9UqzpqhSLXj?j!|)bW68iE1A!* zSX8CGS7_ea;}zC7k>O8YOw+xN1&1GH5aSO+}F>t&mCl9W@KPo+_=V|aiswtFvZI9Gcx{XVFBg=HUoYTUl_z^HDCr(;3O@} z$0Eie60KT2ZAofi-44so2P)FyURXW<@XkOUq+Xdt!a%G6y8<_m0tFU(16u=YHqM0B z62?eICPqdBJp&y!4sAAI_F`vZ6jR73DJihh*Dp#f$S=+;$uFwZD+Xn)Vqn(NOU}>L zM^4bd90^R&j120#9#5(HxbDC`@n=tOT>Todq4~@1vvI7|{_{)I*4w-YtNT+_VZnS; zJ4u>h=Z}{OXV07q>^dG`nD@}DPC`F3a+_^RqxR$GmS;-seYFqXG0jZeA@^m6c88Ey z%OS(b7Sjxu?X(WIKddr2EIM=2o1+JJTQEF+BffISo#Qo(&GU`icLgb#$Qo5~hAppA zHCt)xed|C|KG$xc6YbvWflwHkAJ`N;S$GWna~v?ckLbo2AuyWZ4kyc zX+u-%jpoxzDSLExs9p_Ow1e%{+DS`P794Eb>Lr}zeqN6|Y--5qbF*$|ZCSSIwj)QI zdinRP1x`8K7U!;)1{h5`bYI&*$>YLRM+?>1B`;&=ADdEo!S%1fbm#sFtGSN16(@LQ z>fT#gah>f});w>!aw`R4CB_T;Gv*~HWSjbO=k8i)dtmZ|dgaZbYl~F<+(~9wXMVtBZBX`0I@j?$ iyhV&l+i^EhYA!pv-tYshWD z$;KSY!Y0h*>|rQizz5=R3A2ZL2B&(bRvIc9D1bz`g(dwxgF{>u-11BFQW8rt^Yav3 z^HTDQic?bzH4M~1YM6!PA!?v{72I?3lM-_jg7WiA6x^K^oE;71#CZ+P4NMIz4J=J8 zj7_4%c}O3XtzA$T%w_=^x z^5hAZEU#>AuZWkJ#vdSUYR;c^?9NSL-z9w$%%AOzHk`OP#2^S9(6aoDjQ?3!fbqm; zzz+;USz!>L)qojD8OVYJ_*lePL_FF>);vBuZ$g6A^;4biF0bv`5|9RTIj1%oBMW1b zxhNyZ1P0`IWzJwQNM$lmJDwSR=j!uK&rk65^c=oh*(05N^<>Z#Ki?*=V!2HXEh|+I z_(bJ;Y9>?&KdSS1ox)_uaN9(|h~xh(Po`}h_e9pm=FBYYm9p=?{$P<=n+$uCRax-g TLyO+Nuint$AHnY(Y`GTzFR{ZH literal 0 HcmV?d00001 diff --git a/config/systemCertificates/3c9a4d3b.0 b/config/systemCertificates/3c9a4d3b.0 new file mode 100644 index 0000000000000000000000000000000000000000..12f481ee4a2515594f587101f93cf7881798af89 GIT binary patch literal 2007 zcmb_cX;f3!7C!gp5=|ro1Q{LzSs+Fb$c+*3i9;Zuj7pUtjkFL0k=Q^W2~sHv#7J;J zXi-z3$f!W26qlelKtWs7iZT@hltBhX6lzr{S}HxE>go?y*Zc9-Ui<9x?dj}$?min= z%xlLLT9@+)D1xH%KfQM0G$*lm0H+X1wke(|zf%xIOAFv`%!Rlvk-)_W+9X#FCvc0a z7mvx*#dS2g1={oceY`YkCIw%h(U7&VIk*5PX&_M__1KD=8&Q}{+!4}$S@n`eku<%z4 zi;b+S?nV9CeHPULy^9h=j(U>IH?)uLGB)o@?>4-m>**ByOmHrP7reyzZc*ngQq0BQ z5UH|q?>)by+cWKwo6|k#brfwL2TDyNO4p9QbQjkaT)jo8JF-q6DEqxV>xV4KqmP|S zjD63NC{}@qm|wS%()iSk9`-TWlRG-w))10c=aLJyaYW_YBKKr`K2lxf(sji*ZCOD{ zQOPBAlXa_Y#drn5vgR`y6<-!`JaJ&+4q2Gn%C?WP{66#RE`KxJn)u5|P)@?@ zUtZ|s#C|z^X^Vr&zShaxJd>GA#Hl~Fl=@_0z0T&^4K2X?$pgOPcZ9FGA}-J!}(#6q9}%|R1hKBEs-$<;ZnIsC=&3) zAdvD!@fu&IgFq_BE#7BCQuNr)tdl2r`Rl;RGmPLa4C9jB&%H4@W2vnZ|{NDUe;b0ue&qLByZ}J^&;LvgNyy zP!u8qa|NOcTtO_50|}4<5eNf($TY~|aOJ>N3T+}Fge-tI0hBL56tr!DXdJ}9_Z34- zgSj}60^x2M-0y_(QFAdG+uu0@piTg_5+H`W6Xwv^_CWr((>$QJCQc6P(VYKxHFk4R zUSI>1AAyy?3E+SU$r0{6fDLe%v-^XsP--fnfe4sE4x+(oz=mje>jlg z`1?CT43~VM3B=($MKUp8Ad*Cd2pl5hkvLa#=@!@~+!y!G_srjr;{JiK|G9TU!osDn zf5daM)r_k7{}>$3MBGSoj2;GuZnCzf%h+$*@}C0_&T2UD5TItFd5`|&?DTXu7`9Q3 z`z{liv5nnz_o{7ra=I(ZvO3z=;F*(Y1*J2@ zH20T38y-(!-QRJz)OniTMY1>j^@ahRRu<+y>(Ckdt=KP=ZQ{iV5cCW-T@sFLc8}lQ zy(@V+yCd-xLJzXLG4Ao>O0n$-3MLlS8H*mE%X(eq&ot=~^osT0^Pr zI2JrOSmJ1kfvNSpv@uR?$U(ERhRUX_K|et5xk=ytNIxTZc#>7fjl4fV@?)G`x}6>i zNI&j~vzZ@q^5gRJ`@YKyz%2<4<}qP!UacaZFz!VS%B^k@7n>LFO{4VDT}Qv`S#+V& zs&{#5dylnhe3a|%m-^CapECRN^51m=y>vQR)}2a!H!*FYnQceimFLmP#nGX4TGcrx zG50#YRr%vnOOEIz9pe=iUi4~fxZheb&eXFzX>xkv0rx@uSTjXAY;>V8;Zz^jnmEx^ zuL@@OG#y{h9dNu}qpYj?n9- zrf0AC#CAwI@zd8r#tE8PZ`U>Y-O5*Qy7%60$xB~g5cE+Vd#AN85K^Mn+av27|^eh9U++Y|No7T*BP0 zc_l@q#U*-qsU?OE26iA(ZV~hH@^ZaYgp9s(KybW~fr*7eW?piBQGuR9Ql&ysYMP#c zMowmKW=XL^PG(|~o~EIyfilNcj^BP$im;<>c zhNgx_QA5>RO^iy&5yZ&Kz}&>h&tTBR$i>ve$jGqP*L$T<+oo5G71%|^Qna+aFYf2| z^6h)uP_{IEdxgV+Vy6=s2W|&z-;LW*Hp6ssx76GkVJklQ=clYYV>rYfPC8%yV7_b z|Jl34^I%!0r{v!QEB1CSPS-y+e@~%g!VcY+IwvQTrBzRPw7%k6YH+O0wK<#4Ycl`T zUlOqCipM!tqtLFun^JuEp3Gn`yZ1{7b3a8l4 z0_0EzW&>a-Gcs7u?hl)7@H}{CO;zP`-|5#Sr%w3ICV$Gf#x1#jTAIo)2Wdt1Q_qTu zKl%SNocZ?zk55MMv4$q$8Narzy%lTw@m$_FQNbxqJn!tMt`}U*e_j8cJad1zj@-%J zv!q<6zLxM`CV#dzTtI&|3ujcz*1Q|CRu8YuyO>iMS1BWM^zj9s$=0bhZ|~dgTlRFS z)Zwj?hxf)s@BXj+K11@f&}8)(X5D;)3v%0}*4&HwesR?b^=1Dm8;?}ZG!EY-v|;4~ zr<}>B!tVXcZQ313?^lna{o$tXR Z8g_pFN9~%pS!FLHCmgM5HWf?_1ORo~ir)YL literal 0 HcmV?d00001 diff --git a/config/systemCertificates/40dc992e.0 b/config/systemCertificates/40dc992e.0 new file mode 100644 index 0000000000000000000000000000000000000000..433bb684bf3e53e453f73d9e7e84369bef1181cc GIT binary patch literal 1077 zcmXqLVlgymVwPOM%*4pV#K>U4%f_kI=F#?@mywZ`mBFBKsv)-lCmVAp3!5;Ldyt`v zffI$bX zmFOurmX>7X7iE@I8af!*flOf*HYdfDp#1z2XGaAi14BatIdNV?Lqj72Gect&OH-pL zab9B(*AU7bwC-+VR6-77Mpg#qCPsb+gC<5UrY1&4hLyn#kM)*)>-&{(LwBm(4;`%# zzq31A5~oD?_uF=wytkJS^Khl{adN(x#B-J&$S5PUlvt4v0=UWx@DIQe{WUeoNE*HKJcja z{b{kUjpUea6?neM<2froU74aEljhE!Y1y=Jdx>86m80C%`X5ek-LkFZnl)KwsYX%pMCVz{ zFZ#B&>|9yWFXC|g&b>8`DLGptXEP<|s-*P0Y*Kx7F1Cax*(j#B{V5YOBLm~&#!iFA zHUoZO8j%%dWc<&)^Rr#FOI zl;1h38n}a`_0%?#e zYK8#D79)fF`%1@$)p_=tdfLpLy!>R$<$BY0sWhJS7vfhuz&yQ8H8=LMlIDt>MZ7Ct z+pDWb0&&y^KE*-!|Jgz=j)jtr{{WZ`M|XFZvpe$F2$wmgxfq18yD|uw=U@x zcUAKdo7ns>z4okca{8~&%tF&D*m^gnzwNW%H{YM>>t;^<&pz$iq2swbvzojYr$ V?*^M6UJSES?#{RLzNmhE2LLi_kQ@L2 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/455f1b52.0 b/config/systemCertificates/455f1b52.0 new file mode 100644 index 0000000000000000000000000000000000000000..011ca95b3f2d50a21c5023263fea135139625a60 GIT binary patch literal 1090 zcmXqLVzD!5Vpdzg%*4pV#Nrj)qhY|y#;Mij(e|B}k&&B~!Ju)UA-4f18*?ZNn=n&o zu%VcN2#CWa%=8fYYIDi|3USSp|xrJ$>jmS3chSXz>iUzAyunxarzoT`wYms4p7 zR1DI}EUXFDp%9dxU!vfgT2zvmmYJMbl9`{U;0V!JQVBH3-N-;roYw$orGdGjxsj=< zNt8IRu>sH^AlDSc9r_+@VpKwoG)7hi<|amd27@L>E~X|%MuuH2+lp?_$B^Q8gf z^0HS(JEl5HoxGLk7g2Qn-?yg9{l$rFTuaq&Y>vO|>L*il&ClplQ5XOBX2}a#4Gj#g zavP36pS52oTwP{yhCWyO-mGlCxYW-w~sB)7Pcj%*l8Dd7lG5Qr@2M9^|MnF@NvH4q?EAk4$Ir3*BChi+bB&*oPg41-?Ju70HrXTD zy>3q6^X+w8gEty0J?{^s<9zX}@c&** z?E|0o`WN)9)PE&@gga#373pa+jBQq|O5MzIca3e%jokHDKbP^J zweGM`nwv9u))CwNP133M%lKng{du}c^wie1$M)D>XnFC9t!RU)`=(0A?|1XGb38Vg?IFcWiVscx hA1JU!G=%ZSAJ&bX3+qdoXL(+~<5%6~k>Bn54FJ1YmpA|b literal 0 HcmV?d00001 diff --git a/config/systemCertificates/48a195d8.0 b/config/systemCertificates/48a195d8.0 new file mode 100644 index 0000000000000000000000000000000000000000..71f9f88dd2a915982047b7b447940d2665519a9b GIT binary patch literal 1525 zcmbu8c{tPw7{~qQde$+9WJHc3jcU#8?}tIdBZD#HOraRt;h5IcxCUVyYbIwsid3%guz8R~azvZNj@{?kr)U4&=l$b-KHukgzt8)}_Y3loD?=|H-WE@-G@$WTD*{*59q z&>=DYhch3h@%@_sQVhSmwoQ!G5YvK<3!CjN7yO zb0uNG^~CnxRp)@uA%hTkM z&$Zsoh3nHi-!@CXGf8jkx}2O7m2@GA>eCHHSF_p|jr2M*DXgeqfibSrz3~JsAD5C| zkYclD9}!D+${9rBDOGiLD!R=b@a}^VZT{m%pTr4HTJ-XtraH<^y8F^>9gi9uSbPP1 zc_VINXXn*Ag=WNSG*#>`+Q!$(ua$1aD9$eyB-C24Vy>(u4hEs_Jd+$2OlrkC;CmGw z^>E`)X)6J$>}I(NnesZ#b;HzxVH@GfiL+x z)!J}eGVaj!%ZB&U!jg6xYtNhUf z1WXx8VJ+7NYzFRP+cIY=Y_FOqq`t29nB~t#BZ}csNiD)(3o$p2OT9vW9T}YEL@9TN z?6~D%>MN0!vnyrTMOv`}3=W6^MZ67=w+8a6M9EZOZMA`7YHs0?ypZ5=Q|cU0nkmeUNa{j>+*Po?-?0aaisIntNanlf}h3K_H2Q zv((qYIT}LdAZ6D`T#8J&?B$O0VzO~|OfOatlf!ZMW%}W$qFWD^7t52S7NHnYn^ACKyK}mF2P3THPFxPyN>qI-*~Qgsr=s1Mrvebz}m4I>Co7l znZ;V_G&Ac6I(eNMQ6rUnBD6eHZnEoJK_Zd#u&8i0r!MYGZszbG%kQxDuVv zNDOR!;u1e=wz_b3Nfp${?lTzdP-pWNn|<(am1oRwxwNYCE3W?9q~ZJedbQ7u{?sY^ zI31e!HHoS%{QXgssj~Z=Nnx6{&Fb^btcQnp)>gyss1ftiPyaX>3;)70=*tbgh^*~| zLK7FcrLj{D;l`8As$ntxdH&L_0unLh2sAcBRIc zuNd|=r#~292-KWQ{ne@XVYJDuB4b;Q;B-g+>t}{q{X?kSLi*TzUO(SoKRw6jkKfd% zUF)TUsRqm6Tp2al-7K~_9w2$1cTR+pgGU>!$DDSSCZk6QgN8$A36fcnChYMoe8SVe E04K$QhyVZp literal 0 HcmV?d00001 diff --git a/config/systemCertificates/4be590e0.0 b/config/systemCertificates/4be590e0.0 new file mode 100644 index 0000000000000000000000000000000000000000..7a8caf9169eaa54eb64a2e7e91c472ba65c282c1 GIT binary patch literal 1386 zcmXqLVoft>V)k3W%*4pVB*4Y!)WE>N=&F3)t%iYtfyscEjZ>@5qwPB{BO^B}gMqIh zw*e;`b0`a&FjHu-p^$+9h{Gk!>6wz67gAJOTw!|uI6EpB8pw(B8k!gw8k!lJn;IJ%MTzqoBXg;3T@#ZMvWFO18JL@x_!$hE zn7Ejlm>3zhDNXsa#AE#n_iV1;>Sa$p*>_o2dFdEx_4IC7dDt*}MR{3^+O{=~PP`ni zLnC%q{n(RQ`)NUL_X_uyNo8_^?>Iy*ZgLU(^6J7bIsLfXr;8oe?P1v9rR}h3%|mPN zL%MUHES&vD%1Z77$L0%9R7~0D&)IS^DEBt|ss63eADTb=AJ<)aV(sav3QG(%!Xu)d z^h(cKJ&%{?6PK~2k|o!4z0bkrJ6&A=wwyLoXpGdIm7nY3k$B4Ie(=ThL3>>0uh!3Q zE_z?uaEr}YI`+h^AUBK+&&Lvgv69P7!KD8|Df%*E?Cc>7gFD%oZ z%&1x=G-FO=TASV4j~h~DegT}_)GTyoJ)GTmYNq0%x7^|l@td-h|M&7{7}ZHx!Ew$1J2=eC#<^5WHP=g2-u!XB=(fzB+`Xys?>kJj()8bb+noBrxVL78W2PIwvrOi% z*;_9pW}Q9debZ-x+iKCsh3+Amdd(W~GKUteE)r*8>vMh6{m9t1{+6W6lcb`<_mz%) z3cGSQernO%-1zSv%+Y_3YAyIytlT0X&G?*&nUR5Uv6F#=0Ut04%knca{%2tUW(+n1 zeh^<6#Ah{N22uvHAOSuWF&2@>g%9T4SnhQ5cHzYADU)9xUVKqxF>)#cW*cBCV`Omu zb(d>{;6#hHzOmn*@=XtsZ1QLi=~Upj;J$q(*yF|lJ!JB%cM{@hu4NB->V^{e^rO5b*UQuUna(bU*K znID2P6Q`C|a>s=}vyhpxGSYb7iNcb~`oPX@C$e@JoXD~`oHy^Gx!5b#B%f#@_qWTp zY>o&!?)kZ1D1+0m@I&qoKlk6)THhUwaFARgyZooOv-zEjDF5@X52cjc+ah}NOGt>6 zzRdOMg&`CAZYsW)WpQdaO7iq{pAY7 z?-nP29G>aC=lJ(M=Fj~KcX{_OEtZYRo3V~Le4T~4v%a{k{E2fJ0tYMBNiu5-{L-mx z{`O*L#?H`BEH29}fBs?VmixHKSN&&V^{(wt7YT2BooII<=i;;9zvAA?Zke~hGJ z@v^IXXY9f|cV~LZo2Bpec+$Mh{I!SGdj9l&arPH1r`~57wqH50?dO!j>hzQy+a`KB zRj2A1Wbu5R@NVj}PiLFn++67O=G!Lkr>?Efaw{gY=*?-$HCuVaFh#ztnOp0NDObhG z(DRNP++P~ZpSdq_1zXEbjjDKyo6;*SHZ<24A3SXBq1D8%ID5yL6{d$UUfbtG zii*I``dtS`eb8x}SgOO|8em&FwalUYlTkg&yqP-TC%&s2qkHlW*c-L;J)V7J2 zKf?KY;Yts^zpt*zGchwVFfMLfW6-$LfDf2zW%(Hy|Ff_FvjLj{KZq|3;kJbg0lyoIBv6wwm$7TcdyK$8Nb>hz^PtVnMJ}ttO2_MH;{e>7JCC*18X+U zgw_(qNJgN+26_fMY#iEbz%0hj#3-haQBqQ1rLSLZxpcxs8k2O9}zog6mV5-5RS&sDqI`Q#Ii7VT(G9`FQJg>#JymAbZ$d6bX z5T=lIY_CRU#Kb!j1x;64$?lO_nlSH%e7)<$%$s$)D~b-X@oSyyZ!Jh%v*0ZE4ol6j z79+p5-L^-xZeEu!diO7Ip_1dqLZ)P?rVUA}c$|Lf1(^>Z)eW?-{cjc;g@Y|cpQD)4kiw`odbu{?wCfzz=ed^Y$8=r_pSCq<5 zugZ;FsnuV7?{Iskz)a8LiW9bb15Hb`u70e`l-Am9y;pU|tSH-}#0hEb?|82HUJ)$e z&icpA{AY1!c;`Q_)9a$eSx)W&KPldd%tndNv=U^2hnRYwq015uC2N>C={EkxOh^ h={?O~&%I*5F)K^%%@eNOT0XBi6D-f2O1hz!2LKjuUkU&K literal 0 HcmV?d00001 diff --git a/config/systemCertificates/524d9b43.0 b/config/systemCertificates/524d9b43.0 new file mode 100644 index 0000000000000000000000000000000000000000..1353d28fd986ba4777b6b6dc9e435bf611484f16 GIT binary patch literal 1213 zcmXqLV%cfX#Jq3;GZP~dlYoQNkrc(v!ivm%yPpV29hEiUW#iOp^Jx3d%gD&h%3#pA z*O1$QlZ`o)g-w_#G}utwKorE`66Om_Ey@heOwZF%@XSlrGn6-w1xauVi@_umLW)X@ zOBDQ4OUm<$vJI^aEFcODHIg+Ij0_Ac6ksYLMkweixaAiqB$k$BTXk78o_|azpsrq)Eec!%*cY5@6e|u7AJcIZBqj#T_ zx)?cH$ra{hp5`ufr8P1zZL=YjFZmV}?t>VjMT zh<(}}meruz%f!scz__?^lR@Kp1Abr{k`-oT{LjK_zzn1e_&@^uAORL&ZeTOWW#iCh zV`ODzXXIf?G>BgqyCB*i(jeR*RE#q-H!(d`KRq+eK+!1C<5 zHNAb=htD@;UGb36sg~3;P!&_oC@Cqh($~+)PtVr_rqj$~U{29X&d=2^D+Y^!Oaf&X zSw0pq7Lje`zcM}C=LZX2J@ks*sEqyMbaqMPXa(j(V6-wac>VaXf%%zEdi9ej<;iFA ze16vQ@!mPH({yKnfATMtUpdV^?sKh^KhOGEW;Au;#_~ODX6@Vf#8B~AZmgbD zw|7S34cGP=6OO)aGdO0t|HJ>op&iZM?^!3Y6@J<=WAgSlXPXi~T0HZgK0_<27XYJz B$!h=r literal 0 HcmV?d00001 diff --git a/config/systemCertificates/52b525c7.0 b/config/systemCertificates/52b525c7.0 new file mode 100644 index 0000000000000000000000000000000000000000..1a0c2e285ff94f867385bb83894e2d0b2cac502f GIT binary patch literal 1380 zcmXqLVofk;V)j_T%*4pVBvKI(ueVl5()+PFyQzt=#@1<9QYRbmvT19KA-KZ8LN z6Bknx6C=ZdeE|Y}FF)ltY+;$xy3_E~9o;8_D_Lx$Lk~WWFpyQ*a`=7gy&j#12W{^+ zJ@a4d-k$R&+Vh~-)!qGX+Sk-K&1!pN%RDoP@sjDhHMc$lpG>p4vWAKAmda)86-;jH zm&iQ+Q5;dW{Ttr|-mM?bpZWFkn9tM0Z3bMu;&rC4kKW(SH|Ica`{NFa*7RR?$5%fP zp2I3J@yE-H;%bx9qO!A?CEZ zpII(CJo4*q`;z~(d4YOM9LvG46ZRU|9(lhabC1RBB}=AVOuChMfN|Qo(?!;>XzTff~ry0QD>QvoC2_-+L&8&7%T)=1vlr#VZV zGmC#`7uJ5bf5fNu*kZjCQ!7swFY5F2RrwwFgk@im^fGl_�MI*JC&pw%1SD>Hm>e zCa%LtT5$XGiMQwFe95}s!#0C??HP^tOWi*QGchwVFfMj7a4_HprdU~FM#ldvtOm?L z%770fzz-5&0p<}l16dHCk420{WbyQCpW_w@JY4NM-$p#e<{e|foHNL&447Gfsf>|9 z;#YL(AG@mK@#V))-9I0HSm=mD>=mO`JF>1{6%}=xp}h3jglLJGK9AQrEp9S2>p1)J z_Ysz99^H(`dl}D18?#MwODmD}e|vD-&Mmx&XOio#>y`IRlhIPn$ZicUD=-%R_t1Zt za=FAWsh$^mQ%|0^|8i3N&gsVV!*xKw#pRx`=0ykH&A zeW20GHs#^|<+^@*eUIGGJfvGYG;ExJ4n`rm$hE%~Kf%22{LJtRjzKlSHr+c%1D;=X+8 zK9!IfaP^{CDbGF_Oe@eEm}GXaKG(VTbOb=(d%{0{Ck_%r!#MszndGInUT3V&gxA~=APr$t$y=FcWx2& zKRmT6;`+&)mpMB>YbM8S(fOcj`!*`|!OCcdLmo35bLYvkY1s&E>E@rkNae$_-fLA4 Xytk!HOP<+`d=cHdrI+Yh%Z9=0vLxr;MA<88Rzf(smu&CfL) zRpcKRiC$oo`W;uGyy^6O%g5)B`W>5;t9Gn<_vTybbGh1HHkz~k`%qZ;=CI7mrv zws2l+OXgd~I@NQRMt8^LO(rromW1YQm$`6nW~jCD7o`V3HPh7IC_Tui}_mnB2 zz%lO1x&TWh5w+8stcy!R-PtP}Ems%_yF6v-S~pEt)ro&+@R8Yn&OVX3XY*_IH8wB# z^kp*)WbW$Rz9TU;Jnh*3nC`HzXgX;3)+isaF<{8L>6!5W#v0#@5WkFefkbx|~+}wto41swV zm<$;i!Z!Dv=9=r-w|~iziM!LpSp#R3{(c&uQ#J3S$gkCxyX^i?)a+00zOiLx2qW*l z$!+>Sy>gGoeGUJ4DpW>jpF6+V(fe83Zmm<4J=2ue=k~oPl3~ng4Qw!)J?- z&40INoVazYKhS2=?}>M0p3k29a64~N|Dz>GR#yCcEwbjAGwY#LOAQI8!%ds!vhGWL zJ1su7#O61rsb2LQ;lI-SvBz^8t-|=vSU+6Pq_4Eb?Ub9%0vVrcE?eUCVnow8AF65o zI~J6rU9`VHY5TQ0ik|YoD@=2K!5@qg9Z72!pmykL9nfb#0CC;U7!4g$mdYm$5^C$jo>QeH)$QPh` z_cSw)_{nAl4nI@huI{%Vn5LxZxYVDXsyd#AN85K^Mn-N{27@R=ZUas>=1>+kVJ1Hx zLpcK(5QmFLG`J)&u|y#ywMfA)6-eeJ=B1?O8EPA7g5;Tbl(5Px1m)+KC^$PR=qk7y z8_0?C8X6lK8k!gy8d;baMTzqoSpd1lM#cs}5JgkFo0yc4y~@bSz}&>d&tTBR#KqLa z#K^GEXi*4%!Ec?I$k#bXmIS_N)!KZ<%jDCB_|JUDWo(1xIyf?J)xC{R>!6;|0a%bo;=!oaBnLr~GWUJ`I}vai8_Gkc16sa-6H#|All4 zI$iv(vMZrNYR31If`7#hno5O~zIVR-be-S1=hcUg`6UK=ub$=Vy-?n9uSc+GVG4KK z=BIl5&MlEXsM)e;>uC<QFNx|m(Mfp+Y4xKkzmt6nIea~6)idTeAPnYGq{VnYu#jMSE zUS8gEDo4^Wh;yOrhOGTf?+XGIjqb3P^_>2m@`O2Heb2=7)ki_S^(F0EFWyyaO_bAj2>vx|GzcE4GC(7FAY^COdeQ@c&yvRmF- zAzL-yY@W~to>ZX;q6s(E99$lUB`g)Vl4bMP@eW^<`?mMf6HEPX{yV-&_R8B>&&?~d zPN%g9UyWIC=YC!}+r`4t6XE&m`OBl3m>C%u7dsg^81MrVw5%{A<9`-b17;v)zy}iG z2MMqM^9`GUEQrs?BE}*Tvi8^UN#W~Gna+V0_1I;~CA`ZAIte+##^usjNQ{U~%fe#C&G4UH8 zE&M!BxpvC-zgCwyo7oiqCfKesI&kS-@3Ifiw=~soohdk3+3@3^&v(-n$u7g+TsN=R z&;GDzR`y|5ueXi~A_f;%2|DFnR%T-1K9+j-ZczEH#_UZielc3?oc2m9Cw+S7lzDp| zhFpD;Rq@_yul6ikhq_}2N-yR8&MHD&ssrpZCbFDml zIPN^r5YpIJYZ~+Ffmofebk=pd>+}BTmTo#Ia#fl6c62_sU4=gHJ>y=n?HO^c8GLG0} zo_t66>l9gghrqA?U#;GrIQsgKoUGW?s^fJ|g_HBVMYkK=U-dS;)nkop)?LfYCl4zt T_MKzhzmVs9L$zYMx6mZp|bgTjqXj7rEs$H>aS+{DPw zV9>l_zdwwUxW6-W&ir%&yN$rU$3d+?Y>=Pkd=1z zf!pGOI~h0svv_ot-`o1~cY3bl%RQERjcz6}ecZUhHqU&{BmGC07pZk0+Y##A@le@r z=_M7*Ecew6R~BwwsrrxCe!1+f%Yg^Em)u%o@jf&_g*DY}vWdTL@7iNm6eTb9onlQa zWG{Aq+9fHpm&Ny--<+i$Yj&%BXJTe#U|ihTXVBPfAPbCkSw0pq77^}`c!C7vS)2?U4D1%zEU;>` z$S5f(u+rC0F3QnM&d<$H$xluMG4vq`%NaRc!IPC9P&IOt0aH6L$`~2!X3U%YP5R|^ z%k35GWQ!y`FSkE&ZhCEha@E%rTi=J)C2XOh^3K3-b^3TO@L< zkZa^Rps%3s*gf%%hwGk?$L{Sa%Qim2plj&n^Y;1N^Bq(E8y^UJq0*+da`O^V;oy_BL*g_ah#K@!MD*l$mUL(;{fiyAyBp4E&~;Zc&l`Z@yn#LTKksX(CsgtuDSa0t7O=+sNWN0)=z%@ROU+h z^jH?Yeca8<#G7{-2rW2jEXul*_xEwuvd1^PdjFV+FFvNIvCqKOQ0{oezKBGNHP(+9 FQvr-NhT8xD literal 0 HcmV?d00001 diff --git a/config/systemCertificates/5acf816d.0 b/config/systemCertificates/5acf816d.0 new file mode 100644 index 0000000000000000000000000000000000000000..13d993b9e85009d8c276340f3e375fcab5568907 GIT binary patch literal 526 zcmXqLV&XDrVw|{unTe5!Ng&UC<%#Yo+g|Lp*1EB1)4`brTx=X#Z64=rS(up(+zq)6 zIN6v(S=fY`LW2#J3=}{dE@4Uc{QUHsRE3bD(&7?@;MAhB%;eN!1s@-0LlFZZkQ!!T zZugL2g`oWW5``cW137VCLo)+2BO?Pah!W>DM&?q_qA~*kHg>T4nHbqvwHsL&l$etk zSU#5&FVE;sSm(UM^k}0&wYTTo-v<-VJ-g?&H~VU$gy}kmyT#u-CmKY(wt3fDv&f;$ zdgZYl?l-iaPnwuj{BmQF<$TTgi)LJokBewaBr`ux z!LhU?BfluKq|#8&KnJ9ZSy&Zr0zUNya^k!Oh6culmWCF_KoBL)YXst&L%9R*z$Qi| zH>RRp-BHPSaBf zaZs`NF4cM`!sql7b*JeU<~Mg8e!|8a&9F33u7IWF(ZMTLtFN!MW|v^?``f(cRoYDn z>5Q(g;ZiepeSKSITXXZ?lq_p+@q<_U_oiA{O}$_nYUX#pGTcy0?nY#)XN1Cxy4CS@ z^Iu-`ebZdB@_5dTcbZbLr$UZytePrYDCecw z#e65r_23f8xO}s-hZk+w{x8PjQP7?rF3!&;>}FzSWMEv}#1v%E#N=mS%f_M2225G( zjEpRX2KolNFunm}n_@;uNkOrdzJ7jkae-c8X?__ff#s*A6$8^ws$Oz_t^q$V?Z^r< zGX7^_HDCr(z)+R~2`R8NF$w}Xyghd51EWFXZ-d4wFguu-3>uG1H695{ z&B;v6OHNe)rp%IzR0UiqF;yX{QXw&~QlTKRs07F=E-uYYEmlZOPEIW-ff$emHUMZy zoYn*fg18s6q57vQZhk#p;#e5O`)_nRYxHiC5sdk zB_@|-CZ`tbfYqb83z3;p6$0{swp8jFD8YTjC?*C9Ibgt*mzTrCO)n|eKo%4>d@N!t zBHiA(Z!c@^WRrYjX}R*l^p>pC@9!Hlt^>&{votO+L^Bp5Y*AOI?*%#{F8~z=Dc!S!21sOf%>3oaJKmKfb$fN$D@I z+>H%=oMAiXNG1G>J$Sw9j$p-wYq1BnUtMc7li8~4Oo*zbVPmzhQs6GPoQ1pR{bI@S zR4eJfRQ&pk!J=ocB9+>IO#jOF_tlw6OT>-@NxV`#xAEh%md2;MR<>z;a*m1>n!85s i=8C6WSOK)aiTW&Cy5CsxFu*cX^eV{R9Air5#8B literal 0 HcmV?d00001 diff --git a/config/systemCertificates/5f47b495.0 b/config/systemCertificates/5f47b495.0 new file mode 100644 index 0000000000000000000000000000000000000000..194de84d8ce9e2bf50334b34b7c32dcb7562af4d GIT binary patch literal 1471 zcmXqLV%=@f#JqR`GZP~d6Gu3g;B==WkIxwJvTezuk8%uP)E3yXR>iTa6K+jlzH-<8df=V-pFE7!5$M}JsBr-S2*M?0Ma^Z^1_!Oae3_J_rRAiW}^D zR*}5t%cixnwKx5HXxS6Di(6sJz3S#2{~w3-ZWnxM-ScVV!PvP=xP7#5Zj$)Ab-p(f zGb01z;$(wF16g3|mgQp+V-X3u(P4FBenr~b&d=2r1yfEkF_~R3;0H+yGcx{XVKra| zQU>xM0c92m1F;6|I`}{e_(3{YfVqy(P)=-^{%y)(Ypz@f|vBZ^c_ytQ%>8EzAt~<0b$F8Rf|ki zCzl4@TRwL!UwdazVV0PUq-^t#S(>T)zSz&Y`QdX^yJBI3@975?v+Z~PdSKvtzU^|V zfTYC5=}a57i<~mnEZFN8bxUG@_Ke00e`oEB6ZJSND7y22X3Uls9pCND)@@JvE0=Vy zph7^#Bl^~!B^JBV--g=7h2Ouz?BLV5c6~>m6{oDOm0Cs*35r z<<}aFY7r#|4-_lqPM-SLvUa!D<8Mumb*9Jr$xoc}>z~fz8)Z^Ed^cJ6&;BLrkx;4j z==0x|7iPUE==ZF;_H-{7-)-H`z58E3UQ&Dd_|(D|w-(nNJ@lhw5{q=(nk7oX4%^oJ z^C>(3dy3Hk)A?ogc~2+gEm)?uXot?ei`uP!muH;V#i+e8r$lx~@zm$BZe4DLNzJ@rc*6(=~BFSC?? zHSh8K3u*bRZ&sDn?avll@Ota%&G0Q{r{~`8m8+-Zt zVglSY+wNza;lC*|#NE!Mx*|7hvR?74G>wY0vLgEz^y};G(Chmo(skzL)|%frb9t6N GoCW~9rDq}l literal 0 HcmV?d00001 diff --git a/config/systemCertificates/60afe812.0 b/config/systemCertificates/60afe812.0 new file mode 100644 index 0000000000000000000000000000000000000000..b40648ca3f9907728a575d3d29dfc9cd11eee0fd GIT binary patch literal 1049 zcmXqLVi7fHV*0y)nTe5!iOthd=Lv&=0WTY;R+~rLcV0$DZdL|^#^r|G2Apinp)72| zOdg?zf(HB`4m%HrQ)xSQr^biSrr(xdvuX z?hx`x6QdGxG%&IMYdgm7NTZZtamfjR~oWi(1?#;K}kN?-E{8N~9J?8blW%3*;i@VE0*UDLI zBP=(t!*+4N}r-IAiMKQddt&Ro9olgaXx z+m-ptauPdk`b`Tk(ONXFkhk>;NX>k2@vSdaeD}=%74B|95GP zzJ_;_N@ElE*Tj!9c{>sfJ6IGb-=lN5Wy0a8 z{$1z4EKgnfdd9`ytef0QMU}JiTayhMK3ttAuPJjVXG1__?1X6R6}$%L_t(~+`#86G z?@6~jg=Iez19vIvSMOUYn!NDJ)b@|_c7E>sY}>kH$L)PvcWVB;WzNdrIfc2!<@tVR z!}F!xsu#a3OZhtK+iKR=wl9}*nk!xnGWy)Djght}`7Z-w_=)aD&|#yfF~Ug^|^ Zz$|ZrWgC(fPX0Li#?pWMd9xVH0Kw4K~y?PzQ0igcUsVN>YpRQcDzqQMi96N{2F6x@sQ zOA8D|4TM2TnT2^ggM-`^g7WiA6e0`_)UeSUJ_S;M+V-u>HW)=goaf7yL{%}fvF;1?F_{JHX*^)7mb z_cWAjyQP1@qPLp4KvBB%lYz~z{&jb6C9i%h=6|S9(7WzD_ly5q%k{o&s`h%|Bc#ex z(95j3;9;=J8{wPpB=-w!_Uf_kT$~tqZ%sS8l;RAn=gy-c5l%vESRjulRoaDHHpQelw1#&mWmj<25Ut_nWV1qwMTG%s)L@ zZ#3Rz-J*5P@#PxEvZ-ABH|}5EDDklY(M=kbokat@+bL(=ez`Qo=d9_8$g;*;h-`WLMh;lRc_g>Iv-DFqo zCF5PpD)i^rs|NwXHO`YuHlHea-Y3t;=GdnK4#`;nE(6$dNYTB&bR(NQ2+$oz?wqHJLsjX!HYm3h*_fBZ@a%uek ze*2NA(-ox)>ah}I#svAgPldH?sMd^L9VXJTe#U|j5E;9$T9Os}&1 zjEw(TSb({M&43@o7Y6ZJ4VZzHfhFz=l^iUlGsD^9O_ z?o;@C)1`#9mMgeli7SS+ehlD?e0}ag-X~KPhVT7{&D4o6YKug*3J5*#Pa(8&H7gpwUsuC^Ywq~GKr43@rUtb$j%*V zXSzC!JAHIpY?|)Bn-;WsJ~s2)HigcR z-KW{sqcnToqipMNtEK|qJDkTmPjj*R=DdjQJNf?H>f^h&YWulf^SYpR=4sI>j;y6q zAB!&hzU1vmo%p4{|F6+t(%W~vdiUeP>Iq_(+2h=TYs}f5dM+QCHs|Whty&MJN;P<_ z^RZ+cWl3o${YKsGG(t*4WP8`@Gk9!gJ;MzXRq} z=D1zmBD#56Ufpb-X;wRebnUN2Km5&csO6u^ip8C`)?_`D(Av1dIWhXO{2lAwvQN4% zdQ0z%8|T;t|E@mm82|syq6>)@52x)|6WeWmz4WT_ftiBq<~klMDs9=vbavg^PzfBsC{9F*rXjwJ6b0-ar;4%FH8%B&raUpI@Tj?5I#?Xdoxf3)F02 zXkln%U|?zxCC+PXgv2G^;3g&|WJfZxGB7tW@iQ1SF>x_9F)=b6+V@)hgW}@PnQEbR zbB~6KO^o^bUU7eLLzV8Oi9N}NAKs{ZIK1>yQH?e<@Vz0PCX8iqTm zrEj!+;}5ofRY=utT;XolsXWy{Y(o8uaCVR9lI!-nrf)QtX4Cq2@8_D@=HGFi(HN zd>c@`(x6xJGG|{#dhC9i=@P-aHIt5>iYq#JeA<=Ux(l|*XEMKe^(f#YkIjcQpM!Nj z$b5a9V`*93Aa){XgYwx2c6aXDxG&gk+VyBgM)$s_`-|RP`nB|}(Az&VBvz`G-O=zC zP>{J?FIKMmHoxJ!=k8$E-LVgR9XqGfJf&^E1FeBrC7FGjhAZ5S}65wZH0j7O6aQcB@!iOltqHAOG%m&;Q4F z8Mgyf{th}yrXM6XUdT?@*|6fl0S9x_Z!Iw~kJmd@{9AsKH{ca-OWC);_szk_s{ZqZ zdFu67UE_JC9`e|iE1@Xq>_ql!OZT6cnf>;Nf4Ikxsp0F=#P-9lpd|>wN zn?mqo@d6X^xyc!F*>4W}w(Sr$(2sTFb$7lhy(*G#XG|}f$J&zi_~U;JLmY)49arR= z_dt&K;el%B)(JCrJkr8Gor?YS>MGDT7>e=pv#tH9y7 zy3GC~VZpzWQ!jj$;S>9s-4@|1apehb-_p6!6YrF%1lS+b`h9czoUPZMUAXx|vRky! zW9{}=HzGT(OxQ2B`R26VoY{Z*Tj`S0X}MtlozF>b literal 0 HcmV?d00001 diff --git a/config/systemCertificates/69105f4f.0 b/config/systemCertificates/69105f4f.0 new file mode 100644 index 0000000000000000000000000000000000000000..391ffc14d3d58e371d34cb61b6f6d7e875022792 GIT binary patch literal 955 zcmXqLV%~1h#58{aGZP~dlK{{22T#Rsxc%#Yn(#;ZgMp<1FB_*;n@8JsUPeY%RtAGq zLv903Hs(+kHesgFU_(&@VGxH)n8zhEJ<~b0s6@dtFWFGiKpZ5@Ei6!8Uapq{lu8Cl z=_Tjq8mbs5fuxv)rQtdpi;GK(Qd1N>T@-@y^Gg(*9S!8fc@4}A4Gj$-AWEFq7|4Tj z>E($l>kpv3$06|T!a+IaJyM9L+h==h%z5~h3H&n`6knO%QngN5Be>BBw7H*e@m z{L|pyyuA6^;XIcEiKf%U{zcB|F3Y|CagjH#_J8i8Tk{ew^i425RuS5+u<-oTT&@$I zHHI^cbCh1TUoeVVv`e^2@U5lz+?iHI3!nX3a`URVVd=WoTBUXNjBah;G%8PQy!9kp z{79V)--a!dmW6HJyJ`B{Rm(qYKf1zxs@R493#Yy2h?gk$XJTe#U|gJRkZ8aMj8s{E zM#ldvEWm`+X21{P3xoKq2FyUpKo%sx$0Eie;`(~g`Y)4CHyP>%b}wJ9IQMhz34Q~4 zkhC(3gn?KCb_J;E5Eu=N42$^o+<)};!{egjs+1}FzZa$5FnZ!tnzXL{^{1;h?}cri zf99Ns#!lYp2{A%G5l=4LHha28OgGJxTH*dG>{#V$p&RLqE%)m=ZKgcip{Ap-*LJf; z=lA&kN{^!6kyGbAS1*C7!+57pUd^V36yI8$>&C2N9s*gf$ z3C-8lS@wCKo4)UGx>knZ{f6f}#%cS7c}4O**UKjh$o=Y-R?W@nU%EY!apR@MY6}Gl f=dOKp_~+r7f!np&InL=l3)r;$7niI4q7R<{?GSav literal 0 HcmV?d00001 diff --git a/config/systemCertificates/6b03dec0.0 b/config/systemCertificates/6b03dec0.0 new file mode 100644 index 0000000000000000000000000000000000000000..310219dfa956b8ac16752f89ea95c10e1b993d87 GIT binary patch literal 528 zcmXqLV&XAqVw|{unTe5!Ng&UCJkHs&Ff$vt8*&?P zvN4CUun9AT1{*3FD1bOz!jkU!`RO^S3L!CsYPX($*IK(K0eNdA_hVrHO#`? z?jgYnLHYS53PHvOa^k#(W(H|pmZF|x60H?lA&F()yw z$om_&8*6qgY`J&(xMGB3=c}-}+TN|lWPQ~4)T;#+fvqRG5YpEeX)~) zg8?7VE`M}hrI(PPU<}2@9d^eRLC~o4K6LX77nu57&S32y? zNI3d%M~L-7GjY`$2loQC%rl)-(yAKxRpm`ekV?Q(`P(l}pDcUxrYY}ht3>dN9gk;e Uu9|kaS^4CW>cq`wm|nyJ0COp=ApigX literal 0 HcmV?d00001 diff --git a/config/systemCertificates/75680d2e.0 b/config/systemCertificates/75680d2e.0 new file mode 100644 index 0000000000000000000000000000000000000000..5c715faed85eae3569262d7f3dd3fa93a62dff60 GIT binary patch literal 1078 zcmXqLVlgskVwPIK%*4pV#K>sC%f_kI=F#?@mywZ`mBFCeklTQhjX9KsO_<5u$xzxr z62#%)5ppj|O)N<*Qt(a8OU_6w1~Lr=4ER8j>^$tji8*QcMJa|-1`;3BO}8;hq+(!9=D%XaqM2>(L9Krh@_kR3etljY8_*?Y$UTeg!qEbyv!1#k$!E6ZWw>z%zdG%s za$rx9->Z+J>%N4{65={swaGZ)(XGzV&q@)W@7+27zPW8t&lLap8J}iMaBERNUbg@7 z8B?9^IQEp(rUM=uR!sbvIKNCGV8z7aXy`MkR z^P}$lH6^~%Gq$=PeX4o!=LCu4Npto!A6Kik>ry>_;O^XKrWpbXbNg@HyL7l^4sYBG z{gX`0j0}v68xI&X?lq7F#dY#EPc0sPf3X5{=a{Ob{zMQ z`qG)eTA#3;)$8-OkB9aj*;&%IO}94t%%#t6clD1w$U1!3gjuI{+TEx_e9O6J9%Sua z&7=Q0#_D{Ic_?T5yAv>AB-zo?y~ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/76579174.0 b/config/systemCertificates/76579174.0 new file mode 100644 index 0000000000000000000000000000000000000000..8c5b0c061f52df665b673dfb787b0780250ed9dd GIT binary patch literal 1076 zcmXqLVlgmiVwPCI%*4pVBoHtq=Z(axt8;v>PJdt8zhJEaFB_*;n@8JsUPeY%RtAH{ zCPQumPB!LH7B*p~&|pJ30~rv9TUfNbyj-uMC^5I7I5oMnD6^zeFF8NgP{lwAB+n%* z9T5bSQwWAi0vSbRnaQce3Z8k%hPnpYAXUu5DiBrfIr&M6ISS6HMJ1VOnaPPInfZAN zj-@3T`5=Q0O%c#NO$Rdl&#n?LKl7De^TfDX} zTPwfr0h`#P+0i%COR{4d`ZedaN#C5qJ0rJDKqKNw>V|r+8I|)N95$?L(B9f}z`EYt>cf+t6IVZ%wchjM{FiK9lbS~!i86hk6J5^a zFYsD9WrOdn=POOBiY!(*p0SxCSo`|KvYzd2r%xGM-?TOF{#|9)rt`e`I#>9bl-ZK6 zzwongbgf|)mrVH*rK;3xqO<8+hOAKT%q%6Z^U;yNvE$; zee2q+_~+osnyX26zdjw+z5Mq|Dibp!1LNYx`38-1420P@wb>Y17@N#Rm{{24SQwlc z91XaENkW#Ng$0-}+YIlCR6+} z{UEq^yT@aJZ@l;IFP+@BDs+j*E~eY}BK1V0t>=o>x?eYc74KUnWVT!W`ocyQH-*JI zxhv-}*4b;GW0-vZ@5xEUot-K3o@+mmnW%GV=egQ*`GzwuKihXnZo&snk;)k5)xMW* zDa!lKtepGsy!w2B*)kox8@f^)4R`S6Oi)=eJEpLI*X}wQ>DyTi{EB;C-d?ud;mfA( zl^dVDpCxs{Hgo2?6&i~l+HC%?NpQ~j8i!|hpF7tsx?#0-W$!1GnMbY&JY@UJ*&<;5 Y?ugHqH|jM`he~Rix;Rg6VOHG(0Gwrz!vFvP literal 0 HcmV?d00001 diff --git a/config/systemCertificates/7892ad52.0 b/config/systemCertificates/7892ad52.0 new file mode 100644 index 0000000000000000000000000000000000000000..c55cb68833c0b472a02ef4356c8a08c6ed0ec319 GIT binary patch literal 664 zcmXqLVwz&m#3Z$VnTe5!i9<(oPPEut)~N_C*_cCF*o2uv zgAMr%ct9Ku9@dc5io{|=0Ruh|pPh%@Bfqq`BtOqk!axip!o|ZM9PFduoL^LsUzAvq z36wE0FapUi^JoKQ^pf*)6vaxD6vM?wyCo!*CT%2r>Xdnv=P+2|} zF&2^NQ*lr4U20r)c7<+A;I^AZv!_4vH{b_J3o|nQXJIv922uv{AOU3-U>r4I*8z%6 zS$>cXVB|BlAtwdq35kk?=U literal 0 HcmV?d00001 diff --git a/config/systemCertificates/7a7c655d.0 b/config/systemCertificates/7a7c655d.0 new file mode 100644 index 0000000000000000000000000000000000000000..7a991b766c37179da1de553d53c9b6d9b0c0190b GIT binary patch literal 442 zcmXqLV%%oX#2CGRnTe5!Nti8X{?(G{W@+};+_P@Jm{-R9$;*I?jYF%=%;uPzSe2h=C}|)L5?~e!|uI6EpB8_0?C z8k!oI8kre@L6kVJi2)Lq5~CvxgxT1^Ze(JFI+mG{o!NvPvMpuV6tNOBFYb%~JOZ2mNz<8|7- z#ZCqe2K+!T$qF+v{%2t|U{dSkN_}D7~2eFL3}iABF2F1+wtrXpdP^UR|= qjsTU+VS4{@%AC#9e!f1Y^<$gPKdT8MV%K|;RXk+w8`NISum%7{D~MeH literal 0 HcmV?d00001 diff --git a/config/systemCertificates/7a819ef2.0 b/config/systemCertificates/7a819ef2.0 new file mode 100644 index 0000000000000000000000000000000000000000..42127f823686338b34166e3ecf1b2e27d84535e0 GIT binary patch literal 1467 zcmXqLV%=`g#5{iiGZP~d6B8?^0WTY;R+~rLcV0$DR#pZBS3_fS zS+nZ{f8&XDK9a4n9P?Ley0m`QZ(M66H^FWH;x;uYxqo#s5>_#D62!HvN}7!gY7;{Q zPrqIL;Mt``bzigdCAM>M>;8Rd_nzz6W`UP?4!Mc{i2b|d*8h2)QFERdKU10Z-F{cJ zwoH}jp=;^?R;LAY=V~NqzrUVv`1s^Ky=D_X*Z;UJD12m2dD+2r+nKT&t5&);KVp5h zGwk3L^L~%QWTiLasq9m`yzloPi{g5^;cpRKQ5UjASy{`B%+%#5C|#p|=T z)SbN&!=&wF`Eb+Jsk%<>*RO7#;JiIY_~X61-;Vs~w7*#Tb<*L9SGzhcOn7rA_g?3r z)WT`qyv%>+?2i^(GwJrLf0Z?BU$6fzcKY^NRqdzpzh}*V6nMren8)K8-`W$v5G-dR|#W%xw*>(i&VPdxblwBb5;@`C@y3;B2Hh>E_NzWLIkt@}Rp zOp}x9m(5v{Xuh+p*!cSNY4en8o0j-AK3aHjS9<(Z_QmRg@5BVE_qclbY+|{z`u)|v zJb~u|vN#NXPQ1m_pAy4-*s5E>KCd_3*6P~7+USmxalg+b-sv_jzwBaU%9+G6Nlf6z zJazZq){2jRyq1k-VrFDuT-><9pmD7MKQOh*3NtePXJIv922uvxAOU_B7GPFjGmr&w z_*lePM5J1h_IUUhtFl~qci|iJ5lOd;Q?d>6K+?)A=?19{SQRYvT;fipMBRj$D}jlc zk-?5j%y&Lp^on(bvHGm~>Cc2+n~#`%`+Pu+hj*)cO6-pzxHyn{qv1F_pPoe_1tOM zt(1S^$CG20FIhTl4)1y$T9w-{Q{`(8#fO!ZE8stQtdoHUi{U&JfWU_qL%Enx|r7HnHwxP z>|e(HG-ZEsGAS>-etE#u@4HUSe%7~$@#wX*{gsKIZDbzqY>J6paQNj7kG+zM1VtqC zHnmA-*m;;sb!?BF7B}bkd-WuaM-wGuE`3zIyGz`uX?kH}u;I%2-)fWg7d>1&S@ukq zS`??ng>%<=8^pF$EVXL)>Frv2)ouDG9f6&DLX-|L24p(V`?BeM?vFROK0e;~{{F=N Z5G`)igKCmTf&^GouQmz1I%IfO4*(18XjlLM literal 0 HcmV?d00001 diff --git a/config/systemCertificates/7c302982.0 b/config/systemCertificates/7c302982.0 new file mode 100644 index 0000000000000000000000000000000000000000..662b094951cf68cd45c1daa762f463f69dce016b GIT binary patch literal 1076 zcmXqLVlgmiVwPCI%*4pV#K~}L_M5`b%o`*Pc-c6$+C196^D;7WvoaVoE-~ab;ACSC zWnmL$3UD;!2Pyz^IC$6s67v#s6AeWSgg^r9Jlqfg1?S9?N<$R`C6Fi=k90^;X>o~j zevv|OWpPPrZm~kJo`IHLS`N@xWb_P{1T921!qTHLjyT+UPChjBLfpdBV!{&vnX+1BTFFD(9j%6m_-d0 zZ!|F~Ax8isD+6;ABR_*d6C)Q>6C)$T{=V%~A01K?$~Klf?hwJXI&xJn!{R>;#{;VS zt|+MOG7`F>9O9`epfqEy+ogji=lMzN>F`;6mQu}-Sr*0mOs?Bw|BPuRcA2MMZmn3# zw&yBC94FT&^{Svhx>q;8+R~Y*@>xpw_R8}?Z+TR9?VR_fj-lk&D z|K`stdgpvm@z%OFbKaME{|?kSSv}{T8hmSe2Hymq-v##lUOH1gtKCh`Tsh^2fZtJf zjtMiR#eH|?l^=0^6{Yq&t*q<^n|xv}f9TQX?E+y%Z0t)v zZvOyv^J;?I0h_Q&g z%l5RXvgdugk#l?3iPe(xi;V-G8^{Bbi>xw>gn?KCb_M((1;UJs|5;cKn1Pf5A4q^7 zB)|g95^c!Q0L%x#XkcVemAEpoU-(_WoUCB*EnOE)$pv!RhVy*+=B>4jam=5pt+KFk zhLwfc@7-zhJpNCZ@ZR>yj@etf&Wb`os+n{;n&#eYy2< z#HRA9GV2`u0Ga2vzol2oe{GsNi+#Ds`u;l_is_t}uK7mENXqn;#~hxbVr!J`U3aBo eO7lK*-*fTD<@{_ObQ(|P=3i=b%_gc+M-l)vmxDn7 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/81b9768f.0 b/config/systemCertificates/81b9768f.0 new file mode 100644 index 0000000000000000000000000000000000000000..dae0196507d9166bbf9de6ed93ed5bd91d2a6f7c GIT binary patch literal 969 zcmXqLVm@ln#I$w+GZP~dlK|727_}^JhuQtym7mtRsg@h?vTHrk&& ztLnL}Q0ws3DJJQQxMViOXD)Ntcx3yg{tGjftaOaDx_oEKHJjTd7E8R&_^LL2_gWe( zWby8^XKvxdy5w!Em&G4m((=PUDRAG9qi=3oOnS`rlw%^#5e>)C->0KGMe7P*nC|y2 z;KS3U1MC5c*hY*|CU8utq&? zd&l;QPp7z6SghtsIkZ15c52JPg{pGxu~Grt3PNWbcjs{jTI}#X&BV;ez_>WsAklyi z7{#*ujEw(TSb)i@&43@o7Y6ZJ4VZzHfh)yU1V#fRgNzj0^gGw*%(v-CW8(-{yshZ|Lo0pNehH&82Z8W| zU7xFN3a0j%{+jp4b?dyFK8D^qCcbdi>Dyd!?)Ky0%ED_;6{j%X3T>aIlJc!9?aaM7 z=4V%!Y|Nakd}3aOl6Haf<4||QM9KFNM_cv%48AQe6jMI&{86fy@#+0i(hF>VoQmr< z>`vh5)a7A|3EF<-C)bRNqVe;E_SKjrTkLgNQvXCvo9oE*Ox~A0j}8cg?>JE=G%@s( zN9K(^T1?UWE>{!`Z-3cUpcXqJVcs5ZaZdd$r{$b8PO_^XycF~OmEz6}p*c2l_Rss% i5HmaZ>>Kx0s_N+r%s(?U)rMSO`QxRY@Z$0p@?HQubYDLJ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/82223c44.0 b/config/systemCertificates/82223c44.0 new file mode 100644 index 0000000000000000000000000000000000000000..47d3400beb8045c2698e334efc202e160d3b205f GIT binary patch literal 1373 zcmXqLVvRItVs>1>%*4n9L*4Ezka4LI4DLs{5_nf&|>Weuc3 z94;Oar_#!T#NuKF$6#Gc3u8kwV`C$8Lj?mlkTf%oI853(2c*bIAt*n;M8Vn7Ku(<3 z(7@2Z$jrdP*uua#N}SgOnM-y1nwXT3y~N1Mz}&>d&tTBR#KqLa#K>^{c-;4c>{rTv zJ1c(q@-_3xJ0r&1i`(R%MDp%>UfLY=`jt$gsK;(u_ESCUHr$yu_toKqNo`FU#dE^g z{(Gl<;L$So-1_u9PtCiJUb~A8Qa@kSZ{Ak-`1#j)s}p`+{y2A1N!JsZX=|bzUT*zj z*uFUM&+)p2`F+9VSEe5fHJ)TAp@jEsPe$;eKTfo%f_lz2<4@^;M@; zpWn~sy3Ox9*>A;yv(%X)0^NsLgxtCKcS@vJPXK`;!@S9ATMRiB|pGX(1 z{j})k@9$zMX_@mq0~b9Kl}Kmvs=u1E)pxV;gT&Xd`(DoAH@YtCZKD^(7&MXd)BRVy zH`pAKR|!7(ci4QMNRa)PM`u1IPQLgzJ^Omly8Rie9h?`0n+8{W2>y}i#GZ2Odj4!5 z3*O{4N$btJ7Zr2yepTFCvdZ^W5wqv*BzB&F(%!~|-i=7M{4ETX5S5}yj@jnZz0W**?kOc|wv52vVoNOq6kTj|3 ztJ|EP*^@!*KHb zIfeIZpQg=wxum4NO6e;ES)#Y`L@^Q__xAj;~+h9Mf(J?<^!lM^Ie=8NsTWEbzc`o?J8 zfmLh1U##+deTDsz$9JW^4NK-{o$K4QDdEdvr3=chr$kj{-sRu#5WXfmGT`RonGf^+ z^)gnfD~sNnG`E`5H|n{!he4FYGp^ic{SPkfes;emPqFD>hNbV884+noXS^oF9sZ@x zvawRMWagQDYZdOPCCI!E3tYDN)sw~c%l{|d`55J!W2Ef-Zq15!@4SRKZDI=#?W_EC zs69iL`)^F<8MX_vYC~pfowSsaT<@*r{5d%`D∓W7#JwuU+7}FmM0$M$V5XkE`*n JnIRUo008NES5E){ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/83e9984f.0 b/config/systemCertificates/83e9984f.0 new file mode 100644 index 0000000000000000000000000000000000000000..6eb01cc84d343fbdcef5934f70abecd93db5593b GIT binary patch literal 580 zcmXqLVsbEOVtl%QnTe5!iH9-75;r&S-1?i*f_M>JkHs&Ff$nx8gd(OvN4CU zun9AHgc=GO@Pjz)JRDA?DTxKC#U+Mf1|lFKE*@Ur%;ci{;?!gXpOO?kLvaI9ka!{w zUzlTvN2somv8jcLiKV%roPi8Tf|*A&RX4aQGd(X~At*n;M8Vln!N|bS+(1s87f4zd z85tTGm>ZZyiSwEmA#n%7Ns$J^Z0z7LVPb>^4l^S=vl9c$v^%z4H#St~A5-7wGGXK9 zFwyEhXO&v1mdJO>8Jmv9wOPW91$HC4A3 zCmSS!!&Fw7k?}tZs{u2RGT;LSkSsq)02l|1YzDF*J|Bx1i%7emD96QB2P=3su0MC| zoRXN6YN%?U3=-rLmI*FNEK18v%}G%R zNlnhk%g@PA&rB`WQSi)5)-yCRFaRlI7S=>43(C(gQE*NzD#=XCOinCGRd6gV$;dCt zEU8q`Rd6>lkQ3)MumnOw12BjZ=QTDrG%^MvQ%h6Js6puBCPpRXU}a=wU~XdMXE11D z-d`>a1oOIxgTU`Ca++d%i^=IX| zlXqLq{r#tsVMb!fd9@~oBcjv*#k4g3Mo8warek|YaTNWi( z7H4wc#k8=QU7J7DFFCvSj*(%_#Pbj01%G6(@{GASbIQd{6>DlMF}~T+m0oT5 zC|$2-DzloN^IR{(Z+u&Mc5i=VUaz!^VKHBI(C_Ts)<-T^2Kt?y@FksH@`R0B6)$7$ z(TL}{&sq({XQ> z^=Zx&S8i*E#_zQ?Mqg)~is-A=dN(1mIOV5VNu27!uW77$^_HS5wSEV5_qAqz0RZW3 Bb(jDE literal 0 HcmV?d00001 diff --git a/config/systemCertificates/86212b19.0 b/config/systemCertificates/86212b19.0 new file mode 100644 index 0000000000000000000000000000000000000000..d64e89dec68ce83c11ddd3a04c24439db34a807c GIT binary patch literal 848 zcmXqLV)ij;Vlr94%*4pV#8KnVVkvWFrmg`m8>d#AN85K^Mn+av1_KvEZUas>=1>+k zVW!YvLlFZZ5QmG0+c7OIvnV&DsI<7mP~JcmB+ASqh9s)sms(PuUzDAhmu?^@&TD93 zU}$7%XkuVtWD+ILYYgNW8$!8MvZaYp3EBCKtPIRejQk7+O^jSjO^l2TTUyQ-i|b`i z$;nO(TJU=D`N}CiPp34@JRO?ilG>l1@`&wmjJfAG{n;%oa=M=q<{J2&X=#0=b6#%V zKeN@w<)$t-Os7fNn!TvvyK&WhVOD1M%|E-X)>TGb{c^2v_pAxZ*|WBHl(h56#qXS_ z`)hTu_MP2jc9VTLIC|t3Da%~RTC22cCZk?%>gjzdX`w3K4lWy|uRlE0df=Xbz3tl_ ze?ERx4!*NLb$b5IpALn+wR@*tIk#^?oVxP8zsoMD@iAz=wsHGlo3P(L;L;s6$G~|a z=1we&3&K}Ox4+f>RsF7q>+#C8PRY}bKkvGjC7yp&?slT~+m}g=W`A#+d@QQ_%p&@)3e8Eh{hC8W?&DNzxdiXbapGf@} zF8ef6kIO#i#>KBsIk)75FmOE(^=&WB-5xP5>Td2Oh6P_{d+a-GzGRo#gPQi%=~AML z?&&Rx-n(An=Y)W>1(840)7?)WU%+lvdr>DgN75>7Ywh2O`Ar-5aZJ7~;{I`w`El2I nHpk1?r>vNK|668rQ^F@tCzH2P3?Z#DVrG+gVty@KyZ<%-?OIG! literal 0 HcmV?d00001 diff --git a/config/systemCertificates/869fbf79.0 b/config/systemCertificates/869fbf79.0 new file mode 100644 index 0000000000000000000000000000000000000000..1ff0c9cf054ea45c3944aeb5ac6035e0362135fb GIT binary patch literal 559 zcmXqLV$wEfV%)fZnTe5!iL1JBTT|E$p_(}>47k`hwAwt**|IP*8$=m$8*s8QhqAB< zGld2l3L6N5INZWqsky3IqP-kydc20|b~E@AFe-_n$fqC^GHyktWK138c=v#>Z+ zsjIWILQsBwiGs7Eg06zIv4Na8uc3v3k)eg5g|UHwL6kVJi7^tFrgoPZ2(Yn(eaXbg z#;V=O!l1;Q#K7`*Y2vzSH38X|+m#H~v3+UWywRy}s^y-`L66t3|M_XU=_E5ZzV@lT zJ1wJL?!JHF-wAd{o86)L&5N^sCv9l#WGbljIO_HIrBaBJ@8sQ1JnPHnC@-tMo+x-O z_4tqae_ubXT6dXRSc*($?DOtY!+2Jqe4fsIP{EUqM zSy+Hk!)Cw_;tPZLtOm?L3ORn5GZ+j~nG6}W+|Xz0{JYI3X_vE~a7)qFb$4a%UE6vm ztUtmbO81_Ek5cog$t&vK2{|0U*6#n~ek+rKj7Z9pnrY2~b2eOzO7vdF?|GTw&%!@X fmj16_d)?r|@$&k8jqITY0SY2t!!5X07zP3WZ=$q_ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/882de061.0 b/config/systemCertificates/882de061.0 new file mode 100644 index 0000000000000000000000000000000000000000..f49be65d6093ff1e64e3c8771c58d744684ceb2c GIT binary patch literal 828 zcmXqLVzw}7Vp3SZ%*4pV#HPT;DptT`z{|#|)#lOmotKf3m6gH3+K}6TlZ`o)g-w_# z$lp-VfFH!+66Q!wEh-82boVoqG!O>~aSIE;gcO4O{X-O-9S!8fc@4}A%neKo&5aBU zOrpejjSZ2wlo{T{sD$iTMpg#qCPsb+gC<5UrY1&4hV8~X>rSY8^=-YqMMHX3_=Fc1 zl`g03x;**Cl{IaN4p|A|86hpcd$K~9SpVOjJxgm{EPKD#VU7CtzqNl=emuVRgFvv# zgzmJHD>_!Mk6O&|a^EhuchSYwI^s=@aY;H0nNm0JJ*v%6cjOPVaX9bWN59U+x?Zz5 zYr1XI!3%R5y;eQh#26#nA3yWR#Xudfua;QQC_ z6FuAQmE+e993_V@bQo`|xn6SrPRm7SzEaDDsty{jDo*q1=vmI~>CO|A(N}8{c=R}R z3Kz?PxbLyiKLj3K*j45I`<^)igH*J}<4bdj?Tp%IEIb*gfBoJXbE%*gnkh1Gx=NEz?}BTSYbB)|fU`(p;OAU+?97>me*p4qomJvV=>X}h+`sh#^m z_JW&FkV6@mB!HpJ$Y6I#rc=-K&yUi(&+1b*&e+0iG(t z*&=L3?>R3oT=>|b<>Ye-qY@jBJpTFKSH8<#p4^raGCjE{;A-gkUka0%7R^4aJlRhy zv}{2^W$sx;`Sbd^dn6xs82*TqYUDgIeObxzgd@>s!uvLr{*`9pyd9ZeG&%FTq2sj< zi~a4J_KH>hT=isMhw9x#b!C~YhU_e6TcjrJT~JaO(3!hOkv)9H?K?} bNnu}T=2T|}OW$wrHbnV(x`af;J2e9Ue~Ubw literal 0 HcmV?d00001 diff --git a/config/systemCertificates/88950faa.0 b/config/systemCertificates/88950faa.0 new file mode 100644 index 0000000000000000000000000000000000000000..2913bb06fb98e842ac0361867582aac63e9f7932 GIT binary patch literal 657 zcmXqLV(K+$ViH-v%*4pV#8LX}{^^4m(JKtN*f_M>JkHs&Ff$p{7;+nMvN4CUun9AT z1{?Aj@PIfRJggz96^X@$0tS2_K06P)M}BE>Nq(N8gn<}Hgo}qiIM_$QIlrhNzbLUJ z6DVV7pbwH^=FtGk=q2apDg@={mnb-=7L{bCWhR3aDL9svWaJlRmQ*UZIy)Q4iSrto z85kKF8Cn>c7#K&1^O_hUaR=CSWd;Il?BI}MVq|00Ze(FlVoqXUam`y9aAcXX*}Qm- zUh&h@lv3>PRQ1W8;n=*WP-R!2=S~)B_h}KUb*G+qJCDQkg!=2wp5TbrNnQUwMDu4G z1|>UMcb4W65_T<&9<^!w?Oi$@e+oHgJFNeeSF{%2t|UBE$dHx;fZ(NKK&DrE$HU9Sw@i|Y4^Uv z&tIHnpZSxQJGRK~$SNiS`8~V19~r3puE}i(<(g^Nz-#<8ZSm&CyO&<=?&s857F+k| S13O1X?xmW{y!iW1vr+;2{@4uw literal 0 HcmV?d00001 diff --git a/config/systemCertificates/89c02a45.0 b/config/systemCertificates/89c02a45.0 new file mode 100644 index 0000000000000000000000000000000000000000..9e42698728dd31fa171527c1f0ba5bbf0994c2d8 GIT binary patch literal 653 zcmXqLV(K(#V&Y%G%*4pVBp~m;epM1fK|qKPJkHs&Ff$u8wiGaUlsK=kg@K`=g^{tTrKx4qpmArJfdCsjIP{np z*;ut3Ss0X&Wc<&< z0*rVz1AdTlVGy6yfEh?3$2)TdgFz~jA;Wv-=&Ci_E4YfbcijKK)lGzx>(_#3wH(K! z+V@JVDBi1fDuHM2xta6N$M73G+$UoAipfCa%VZnR<;GPL+}t-O*9y<}+nz6B-Vprn euEGP;S!NfHGwytL=kDkKvN~2`;WsB)UIPHw3dtk@ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/8d6437c3.0 b/config/systemCertificates/8d6437c3.0 new file mode 100644 index 0000000000000000000000000000000000000000..40db2f333a839819fc315dc43e7fb5c5fe6a9b80 GIT binary patch literal 922 zcmXqLVxDHu#8kI{nTe5!Nq~E@jMX*E^jGQ1`wy?5^~KwOmyJ`a&7{?6BzdL_zL`E-}+o8Pbt(e zb^6}R;+N!-KHq+o6VPMd!ZYps_S4J{PUS8X@saMl`<7utP|f;@IU6m6FTNDwIKZ$$ zMqBV!d4bvNb>}ME?=%%W<18r%&0N1YWB&fT+bTDInp>b5`epV1sfnLYI^@e<+&6jm zz~H^#qVy;T+e*DKVkc)Neegb?d+5{ID2@RUXt-TF{W~t zsOODbHp^Y~DtFkk?1@>>{!n^-VBgs{I=_DW%l%+gv#R?^`c%VSCT2zk#>Gws4hHsJIWzRrj@t?QSJv$f+dAEB z`8DKF1|~CLC^IsgS{mB(_=IC#ruyjB&78JqQl_3o&g@#2E1gR> z8k%>VR6Mgf=WMsktZVx{E*YgA>^ksS-|GE=$5$q{T?}~4e7m?j-^()i?LD>QTWi;A zJ6$YIdhDgmbUeWOLFS`rIeac@0xtb)SzrICT(eC2g}KSx;FF1~76q;MDiCWsWOZVr zaDmy4^Y6ZJnOu$b`O7|M(XN|}MKPa!58mb5D8qXsdEeSEBELJ|EOO-YIddZ1;X)qs zs literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9282e51c.0 b/config/systemCertificates/9282e51c.0 new file mode 100644 index 0000000000000000000000000000000000000000..cbccb435dde7829075f291c4f29f36df4fa5fc84 GIT binary patch literal 1425 zcmXqLV(m3(VlG|4%*4pV#3JE!=9&R78>d#AN85K^Mn-N{27@p|ZUas>=1>+kVJ2rk zLjwan5QmFL-8myOFHyk_NaQ7FCgvzOrxulDre!84mSpDVDL9svWaJlRmQ)&w8VG}Q zF!S&@yE!{5xP~bN`TK_$$cghB8W~ssp|OFvfnk(5uaTvpk+C6^OEY_$n3Ryc$jHjT z+{DDsV9>cSyJZt1tR$udtd~arG_le5>n(Qs!q*y2rbUiSoKD}90sCw{atnIsn`isA7*_>3C z%~~zHaQVm2Zx&p2IWKy?NMAO2`iq%A|4v>K(%=(xC1|yt=luz1cf{|rzqjy|ufi48 z7cH8>+c$Q||NnJs!hEikx{mf6KT2r66N}U_@swJ@c6~+1CFY_kqerhYeDidsrBIgU zx%sf~q`OAP+LxHW6g#&{H)B0lW2#lb!P#qlb3;yP>3X+HZ*F*2;L4jFXZoSuddHk6 zECroHs*`VV%~VRrN>1=AW1Hc(w|T8>M3-vorQ@k`x_!s)Z#(v|zKcasRI}uR-JA(? zdGtPZ*+s45;gmam)n@VA>4)V^ep&qF;Cp-^R=fFPSk}pHD?)EN zHDPDL?LO|G!V&p}2?9X^I}bW?zAutbH>~(SjkTAFnUR5Uak4?8fjltT$||!+7>G59 zJpQNqSK|Wr)?M2c9of&einV9*Z+!!PkOE;w#{Vp=2FyUpfDa_V4-#MjW+*lTSrDI( zMT`Zze$<=>OoogMs>gO^zivN$ugP+n?FX0T*)7G)_vUK*?^3AWQ?cp%^bOK;K3}iY z`|7dn(r@vOXP2w&-v$d`c%+|Id7434& z8!>V}SQ3H+H8hz2zYk7hSn6dWmR9qZbIH1S=~DTQ+}Uixv-{f$S-0r-cBUC?mW9j` z{GtA9ll{a8=Xj+*8%V9)uM{hNdA};F@54z_^)u(&xJ*8E#lbVDq5V3G)nTI`Q@*et zOYhbm>E;!b4?ZooNqk#IdDMd|r%$l2`)Z}vXTJRcqqnnWd5`7v{-&rOfloUZNIcJ| zkLA+)z1W@4cA0Y3F~;NlC*ti`-8MS#me!DDaj2UUl-U&*iJd&;VA2{EAHRF zFw2D}&d1G@OmP#qB|dRGYr~rEnUiXtFS^0bZKnR*qcWlE@O9ysA4LxLy-uH>$-u?H zEjaa7m@9J!*ZlMgS1UKJ=yk~DJyhlJ>vMdH`=rysJ9kH(^Z$E6G??+m{nt02mA${9 iyxV$Z<>sqQnrAx~PviG8eeUOUp!6*J`DZ$>tMvf57f$E^ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9339512a.0 b/config/systemCertificates/9339512a.0 new file mode 100644 index 0000000000000000000000000000000000000000..6410587fe66e459b9df9dee42a0211149212b348 GIT binary patch literal 1697 zcmb`Hdo0c$@Xvr zjIe^}8j#wug(fP0wp=+Jglug|HiFiu5+D;g-O!l6Rkj*=s}hXp|Adf8ICs^Q^bpvZ|&@NyZ}tuQa4Ly%u9p z2HMd}8&0Q%4v`hrfeH0kM^(Rx1|f=+M1fin$(5G$W(>=kS3tetM|~P zl3vVGh5Hd3{k6GA_fHq;Z4SK%I4NB;Fny!Z{4{md<)~6mkE#8Mon7yI#2dwaXV}|| zc8cc(&qrr{E3rnLWRnMdM8~COTfDJ-@g1#3XN=oSMSae^&6=R^#@v8YU`%ySfw>jj zKx+)OCb^%anljQBi_0BbdQ?~$rgrJLH<-T8?4%KeSpM~j9n?0~w!^oiPvR>22SnN1 zq+#A+Ri|qnJ;=V@bjglJs>lsB!*R-w<$WA`bx*G(t7x4y?akYO^^zoqkN)hzVHLKT z5nN)Ha8lT|&y85%a@gWyZC9Z*w$9ZmK3C;6*45j~y(DuX$6Q`-=!sLBBC%oY+{NEg zL`~N&7$v=_=3m$7pzP~>e^;8Ra-;pH!>*mbKVb6?Box1(#*klo0;-Vkg?h?3mpObe zJ!7xq%`)5LZABDlLGE=Zg+Hl!7Be6kKmkPp;2b0X(jX<-d(|WYz!C-vp=BGymn*j+KT(|@Z^=GFj^?t+oM18%Dr3Q#6@|dTFq46>$V?8K zi@-=U!s3z{OeQN5VX&G1rn1OiGxDFq&YW+LWDVNvU3!JiNLZd`w&@+2o@VL zfHr-;6hP7nMUcpCG#Zb`GdL8@iCG3TB%Bk-2sdDIB52G=E~KzLq7nup10DxyE(eMj z5=LdVg*Yy--Z?L&g&3aS>^oB11NK4eWm_8)06D)Mj?b+d@xy(66I%1{4wRVr9oVN^c;Wp@3U#VEKk9k5&Ov&` z*`vB639C=)7W2Hf3^rd&T#)+3H{d!R^1_rNbZB-*!%J42?|zz)SC*8bSxP$X6RbK+ z`XeQ-fAnKz%$DEy=grEQ z2Cb5%x7tZATk>Xu-D9SdTrw}Y;vM$7oHNz}bBt=LAd=((}N)@NO?`i_<` zM@odW)YGA(&$3njrIYdr{~4R1@VP8-Ab-d$87ERJ%;!CXa6}e>xT5P@9Q2>H`K3AQ59y14rKUh_j>DQ`YT{@Len*7u*uAo vT!v<z1rz7*%>{Ot1${J#G=MD2x9FjSRN_ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9479c8c3.0 b/config/systemCertificates/9479c8c3.0 new file mode 100644 index 0000000000000000000000000000000000000000..9519275a5d737dc4eda1a28957c2455192a9c7ad GIT binary patch literal 711 zcmXqLVmfTl#N@SrnTe5!iIKs8i;Y98&EuRc3p0~J<0?aL15P&PP!={}Cifsiegj?* zhh3P>u_Plkuh`JVzzHP4C2Z}Hnv;{7mzk{Kn4FlBnhRtk=A|eEr52|q7A0pWc;*$C zWR{ecWaj4;D>$bXmFOurmX>7X7iE@I!c1W%%@kK>XN92r{1RtJ1tSAPQv*41ULa|1 zU~Xt&Y;I^2CC+PNU|?o!0ObxX&y*Pmu(5;Vfr*igRlAXeL5Vqufo0MH#~0pBEisRN z7z)m8OY!4W)t~FA&$Z6fzhvsBz?AIX>}U1`Q$Mh}xGyWR2q>G%6xFv*W8P0)znSlK zJo0^1HD6pTjJ_{>u+)6Z^bJus$qhyqED-OWxOqlY{q-_u3S3jpwE3TvLk_#ZN0a^7RPMu$UE+JNwk5npaE_ GN)rJ9G~Y4+ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9576d26b.0 b/config/systemCertificates/9576d26b.0 new file mode 100644 index 0000000000000000000000000000000000000000..e5e2343aa815011b5044128b849639f2971c30be GIT binary patch literal 1389 zcmXqLV$C#YVh&uu%*4pV#K|yeN5}0AT?dm5c-c6$+C196^D;7WvoaV28FCwNvN4CU zun98-dm9QH2!c55!dy;8i6xoEIf-S7FhMS1E|<*W%yflBy<$B>Nds|^N@igJXGaBy zcu;4*IHwBb49)#I$S)@^iW}FUE}Z7ZUGMt)_7JtTU{ApbL)SN%={bEnJVnE z9a&yF?%l_%V#qPE#vtMS+I(A0de%HQD-6l+WGeRZ*^yIIKzvXkzmsxS~ zjY}qz!=|0~;b9Q7iI+Ni;&{%owU-T-?|Jd`VcNAzznQl|7Q1+! z&Yt(WH|_4s^Vd2Zzp+f}($vh&wvu^XTFX?(_xZr{y{9Gb&P~{KC@o>zMwWLcpSA6r zmFBSGx!~JISLW_->5(rEvI*|Jd%l6mKh>ck#y#M~>}T?g)lXbjM7Pd*bT8`a@t;;M zY2HtaLTaAm%-PImE52xxiO{vWO)ETiU#!w_*tbYb{{9nldBNh}6Sz{H7xC8oU}Fq5 zuHC@9}Ql}`Gee`Y>kcbvbt*>jThWlg@B($l^t?yx?hy{#f=i*o*lzn3?~mCDbY zx?;_@TMv&KR{y@}w)xVY^esstyEwlmZ^tN(mW2zxIO(|ttB=}vQW z3g79id#?E(tg*@K70&%#{o3Hd9pCjwuWnoF6J2=nh2g#z7Hl31r5?SybWg}KLh645 zUsLI`?I+oD_}>4w_&B5R$o6_Z(F>}XdzI#Dzh(XA=Dz0bfe%-#AH8`uEqa2mpIn&L z>kaRx?VhGAxa*U1TS>~)6B?!WWleWoGH3iU;$`|=v?t{-?UJ%hg>#$;31nFFm7uk)%le~((ozJI0Dq|XUT z)1QbeWS{LEWLMKI3inb%mXcwcLZxZUZQgw+UL(<5|Sg9a1O+@Nc>0yz^a%xQ? ziAyh2f?3_A?xoVIOH?=0y0qG|RI8@5x*QBOep>&6{q&yC`@H8p?|IMjfP9?_kPnmG zgh2r))CfJCulL>9Z55G&zSWuGqXG?d^=yQG!W9Dm(AR;04BT!|PZvgo>!P4k3JwjL z?*Ia2LSmlgvXj}dJd78c%VBe)cue+L+!4@WM~9*8{?o}6PYjvO-X3IddCXYm=_nop z<9Uu3&*n0DsTe$na{|$31~?ZS9_Nh5JL2&8a5Do3Jm|EI1Q5g%!vC)`_)yD_9{}h; zV0;6p+DzD`(8S!Z!3-zXq;EQ{Na2>e)i~QBqnpBIKXoKv8cN35iy@g zO%wa{#aRm!=JDYC{E11&w3s&qb@HdAOK$GeZtGgw;!mh&zStskNu+mHX_@8;N)_PI zt-beJ7*$FJTQ6XO*hpu}06`yRD;~MpVbf<BCfabAhZuT#YnIuPZ!Pxg-nB~ha$V9;9S_%) zCv;t3Tljv;IHAjDJWlm!%c?|#IQe*Qt4+n|+*;+}p>Oc1VhO##rTY_IbybGpQAimS z20#GiNstU0Zrj`f2>@Gg_;!$lAaaLMJFEl3whL&n(=dda!uRS8gk=aDIN}5MU9?@} zZ|}B~8mvGgT|HY}01oh-On{vYkdJ-09lUMd0g$R%_lSFY@Tt!3uG9H}Bdw1(kTFNRzr4^jsyF0AOl%Lepxd+)nhM&d;ZKl6T&Ywy`T z9jCP76&ia z(lMgy=D66@W!IkaJi-S`Zl7=c9%)ZuhPZzu7KiaP%C^%VQP(;YXkxO~QM4iT-(OwG zDN}DMKEIiymc=C*&x(IQF!#q4T7|Ax+1PVBW4rYQ^V63XWx#5JL>3p&5U*^E7Qgk# zx!@Lwe3R4ClRodX$@`-(h`^nayRbTpYdiJ7=A?hh{!xXOC3~B)W|mea6`A6^2_=oyUWI0v%bb<@OK6=P}2*6fSU_!i&(yw3l4*wv`z(>i~BUY&78xh+!tJg54eHF-tN zG6qHWA1r!#>0wE!-Y21+ zz#lbFbnCyaiGM9Nf1~cjU1ugbmHVikoM4fE`@@;veR9(y?XD*HJ!92)>scx6z02da z{?DSzmZ$#7-!Liqy2atVA>-jU_XKstW94@QT#S=ko_UYmSmRW{)St^kPKUGwxUT%^ z$;8aaz_{4Sz`=kYm?&h085#exuo^G}DFa!M03VAOiwH;A+0*R*RlXfP`*!z)J&#(< z-Acb3@PVZHLF!q6sgn&klz|Bo7|M(c%T}yaI>%_cZ1Ml33m$X3 zvd6EzT1R$NgHj9FIj;L3&a)5@0_9^{1SKg{Ii zy}4??Vq?HfwxuinPc^@=>ffWyUuWvNwsbvp;=EqMr2oD1#>|&{)UUYr?&5WmDL*f= zL}up_!y|JvN|;Ul8%wG!eaTz0-ER7^vKQ*p7N^~PxbBl<^r;zP&BX;z+N3TSI_}cn zrz;#)mhbn%uaVC_nptUq(7vUN<<8qn$+*!J8%TB(rytMlE n{8`-UOs1L}9i~42`C?9JhosxJ?IvIA&RNd7Y4I`eyT1+q$_H;s literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9685a493.0 b/config/systemCertificates/9685a493.0 new file mode 100644 index 0000000000000000000000000000000000000000..19f91c27e6151c05dc3d0db9460831d30a63f74b GIT binary patch literal 820 zcmXqLVm2^nVv<Bu#0mlV#U+Lc267;AW?^v@afP7#{1OFcM+HLzIdNVCV*^t|Qy?}r zG>H=DHG*(WOpS~zqo`+56QdHcCm2~7n41{+84Q{jxtN+585!36x7hYFjmh)zqAd?6 z{B-EA{P}2af1Y(u{|xebTYYY1TWI8U>zcTeWcIy!x^! zhnD4Rcl>bm1e?XPD?E=rTl?e&^c-ncKPcQ1X*;j9WZMmUbb^7cZ+zez^nX+tEURa=h`fe@okR&v{|yNp_{v%iJ6gs zaj}|#ih&R?%4CHZ8UM3z7_b2;CProhK9CqcNQ?!TB#t46BrrJuLz0n!&+V$sx<~Cd z;~Kk}W;k;6`0TlL`<=RU)AKCXH)7rXtqVSHD%cw}ZP%&1+;?u>dC#@ zicRM4W~`XLO>bMe`jus#e`O}8md$h0zoV2h%l}i9sO84O>)L@Ya%E;5xT*DJVN>1g%6x-436XZ;sY=6nYzw?kH@lxOz(0D!-b8 z8-FjqwpCq!`s%y~vX3sx=*YV~`m=B1!a2XMX$BX!%@4le%olqtxv5aLq2$!JM@-o_ FqX2fFIMo0E literal 0 HcmV?d00001 diff --git a/config/systemCertificates/985c1f52.0 b/config/systemCertificates/985c1f52.0 new file mode 100644 index 0000000000000000000000000000000000000000..3492b9555d8a927fc048accbdfd510d973a4bf8a GIT binary patch literal 1415 zcmXqLVr@2PV$NQ`%*4pV#OL~KH*>S`;nq}-Xa8LT4S3l&wc0$|zVk9N@~|=(_!ue} z$gwepvTzHFyXWL5CFTTYrspXH<>!|uI6ErnDg>Ds3L6N5RB#D%AymKwnUMtzrbf z7RhT}D$uKbzGw38+~7wZH9Z3C7XQ;Wl_%Ccc-3RGYRi&upQm~WvFHBn+0=Rd!h*!| z6A>jFt|(i5kF`3r==NOBd$BIM6FxSc4WIO@ZchM9vdR7I$rAgr%{Ey+S)*dM{loih zGQ#1Lx82+H<5BDO;zc`5SGj(AFxPBhen{8HqOd%@j-!E2E}~Q3Ek0^7ZML6Z6u0|l zHZ#w1gFS`jPnW$>4}38Fd-9e>uasbWK_l0SS*5b`tlC%^=G|_%ruy>^>pb;H zpEAqnS3j37ywS{m@&A1T!JnWsAklyin0{sX85#exumCd!n*l$FFAUt}2QM&?2T3clNEnDUU{`>etANRnk)c`j?Td?lrv{y!cYtNV z#LQ-Z{64y*oN&oy5m`>wTczfjL3M=6i0;sxcI$G64QH=U6C z7a^^oy&`9ATM4e8`Et>2H?s`?&tUywgCL-KSq* zf7`U1Go!Z543}AQX18c(@Gc!z{wGJ~Np6%dx#}}_*W2&%>s6+*RIFg${jTxpt@xU5 zuZ0szRF`kI^FE;yw)gmn_ZE+0CVi;XtY?ygew1xBAHBZk2sXLxY73M8i@v-TJt6k1Drt4hk L&8$%;mk0m=(y?My literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9aef356c.0 b/config/systemCertificates/9aef356c.0 new file mode 100644 index 0000000000000000000000000000000000000000..684b051d9c6e4c99b33a0260b2491f20fdd56abd GIT binary patch literal 673 zcmXqLVw!8v#H6x-nTe5!iHBov>-3zN>Ps3j+^r3`*f_M>JkHs&Ff$u8PBi2;;ACSC zWnmL$3Jo?CG~fquID|Pob8<5C@-vGK1q}E=LhQoq&Ka4>iRt-ELLxd9docyH390gZrXN3S`3ljzB)S{Bi zG@y|snfZANj-@3T`9+x}l?HO+yoTlm7DmQ~md0i##!=$DCPqlyLFwi)0|7R6aHujd zvaxD6vM?wyCo!;O-{LJbPF&6n#nIIPs9tjvgQ0%b9RaW98+p+|Sos zuY8)(Vv)LFv9p0AIL2g!85#exuo^G}DTn|+Sb&+CosGdj78n<@d@N!tBB3i=IxihG z+ADE7XBoTSiRW|oHBCTH5X|We1}RJi=8Ti3y9(7U_-waU(yHk0mw?I4Li=1U`8zJ@ znKM^@@wY>ho_mP=^P9bNV)(ja=0&@i4AND(HuA*1TbVp5|LFwoe`!jm-2ZkNesBI) cwO?SLgtlD&H%+-Ik?;Ey%})o;SeoYz09fDDT>t<8 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9d6523ce.0 b/config/systemCertificates/9d6523ce.0 new file mode 100644 index 0000000000000000000000000000000000000000..2ae55653898a9f1c3e47db696d90461de815f4b9 GIT binary patch literal 1460 zcmXqLV%=cS#5`jGGZP~dlYr=ny{Yao>vv3Nh8dwP;S~9L0HAC$2JoO~~v&^Fir}{PXWwN`~8YL_a6jGC!cj~6lqNz5wUZ(HoSdjAgn$vdI_tU?8`+9w= zmnc(2?TiTTggs}k^Ue}B4!)T9v+C;gip{f(zcaL*ll7fqv3|vyiok-d7=h+M#qWZ) zCT(#~JK@B5#au{~XScZF~7x%8(`4)$$VPJ1+WLaE7& zm1f#qv!?8v`{qp7#viJkF;Uy}d*pK~Rh9>39Bwgvl-8Tfr|NrEa?`U)^W{o&LkyXi z85tNCXBlJ|$O6-}EFX&)i-;W0_igE)9!^r@bUhGisaJ0AQ9N_ zgUe)Y2q33MULt$(5{`CUH3o!8hlBTDDPz z-6c!w*wVfVp%?BqBcz43;wop)=h8}FrfScY8CHC_E6wA#W@C5>+o?IPG+tPwt7(6{ zy45~)@(;7vzTRF3g?7nT@6`|3Zn5N7tmewWn5ev_BT!c{>t{(uQ$3YHKtgH-Mtj3x9-4R4$+?SAd_j= zX0N#{+n301T0MK6WhQr0f`fut|N7r%?{qo5WOwYJ9rNSWQt1W7%WnM0dtl5GpRr24 z{q43ovfLwG$wvlLOee+iZDU_A+0gGkA<$dT z_ipQ>OI$%*;mWQVQP}O+>GHfT zB6`J+Ug4L^a}K+|-7GaXXi|nvRg8VtEg%GW32}?dM%$(`j9?+%LJAMUf-D k_fwPSh3LN<&+<37T(MJV{qAL}J?F0$7pL#5#vg)n0F*6I0{{R3 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/9f533518.0 b/config/systemCertificates/9f533518.0 new file mode 100644 index 0000000000000000000000000000000000000000..74d17527c2ebb7dee136eef4496ec192d0e2e111 GIT binary patch literal 1869 zcmXqLV)ry?Vl`aA%*4pV#K~~-?B$nNYn9I#@Un4gwRyCC=VfGMWo0mETw};>z{$oO z%EBhhr=}_-mlhSJ=9MTUrlb_578ffdmMD~$m+K`b z=B5^Lusr>O*BU4TTH@K!&gib2?fWnVT3JS(qD28%To0xP*lqofVwn8Wn=| z9Q6#<4OBsr%))Z+Ir&M6ISS4hiMdIsMa7xvc?v=K`6UXv3PuJ776x+Syg<^zz|hdh z*wDlvN}Si&!ob`Z#vN+jX<|}Bju1vx2IeLveg=akCN8EXCPsz>_roqfv6@}xx<&Z* z|AX5kyUiUXrUtpc7N4ux(Px^&W~Aqy^x2bTf31tz#=*=+N&$uk-U8g8&zq2ZOQt6E)LKdBpUE3QjJu=D-{PHI>k<~Mbqz}1m9{tI z!OwkCD;jspIaZWjKKPFzbVGZ{3-t-6vOdOZr~jF*H=||0&dJ65FU}AYd7J#>)QpY@ z@tJR3nWxv;w8?e!?E5sar9ai=27^!Sc0=(f%_=Sl6@$g*TdP(w)~a3m$=4V8@vpS; zR!wVhYsYPhcds0-5*?YM!b<%W#S}wRwIw$k=sj=)G_TZ4ktD3B5nd{%VyCCJ|v%7oO{Yhz+wOM|W z?Ox0O>=)TmHb)n2cKY4TX&28CbUf+E71qN2M^c{rSlIl+PH6TDxhrPA`i0+mHNG{k z6uy*raN=%{119~BJ>EXIGll*KOqrw599jIfX5pugfA4w4`zU5X(7DNF^E{$cy}- zU||6kc5DW=Aie^NnSqIc5gQAT$zY&mpuxtW%?2#-*qIo`WHL%h3as??3-WU^lPl3m zG35LREFgjTk&&UHqrTwYB#oP_Q{4Vf2w(Y8|GpG&_OBW~8Bdi;^&4)h@--uaItqkd z-L?HXJ2)i&VZx#noIBsVj;uLm`tgp$%a7?#*Y9$Dz0e&on9#av0iB7&L=7L z>DQFCzU;7!o$*3(`NO@oPEsYa3f5=j1jKrt|NomW_L+|R^+u~mhONcf$qL^LT{$fI zz7*6s6hzry$aY#;VymIglv`Rfm9y6)`Peb#@JW;7Ob_<{B{qlT8 zUe}iJme)({FT7i|sy#aS#pFlXE3WJ)s>qgpYxyMh^z2pbSN;7M{@u))Z)3=>!NgcQ zf5{J@}2%a ze`!8DKvs9rPo{ULBOE< jD3{-G^RCSO*7Me?K0&bJ%gfp8u7(^aX}HMkH2)v~nv>>) literal 0 HcmV?d00001 diff --git a/config/systemCertificates/a2c66da8.0 b/config/systemCertificates/a2c66da8.0 new file mode 100644 index 0000000000000000000000000000000000000000..99bcc84b7e68b5b28e4444f6fa21bc7c2baf497d GIT binary patch literal 1428 zcmXqLVx3^n#9Xm}nTe5!Nq}{>bojhJMWaWS?0c7&m&O?IvTn?JkswJuAWqo zP1e*s_a@Ho#N;1}iL*^!vmT3k6D_sp^~v*R*O)lOZ>&mtSAN1{MOt|H{E&z~9_{V^ z%MEUZy*pJM`*`h1|G1~7&kaxCnjCkhufO5ewuv(wCR84-IKFM;k*!%07R&;@H?Ej3 z(PORc_}XMAFtK2DXp^JS_1i4PT6q&0YZQI1>{%zxTpC-EcGJqxWtOqSeva!=o=Xlr zTe%?p?h^Gq3;iv(3Py;3SBY`!Px*c@v!iTAnQdgOQ(1fG^vo)c4-XazNvF*!Id#ul z?m1ubx@TA3Pnu*k&-M<(6Ia#FZL?e?wd)Q{*>Wi{_qFlOqxZd87|ztnOg-HHU2)SU z!R@>2KV9u9&~Z#ywJ}-3WvWzJQr)+P4ZmNcEHl2?$^LNf_GivZBz7z-XMD&%g-20# zQ;4Q&XUw*5U*l71pZrEK z{)j?gcK*iIZQcHduDQm~Rrs?|?&yL3MH}n5)MkEtlBqvKR`=`8m78RrN;5GtGB7T7 zGH@{92PS7(VMfOPEUX61K+1p*B)|_6U;*Z-HUn7@pN~b1MdZ!($4!?CV^e(Y>!sU2 z-!)^M48K2eDg$OPU@Bu|*qwN@c4f{!@gozZ4=-HA(EB(ggFozi`MQFie`k5k+~v@ z;|G_o$XKF&XYNn+bq1|Fzoq+H+4VTN((ZIU8a!-?Xwiwjs2;$JM? zvV8rD@42RPYNEQXEwY&TxuW}v?-ZoX1m*e!D1M{-ku zW1+3RZ-H_fkJp{XOJ|IxwD59pPM7gN@Ge`S#Ng5cOA~=sMNvkM7okS?3O#RXhzIyS z+vj_+bj^iRza4itFI{!{FsqBdj@j%-zaF{nP!7&v%TEujciZY?pQjO3sdj0}ilph6 zfR&$*WHWvetKHnrfA0t)=$1ze_=^}`TkG{L*Rlgt&`^}&Rl)f&LXk-+o%1iN!lfsC)s~w6 z?Tp>inj~vqxWQ7QGU@KxG3!Bhh+^5 ouE}lQ!_OaFs=4ZwaQTyaJ&lTM*#+DM*S6cTUo72o{&QL#0GZBIfB*mh literal 0 HcmV?d00001 diff --git a/config/systemCertificates/a3896b44.0 b/config/systemCertificates/a3896b44.0 new file mode 100644 index 0000000000000000000000000000000000000000..27d0266c51590d8c9b59f40957ce1e9ca390ac44 GIT binary patch literal 862 zcmXqLVvaIsVscu*%*4pV#K>U4%f_kI=F#?@mywZ`mBApuklTQhjX9KsO_<3mz)-?K z48-9Q<_~st_V-l?DJm^4(aTFMF;q8D1<7y=%LS(<=jN8?WhN(6QdHcw-{L&n41{+84Q{jxtN+5 z85uTj{#SoFcjJ4pn((DOxn*7Y-uqL2`@HM=@L99w>;HFJ4_?096`i6qYgWFFm0D&X z>rAyfS7ovakIkx;n|rq==U7jAx|iLL!VQw@D>-?VP2KO^!}BY2hV_jXN(;RUEh^Vc zpOm?|v+k8*2HOmgY3-L1&GzJ~hs_Irci=$SU!(I&ZuT8gzTUgy^9|KC)1MSreA#BT zWv=yfHRr_(_jpDY`6wH-Ge&&#+b5F|mbU(^W9*5|zFMJftL1OWJ#w(UeYSSzq=q@> zcX_6z%)O)ZJ*E48;yuwRL81$4gHC#{P&|2T>dW(AZdOU7GPRoGvEhtgc%wCv#=U411aPn2BsWf5Hm7lIILW;`-y*SU`DO1;7AT4A{kt!Rn;8HNfKyfg literal 0 HcmV?d00001 diff --git a/config/systemCertificates/a7605362.0 b/config/systemCertificates/a7605362.0 new file mode 100644 index 0000000000000000000000000000000000000000..85c1c66bfee13097c9f6759700e86f10cdc0b4d7 GIT binary patch literal 804 zcmXqLVpcF{V&Yi9%*4pV#3*aP%f_kI=F#?@mywZ`mBGN$klTQhjX9KsO_<5e(~uu1 z59DwOvjykpr4}U`N*aiR1ek>dAOZ@`If=!^Mhec326E!O28ISE24)84MwTW9QR2Kt z$XrT{ZemnIb|@n&19KB2KZ8LNBNtN>BO}8EaWB)kr#|pbJMQvJ%>0kX-o5n=x~A3- z^H-#=+|MlI+mmnPe$_E!i7?ASQ=VBZ&VOQL|95VFAue%tV*KyU$FKJL#nwoxT`sMB z`>f@0_|vtTN4{8TJYQPfVwSo2Z(P~l#kw;uPw-RLsFg_m7-Fq9w=8MCCoN ze$Qo^dU4y%LaR&;d;TpCosM^WwV$zK`7W6Ug@x}U!W#psVzNuz_?nq#9PV3@_o>V% zPrdn2@#i}dFSbm6RqB$>lAur+-ahy9z6BGMZM#$+-cr1Mn2DK@fpM`hF!=d_u_G(Y z$oQXy)qojD83=*|_*l4DIJ_3DifFkUXJfz(65?lJ0VV-9=5TUNtPm{g(OSJw;ph zdY`EJQQdr4!*34ft91KK=`7NRMQ;6g?x`~If^62WM9cTt&lOAA*l!4JQB){!Dr~%E zGs|q>vS{9{oLTY{tAGA{@3hO$Z{8W6-YIu(y3UDv;}np*?n~^EjY4-$S+CHWD-y+8 zy8X@dAPMp`!)X>1t(!kur*w`RSoYxqcOA9NT z7?qGc#>mRR+{DPwV9>07hYY~s1f6c8*c&H8osqivqT(gi|Wd<%A-yIy47IeB?Qi;TKw zk>}R`)>G#lJadBa%?rLRu4&IVFKd5#?I)`??{tR(n_X*4qvl-ooy){^$$NI1w;Q{7 z>e~4^9SnDrIv+etxstxeurkqR_bJD-F9Q=EDi(PzEL+ zU??*(Y%Tu5d?zwmw(R9%t?CIHn|u!#`>&d{@yd=T>i<_xn|aRdL2ixDB8w$#1s}dR z3cj&-@3k*#|7rbqNxpV4!-M~pJG0pNUdzgSTU0dRbd#-MQ}?Ca^R?D1K1*(!TPgYe z`)(f735UDh`tyH1BXo0#-R=c{6sE@etLY0WH~W>c^Y5R1af|Fr0hWKK68abU>{xsL z;ROD(>$r}`R&NiubS3fERngnm=eGxjyk7eF^~u%+stV@6`_A#0v^=zF+*I!8ytE^} zEq$Twvn?@++w5-t+pckR5&OEWr%v^13B8~G_K?AnlUh~3Kl>_6&onk!p!anpxBZpa Uhv!@7KaxBY-*rtv?s4&U0COv1=l}o! literal 0 HcmV?d00001 diff --git a/config/systemCertificates/a9d40e02.0 b/config/systemCertificates/a9d40e02.0 new file mode 100644 index 0000000000000000000000000000000000000000..d5f8989dce1564daf6738935bcd542e65722375d GIT binary patch literal 1355 zcmXqLVs$rYV%A^4%*4pV#3{&Nvd!<9nXZ`uFB_*;n@8JsUPeZ4Rt5t{Lv903Hs(+k zHese9e?t)iArOa4nA_PkC?wd^-A^Id(NM-f3M9%cES#KLR00+a^7ju>aCTI1H!_eD z=QT7pFfuSRurx9^HjNVJH8DcsQp1WSCM9HtGqN%;H!<-u7&I|)F*PwUG8{NsDmk&% zrKF_&AD{KKJ2x1`&b&*W_?$ccoHbXbRL!Bs>zn%8uE+Ij_wMj^e34c zGLG6j$%%4%e)jmU_eb7%@6B4W=I(9Eyz7xtT2nOLUO961Nu`#9 z?EYu!ABCS1D%ia&^>b!v^4_VxrKg{LvSR(Wi+(F^b``3eHM89_?a0TRmFu3K=grgL z-N3i?RA6<5$YBNj`rjg<4+Urby~?$49@FEb_}8Z1Iy;J9*xCB8(b=un_Gocg|I^7@ z=a;TN5!36<_Fu?tO~q*ucGCwd?{~jkFX}JW8NK&g@3F{r9j$x^J73GEA9d~fpKETW zU6Iy2F;Ls~e_(l8(!w|Cc6N=;55iUk$jevFT%EkXMZEkYul4=!a}qb3&gin*^u|WY z+`g`V()pW0A}O~7m_!}_`yY8Nv-sq%ncv-BK9sn*afgxaX%U`)8_lWB?{>zVKg}BD z^GkAi_O)2y%ZFk@_81i}sQCIZSMK!urOW0k-MJVzuc8UzwEq*6oz5m9NWrwpaD)RH;v_ z%htCt<*)m3&G5hKNv{*fyH?(u@9jBTFns1DXTf{hjF+6b-kVZ;<*bc{&X!rzUip4K z;&McFl|sV}&Cu@;9RIMX{oiT!)mel&t>U5J##;*UZVVL+ic94fG!iTFS1>a6&o!C# z|BJr_mli+D15&qmJwR=9o+_eCy?pKMCa!Kyre0*^e~_sDW8x60b}7pFd% zcD*DeyU>rxW>xEFg~iU6WzjhS|7Oh*kxLcn65YGF$u-I|EbG#ojmbt&6CVUC@h#`_ ze091`e#N7thHnC{K{MDS?kzp5U%%?gOFNFDH_FURHp^Ds*ppsjD zCMSQ!Z`-U9xO}wNKy4P z)iZlCAA98SUN}Bieb%ZU!jtaG-A|rxx>C&SP0xsC%f_kI=F#?@mywZ`mBApwklTQhjX9KsO_<3mz);&j z6U5;XR`NZ!)qnFgG#s zGZ-{6axpbAGBW%vU$srONF9r~Phtkv}k(=n^9Nt@RHnzMh&vnve- zGd}Zfo7}(h$_=wm8~${i(pe~KJk{{l0qIZgl4iCg+wZ?SS*v+P*-l~k?dSZQTKkor z>q&i@%DIVktBYUxLWR96KlyRh2CV(c%IoUyR`^%LF8DXg4c+UhvR=}^&RcIVoMoDK zqMPk9!^BThI8uE!ny@icbw2uVoH_FR)oU-78*P3z!=dfyS#_cAGu7v|3)&g1ziDaP6{|}h zlV>g1$N4RM`#l3bkTgFd<9`+wVDe!z;0N)AL3~yNW*~(e%D}_~3}r@!1q&_2()5;x z$t%ub`z8B!r_xaiwHto^Zx+{A-g8r2*k0bx&M|A#lB4VSjb?Dyq-k!OU8@@8>Ac!U zPdl%wV7(aMW2T(nPR}Ify50yq@xuD<^M_ybxMfUYaw5Eb_jClrPnFsKcD2&h)XlBC z=JD@X`?N~BE5J&2FYlh}kO1zTPU}M#NHnfZo%w#>lR5j3w61pC6q0{O_3Ybr?GT*%JyCynJfq{o5|3-$iocx%**=NJc7jCf@#}+Nu6Aa(g zB)Vu$f9{5vURkfWUpS|w!mpAX%)qiiZEvkCG^mnA+^4C*)lq@SB z>T>j-*)ws6<9CsR$}11Ao#pDXdDC^Bv&S?a1qiH*Io;GJE@4(X{aMGX4ZbFvUvzdx zrD<&tpFK~mY_3A zQ)8QOw16=sw=C`9#M^o72NE0fHtFg26fD1JZL@jele}$5tP4KnOq$Ml*1cBZz~|lb z_^)-ZW8W6Ve~z2Sefd+n9eZn!&o*6oX%^A4HGpMG-biBAd#o8HV7ynl%4x0Ln8w+ge~r>0C2;MIC` zui&FZdQ(s0y&Zcl>d*Pje?j}LblJ`)mZ3j>ER@}`s)50$>G`I5&K-LU7U=VS4Vu^Y zebQzw23dxX>1+=+vfn(;ACp>ZlN%ZSF+!xhwY+jw zQza8KBLm}NCj$p?VwUA&5n~Z~bkbqI@3|MV7S^2Svrj#$*^wm~XuuCl>$1X(jQ?3! z4VZzH0UtRMPv^{nBddYriYf{LE^9zMS-u<=$V< z$`hx-}zrotGK|;V1Lvn{mP{edwFjD+>~tIW1iYtkQEcnS+sL)vdzZ3 zKmHi)H*b5gyKjbi-7a~thXsP4nD4758L6vD7`4p*&tN6IYnJa9{~aO)N*hmUPdKM} zu;7dS-1<)wQu5#1+&ZXcMQkUg#__49hsl+0+ zSpD6xnjL-Dms(w)v2ae0K|zz7;f2y~zPh)3o@Z!Yb+uk)?UOx!|DMTfe!;V1yJHUf-Muz#)AcU_0Q?0~ivR!s literal 0 HcmV?d00001 diff --git a/config/systemCertificates/aeb67534.0 b/config/systemCertificates/aeb67534.0 new file mode 100644 index 0000000000000000000000000000000000000000..f1317bf3b2bdd38c9d3e97f65379e76cbcc0ef37 GIT binary patch literal 1370 zcmXqLVhuBBVzFDm%*4pVB=An#_VpFTdm<~6*06lOdxX(|myJ`a&7D}zDf zXG3lSPB!LH7B*of*I+|y14|HxOW4RUJvA>mGf}}gu_Q4kF)vXeB~`&WwWuUBEi*YW zIWu2D!_U)AAyC)A!obkb+)UR~(@?`e4WyY{SUxzls4O+JSRtS^DJL_z7+tTSsev&> zrA}CCdTOacMoCFQv6a4ld3m{Ba$-p`&>p?K)Dr!&)S|?qqSPD(jbu#&Vtgq%DWSs9p{82K3tni#p5niv@wHY*+Xe>B}`YKMEX!#7#+&&|au za)F;`bRC|woRj7x?vVTZ)Tws;+s|DdDX~o=lW!b&@_%zc(WkO+n`4~< zDlbg2%jRL&cO#q6PwS1{r87;7BvOrq%jeCCl@h*j__pnd=~eFv-Y$PubGz`o?v$ka zx!1m0?6Y6m$|bpD#SP9VX{I@;VIj^-+Z_*;kh~!Gb01z;>O1Y zjSmcDfeA`hkVVWuq){j}IX*Et*#Rlt8t{Xpg&7(Dv#=U411SSOkN`hOfCZQ_*&zD) zSj1RF798$&S!KS|b^r8+sEZ#f7R`Pc+iOq{Qm(*KVNhmJ!p5!5#>m3>wStkEk;@>} zK!=S3D8S0f&crB2Fyk1Q!c{XFXiBLQnca}n0kD_=rUOQX1s>5&jNg1cc36g*&S|I$ zo_RIu|HeY=GnSlF;;!9#zmG9G_OjfKzqS5n7dSpJnY{n>qqaHblO}}8+~DGcjoS~pF8JZ`;Mwaj+f=!^#!Y|?%tfP zlOor;e^1G@g@>zz-tb7}HS^fKC~}+s+v957^k*9v{&@1YWvvES*cw(ZlOyXNU_KJ}$|5)=16pS0Hs|8}08t833E#U+Ll+H+Fp%w3u=)hej|>&4X^d7s}!|Lm}>+mWBg{KN?WtyS)D literal 0 HcmV?d00001 diff --git a/config/systemCertificates/b0ed035a.0 b/config/systemCertificates/b0ed035a.0 new file mode 100644 index 0000000000000000000000000000000000000000..6927c52beb79d15a2169b05277faa8545efa2f4e GIT binary patch literal 1349 zcmXqLVs$iVV%A*1%*4pV#Kg1DfR~L^tIebBJ1-+6H!Fidpdq&bCmVAp3!5-gNVuVp zfdGiZCCnM(=o#+lr|ax!C}6+`65|$T56aIkQ2>g_7)XIcn1zKy!krxz+;j4i5_1%w zvIcVEyoN>wW=7^fY+-C1CC+PXU}$7)XlQC`X=)io3oDzLl#o5f$jZRn#Kg~F(8R>W z)WpQduz~gViPt?x^12k?_xa8#7ERNmIUn)RtK?Z`WAM)pZpHeX=6AMh=7eH!2C2kr^_+D4Y9K~@^g zKdQx!N$g0v=B_&N+y_Y^-?hnKFWZ;KYkpX0AfvTl#xl{p@BT`feRwp{x&POxYXa(? zKJV`y{McGB`_!uyQOY1`R zeMUMd3~I@VW`2v^w%gZk)?Jf3VbRn@=g!}1dd_YlIql^R#Z{Vh%PjWwX?iK9RmyKZ zyp=Qk-nA?2ZlASoJySAIINi97e*yo?6I1K=hfZXzI&Uj_Apaic6vpQ3CemjdmVVeV zJN@d6iPpI1TNhkJk?$^;|&1cG< z_kPcQtv%5P0{R^b3fnjNZf9B9ve;<-x_8;)-J3T4%Xv7Vr(?x*k8>w{Pk&}RAD_kL zv{6p3T)%I@vq^kxe^`|+sXa6dtTnpB&&15gz_?i1KoOjjW%(Hy|Ff_Fvjm#~KQJN7 z3WNBp2FySTIT-=-2QV2iGQ^uSmc5@Qd-dton@q_qVh7hPCmmCXs%(LY@?*Cio$K*1{dqEE#hF_Y?yr+ELzj>N*-wy^R$ltrg zy-BxpyR*mS=ie%iwZt|=CQSKLF{9sRa^PEs3GDY%l2uOo6|ye8K1Hg-=%Z4J(z>O~ zZU|-iBrIlnr~T$i@+9uKefnkDi?^xm>1V#d^~op2ZLek0(`m0wk_9!+O#Qg_{rfu& z5gsqScf3kn^YTx_)~zR8f37(=|K`qDNgaJhK6*C`t$o(ra&6wB*Ub|1vvy0XBp4T* zdGp=qbIi@k+V}I8{5z?9SmmAQq>Z){{ngs`rWLCQzgn^``QX~x7G@iPiZtwo)-DQ}?yr@z>?& smRW6OHuf*O_&g?rG4^!DmyndkVdA|DJ%1zpA7g){$0Gz-*d;kCd literal 0 HcmV?d00001 diff --git a/config/systemCertificates/b0f3e76e.0 b/config/systemCertificates/b0f3e76e.0 new file mode 100644 index 0000000000000000000000000000000000000000..1e6967febb897f69cc81064c6ba584fc91bcfb13 GIT binary patch literal 889 zcmXqLVlFjkVv1eB%*4pV#LdD01dO8IQHQ4(@Un4gwRyCC=VfGMWo0l3H{>?pWMd9x zVH0L@ay67R5C?I%gazDl@{;D#ZXBDIdNV~3j<37Lqj72Aczv@HL@@;G_rtlX=ia0qY|mhT4XLYN9@iB*y;{bnfPJAYm%&-lUjH9=uk-|n%DfMFcSP^|pO-rV^4V-UGNZM8k1h|{k<)o*_D`ErPycp)6|$LBG40x&lDx?- zi5Gj1yKO4vYkMKtbu~BVYK7R;MK4cqS-k$FBJ5urGFiCQN_vl+$<}Vxo}K008*j@i zOkB+woHyZIwRy?T0{4kZfyrW(>o%@)RO2`yseRFHmB+Odt?SJu|8=wu=14kwv9~_I zT=Pvamo3g?nKC1yUkTQ@3 z3GlIqv4|v8r%Ac;PCwNdpkK>!)?~&1KYzWELm8NqfT7IDaIN@xjepsN-u-WOE!t;t zRKsX%&7Yh(I@)_V=LPT2j$0+@vF$0x;?1XQ6MZkcac;Idyx?(isPv~@@7G#Bblz#P z_?do}n)Uky0bxInas9P8dxX0naLV)|MR}r z*_rJ2ZPlOqdous(33;T7A|GKXaDFy3OTT)%0X$;N61lx5I1`pJY9Zx%Ta!?LEgc?CX+) z_6G-l(SCXS@3!wv@vWB}C2luvW|286zoa2wRN>@3o(?YAYiXg6{&<|!RLgt-09X)I A(*OVf literal 0 HcmV?d00001 diff --git a/config/systemCertificates/b3fb433b.0 b/config/systemCertificates/b3fb433b.0 new file mode 100644 index 0000000000000000000000000000000000000000..ae9933cab4f4f764f56a9dcd4715a0ddace1f809 GIT binary patch literal 765 zcmXqLV)|*&#MH2WnTe5!iI-tnccmr+5CmM9_|t%kjYF%=B%S$cM z&q+;B%+W1LEy^u6v@|e>s5H<>)>JSuFf>v?F-k#KAuYd1A+fY1BfluKDm6u+v^Z5E zKQE`!(AdBbq?K7%3#vmQC_leM!8x_4Br`2DIk6-&KTp9CqOqhBXppP3p@Ez@ub~kT zS{RxdnHrl#iSrtpL%60O?lACSnSlTsJ2=Le7};308(A2Xn3EV-T7*wt*p=&8{V3(KZ#CMlIK(Vdy@k9QoZ{rHLL===rWqOW$dNw)b13*@q^s4rab2-lXGiAU91)*2g-kaoOETSJG*`+b>p!866T<;&DQ+%GugB6COSlitoHUFB}~aueS(ef_=l{+WM%|NpIg zww%czdgk?3bGEJ39DiS{cY96w`S92BJ~fUPHIp)Oi*Mwstx;s!F>||`W3+0*x(gms G@7MqXmHJZv literal 0 HcmV?d00001 diff --git a/config/systemCertificates/b74d2bd5.0 b/config/systemCertificates/b74d2bd5.0 new file mode 100644 index 0000000000000000000000000000000000000000..235e1868581921cf51a8c6a0ef2eb6b70e80804b GIT binary patch literal 594 zcmXqLV)8R+V!XV7nTe5!iOc32`^t<0zFXZb23%|$T5TTZY+0C@4YCcn4LI4DLs{5_ znLParg$)Ej9ByH*)ZF0A^gM+CZ%;#217(mPm#|E#Z)r+KQKCXfYH~(ieolURW@@p5 zPiAgrNotCrf`J@J8MClBRIjVEvqDgQeu;v!qk^u2yRm_sIIp3Ffsvtwp@p%5fkBiw zuZb}dm%ffEGZ0{72ZsX_BO9xBBMXBPa}ooK@=~51xNC?UzDZN$}-QY$w3;$kNQ2LoAPK*{p4h_Q&@!AUpdn?yYZa3 zjGm_49FJrt13r*6KO^IR78YRSu^I4#_`)DQs{u2RLXJV^Oa_BACPRjOpA*kB3CN~Q zW#1u@*U`$V-^?LC;go!r&kJ7Zs*P)}HgdYZw_d}+QWGGk66 u+h=8rPSq!VB;4!`><+d5-BbNKmGkhAX=mM6G<^~aEmx@%5}3-OvlsvcthZ|b literal 0 HcmV?d00001 diff --git a/config/systemCertificates/b7db1890.0 b/config/systemCertificates/b7db1890.0 new file mode 100644 index 0000000000000000000000000000000000000000..d0e8f0bd110db8e87ddcfb7a31663be8ec075664 GIT binary patch literal 895 zcmXqLVy-r5VoF}X%*4pV#K>sC%f_kI=F#?@mywZ`mBAq1klTQhjX9KsO_(Vp+)&6s z0L0!|u07bM6G(aNEJc=RV&W;KY;nbp%%(Tqp z#FEVXJO#(nl8pSK%#un2IdNVC3j+%y3j=c_6Jz5jab9BsLnC8DLsL^rQ_CpYJD`bC z3E9((tPIRejQk7+O^jSjO^l2T8|sR7EMcDVZ23J-i-}%>4(-cpB2z@Fw+af}{kQ+> zf!$$`T2;T87V-ZGzTo)Kh4Ii9nZt%oV(zWRN@bh4^7)^t2KcwO?b|;?Pas`xpCD@+ z>x3hb7iua5HZ;U+e|TKG^mNVqbz3jaRW?sve#dE%?j#oJfP>XL?4(bIv2^PP&0f1Q z?B&7#Ygb0J8*FR*KHc??WVp3<{uB2vGhP45e*7_gafhtAOicfSGSyiDKNf`icbQP8 ze97q8;ni&W|NP$nd2Q{aB&KN1%chGb&vH&lh~4zd=)X0~dS8dEpT{4+SN@xQ`YC_6 z1@AkqKmYh=%r`K+n-i4!v%7Jh(nFaD=3Nt|JK33-85tNCI~h2Dqgj@pk?}tZ3ox~? z8Sn!mSymXtXEk63QU?M}6nW-k2~4hN=ds5cpSot*qX>-jQ<`c9`=*94yi zpVL3{=@#pee~$u=Shdxjxm72?X+6nQD|pkt*V?Q%b7G%ecz-!7ZJww`Yt@S;hBb1_ zIWxnYE@uQv>*rag+!GI1{kS}dMSh1u%R{pevEvT+ zthd#AN85K^Mn-N{1_K*IIRhCs=1>-9 z9#O}V{9=WWqSE4$)Rdt7{1OEt14BbYUIT8BJQoiONZyd!fD^=J6J~O8HINhMH8eCZ zH!wFeF|{x@h!W>DHZU|Y1|m~SQ_Cm{O>bgULUt}AD+6;ABR_*d6C)Q>6C)$T)K=^1 z`C8U`*5{Xf)->IBUSf^is+&K27uZR;@7y!%{-=Lu?A%{eO*^F0XZmF&&!48hxd)4q z)c3y1e*L`bOo-itfb$Jkrv84hwdsn;(QPY3Rl{#@4EVMoAtkaZ^E~tReBOPh?D9*B zUad0FDo)zxIWh5s;6FZQt?yY1cbG(Z<3zLmJZ?I;_2}Fb&YZ=OGuYLSOHb2IEGf)! z{`lRrQ{ch8H=zs7l@_(Ludf1tm85tNC*BVqC$O5B8mXAe@MP&I>wv9T=I1}Dooc^+4-5zVnoZE^9{2*yz zM#ldvtOm?L%0M0@pv)p+Al86ghXhE00*jylKQIQkwb>Y17&quLvoJCm@PTCbL1wW4 zQ&t;t1Od|%FoGBv)XGh6Pw{Bea-6GU$2KA1NY5JXkR9?nt1q)#KKW%=y~)<^?R@3E z(?4g&ynpxCVcGqKlNWNet$D9-p^|ZL#dpaYDuyO3jLUY3&N{4q=Y~K38HwcoGx_-@ zW|xXRRQz*8?YR5)W#=P`3hQ<~^quN%eR6&7!Yv2ibbi~yZ?W}J${p47%Wl7(6*F_; zQI30mpWV88Ey|VW$o4~9Mc!`_{Ld%4_3PK$$M(LCTK*wSX{AkS$T86sd)wxnZJw4< zRoK}1ko(~)LFo*RGnw<=%yXRQVx(5}sGY0O_VtsfC6{g=J$vk4LjBIq{w|Z=Yi*aX dTP}H%yLO|wqtk|639_I5aSCqu&|bZKE&wvJSqA_B literal 0 HcmV?d00001 diff --git a/config/systemCertificates/b936d1c6.0 b/config/systemCertificates/b936d1c6.0 new file mode 100644 index 0000000000000000000000000000000000000000..d6aa0f435805de638e5c6cac066ebb0081fac3c4 GIT binary patch literal 1415 zcmXqLVr@2PV$NQ`%*4pV#2-7k*C5^O1e>hX@sO5Gb^~5EPOUbNw(q=*jNGgY2G)k$ z2Apinp)72|Os>I(f(HB`4i^uHo1brpZjiIDp`?L0NQj$9z|mPD$k8)O0VZW2C(dhN zVQ64vX=rL{X=)ZF&TDL7UF29mP zo<&?GVwJg<#Qmq1SHk~ZKd3X2apEJTE6fKX{*=4F>9;F!-nGW0*Vm#fy>G*bd;{Z% z!k8^zv-7Sn2J8^7%kf(5c~L>~-JS!Q5~<7Y{d<3xYl7l)sq{%s0yE!;yx=Kw*2};OYibA`6D^2j>=>)vU=%XI(l%0iCS#h(o0N=KP9%a zef67}zhbpd;EVGC5=YBVSaRxkPBNOgVz;<><%X!E&lVqvOm#PHj$8S{lzZmxCubFo z&Gurm+?w%6Y1g~Z9&Nu@pEo}Kvu)O+3+)0TcK zYhA3-|FR*kF?eZi{0@(whklwZ)ARhlW7?q}_RX_9BL2LVmbs@}@M!uZgN2=s_k^xc zzvlgR!rJa%$*PgMD@^a6nr^)3>Dl9RFTQyn$LBSHO)Yut&YPyX?7PZRb=HLU*M4E2 za=nphTI^zW&#P4z!hcFX4|XeEwV~4KbVeb^%Y?m_ndiQ&KOE+8d~MJo&L{b8?p^Y) zHPmC971pzy%n6&-?e>+4nUR5UabvSVV*@zR$_g_w{%2t|U z16dHCk420{hvvvLjWK+*~<<_4w)#%wG=CWC>tfhHS= zHX9==D?1aTm~2K#Nr9EVetCJhUUF(tiC$V>Zi!xMv3^QHa-<$ta@_YXqxlaZ2KAhU|e*6D2^Rnn~c^#kECmAVC=C#V| z6G`LI4K4{!mAks>u5zRG(lllDbk6>V<*S^}rUr7n4UG8r%<|`H_m(B1AIo+xdAG#+ zNc{Uv#?u5Pwx3MhC-HFck~_a7eqP=qJlnF$WY=ZK-@lByw6<%vac4GL>^s|~$6c_t zS8dWexvz}cTsN;xpPlz$g`|v?VmFVR!&>I&chl;=?o{AqelhK5lj{}B2MZWtug`c^ zJ1@QX@GPzGtGgFkiM%)26U5g!V-|};i)@{1=H&2muh0DmsPUJ{V{xAS^P07?#LHKG z7k%A&KUzP@I<@P!^7h%kW-@9oRXN6YA9tO0TSdA7Ie>dNlZzp)Jx9K z)lu-wOV%?qG|&ghF$-(B=PQ6E6@v2fOB9?_i%K%nGLsWaQWYFaOEU6{GD|8IbQRo< z4CKUl4J?7s&;Sgg#CeU)4ULR}$kfu*GHQ^xvWZa%Irtb^8JL?G`56qF7`d357#SJ% z7bbCh{1s{PUHYWN;_nTf5igaRg_j*waAve_`S`5WbH4hkZ!OY(3%1-Ym~q^QaU-i8 zyWhJnzx?$h4V0d*mJG{&)WH7dvsh_^WnlHwpQhVN{8sih2|w9pzmmE6*P?x0qFMF# zxDRiW6k$E}>hKDdDb{W^M!cUH(v(j0X6Bmp2uf_fyh$cui^VUdo^zM)y0PEmvU?p{ zbE4+=2JPS_laew6Raq0ITpD|HRyt2pzQ4w*aTcHEQJIx5W97EZn`gjfdG2FJ!*B1{ zGe&P(lblsen8MTpk~+x)X@f+aLO(Id&r>-Or*e2W@MOoJGS!b&*_or%!wcCtl11pbr&l1 z`KPvT`Mzwjc#DP8E!OHEOr<;iF5P&2-M8!agii+x)OERCoc?RO zp0?oX2^-WKe!iF=_0oL)>L>SeHn)n;wY{n0UpdkAT0G0^hUV3?m~^)ae7P~m>;X85swAuG-$dtLsriJBjr{lsYTTZD}?Q6 ueeG2a{zo$Z>cn@fiTid%Y?Cu5kMFnT*;{6|q@Jqkc=X6+U(EMcGG75Um}y7= literal 0 HcmV?d00001 diff --git a/config/systemCertificates/bd43e1dd.0 b/config/systemCertificates/bd43e1dd.0 new file mode 100644 index 0000000000000000000000000000000000000000..91d8e47bc5096b56a9f08bf4c263551c2bc465c0 GIT binary patch literal 1491 zcmXqLVm)ur#Jqh0GZP~dlL&`ce3#GCHw-5yJKR5VY@PBBnW!ZOylk9WZ60mkc^MhG zSs4uS4Y>_C*_cCF*o2upybXm61V9`PVNQ?yymSR`AORC&M-~$^5CN&<66OV|%Lb_p z$S*E2R4|YOi8Bj}qlha6<>!|uI6EpB8_0?C8k!rJ85kQF8CjZ`MTzs87$I@#@1Q0o zCFDS1WMyD(V&Z2oXky}GYGPt!*xYgb)j56zzkScHG3UOE{BtP$zGlY4WkPoq2X%5#99epkL|Bt;^p(eQ7%L$r+jF-toQ01`5W(H<#_cYA4+HQoh}DZGdjT zDT#fI5sQQirtR+R2y2M>u~*0Dp-*_n?#nx;zCV5Z+bzQqjb+b5I=?y^o_eY#b++k2 z!7Xde-B+2v&fFFHHRWOg-{wxw9bNjYms(skYWgz*gev}UZw)?uXogJ7;&~hPDKEKo z=Y+Q0tvpw`&Kb9UGU&0rG)S+5&a+1;ViUPl!YZP%R+c*tS3Z$p2wW3T~7q|FT3@?FUjt4;|7B<%lieb3bP z{^>{mP0wPSvbZL?RaVQ=>O#oEiZG9O+#C{_RXQ z{cT)6{gwOp!5L&|}liJ6gsadEOiq5(fJ zY0C;TGX7^_HDCr(27Dj^evkkQFvqbO$b1M{BKJmiU^2#r#gMvQgv6Fsh{f}^Y`nqx6 z`UNxB?pw*2cG^PL=DxH17vH=syTsl8)c$R6tjyvy=KrPtLu6;e=2+iV(;xnPB60M` zRf`@qo4=nl9=(h5?9jPiY1=n%g3Vq>FRQ!J-)3z&XRm5dZ&bU8dCG-5RSSde*6Z81x4DRQ<}_&AOT!G;P3av%BO}9lQ@tB&azZoN3ZDvRsBHGXaYoVo$HxSV&Q9i+dtb%5 z1#{ks`5N`&yQ>z{Ys19rn#Mloj@NLR*YWQ%n(^jLMAuTl1Q@_LeZ$Q$;;^+NU&P>dV42+8#=NdH5G7x6t)MjI3VQexN zVPavEV_|S+a5Ufs#-c1g3kxurv>EV&IKqsK|5;cKn1PgmEJ%QlMT|vcy$j1B$2yPZ z+kTczZ{D<2Jv(=DiGc}7TAoGMK-)lbf%*c~Hsy?xk^(Dz{p6w?y<%|6DFLM%z2y8{ z{a|-zM?Ii~fdJecqKqJW8IWTTm>7XE$jFc^#oo%bgCteU@ETpPw~##xk03Uahi3ly8!0l$T4KU-+-mbMhYN(!SU@s7;!Y zBmGXrjYoWQ(9+vWCr&(XemVcSI){~?q`cMgh#2wnmG<3FmS0v=o~y`o8ty7U!+rx+3#`-cjS-zs$Xa?MBB%D@}uzbC)a|lB8E0 z5BJ=Y6&jc>>b1|5{mIqR8RnG+BDXc?<{ZsD;~u)m;QN`F`a_3j$YlG8HN38>NOfJr mAhn){H#Eh>W5=YOAGZW(e)3nAzm>B_-sRz4<%+=Q<6;2D@5qwPB{BO@y-gF)j4Lv903Hs(+kHesgF zU_&tj5fFzJSuFfdaE0)SOqGs z5R{)^qTrlbRFavNnVeXXnV+ZNSXz>iUzAx=X&@)gYhY$*Xk>0=U}S7!6eZ4U1m&87 zxI@uPO^iy&5yQyJz}&>h&tTBR$i>ve$jGp5>NaPmU&nH_@;&ZP@v#hNeRsH0&@sd8 z?VEqI82cAmX#Dvu;FhN6D<`#4%J10415-OTocwRtZOnXodvmp&LQCA+O<@|#e>~Xf zP-uSiv^(E)t&9UoQ}p|nW58uAarXCLt;ku* zQ^j>$=gH?eSLX7>%=qWA{HU^fOx)kR=W<)VWw>5!YmQ#j)w}VrX2U<#!j853_Vlj_ zn&!PKu=k0uq2voc-}$%KY|gs6$1{|guAt}4L2KiN2(nX{P%3~qwft*Qh%G6 z^Jz8|_^!8T)0bMfDf2f zWce8x|Ff_FlQo+GKZq|3;U_U3}qt}Gvm7z-|GaCZ7u%kId)B4EHL%@JmJBsf-MhuNZ8&&a9wy;b-!Ti9DoEVVvC0^vwnXiiG^qMy$gTZzr>@VQbz|Pkk58O?9|^ix?O(sQ*{L|F zd)4mcn&-c!$Z+{y+_P%Ue60)r>+5gTzS{WKK=okDEt5;p70qF9=9nE;dnEWR-BWhb z>Ym@P|5v?h^;#a#@L_q3*A%^Y)|oazjt|amNj}f$ylYPLo&E&t&rw^pRIj_mJ;9>% eeWPsJrSIVdW}El_(O6%o+8QnVPp&>{iwyviEV63= literal 0 HcmV?d00001 diff --git a/config/systemCertificates/c2c1704e.0 b/config/systemCertificates/c2c1704e.0 new file mode 100644 index 0000000000000000000000000000000000000000..bc42b2d8da356a2f403d4004d30e41925afe1588 GIT binary patch literal 1060 zcmXqLVo@+?V&+)D%*4pV#L3Xoq!TZbbiu)ZmyJ`a&7d$y$iY=PrxulDre!84mZT~;mX>7X7lDiu zHxLCWWai<6D|B^s)HO7a6X!KFGcYnRF*GtZGB%D9=QXkfG7SyQjVuhzqXxV4n;4al z1DuhSfw_s1pTVGsk&CH`k&)qi{{z9T^H-FW-M-Hs^1e7(vuUmSvBlYM|HT{sa1MMa zWjxVPd_l>PE6W+5ZJK14HTNyw&ypDqm+hGw*qR((Y<#plaJg)=TK4LDzr-hM-#E5L zZsR;j#;enpz2e<|Bvf9#<`T!%GI>qWb_dJ57OsM&7iKLtd9eTNi6GgX?sdF7b|2&U zRva!CRp&fWKGf=1t_#bmIVd7 zpmTJV;%wWuPSycxpWd7+Ok_(^4DqW!IM=RTp{L=r){W^&Cz_2X)^1o7#UK8{`phTQ zO;>94-}oL|XeCWsAkjb;82_?-EMhDoF7rIT zp2_vNvcS9kU!;nD^Yods+6?4D(#k9n24W4^74U-;2s1MNXJIv922uumAOU`m01Ge+ zv>`_WFx>;AfsujL&NN1}VD`!5#fkYv+E)(se{zmxI(KBs&MAV;>9LQ}b4tth@8(%$ zc5JQth=1b*mIQ3Xo>!nZfFO|fkYq#pQ z$>e-xlD(pJH*~^lEkSo1y||K1O-f5^gXLY{s86hYt|a#2K!(|kV;}t+T#SA`ym(P| z)x8y~=di3_tH75s!*^-+0gs4jnZ9?}djcmfx<8-awmV@H(7#CZ*k4J-@{4UG(dAWEFq7{oD! za_QxaG6MlNcCg=>7};308(A2Xn3EV-B%kkD<;^g-@O~dSGwr3ihg>}{a>JD z{???R__R9tr+1`XE4j}c3+9^J8_RTaW#m1ksBcrX_MkVKPu%(&);RE#zHV;(tQ< zalxn3qI)%+AI?uKN}LxbFex%@XY+A^=N2y`)XZwHJ~3&tWHP8R3;tm6G%49?=A&(k qt!JD3lDj1^sW5J$@bbG$@+O@zy7pBu?YRD{X~|isu9K!RZUF#I!3zuNw*>#I$_)oHkQ8s6cnOp%{? zDSFqx`h@*!Uq838(9F_*I*~i{|C{`XtGXxe`J@&0^IT`S#r{lA;_+ThrWLXhL}AEnQ%!rz;I7FY7@yY4M>;G(F_WXF_?&-N*c zD=~D&$!9NJlegTv=k4O6XX}%F^;<8An9kDk>v?4~L!)isL{3MmEe{`m`t{)?*CNNe zD<3l-?+~??xgs^?`uvngpk!3Kc_{J_YP6=r1o&%$cJ45SR?K?2GwzzA*- z+4ZYXwX!?hQB|>xyYTg<6uxf7bOTwC0zMWo7VOff=>{0=j0|-V|Nojw*3OaepSMAK zPhXG7f1L%l+@lY_Z`57S`l`eu`m>!M`|;ePnOvdw=PN?}-Y+=*_Lxh3$k)XW`ajf!D)nn_ zYh3&=*H1^fA^pu-h50;5iC3rpcYdpT@K&s*R;&G*)OT(Cti2QB@4uV>W&bta7=L$y+X4z*1eabiBW#iOp^Jx3d%gD&X%3$Db z$Zf#M#vIDRCd?EXY^Y?Q0OD{7OS!|u1Q{8~iSrto8JHOv8Gu2QIIl4>mwFa8F)1N?f{~ShxrvFN!JvtW zi>Zl;k>T9Ezsr8Vc_U(C!_F3!6Zu`z^zQeAb3<2MK5M;Xa?yLPU%7L?eQ0fnUg!}t z-}318cN%NnpDxP~*?E60W6n(ZBTBOK{}q)#(1~9Egk`^f(E=%x880j|-b_`kE?f94 zb7!mM-p-zXYu}o^D&F(I`O)dxgO|>EZSG~A*X=p^{=w)Ad2t`~4D_1*{MxfcoXg{B z$LyoCv+r#?SK+$HZmaal>!r5_uUH3W8S=G+lh?yyL0M&+@8_f_B7JzY?LC6PbS+s3}<*2995 z8;3F${yfO@a^a);-Jv#RZ11xC&P?hs@SU~SpW91(e>3(hr~CB66RuIQyFPpf7IhpNXsIAwOa zBk{M~_6w)qiT%F3%;(;urB@!^|H>9}Pj9aGmdOUI8qeL8x)WH;>tFEl={7M%$;wU7 zI=M?zPF-EShx4Gs!v9x77Pi{_6;WZ{)P8x%b|z*<2FArs1`Y;%z+@`R&&c?ng$0-y z*bMkVd|?ou)qojD8OVYJ_*lePM0Wo_)u%k)f99#%k201m6;&6PyUB-~%79q~n93L# zwq<@;R{n3^JMPA{4-c$7{?k;}p=tFqmM!;Bf0yNN{!l0E+uQT*v9Z!&%RdhH^BldM zg7=Aae7s~4cO+w`%#5JPJUu{!wHr&?c&_;{|_J>l{H=_}_XluLwet>c({ z{=zq#bY{^+&Yz8yU*7~TnSZjMvAg(4dD)%jMPGS5rB;;Pn>0J+$7Y?Q>X+FMa5OBL zG3hbmG^SNd@A|EeUd-h(HYl#x=^rAtpPPN*l9*?wPsX(L^FI(R*QryhyLH6-_Hwau z_6=uCUlciAo7ytBt@+cF31>OouXHmP+=@EJ?DXZW`JxZf0U_ReH(KsVYRqhOU&kqJ z?{V>P{-X^E;$Pn>GcCQv5S=?=^}9tcrLA8ccTsok%bx#rNz0z{pV`yb*af;S5?pqs z^&MBnC%XWPDwQNTaRu|-EZ^;%vrqn667hB0?>T-FyQeZeU$}NQ`#ZC2l}naw2PZcN zTxxV%5uX&UvpXlHgCp;~a7g@J-6QGAm(O>a@1Lvi<#$!{>;-a-3;~Cp@F+zF3A}X< zYiIZ&60}^ldvebrU$=VoV}-L-?mfBH*3Da&t#I(byoaebvKB9U(b{dr&LOkwYk%l0 ziPE~KZyM7sDi$v^b>VKXjh+*iuO&Y1VzY8bTJE#9M+HXuK}ye0Jg+~ZlMt(ac>O$A X*267K+yClt1o=1JUHsun8z&P0@xWTd literal 0 HcmV?d00001 diff --git a/config/systemCertificates/c90bc37d.0 b/config/systemCertificates/c90bc37d.0 new file mode 100644 index 0000000000000000000000000000000000000000..1e927a7afe06c270670d6bc25c4d465db2e0a7e8 GIT binary patch literal 914 zcmXqLV(v3&Vk%p}%*4pVB*1L-@!4|0l?!%jq->Ps{Pom;myJ`a&7m8Ce;an;7{S44N3Zn3@aHzbQTHIERDpF(!1g)GQaJ{9Zplk- zye@a|@AU_#r!O{6V{hxNd-12ggQTEo);V)vP&-Tc!p2{-S^Rub$w8x&gcgr9D_VnJeCX{_;|J2P} zlz02&x_&wBDQX2hucLu6-|8C^Skma^IW)V_ne~}jhi)FnV1keK@Hao#ijU%z$=y=4>cw?qzQ zVDbWnG9yDmy2g}zK9A(rhIe13OI+=&wK>}DRsV9|ZEf-U8{&)0wTy%<8`GUyls~zq zo4)DT|D%6HB9Fdi`2qHg8zibR_3{p5LfoBYYm zyzW}IGxc}J?B04s;o;2qU^mg*8M8lpHn?hM_^7vK-s7%Yx2D;d3NMZS@UtMGz}-N8^%tYFG2u-sL@JUi+4LlJwK^__B94 Uy+>lhq8Hsv%iC;f{?uq20B`eLrT_o{ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/cb156124.0 b/config/systemCertificates/cb156124.0 new file mode 100644 index 0000000000000000000000000000000000000000..ed68c11b82371f71b634b4f51834fc3cb10d6741 GIT binary patch literal 1615 zcmXqLV)Hg=VliI8%*4pV#F3R@Hz#oR>0kq1HcqWJkGAi;jEvl@35=(Gi3+Yx?g~zsIhjZ2XXYw| zq-N*k=j3N)=A;&7DwL%vcw|=Prj~$tj(SJu=^3gSsDMo1=8*-NkPb8;IJKxGGc7Ya zvA8lnPr)~}C_A+((@?`e4Wy2lM;@lm8KN#Zu_P0y&at#4BfluKq|!i6oY&CUz}Udl z(8$2j#3D+Z*9gQlhH{6dr<$0QkRykYm4Ug5iJ!rsiHVD;iHVWn(O3J)tbuZ^Ng;7n z++QWwo7dH?ulatZD|>0Ov*k|j?}v}2blOhQ3uy?lv}E`8zT3)P)_!Kc{#2hcwaaby zxbx2__|elUSJF2rSK8s?Oy1q4c_&t8&pOazxc-#$>DSsOFZ!ovGtR!s=f$xqdQwTN z^W}zh3p=9MZGIJZT5MLi%ZY{GLNdz}T@E82mHCq?|g*2!ldeiTkS$5Z+K;zW(r z@e72442mWD`XBbNFFL&2>%%K~(G~Ah&n$8KA+7X&GoSM=9hDtNbz-i_{D@82dw6o3 z#&Uc0k9~5NwE|cdhu%E>+%ovUjCnmFN!@B2zSs8FJUKQm%_+3W{rRSd-n8%RHF{>x z0%YuOJF6Vs-{xMqxl-nP)ED75IX~w>hsgG zz$|~-DLo#S(4(h*#WF3ve=VgaYBM9(%B@`P;{V@IbkOQs=w@X&O7i$eXg6ZpJAD`%I0~3scoz4-^*V4vFG`ksF>|h?lGa~ zLboUtMn`jhIDcnBV#=$P*E6`1mp|aOU$Fl2s!Mh60~b6C)DE2_Djs}#dm3Mw&ySy_ zJ`XdnyBCbE1iVk{zhk8f}Cyf7!EGUk`M*1t1;mtOdV81RFn zg&7(Dv#=U411SS}kbp9agn?KCb{%{m1^gf#EWpx&4LKPC%LrgHWMp79xBB9{-Sv@c zsY?I0@}L(oHv}f9e*P56w!}_O^G)o<3#)4$a82;2c>mHty4$g8(Qx4>)-V+_P=r5bOg+pS$*R&lI%zvaEub99fs@J_X&@`BR zMRvxzpMEy%YG*lE3(i>Dm+f78IbDshZCUW81nU~-`p~XDQ>6}SSo+92Uz+%(D6(s3 z*dO~Xb8i*QDU0fH4tUpRP~?06zvuU3E7Nc0u3-{9s(>gYaYQ`$BzL2m`$p79K@v}xxPwqeAy!NkN-^cZjzRdU~B(HGe zz;d3}qZ7VZ>rPYKsI$*!_3Mq7x=!A%5ayTToSWOvFrVqx!C&%KRh&n>o^@zVpWoU2 z*E~Mn>YPPnoA>%c?kzVy75L9L5`Mg4dHB;?x13M6n0(SW@+$X>*879mWw(CU?QXTX z6nw~cU*SX7i+`2Vd4)@VpHEF!n!9cT=S9x{vL^fgDNi@QWckaMmyLVNZR^FW^J8SU O)xFrV0Xz%f_kI=F#?@mywZ|mBFB~ z!I0a4lZ`o)g-w_#z{gO@Kmo+z5|#|j%dAQ*$yW$TP0q;6&&f~EOf6Oj)^pS|R5wrs zso@rub51QPDa};?QJHC($%!SI`FRSCr6n2pMVTd)hAIY1Acf4r(olsVMWw|hsVNG6 zsU_w4McE3@jtWKwN)r4=28M=)1_ovZ7RHvQW>Fvk6Eh@%!Qjj$CMD#+V`ODuZerqR zFlb`pVrpVyWZ3(&;>WYA4Lm7x+oY$Zq}wZ5$(1tJzW*JQ-gELyO!mr&&vrUJRq&pD zYj*X{nXxx#H+WxfanM%3{9>2EZaYq?<(^aDYdfeMntpuwyV*Z;e_t_m1Yt zN2ctr3w*t<9o!tYW1*wP?2Eq*>-!(XKip`~-zVmoaGkAJ;^!(gfz?`3bKZj)%5Rosmy2oLKC{+ZW=Z=Ux8gX-qzu>aCli{S zb~|1Bkoe%>V%xOEv0o(Kb)4)Kch#I}RLW%dPE+kfHq*1MNv`$gqEX5jomcGc`KfRC z;J~xTSNyc^qRny_*rM)!n|waJbmrGzZBpqKoA*!qXL4un^PsS&o1d0eUw53ydM7sX z@l;;toqw9ASx&9aX^8R{E;@F-RPJN-P6f)^?JdN_MpGF z-meMNW8due?*iwog7-6ig+0r?y*1qX&Ql##(G&CZD*S%jnlrCW=T!J-si!9C%u7dsg^81MrVy{s@J<9`-b z17;v)APW-UV-aH!*|spmlIidQ`@XI{zpng{S$5Hi@2>$LNSYs{o&}g`*^pBiFpC0H z86!jCQoeIfUhcQIxY`+Ygemd2&ruO^-ERNjYyt5gHuPusdwIHpk~m#?u&P`b{dATgUe4ZLguych4XC* zCvW|3(4Xg%&{AQmm~!p6qr3$F^OL28d-ulNGikST+`#v3=QVpy;b|iJ_h!jP?F>6- zYPBK0z&Gx(=0|0XqR4Hl5A~#}$&~A;m6>*HEYDo<)B3CO-By8;lM|T3CO%)k%l(Sb zbU~%Zi#(^~Jl{UWdzbE#TgKf!%Uu3P*&LHixv|yo$ugU&72({s-zG|({&=pqJb6ib zzE7aVwI}h%=WlD&deZ7q84+jw<2F-M`a#RvhfBO|&E$S+PVUHvUg09C_+j~rMqZs4 zlg+l6Z#uO>TCHl9s{E{34fDLU?0+ww^{?2d@X)+tMGw0&)IUDq-*UufY2xG`(*@YI z3{+R{JW;sgea0Exx~~uF_?uSbZ`+mA>|B1fYm)fFdC?VOwyuwii|#&5J2mt2$)jq2 zc{5nt)@{2vyJw%|zKzE|Nj{EYI;C?X-;4d`Nz+>nrJs&0m&~8%Brv1&+0^cYJ#UW+ zUGF+~bw*6sH0Go4%Gpf+pMUbsUO4gH?OVF7AI`3uyGer6_3)&HMdE+lw=Lk-`FP}> ba|TCNy!D5&&#MruknTe5!iKAq?YS(f5st^M%HV&;ek8`#x%*+O^hTI06Y|No7Y{E>T z!GKu(<3(7?dZ z$kNcn$iT=XN}SgO$TK#Ca;aranSlTsJJ{_^jBKphjVugG%t;I^yasX7qH~!qEUYx$ zZe=s6>XfL=*`&{N)MD6epN9NeeC>?Tt1lw)FZv``>+5+uTO;9IvF3vL;k}#A>O6CQ zB=szLhpnD|#S#D8U-*|~_=FZ^PnGqPaGF|i#@uG&quHt2nv0zb91LWEK_JV=BE}*z zYrSUG0YOt!wLk-g!&(0vuCBXgW55rR7G`Ap&%$cJ45SSBKmz2E&8X=6V3`tu!bAO9|V zRLErD6xr^4CGh^P%bZ40=Q`@bZRf;0Wq)PY-TI+v^3TZpbt%6ho_5PUPTse*@oYX* GPbC0MBd8<* literal 0 HcmV?d00001 diff --git a/config/systemCertificates/cf701eeb.0 b/config/systemCertificates/cf701eeb.0 new file mode 100644 index 0000000000000000000000000000000000000000..d327a3af2d24e815a3d4b42eb8cf506486cecf9d GIT binary patch literal 956 zcmXqLV%}lU#I#@mGZP~dlK{_$z8DU%rE8t)KfG3#h`eCH%f_kI=F#?@mywZ`mBGNn zklTQhjX9KsO_(V(*igYh4#eRS77tEME-gw8DJm^4QE<*LD#$NNEXmBzGZZ%v1*u>b z=0j28XdoxfYhY$*Xkcz=X>4d{5hc!RWNBywWLlaSn3_gW(WWLwC1h_fvNA9?G4eAQ zG%<29H8CcKLNJ9hCdvBMnx7u|k{#C$pt$2c?hZ^xOo6$kSTopOTgGERS%G`YXK zT_UVO?Z|~Y2lDUVTX1Ni*n$*6Z+vae9oueSoLUY zQQP}P+1(%bZ(okI-&M57MP<(8;?3XJhwD43&0Sftiy`Qf_u1eYcW$#*zOJ~?`sTf#w4B1*&bz86_nJR{HwMMLBxK;8arrN;P`P`MLVRAwNn<@qrWTvMxgPenf} z2-q}*Rb-v#@m@!Eq2eiZJj#lH_XyM{2t*Zqox!)}&CdF}Rr#@(Wxo9HV9j(|$y#_~ z`x>{?!20GVbOvw>8ur+$x`_& e*M1!HSv+f_`Ig?N8s4(=bPnyv*z=a@ogn~YA8Swm literal 0 HcmV?d00001 diff --git a/config/systemCertificates/d06393bb.0 b/config/systemCertificates/d06393bb.0 new file mode 100644 index 0000000000000000000000000000000000000000..0911a562934374fbb203efb9d9d94edf0eb1d0b3 GIT binary patch literal 967 zcmXqLVm@rp#I$+=GZP~d6CHzYMDH8?d{!96EGDKRG~KOd+nC$YF#!N@>PoY%m@ z(7?dZ(7?pN&?HKn*Vq`uH8M7}G_{Nx9FA;aR6-6sMpg#qCPsb+gC<5UrY1&4hE?&m zq~l){PkeeS=F6gI?oU5wgeI`cGA-FWJMyz!*Lst+e|Qhw^pJd)*?&^ukK!tJ$+sI~ z)}$Vff6G);U85^~ZP(6*LlRA5Ex*z>a2yL!ZhUffr>Ffl|2%UK4GaFG`<`bM{I#6! zd+GR$i2SbH zFE>x`t217jH>LT5$uGs#ulkA>*e|(f5dFT*H*0FNv&#wrQJJTV;YVkDe8#3Rah1Z+ z?ZIk+&YQRer$#(Hz+ZOrKyOXs=c0mn`TwN)ZpND)+mvrov(Ll-QIzHN8*?k>&2O_~ zj+5+mS#6gB5E-RP6P@KBfjv+~`;{(&KKZ(lEjAt8EWt$~c zuVqngiAa5PTf6JIYOr}yaQvQIj7ge{mZ=v$vr?)%m@hlEK*5XMJwq76@XU9Y+k zU0TChrRiShu)S{cRqqpCn0E*OeZ_7T literal 0 HcmV?d00001 diff --git a/config/systemCertificates/d0cddf45.0 b/config/systemCertificates/d0cddf45.0 new file mode 100644 index 0000000000000000000000000000000000000000..8f8493b5e37c9e96395026c35c15787e2987b474 GIT binary patch literal 1587 zcmXqLV$(NhVi8}!%*4pV#G$(I{wd?rkxT}>Y@Awc9&O)w85y}*84Mbi7;+nMvN4CU zun98-I2!T;6#zLLJZu4pd5O7+h9U++AOUtBZis+_b7o1Up^AYLNR*35I;5zyxWqZX zNFlhgxFj{VSRq(XAthBINY6*lP~AWkq>7tI4z9{MwWuUBEi*Z>Bvrw&v?L?H2xOeR zfhD}H_4`#o~Fj|s1DWiwGkuPk4ozz_&RgotB>6cU7 zzJ#p2V-=!ns6Dgk(@m}G?+Y1r7%tgYrNVyLN#Rr1l}RkpsbM}jSAK6xjB;1rawBug zcB=~|Haw*Zd;H24zPzoq)cV)C4gc%1H2$i~oY?qM^J92k%9aZUMRWP~>G8Rpi2D-w z?>%3#m385+^ZAjdcplG=_1xj}D176LE~oH0W$)kby_m7$(ihI%<)-^on>db$>9{C_ zt#lDAe;>O=c2!)qUANIUcKvXcNvFR4n|tWxi_LvL-b{u!pV)XbsehMfD)X=^+$g-z z@~YlZlS8set@oM#`F>e%dp{<+_gBHgrFH7Z+w`*fg^snvIR^&Jk(^!e?9aEi?se6+ zY43%FJK}8?Cjb7qrrmV@=cai}?78L`W_Hh9(&5#Ym*)Fk>@W(M_*};P>GgT#_Fq`K^lPdg zizj}#%ehkF#6Hd?7wTLNZ!++*Shezv#4PqE?b|!%NUXi}z)gJ3`B)}qMh3>k$p(qw z{2`@PP#QK>{qm5}^$_83M}zU@~N6nCCi=$9miQhgK(QE;87jfAorN>n5w+Y~C4F z7nG-$EZ6zKaicQodQ?l-4WU`mH)~^j3yv=Rx%%ni&d$4xzuw&a`Et_q+Z)`RK3`5+ zHT9oix=3ck1g=%w@645t2Lx{US~u@;_4g-doQ!lmc~1ZL*lzXpSVc+TR7E=y9ywJ+O`>js#>bL(Ul}V-4 zNAntUvKv>k*$Xa-DX?ihaQ^Xx70u6=YuHD6zhMdp?g<|EcqLm=7-EJn{5zL)?i3Cq`+h;Hcf^%eL>? z)$&pAb_1*K0`U?lS z&C5EKispRfHQo}j*ueVkm8_7-`=oq7PoDDqPYbtwi$aVEv&+$2Yxi&+WI8YRbjr=o zebG03KFocSD85_7D1?VebF$o|wr}zHr@5nIC)=Tfuv>E<>UUQ~zzb!w>=)`~iz`Sd3I04fGhq(X% literal 0 HcmV?d00001 diff --git a/config/systemCertificates/d16a5865.0 b/config/systemCertificates/d16a5865.0 new file mode 100644 index 0000000000000000000000000000000000000000..b188fea1e9a7766dcb9cca02c82d5e8c4fed639f GIT binary patch literal 1560 zcmcJOdo+}39LL}Hol9~XcXI1p_r@~sjKR3(PFT0ru?VZVLR&5)(FJ2EDv^*a zmz5#MM5SDcP6^4SP%RN^S4_38J35^`o&A6Rc+T(nexBcRp65B|`5@_71tcA{R)&H= z2ol@7VD)~L?-qtgVYlNm-7-H(fglD0AihKiWIGn+kH*SF&U=Xth}~8|Nm|$+if3^m zY2h@OMu#2gocKsaBsH8G$zsATk(`6!Yz~V-j}yi47}#--3v6#jGBY6~W)wtISqia0 zOi2hrF`*DmgOsIA5F*Kh_%;3?N2Wts-#!e)0H|~b2O#N?IFt^7KyP7m?%e0q#d6b^ zsh(pmJN$-|n`ItAp^c9CPVXpwuX>2Vg(O+k$iRU58?eLFY22I1;3`x;K`1-5f0z_Y z8AVIR*4X%_;I>UtG5g-$Im5cUE4{sG%=h|T>()AR_kF#K9%j-yHFr8P64$T#EH}(_ z69$X|bAA!`Dvb1ls?E+VtgR>*W%Lg&+x3O+C*#;y zTUaIN@h6U&ZcIVELP14bgLHM4jCNocjM?G(E+RKyt~X@unIS*l8t!`)RuA7UOGr(a zUQo>pH?f^L(zLq_ms>7~VhOVJSoSd|s(jX?s1m{gCAA$q{=4Gho;)EaIl03IXG_uU zA@C&op$#?vXI@Wotn0limp1D0gP4-TVwWEV5SuPO$m1VaR#7UjTyq`iPbwttylE&I z7IMChdNN1{P8gY7ukotVsxAqAqkk$nVpqk?sg^O>R%N5}CGt8hpSoU;T*^(o&x=18 z#GmB|Yv1e0)DaZMHjOU0#Jb*gm}~`~FQ*O~@Q8uIgFR4HlV2~hXw|VxOpkSHxpn=L zLABJ7^OC%!#z=b-&;Ee5<{8@WMuip1ImflAsD@$qa+0wFOm(U|ccWsIq;g9Iu&4%zqb1_<%d z^a6ZTFxp5h)8NYJEosaYPFbv4HnkJ5KbdnZlf@y_jB$b6L zq{QJroSNHZ@o55^DCW`P!Me4MXBBT~yN>q1qG+ZYZtBzPSCteyjbk&WZ)~nqy56FZ zT0iP$l@8DBg6)!w)#UD%6`Ny2-8M$9k}R@tW5>hO!L)K1|NHHFlc) z$n)lz?$&LzctOSIMZ;m8esW$#-{WgbiYDAXR4|_38#s2hit$^iF7B;_$**+rppMZW z<;Lqfyrg&Pg-X3>%vl)XvL^<-buddYUP8}3jGX?>0SR4uw+-KnZio6bbl;N{+McNo zljREyp6z&znWhGMd1u?=x#ep1HfmGLn3d;>ofZ--TlE)4x*I~d)npbQAAdeRSDug- zmn^)9?sU$X5vZRoof|&X&uN%AN=&F3eWh(;%1Cs$S8>d#AN85K^Mn-N{1_Lic zZUas>=1>+kVW!YvLm>kJ5Qj^c(=#PCFQllnxWrK1Koum$EG!2XQ*h4D%}p&z&P>cv z2+GedQE+xtFf@=8=QT7jFf=qXv@kR>GL91GHAd!A)vhKcC1kHKvNA9?G4V4PG%;~8 zH8C+VEDw;pXFt>Sim}_r{J_MfO)LHT(>r5ZZU*1w(YSg2!~bj7#eaH*X1^@7Ml*(w@C< z{EZAcyv5_fj|3n3#x%Y6W|H=P75Svz`-gXEdV5ybOit)f`ZM#E*@;7ouIPj?q?_gy z?`Mkmu;lL34U5#OPCYPNDk=8$@AmiW>>a-5MzQ=oXL3sAPKmN~tg*0A>=8!QZw7an zV&^}&>b`f&Yw3l%Jw0#Ck7oMZ^+aXDlO%utgX_EbO2k)OEb7RrV)Q(-#jWy~_{Li^ z$jch+;@5d7p^u_jjP}9d(i`V@1G?CKy?AT!? z{O-lQ|1)Ldcb$GA_i1N9!U4m}#ZTYwTkzJHyJVk&!jbfx4;;)@p$+wJe$$qJk+XaF z?FQ#V;}q@W>qc?&e;%mjugIUiXY#C{bA%>TR5i4VUN0({6IxQSao5AV0+wC=3wC83 zuKsWMq1e`Tiq=MMN4^FBd^=LJD~-2YXJTe#U|j5E;9$T9OuVxEjEw(TSb$lA&43@o z7Y6ZJ4VZzHfhSs8LF17;XtDr02eT{pq# z+cNJOmomvjIdzS*aUt(j_dMp9@Kf{px(tqoQy3!N>*>`62lZ@=VSm-JYi4)Alicd3NsLC-W&48{+3|UR1oJpLMdu*U0vxjZ&uCPyegqd zTG#q;i*0zHo)_vFENR=ihK`@rq7;-^p`VWVym=iKVJr zcz-f}Saj(N!-^}eZ8+eT3jI{aI#l0GxwX=Q^s$T{<PJ zpuzIluj~JWMV7s_o#N$Ga^-M&WbxU4w|$`&?|;3RX!L4&1dGx=i^FI3f7^c=IsinoVfxII#fbSag)S=t$RR-k2WV#4Xz zpVO6m`(`|QT>mY4_qwyEyc)CPxIYIzEYW^hr@s8=Oi#ZbOB-&h^2;PAb)7U$&$bb0 zKDPGWinC&Uy&u@k3+I1Y{m1d^!R|K<=CPbl{Tkl?+8ATOwp7~d;T;QIn>(xJCrDlO Vn)B{rLC%?XU&4P#>}ttt2LSRMTnqpJ literal 0 HcmV?d00001 diff --git a/config/systemCertificates/d39b0a2c.0 b/config/systemCertificates/d39b0a2c.0 new file mode 100644 index 0000000000000000000000000000000000000000..bcafb43bea2ff5306b4e037e85359aaf537b0e5f GIT binary patch literal 1446 zcmXqLVqIj=#N4%jnTe5!NrZ8Vf!reQyI+qQYi)FPDg1FQz?av6myJ`a&7QWMBYN$IPP%QRkkMpOl!R5R{)^qTrlbRFavNnVeXXnV+ZNSXz>iUzAx=X&@)g zYiMp@VQ67sVQOJw6eZ4U4CWdcn_8M$M$ywLO-xG20l~=1z}&>d&tTBR#KqLa#K^Gi z%E!quTOB&NR`X7X4oF@%VM>X(Ytgmp)F@5w;_m5}2REvx3Du4XKV~(NNFT05wPn}%+X#P3H;KfX42B(9Vp58KwJ$&@p&v$~y zyHC2vwM>@q+A{yCP)gW+tyPY?8gg>PNrQpnf|Tki-gz13${_N+cKAH{#HKMaYJYhgU5z8yB1Z}Y7K^dsIL*>FKdI*aGg9+y=&&WglNsYu+8R zk3J7~;j+zQ_H&;7JTpJo^bzxd1rqyrf86)wT2DK#(|5L=A9LTbOj+@7+hw+64vF{Y z&ix!xb}rb8aoHrtH!O?$c^6&fJaz5#tdH-VV-Kue>UcgTxS-%<$1>e3*@?vgYHf*p z@zRI1AN5?_J@+89)2=DE;#Y1sb;g(Ly?Z9JzS8fH8t3-M2BfZ-kh{5L1IO_-D=xma zoAW1Ds##C_^w!TVbFG$(Cr(>bc)4JjsPA^4;&+lUN2Bc=|E(!au$E3f$8h%+$AqLU zPj%mUEYB978M3e4>+#As7N6Gwxgpoye|+&NN$hk(_FLPxU*!#!uJb-A{I-jc@#K!c zhy!U>8`HdxTs34$dRfxKbKBQVmx-B?fpM{ufrEi8FqzBpv52vVT$Gr+ zGcry#R^RkG!P|fjB+bvr_@9LZnCI9G_(6PO5TDh68Au_gGGKNCrZPqbqf-r==h}v_ z-Mw^4@52&CMecNuQ@MQ)PORcx)vFlZf6T7x)a}44L7T5kYgrnRQ2&&>PyXv2F44xP z*4wr#>2uBz7TcJ^W6F`cI=SfWoqcbPhd(n=D7{e6UUF|t*U}2om<4r z%4>0-X}5shP3udus}3w&_G7EzvoED5cLvWabytcK5j|cZy>0GGo*&X>A6r}QExaZ4 ze#s+&=~Wf?cmk)dP;}^S+speQ&d=Lyx3z+Nms8k7ZmIp%7nGcJTzY;#)!LFHBeQGD z1K~QwXR{8SKI)XRMQ%zphw6#KGwrV7t(WI(CMh)sPG^vqUY<2$(#e{HoclSoUQY^q z4$a#k`~8B+asD&Em;Yzpx3*xyE$+J~a;L}7s^>Iv{CjrMnW$W!PpdrtrTut$!}K+u zhTJ<3eX9$VoEA09l$s__y}-P0AJYQXy9!E=^JP0s5{^CN+R0hU{ek^O<}}mezm*&N zEG&1pYCBgfx~L=apI4)(XzJ`Z&fA?XGgdA1++7&-Y5%wX>I==*@7Pw}ao1`|?rf6@ zcSK?h_HTbJ{-k|-;f00Q%SEp^UH|miaAxf6yJETauh^7-xGhq8JNet)Szt4}$Y;RC#-Y{ban6>7nc2Y7 zklTQhjX9KsO_(V(*pT0V7sTNbW^>FS0&MJHH!?A@v1&K6Feou6F|b@(-DU2-IGFd}!LDlW z71eIu$s3Zs=}O<`C{(<}@FIEdEcM?XEc0St*)BcVxN32}23zzz_7VtS}?ve->5) zW*}w22NK{139taew9P;k#OGrXV-dOh=D1aA-kFED%4UWAp7XgaH~eWMa_BN=Fc_pV z8CZ2Ie%xCpxc0*Ph-v!QUeB$Y(5rnuE%dO?V~v#sT<&}y%p-;V>&~2_;iu(q>T4Xu zWXSNUl)=yXh}9IKi614$5vLs-bYC^fMpwMfA?F)ukIwHU}W6foceNwN#G2PfvF z766ZCx0CFvij7=>~Eu#jFJDZr4kb{ts zm4Ug5iJ!rsiHVD;iHVV6;){?;m$|%aSer8g2QzZNOoXxEZnySjy z7f!hT<}dHBIXS=XZ)o}=QulM;k!AY+^)u_Y{z-Q(+RMXmt@CxZ&gHlLGh{?o*FAll z_vglnCzDieIcF#B2>tu&;GUdq-Jkh-XFZvnlR5K8g@=Lb)wK_KZCn%n7)=XQ-;;j$ zl-{=NS8m6TD=gS3pL)-OW7iVDm7kj3%v)Z+IMe9iobFeoH9KankF-Wtj8gTM)iZ9s zdl1-snA6QK*KX#osp7Y4jKdvmdIR5bZ;M&4lPq;V{Dl3Um$64?uXmmKXmOOvmR&2u zY|rPf`tKRB@574!Uv{j0Y5sfHjxXF+KVLXI$#vdnIW7G0=I)1`2|Ic;!q$k$&f$7q z`1(BGUE7t@7JBTp`M!QDuaeIJ!NxaX*558KdKA5V6N^&N)P~8KFZz5^KTc%UEhu4n z)txS?nHj{i`}+NWtWdZ83l?i6))!njyl9n<;wtxZ8gtlO%l0=(sBgKtZp-O_XW3tT z+6oO`F1s(*_Ta{Uhr7QoICa!7Hn!4>k#iJmOg<-3n63S0S=V;M7^^Jz2Zt*ouPI2a z|CBXjRneYsuS?!@cMJU4;N$r8t*mXF#@sn)_HPcnwcPz_OE42NBLm}NCj$oqSzzLq z-1dvX3?`eQV!Y%y@It$mj|hDE$z6=v87>#hk~ zwBcHv;G~y&yXNW5D%!YL(j_O+bkVFWVnUfwJrA$jEs=Vm&-`UwqO5?l){^e3qyJc! zJv?yj#J_p#`n7l2&irwsm@~pHZ`qtL*VQjiy=C59By+j=!6NsW%oed%Ju4YBWsbj@ ztsuj$k{MpH$?}g?%YvwV%=UF&W!&pvu&f;-{$FD*&4I!^(5|v$6jQt@DbZ6HIwT_u+F623ppi9c~VzYpH|*3bx5Q2u=M{6 z+DY%1RC7+8k=`T1cs7GAD_OCWxuK&gukl#xrg<=^%7~3@v!6?8 z-JHvKeM;?HX0KBpZogQ`X!kX2=1I9ePuty3Id?wr_nc%a*5q*JOysd=R&Ry$GHr6E zZv4ASwz|G;pB$f&+wb4P{iXFj-QI4={}@ah3JxCLx$y3?f=4Wy9rwI!nD{DXPSryt z=9P2u^7&HzbK2YEKIbj?S-Nz#!;9ce>T|tz9w=Ar{onrS-kzTK;`g_Ea$o$EXTUAR z=U4Vt@XyzmVVi3AAJ65Q+_Ut;fo-z;to)`dx}KNAeWVML jZ?=kLrtvjBKYQ+k?y|so#e=57t!!Sg^VjZ{jxPZK<&}cn literal 0 HcmV?d00001 diff --git a/config/systemCertificates/d59297b8.0 b/config/systemCertificates/d59297b8.0 new file mode 100644 index 0000000000000000000000000000000000000000..a42b51999e61426079da0e4a7399e6d3888d586b GIT binary patch literal 891 zcmXqLVlFpmVv1kD%*4pV#K>U4%f_kI=F#?@mywa1mBAp^klTQhjX9KsO_<3mz);md z8N}fdmI-!s_V-l?DJm^4Q3$RqE=kQTR&e&$)A0#$(KA#xPz5RD7M2T6O)f3UEU8p* z&d<#)&C5(qEXmBzQwYk>FL8D>GLRGJHLx@=H3DJ-17pi5ab6G;&ZV{WO^iy&9%f`^ zU~XdMXE11D9*eMzQw*#-0Hac?9RHf`TKs_nVBrGKKRX0(6wZ;ZFs}cpPe&LJzbr3W$P`+ z2?7VNU32O@wEv5R&{Urg*6(IdT$`&!Qm@_N@x6Gjj%T&?5z&2CVauZO%QAyjR_#3T zI%`&J&;?ztY*R5#ftCwdr>xi*%-x^Vh5OrgzfRxLvFhl);LuGIkJRqm&??DRp?5n` z>R0PmuZatvi(TzoWO;wejskfN`|dvuammd#&0113v(Mj)%(DKIFLqu2ub04Uza}xO zHR?RUAJ<-0*^tc~a8TDq?5>N6x>V_JCT2zk#>Gws4hFKo_>|>i5n~bIYF$~L$~vRQ zq45X*bRCP2TyJd78}Nao`577iv#yLvlfQh+Lgn4xROX)+ z|JSqZ+@VXi&-DH&{KKqyFelbHK4n{~b!WarS;f~oi#+5d?fWLb{`gD$-C4iKEJC5z zo<6zz+m5y7k!;+t<$I?4XIOoGsmJBKZGCu5Qbx`8zl*zC7OY9yr_I@J@*#_H_iW8D zn|}=E=aq9l`mNel;wF?c@tw)lH?t-_ciA_=u;{8M(>JE4U*uoc+?*D=^8cHzpEKS6 zn?^CMVmaLv-Cn3Uaqp5XRlIv=eGOM;U{@5k_p-dm>dC!)n|b5X*q&9!ag7=^%WKtN JGpy@12LJ#sRXYFx literal 0 HcmV?d00001 diff --git a/config/systemCertificates/d7746a63.0 b/config/systemCertificates/d7746a63.0 new file mode 100644 index 0000000000000000000000000000000000000000..c4347d3f5249399da3622cbe92e6efac8511c503 GIT binary patch literal 1095 zcmXqLVsSQTV%A>3%*4pV#LU_J#ekQMQ>)FR?K>|cBR4C9L4YB*0Vf-CC<~h~lZ&gN zsDUtu!^Oknq8n0FT3n*wo}1)hsAZr55@zO61PTX*28SpF<>!|uIOil57b_SmI6EpB zDY%9y7#SE?8pw(B8dw?{8kibbm>QUvMTzqoA#-V9V-uqivbPvn8JL?G`56qF7`d35 z7#SI6erz!**rmVSU_syB8kY0>lJ?B}+cf=B6<7K+3(ju>ep8i-XZGF_)qT$TN3vLH zd*2L(JvO#$7UulER;lW}_QRQ!TOD?qJNP*-o7^@2nso8uS;?30B>a6M);*HD#uF_X zb;D}M5s4JJ$Htqsc9#3`?7ulBTX=fD(BgkHSF)TDeUp%3_Lif1``7)G-=-Nh_Z%xU zY4;OkO^hnQ5K%DT2ganVFeBrC7FGjhAY~v665wMIV-dML zrOPKtSW8mx%=)6PTC?l3WbULJ@PVZHLF!q6sff*>@h(U}o~7}sLE|NZ#`Xn`EejeO z+v;;t5(}*K^;0s7Qj<&aiz@X}bW1=fNG~t7MBmxZ7MgNYjSN6(2S|Za50Ewnu^oYg z5fHnEff&Gaq~j0L0Wtt607`^9&bBVD_Q|P5C7EfN$%!SYMX6=^Ksqx&FDJ9O#K3KV z%L1o1hm4XEkTc55%TXMVT$G~^bx?c}(Ej*jP}+?*j!#aEH;PX!iwD`M2ULZel7JZm zn35P7Ox{*U*({mT@m@->lwE)GKbv22foiYYziHlk@bStq70#Cj&xcBHF}Qh7>K|L+ zGSMZv?>BkxSI|)PytvG)+~h^d{h*D4$BV1ZTFyJPwx>|>Q&jf)`!;@|>o>KeigfNQ zKdoiB@BHH2^Z6cAjNI~{7xpYz)*@-n{)yR@Q@gFS=6-x;IK%C{8_SB6yaTS3&Ir4| zUE;s9bHKVPm+B9df!CdFmtStY{Nbek&RfT(w_RvD{KP5u--bsietc@r9Zb}=a&%tj zNKUp;FO@TXmAB&V{F(kGzKxv?-gjqB*NoBM*XX#j=l`qP1h#o+uiIYMTP(U~#WS_1 S`G@c9U{-uJU+kk!$W{P-v-3FCSGCJ|}M1qlYcY@Awc9&O)w85y}*84TPF zxeYkkm_u3EgqfWE3i}rkzmOeQCqT{u^st-Ttpi zPuNmkmnCl_6;#Dy%Wl)k+j2p^jO%-r$o-2B=#+)Tu zi;Mqo%F7u^1`9sFxmicAOmE@hdv#eIoG(7Hcm3FOR^a)gVu#7QIWF2i{KGwEv+Dbr zW!EpRpZ|Z_tgjQRXKB!8BP1@GGOiRB921a~7!G8D27Up^;W=00a#ZCqe2C~3(E6c|s#v*dF#OjHG zE$?@sJ9Sa4^W{uteSatdPU*73jEw(TSPhtglmQ<|JwHf*1((5;I&#?|n!hif^*iLO0nGhl_ zDJ1n#{yI-))VIQlFH>qKa`(NN5Yo3Nf1%InKP4%D3upasWM6o8;uD)$4`v%#7O&R2 znt7sPqMBjtqvHl2|AHv8qHr&l|A zuj%YxExm86M!S%BN#38@Km8Zl)iy}~-kG!d(L7txgVuWKOc4|3zyIMRud_YlYw6na zTfhAmtUdHWW$D_>zZTf6{1tm=>4NtzOZHuR@$`xCH1TRSJEOP9w>#}ATYMwcLfgVL zP?3)>U(ZC?;h}aqPp+4vfrN6DQRvK*;ty=@eS1^6Ry#s+(OMlPsi}SYrcH=-3P18w zgxOSEMmI2=W4YBm`zI&1Fc%*>sMfHX+ev;c?|QYOTW9udUfdkP+jLakE%5Oii8H;k zd*67zE)BTaqY-(k#N<{Fx8iEKSJF?9{}r`6AinCia-N#o>0duL7G-CiS8Cx-;$L%9 zl3~iCGMg*9v);1I(`8E%Fb|SxEs|D$dghqn8}m2Gk+ZpF%g)pp&FYxSVHULeURivZ Wr{~)Gy{QVDP9D@QlPH@Xwh;gt1~=6J literal 0 HcmV?d00001 diff --git a/config/systemCertificates/dbc54cab.0 b/config/systemCertificates/dbc54cab.0 new file mode 100644 index 0000000000000000000000000000000000000000..832df1d8219ae219f28c393def73495c5cd6a617 GIT binary patch literal 1354 zcmXqLVs$fUV%A&0%*4pV#F5)0;IcPQE73Bp^SkPNR*jJ7)ewipeQvrvozO0PMp`!z`)SR z($K`vz}PHGoYw@%Gd6^BsbNJElM=GS8Ce;ao0#|+44Rm@n3|Xv8IB0uUm5?;@$TKP z^Sd5@Tl3JSV%DA;AL^?X7;D|>Rft}voBw?BO|ycmjPregi(8}9Sr!PW9h@G1 z!$VVe+rxbmeebvO1WU}4Q(5HS|6x%p_vtU1^_P}Jyi@Z%xoSoAted|q?zx1EKK;>i z;-<$VUNLo9xf9K;s@r$13UxfgtmLgbvA6qK=lZncFaK-5v{`fO(&obtGv;*usA34a z_a$^{&hK3*caysBbC(;vPCBDDYxeF{NzFc6*s2UpXzqW@<~x0-%n?KFtMPk+g~aE~ z4A)F6PgFEy*HiVJEAi>wXYInCt-CDQJR*PAqfwO3cay!yTKe$(BvZu~4>uJh?a z_&W_hwfO!C8Jzk%e%xVusW;0maQQ{0BV5ZZJaRVw{9n7eE&TDWYpoUKyPRKn)PK9N zPdQg^|3$N$h?tM>mPm$3ePzB>_UvKLUYpIAJ-i>C_)$M;MVZ?ir&PNoatGO&qug|N zO#i(7>ZVY|_q*=+Fiig~GF9Dp{|je#w@Vx|#S*M%)m?h_*5cJ0MmZagFi+0oKIRPb zI`|G0Kg>^iS>$eDC-9V;`Q$7ohMc2Q>JpE1-LG$w;*LBLX;i*>PeNvx<=-uA)jHQw z%x>=Wc-tahw^XTLYlqX9rtMdPCsg?9O8srjce!rOSTfD&0mCD`>{mzM6|LF5|KF=s zD}LPhwyCmfTRIanBLm}NCj$oqSztnyPG!LC0Ze6#44cD!1(N)%o~(JbLuS2^@`=r! zQGs*HGm;Dkgm$)0w9u@k_5Xzd^?s#Xb$~>DRH%|O6n5SPc zty#hBUJZYyaL3Y8vl$%Aj@@5#?s3Gm?RNKeeSU4?aAQ&9*9v?6t4sgfTy!Olg-?9# zKgSPGHx>PIX)<K5|O)a~6N+qdY*hQA3H z43_krU`bkeEtQ7Syo3kUD(~( zHu=Tull)f8t9C5>P~rCLkGcNSu9naD|FPU$n6W@#gZ<@OD~c<26k7ep-ghZcCu3^&{|=bhIK=4l4<32g7AmH#y+C`-8~wJtp) zY0{9td5zTL`5&r1)?Q`2nZ9jh(d1XUXAg?StJm!NSDVfXZQCQUZ0m}+ zEzLREnGTod-}!hrGkfR5T+S~aR|S-DRn=CBFASaLG}DmtZh~Mht3lnfKDUc=MQ$Az zf5JMg=ZMNy>GLA&n;d>Dp6A%Mhvh={v=dqlCV%(8XIp$X;%KX_UH`v%nh&<^;LMPe Hk#Gh8r)NyP literal 0 HcmV?d00001 diff --git a/config/systemCertificates/dbff3a01.0 b/config/systemCertificates/dbff3a01.0 new file mode 100644 index 0000000000000000000000000000000000000000..5a3dc5093cf825f6172ccf9b5862018079b598ec GIT binary patch literal 887 zcmXqLVlFmlVv1hC%*4pV#LckoJj1Rd=Z$_iZ!+LzeM?g^iV_t(^O6l^45UD! z%)-J@r9t`mB?``t3c3o;h6ZxtyoMGAMurxK7RCk!22tX?CdNoyn%UdLsD$iAMpg#q zCPsb+gC<5UrY1&4hV!pi?)*5D^~?j*vmB|J<0!ug+-QYG=S zm6m^^e-!jRm=yH=iR#ag=9{vYPeira#~t6s{?6{exmoMiggI$hsuo<^zqQ(I?V4}J zcg|jy?P^~7TYG}2dA5w2`yFe|u*q4Q4`x}-wf%ZQ-!G{g3}d+3w>KpII-qeQtgGeCJK0wV@s7mTjB3!GBGisPeRL_8$~X#O`q& zJHp~xS-<@6zDp~YuAg&MS?jxvV$R<6{eDNSHhne``g6ZQ%5%w;l~cdZ>x^5}xn|1g z6&bVFccrSI?RnV1w`yn2>;>%*b%aE9{r3 zVztJimrrGX|Ij^RInB|>T3zQzj)Z8#u{G=6BlXp|ADeA>Z~f1Cx~I`hA<^jjf|~zV z2mjc8u!4WhoZ$80doy}$GmSqiUZ9+8oszEPvi54>=`gK|NsIl349(0Q-TTLIWN`w& z`q~8>y0)5C1ufjG{zXAO>4onU72zjbEH7z#1s^g5Qv^3>C$?(&fnU-=KLdbukk z?sKxXzkk4$e>-HA{&{Q1W=3bYpfY7N;f_C1)sj z<`tJ@mXwxc=I0eFIHwks=qWgsmSp4?WtLPLIvCi2Okox_C&iSY{QMGUM+GATLsJ7e zab6&4ZeVU`U}$J$7$weYVqjoqYyjmB9gj3IDIrG!BP#=Q6B9p!K@$@fQxhtr7y192%CENT zuga@cQGb5ywA!<$|I*o$Z@BW_wTeu&jHsG4v&eQ%OI(NIj;mjE{@g4G@~_yj*G9X0 z>Wr_OFJ_!q5UKNtiGSYx^s8y3r1^D0j_qmtE_ztcel=O3>JF2vBx9U&{_O(&#|iHY2KO!el31Ul5sZYrcYQ} z&-i-ogCE_UcU5QDPTE%Y{^rNPz*=3k6Pb~T57uPu&@vNbsS4O@)Ur?iPSMrtvSRK} z+|v~7zf3#2zK^kLDSuVUS6+$so9jBR{%SdBbs$qi_Y-eM;Ht+<%a1LYz_-x6+fdp4 zAScJ`yzdpWuQ&Z^QJCo|xlPDz<8Rkcv6YKc*UVw(f0cblUXQKlOkP6iGJ{J<=JNNR6Bf+$(*GN8!Yf~=&=)n*ii($|tZKl*Uvk!H43L7htCnr_{F^Q)=#m#i7j7cG*0|cJ9AxTLfG>7d@GhcXDd3n z`}p-2ukv3cEo3Xk;lTgV&FA{6YL0_kUvt&(G4-E1yjA%c(tajKGe6_YiY5<0ju>BKF(6t4O3YCR%Fi!RaCcI0b~KO^=QT7jG%_$W zG&L|VHi{DGHMWFs4GoM9qv-9NCPpRX0AXZhU~XdMXE11DDeWIH=x#IN$Nw2)!`q{=Q5tG+u?(dg=-{f(e ziJ6gsadDu5zX3Nef@S$xSb(Xj&43@o5oTok&%$cJ45SQXK>~a%Vk{!2{3pzk;~p)3 z^V2#_^ju)jY17@N#R89^p6AO|`y6#@gDk-@>|cl)N9jT7qT9^J4( z?QBQ2woz~14#mQV>9y<3Mb_Ir|32$c?YF`iGg($SmsBi%?3rj++~Ygt!Oy}Y+r;>S zE99>&YS(A7Y}B+_FFHff;Gf0>hMtQLPydQL@%M*-oAsg!r-|YvpHXG1d264eR~j)Rjv=Y@E(gAnL|E3R6qEa^rTVVZO`< zr9+pKWK7TcWQvAJO_*`-wOstE^5dubY@IXb%!;_6VtrrQVOpK(+Q#F4g}XY00Rez# AKL7v# literal 0 HcmV?d00001 diff --git a/config/systemCertificates/e442e424.0 b/config/systemCertificates/e442e424.0 new file mode 100644 index 0000000000000000000000000000000000000000..3f6981b6bc02fe7a08069effe16ea43ca8633607 GIT binary patch literal 1380 zcmXqLVofk;V)j_T%*4pVB%=3qHj~Ek+g1OsE?)U=FY|))LRqo~ylk9WZ60mkc^MhG zSs4sG47m+B*_cCF*o2v!d<`WH#6cV`VS&KX{IJB7%wh$f%-qb9)D%NG0~wGMv#=;! zDkwj{M8Vln!C1lF*g#I4*U-qo(9p=pz{t$lC`z2y1er@ko0^!EkiEgk%D~*j#Lr;R z#Kgta#Kg$3`81zEdfzLN>C26@xWdfpGklJ3&bLw)nfPC_e(9+-?>3jst$Nuly*k_Q z_Al;WpY=zVN>$o)`TSpVU-h2f%_bvmmwTsf_pDi*C)RAeEXCWX^S79oMcr%XN0&>y z4kd9FbKUja9DZp7SL@tDn|q5-A29mNXsO^VZF(_y^Tu~aCucU3V8g_>E zZ(XE+;F@vzt-2%2x3IXpcK`h>V&`|B57pWm4-{w~c1Y5-_Q<@WY~%5|nzM3c?yVID zGtM^@F?TGBc3W3eS;N7sn7VHJLz$%;wH6uPOJn(dpyWm2z5lk6XQrtMb+=9pms*`& z%I#t+s9{r`xcyOoy8qKRHa-arnc)_4jM2TJFOJ_oaHd?@#Iv;K+YG_iy7%5X>WQ#2 z)j#;B@Y?jb;2NcK;kNfq8srKvx1Rm@zejBA!A*7@ISKU>{HK2Zrn{EWlAYyOX+!OP z&w#h@Padg}dEHQVd)tM(!v9WQo^yTE^p#A^j0}v6oeUfd_<<=_R+y3TKMSh?GmtXi z0}1eh1XzH1gv~$}#OGrXV-YzfeqqmwS4_^Iq}gW1YEMwud40|k-0vt9)CMiKi>x`g>*NVhhs0Aw*9z8L z+WtZ2Nt@<}bMG^fFKkul5>1>{*EVCz$wOto&+IY~JF__PSc&k{?DvaBUorm^?oN4f z`QW7&Ex$c43iwv0yPq+o!6Y-_+KBf#d&`Qbz)!x(c`RB(48MBq-8r5bCuuLpGz$SlZ!R4J{%OB6st#6)t zzejtHQJ>M24~#ZSTJxO`=^dV7$!<~oCyv2M{_6Gvttu(oJNZ_tx<}ibuk+k{{3X}1Ti@&W#5pc|OutY#=>xx|ok^BV z?Tt@L>vm^;G2XJwBlIFapW2Hz+qiX?x0;^)8+l^>#j|!%nkGAKTh47vy%ITbVpyr- z!SZ=Os~#rIy}Xu1;!DlzxXJy&UP_ujJhbh6+tx(apJtmGnQ$W_b!xB6#qafX>h-nj W8osjoY_pqF7&4Q^`)|b08D9WMkx+90 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/e48193cf.0 b/config/systemCertificates/e48193cf.0 new file mode 100644 index 0000000000000000000000000000000000000000..ac4443c70d12575d5be3907e6a217f33bbb478ba GIT binary patch literal 848 zcmXqLV)ij;Vlr94%*4pV#8F<(rmnVfV~qhX8>d#AN85K^Mn-N{1_KvEZUas>=1>+k zVW!YvLlFZZ5QmG0+c7OIvnV&DsI<7mP~JcmB+ASqh9s)soS&PUT9llbm}4L(&TD93 zU}$7%XkuVyU=}6LYYgNW8$!8MvZaYp3EBCKtPIRejQk7+O^jSjO^l2T-=zK1*|isn zeq~cSEzh{=aj`3#i>Jb^p(P&EeFQMhpe2@C&<=P~duiC1+GoH8W z(E3)>N+aFfGD+s2Hb#5do;q6?|I%sSlou!N{Z#TuIren*G40&7tRH?|4$(N z-PZ0)m7}Ywei+;Dct3OcV}*m)G&;{u`MuNi?PCXV!7C*nxD6j^t7Xmh317EH!ETpp z73=4{vol54)%qzUA2BVnVrM#O{`a{1yB8nJWQ#>VO<%J0L{;TYr&ZeZG5^k~`7cgu zG+pnqD@0Dlz$kU@Gn>hA0e)4Ft*+#qk^24flKDCnt<~YoN*cVLrS;o2Zk6uudwhql z(vXRnk%4islYs*`x@7rS#8^b;PCgdg9d~NI{d_t8r!%MSQTaBd-+&(&o3g@;jQ?3! z4VZzH0Ut{U@*7c0_B|YQ^ay8}Id8Ufn5rBU|OlN3nG`mc(4C5A1s@ z!MJg9^4>i^5*udC+j!2Y;L*xjHq~17h5z#3Y?f2G_1HU9iox1+i}lUxu?Bw|g*!hT zV$*(`ex&cD^QM?=(N3m4Nq_u4Z8cuCDgQFpqJYQWtY7H49J-xmvC=rq<72M0aW8L= zeS-Pi%cpYdOzL>&7nOBO&oBBLWa{Y3G)-S-)2w1o#f_fsuI^jjXPF3|^qqAka{D!= mc~O3;Tc@m(zOT7K?BjlhdF)o=DO*{#Dl5+9nrc10<~;z`+d!89 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/e8651083.0 b/config/systemCertificates/e8651083.0 new file mode 100644 index 0000000000000000000000000000000000000000..db0e85a5da32a3aef203bc6279821cd6441d21f0 GIT binary patch literal 1038 zcmXqLV&O7qV*0dznTe5!iId?_oimG{yS=0VFB_*;n@8JsUPeZ4RtAH{CPQumPB!LH z7B*ofk5EHF1AY*PorlAzG$pYhwYbDk%s>Pr#Kptwo0(jcU!0n(;8T*KXQ*zV3KD1L zk%Nn;>IPS3rsw4=1m)+KC^$PR7#SE?8p<2U!Y$=w6cfnIOUrji)hz}q)ypU~kQ3)M zurx3;G&3|bHZZh^66ZCtG&BM-A>6^?$R&DPxD)+-Z3W`CQ&T6rMZ9DQMQ-($*546@0Rj zw@Ga8(OGf+cTC~VTW|iosOx{CFS}_)Y5R@s3!hq_pXudxp;@x_z(OIJskvTXZX93g zYpmC5=}=lHQqv$bBjC7W`i=z+i6P5!{Nx|Zx4@4)X!V90vRuqUwbLE@TXMs?W9LV>5R4 zT=1WJ>#wa$%!~|-iyIpZ>cB}zR+y3TKMSh?GmtXi111z%evkkQFg>yX(*uyt$0Eie za+?3xeJAHLwx_pxC@++%TBfzzB*Q=+B(2OMVIbCkU4b-6fgp>Bflwo6YC=unz(`_b zIC+sTPVefO%{6wX|JeTL)tEY&<;4D5XDfF&Px!E8-}_JR6=&?ZawV4S+dHQ>2005> ztvvN{eb+C0?&2)FS9%V0^6NqpD_`qzm|s`^+%tcl?8b*nN^dWC6e6;5myG5TiEl!? z7Kw;FHZ(oq@PGRQ*0S(}GLfHt?0@oBH7Ta$LtUNx=6yf6D+-=rW(+G>E-*<>+N4o# z?HsAYEH-bM60gazeU7(k|D^rVwf(8>nv2K7TlQwJyL02`HtD1SZd~a|;WUmzV3M0HuD260TGTzWX6 z%s_yR9qeZ&MmARMMivGo<|GD|yUTCx?%Kiqo4a1|(uaNfia#62O6@Uub??~hJr|~a z`*7w0_pZd~K)1Siy7S-lCG&{CVK4Z4zD3WWdCm)a$6V{RmzRh{npMnYc77)yoKtjf zUB~i;*;}2@rQcEh&n&a}k=^gdpVegNSN3)(r*KAf72LSq%!wCQY literal 0 HcmV?d00001 diff --git a/config/systemCertificates/edcbddb5.0 b/config/systemCertificates/edcbddb5.0 new file mode 100644 index 0000000000000000000000000000000000000000..cef2834a83ce18346f5b40e9bf712ddb08a47f0f GIT binary patch literal 1502 zcmXqLV!dV1#C&K0GZP~d6A$ZmzP4MQpWRILc5O1?W#iOp^Jx3d%gD&h%3#pgVaRR3 z$;KSY!Y0fV8f++Nzz^bZ@NjtMBUGcuDC)AJ1#4dg*0Ts#sX zMWw|h<%wmf3Lg16DVcfc#X1U}dC7W)h6ef|CCoe;2qo@0`ALa63eKrTC7EeJlS(r4 z^AsFQOEU6{GD|8An-cpRkDFB9{E~FYdFN*J4N9kf+6EmraNm5=Zb#Om=Pw!y;+(qu z)t3IVI;4=d`-fQHS)P?!q;tvy9!6BU*@c{ISP{-?t|>iJxS!|5H65AXtS>mG+NQeQ zd3QGRk#B#yhMx(y-FcClyYFrbn6c4=uf- zMKufGpZV00xa&*iZk`_Q(r}g?ep(`Ww)`@3M$3}S-laWK+QI6OETHt+Shl37OXsVl z=7P)5r5jpwkJ>)=-S}53e^)BIb;KJdSGC_aZmAX>`NptOsdDe*n#d%tIjs4%=bl}2 zPo8;9CBI1M#G3jETev3{yx9IsOrTKw+&wmb564WB-~sn)Fv)B?ZS%?4eJzL#brO{h6!hR*!my0)4ZJ<(HvsiUaQP{<%!Il z7Z#~)M@yGS-8N<2TYhi1rnv(v`{5};^G~JR{V1({$Bj#X$?&gN1}}TcglBSJwHB_} zZ4>)*F$cFG&qsS*fhqa_9+|W^UpxO)+BEkP^TQ3iD;BJBQ*Sa`F1n3lnNvvkwwY0n zxGN`I4;KnFmF#fLP`zR<-Xi*&vFOg!dqHXnGt?fHeO1r@#bE7~c$4>Z;AE}8Vr*K zRyiDXyptHF&X)PK$g%PAHpb2c`c_4i|Evu5JH9!dWH-_K_)Wtyr=Q<#lHaKH6!X+d z$-Y`q)4t-6dd)*)NB;BY|1d02YMAG>JfC5Mqw991QyCsdoffUTEBom|o*!$(#sd?? zw3gTkIPB|BN^V{`r>Rz#>1DG)&1v+dtYXSfO literal 0 HcmV?d00001 diff --git a/config/systemCertificates/f013ecaf.0 b/config/systemCertificates/f013ecaf.0 new file mode 100644 index 0000000000000000000000000000000000000000..c0310642c08c8930b7b3c7330bf12d77539e33ed GIT binary patch literal 1374 zcmXqLVvRCrVs=`<%*4pVB#`I6@~F2v5APe}3!OV!|u1Q{C0iSrto8JHOv8Gu2QIIl4>mwFa8F)1N?f{~ShxrvFN!JvtW zi>Zl;kzt!4Q@7mXh2^uY@9dvqw|(kz2b+a|n|{_Bu{9Nb`_@zc`^D`&S$fl_FYfXF zsr_x^&vPxZ8-E_1e((LxPm5pf5$cRvzA9+-4`ub!OE%6)zI}aW-3P9?*BQ&c9E)=2 z^%XFF?6*;P@d=3>?>B!qC)}T#qN%FPzHrMWTfKw_=Pz-#?>_7C!S~Ris*bMRyUs^S zUR&S4fqla~!;eh|58T&VmYXBVxAjJynv^TE?S{%FQ#97{*Q-5U!SQd}3!987!S9-_ zIZO-fEVJZF7{4>_sPCwMre_)Tp0q&T+-`Y2u=B$wjsBd}Tb9T~Y zg_p*Af@ZEa+N!x(RcnjK&!UH?QocWH66k#~_fS{IFN?IUKgmBCe^&ghjw%0D*8c0w z{f&H;Q^U9HReOJp@#1SSuHAjyTaO;?3SE79&8vytnr9@J7^(VceN1(^z;tfaInOPx z=GQcDaHxLnyn1=g;{Mvs#$P^5|6lDpe9rs9)*GAqT+f#scYK8i} zI8PCVMGW<`Rw!;;xpC@-r8{}W1aBSB@vw1tP{$i}Hq7SYbk?1xz291T&pBd$DO5O5 zWy7_?UtbRHI`dZg>%T_F8w@jStxl|~nqe-%I+cl;k%4islYxT)A26B9@-s62XJG+m z1~vnJ5MLO?XEk63QU0I87yo|l9B$+J+7C|sz0}7g?^v?5W>w3Tr=R4WnFkro;l7wCyInyCSyYJWA~ci6%)MF-+N!5Klyo+*|}L6JWbEfUl96{km6X*QOV6i@v)a6P9JX^s%P}&yL#Py{$_&M#g=~dU$u?w-lFk&jOnj z(~b$+eLm;@ZjOe$>aG84(x%=u<&Sx;;xlv{zT20+}Nx+-K!?5Xp7~A?d7K{ z|7KcEGJl(Ak?L0WGGT9J$Mkp$p)c>&M>m~lyZUfuZV$_+vR$6v@?Pf3#V>fT-c;uB zW7*}17=9h6TTaKSJ4}uryx}_gpxx0#*_+7$p5IJbvmQts&2wMv=%hLOTLSMT!^_Dt zlqW|qG|us?p{IzMhLx@Cxmo?H&l(C7wYOHE`Kc<__|PzZ z;o>^6C3D2Grc3NCD_Y7uPuA?2{zCnI1rzyKJiGPd$Rvjx)w=4fuWfMokg>FX zO6mWSs23}kYIrywt@P$z(8`^(^Zi1@Nx$EJ3uNicd9ku&;coHGTmO3U*Vw#imQZl^ zyE=K-7L$$gVrKF@&r&SKeC|B>CwpRLlC8t5Q%6mhwyf*yFgCrTBV2q#{o{qAccs=! Y_hw|IMSnb&>>et!Ybi%y=`s&h0Er}BD*ylh literal 0 HcmV?d00001 diff --git a/config/systemCertificates/f0cd152c.0 b/config/systemCertificates/f0cd152c.0 new file mode 100644 index 0000000000000000000000000000000000000000..1c74b84d60b6cc899d337a1ea61debeeeacf351d GIT binary patch literal 1615 zcmXqLV)Hg=VliI8%*4pVB*<`ct8@MOm6rSrKoFX`Ho}0HjZ>@5qwPB{BO^B}gF)jy zLv903Hs(+kHesgFU_&tj5fFzoSxnZ^cHn|>*;m!p1|~LWe49c z-D)N>-SkFHwAm824#J<-(xMtg zn-kwYmRymkUd$T$Znv+s(Y{&bY4g@(PEcZ(Pqdo0@98Z6Gpsfmk(Uqhgsg~6+l-h)wYY7m(Dc6z+P6fU9#7h9 z_bE0my+lu@!(G!P{*lp&IjZJ8yJj#<@AjM~_gA%R&7E5}VoUPUHvD(Fzfj`XJ`a8K zDHT7adfC?t$HhkeEopO3F7{+%W@KPo>}23zzz@tkvcimv|5;cKn1Pf5A4q^7B)|eJ z4%iH2L3}9dt4Mol-m!!GB=>%UoHNm?r z?a!)ar7zu5`Dz|(%E~$RADt2NMXhsQ_2HcZ@6xP)Sudw6Jb6-9b?k!5stIQmChT%g`CZSxIk;jgSJJ0q=W~wQ zjahoFVpD>zWXBgNtq#<6y2>zT=Kg!Tr&x#oo%OZtbeMH?2jkNk4R7Y3p3OCz>T4dq z?ORx%5Zo6!H^4-QfBW?6oOUml=U;Q*G?;&gkj(SSDElBk>B+0DlP)I)3UIGoelz}f z{2lqlF+B_GW^bQ&IV?Xdj(wWKTkewIX@1>;qAwdg>+&~T38+`P9-qp@yX;G=+>Lc? z-d@Wu8KxcjaqcO{vL#H@Tr$FsTs1x~sV{P5icIyAn;+)$ZESdSah_nx$__!RvZkj= zhZ=4yX?{ETeU1Kv4MslGL^C{suFT{(pz=cI@#dw9e3K4LkUy^wf6Ch8`1V|@&(Bu$@YGM%fns1Y68|X=6^oXCv6d?m=!qr^2Aeaw>r1m1~=<) N$anV#-~GQv9ssyCpB4ZB literal 0 HcmV?d00001 diff --git a/config/systemCertificates/f459871d.0 b/config/systemCertificates/f459871d.0 new file mode 100644 index 0000000000000000000000000000000000000000..675cbeb1fe2031aad2cdfddc00627f9daa113bc3 GIT binary patch literal 920 zcmXqLVxD5q#8k6@nTe5!iOcZolO&#;h_}~n81S-jYPET^edlFl4 zKDi=e%UQj`((AJoj`?ct*_M&e^<8mRm}%7Kvb{IX&iX$&%zJ4h+rr5vns>!aO8q`H zZaF^9Z>^+gkk>z(g3^Ms>$O*l&N8-HwYhuMS?9lBUlsg+dtT6b$~iwHvCGO1TIHM9 z+c4_nyq&4jebX;<#-{K6jvI_B60h;bAO5w-VUlc&__G2#)8~t}A4+<(dWnV4R!h_T zSIn8etU@wcbFY2UcMg@C$jf)*YSxlz7lmzfDgs_uO}Zo=_S96$LB_6E=dI;^rw7fB zCHEJfJ=B)qk?}Z_JA|S8Nm-^MZ>66JN1Vu^GaI+By%O^;=0$%L=BeBXP)^sod^HA9%p*>1^_ zd;9o>9$Z+p(4NU;W5Kz(64yAGIo;kRJgD1t#FHhkwjg28s!jhZi>j8%+Qw`BIQ8hS z<#zX-uj}r!D6juDhmHN^@8ro14qK1qa2aZx3z>PMfbg$IHj7 zu`+Pxo37K@34y|Ud~@0UY~bjFyzdTj9E@rB)$1MAG3Q@ToQ*WB=2$FK1uwj1=>&|Tz+h1LHVr3%~ob=!8Q}sSm z)|Emgk3XlBBB94twr>a*Xf!_=ym@#1w@DZ0T#)!ODeqRZ|FYznK1+Ycy;n@B zQi#t56anD%}O;RyM=MVC`YJj83p#gK=A=^U5d=GEofU(#)i)J!`) z!E&mgT#5R>yRX+XF*7nSE_O0-FyIHKPFZ0_#{Vp=2FyUpfDa_V4-#MjW`Z^YSrDI( zMT|vc1J4H^gDZh4#*gq+HN*#Vf!7#UWrXz1swSo~nom9x*j&Zx3} z#lXB_I^X0yQ7gXb^c1zP-1w)y_-}Gy#nSf3^9B!j1vUvs@Gw_yH&jkuThYwfmeF$R|IhPkvnEwOKkI$; zdE#>M)1OxgO`e>+{Dpq-q$3Ft8_qBVN<_EzCPgN1Tf61ntlw(i8PpHNhMJemJQ+~` zI8x8$v5xAyH$Fz?Tjoo>^o~_Hdh4%DyVx=37gu(x&2lY>Tgh!6{K&0Z{qF;}Po3M( zIBh$vp_X@Z=}D^-j=~Aw1A0W)ZOWArl?tzTHc9Jd>Vziy9H#Z_gsjx3nXz1#UDS}g za`wlkySCJbZ16j|QNASJ;#=UW*}rra30_&Lt1jibas4L0Lf!)rZr3u|P6waf{4d+_ ztYclR4}VQjWmV+aI4{06vscb2uB_Se<;>0<>^z%FVs;$Q?^rlt`Il8c_orKZkrGXk z+dhAv?MBV@=?jHEMF>a+GaE?nkm~$4XYX|8zQvrMWxEwWZn^(N=HmQRCbm~G*Mv8> zykE35rl(wUdB%b4bq<$SYDDMjVD#CpH~?(^8c znWiqe%oX@5qwPB{BO^B} zgMpDG!O>~FbfMn1Qdeu^Gg(*9Tf}> z*0AF)}i2s%R)Y zRdMxk;d=LmfRft08`nF^zRb+{9-)}ca~YmCeB;(ugPrbQ?IZmt`C3y-6Hm@&Zwbc1Q{rc}h`cPmw8PecTBE+ObT9 literal 0 HcmV?d00001 diff --git a/config/systemCertificates/fde84897.0 b/config/systemCertificates/fde84897.0 new file mode 100644 index 0000000000000000000000000000000000000000..8a3782c78c2702b7bb2354de74cec53919b3e402 GIT binary patch literal 940 zcmXqLVqRg;#57?6GZP~d6DPyJJC7OpPkQ_};AP{~YV&CO&dbQi%F1A1V#sa4$;KSY z!Y0h*7Gx-7AOPZU@o>6iWad`pmt+^w$R2IeM4eg=akMlPl%Mn;Ac86QtxySCY+RIN$w&6a(y zVjil!6?9L0xTr>~!a?y#!n~*x$q$cgoHpsdL~f??L+zyRcORMQPh{Weah~r@JoU=BZyzSG13oEAz)h?ZNCi_H7 zSeNn2=Srf%Vjs?kzX^|jxrl29=e@`AbMo(aJZ|L{jas&A{u+>ZSySH~Cr`s(D&=63ODK z_I54`V&BwGsIFu6+VVVE=W~x(a9zxAK`D-dZb|c%c6>b4n|bG#RRr68CT2zk#>I_$ z3>tTWqeNDik?}tZs{u2RGLQwvkt`pJ7>kJ1+kcLh6Sk;C?qmEEbk+4+l;s^kgA|ao zGE1yMbOTle3oVwIkr!=ENQsLNWD7sYRV=`C$7UeN#+lIO!Pxf0iIEW`#K4Xm!NBwf zj9^BFR%W?Lh2NakKU|zR@Ac;c{GXOyxi$6KwS5_8wsm>(K3(rG@+;=XEe%ROC-mdJ z)~)>4=KqA5j-R%+Q_8-Ts8@fb$o8(mLpdJ@$sYdeb1pU;RL_XKQ+sSDkEYK;<3+F2 ztx{VqPkZ#X%(b9@tMsbJ^ATDy$#!4)DEZ}SRZOI&-$vF zmL$uU7`gxFb+-S%@VDJT@T#ElZjS?sE0<{K{uTYP!B6{(LA2r@!HFjO9N$;ZonHEX T`qTr{BJ^MFcDug&$xS@~re$4= literal 0 HcmV?d00001 diff --git a/frameworks/cert_manager_standard/main/BUILD.gn b/frameworks/cert_manager_standard/main/BUILD.gn new file mode 100644 index 0000000..6223808 --- /dev/null +++ b/frameworks/cert_manager_standard/main/BUILD.gn @@ -0,0 +1,23 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +group("cert_manager_standard_frameworks") { + if (os_level == "standard") { + public_deps = [ + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/os_dependency:libcert_manager_os_dependency_standard_static", + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/common:libcert_manager_common_standard_static", + ] + } +} diff --git a/frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.c b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.c new file mode 100644 index 0000000..f7afc90 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_manager_api.h" + +#include "cm_client_ipc.h" +#include "cm_log.h" +#include "cm_type.h" + +CM_API_EXPORT int32_t CmGrantAppCertificate(const struct CmBlob *keyUri, uint32_t appUid, struct CmBlob *authUri) +{ + CM_LOG_I("enter grant app certificate"); + if ((keyUri == NULL) || (authUri == NULL)) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientGrantAppCertificate(keyUri, appUid, authUri); + CM_LOG_I("leave grant app certificate, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmGetAuthorizedAppList(const struct CmBlob *keyUri, struct CmAppUidList *appUidList) +{ + CM_LOG_I("enter get authorized app list"); + if ((keyUri == NULL) || (appUidList == NULL)) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientGetAuthorizedAppList(keyUri, appUidList); + CM_LOG_I("leave get authorized app list, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmIsAuthorizedApp(const struct CmBlob *authUri) +{ + CM_LOG_I("enter check is app authed"); + if (authUri == NULL) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientIsAuthorizedApp(authUri); + CM_LOG_I("leave check is app authed, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmRemoveGrantedApp(const struct CmBlob *keyUri, uint32_t appUid) +{ + CM_LOG_I("enter remove granted app"); + if (keyUri == NULL) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientRemoveGrantedApp(keyUri, appUid); + CM_LOG_I("leave remove granted app, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmInit(const struct CmBlob *authUri, const struct CmSignatureSpec *spec, struct CmBlob *handle) +{ + CM_LOG_I("enter cert manager init"); + if ((authUri == NULL) || (spec == NULL) || (handle == NULL)) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientInit(authUri, spec, handle); + CM_LOG_I("leave cert manager init, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmUpdate(const struct CmBlob *handle, const struct CmBlob *inData) +{ + CM_LOG_I("enter cert manager update"); + if ((handle == NULL) || (inData == NULL)) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientUpdate(handle, inData); + CM_LOG_I("leave cert manager update, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmFinish(const struct CmBlob *handle, const struct CmBlob *inData, struct CmBlob *outData) +{ + CM_LOG_I("enter cert manager finish"); + if ((handle == NULL) || (inData == NULL) || (outData == NULL)) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientFinish(handle, inData, outData); + CM_LOG_I("leave cert manager finish, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmAbort(const struct CmBlob *handle) +{ + CM_LOG_I("enter cert manager abort"); + if (handle == NULL) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientAbort(handle); + CM_LOG_I("leave cert manager abort, result = %d", ret); + return ret; +} diff --git a/frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.h b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.h new file mode 100644 index 0000000..5ae7392 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_api.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_MANGAGER_API_H +#define AUTH_MANGAGER_API_H + +#include "cm_type.h" + +enum AuthErrorCode { + CMR_ERROR_SESSION_REACHED_LIMIT = -38, + CMR_ERROR_PERMISSION_DENIED = -39, + CMR_ERROR_AUTH_CHECK_FAILED = -40, + CMR_ERROR_KEY_OPERATION_FAILED = -41, +}; + +enum AutMsgCode { + CM_MSG_GRANT_APP_CERT, // CmIpcServiceGrantAppCertificate_g_cmIpcHandler + CM_MSG_GET_AUTHED_LIST, // CmIpcServiceGetAuthorizedAppList + CM_MSG_CHECK_IS_AUTHED_APP, // CmIpcServiceIsAuthorizedApp + CM_MSG_REMOVE_GRANT_APP, // CmIpcServiceRemoveGrantedApp + CM_MSG_INIT, // CmIpcServiceInit + CM_MSG_UPDATE, // CmIpcServiceUpdate + CM_MSG_FINISH, // CmIpcServiceFinish + CM_MSG_ABORT, // CmIpcServiceAbort + CM_MSG_INSTALL_USER_CERTIFICATE, // CmIpcServiceInstallUserCert + CM_MSG_UNINSTALL_USER_CERTIFICATE, // CmIpcServiceUninstallUserCert + CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE, // CmIpcServiceUninstallAllUserCert +}; + +struct CmAppUidList { + uint32_t appUidCount; + uint32_t *appUid; +}; + +struct CmSignatureSpec { + uint32_t purpose; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +CM_API_EXPORT int32_t CmGrantAppCertificate(const struct CmBlob *keyUri, uint32_t appUid, struct CmBlob *authUri); + +CM_API_EXPORT int32_t CmGetAuthorizedAppList(const struct CmBlob *keyUri, struct CmAppUidList *appUidList); + +CM_API_EXPORT int32_t CmIsAuthorizedApp(const struct CmBlob *authUri); + +CM_API_EXPORT int32_t CmRemoveGrantedApp(const struct CmBlob *keyUri, uint32_t appUid); + +CM_API_EXPORT int32_t CmInit(const struct CmBlob *authUri, const struct CmSignatureSpec *spec, struct CmBlob *handle); + +CM_API_EXPORT int32_t CmUpdate(const struct CmBlob *handle, const struct CmBlob *inData); + +CM_API_EXPORT int32_t CmFinish(const struct CmBlob *handle, const struct CmBlob *inData, struct CmBlob *outData); + +CM_API_EXPORT int32_t CmAbort(const struct CmBlob *handle); + +#ifdef __cplusplus +} +#endif + +#endif /* AUTH_MANGAGER_API_H */ \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.c b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.c new file mode 100644 index 0000000..b627d9c --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_client_ipc.h" +#include "cm_ipc_check.h" + +#include "cm_ipc_serialization.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_param.h" + +#include "cm_request.h" + +static int32_t ClientSerializationAndSend(enum CmMessage message, const struct CmParam *params, + uint32_t paramCount, struct CmBlob *outBlob) +{ + struct CmParamSet *sendParamSet = NULL; + int32_t ret = CmParamsToParamSet(params, paramCount, &sendParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("pack params failed, ret = %d", ret); + return ret; + } + + struct CmBlob parcelBlob = { sendParamSet->paramSetSize, (uint8_t *)sendParamSet }; + ret = SendRequest(message, &parcelBlob, outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("send request failed, ret = %d", ret); + } + CmFreeParamSet(&sendParamSet); + + return ret; +} + +static int32_t FormatAppUidList(const struct CmBlob *replyBlob, struct CmAppUidList *appUidList) +{ + if (replyBlob->size < sizeof(uint32_t)) { /* app uid count: 4 bytes */ + CM_LOG_E("invalid reply size[%u]", replyBlob->size); + return CMR_ERROR_INVALID_ARGUMENT; + } + + /* get app uid count */ + uint32_t count = 0; + (void)memcpy_s(&count, sizeof(uint32_t), replyBlob->data, sizeof(uint32_t)); + uint32_t offset = sizeof(uint32_t); + + /* check reply total len */ + if ((count > MAX_OUT_BLOB_SIZE) || (replyBlob->size < (sizeof(uint32_t) + count * sizeof(uint32_t)))) { + CM_LOG_E("invalid reply size[%u]", replyBlob->size); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (appUidList->appUidCount < count) { + CM_LOG_E("input app list count[%u] too small", appUidList->appUidCount); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + if (count != 0) { + if (appUidList->appUid == NULL) { + CM_LOG_E("input appUid NULL"); + return CMR_ERROR_INVALID_ARGUMENT; + } + uint32_t uidListSize = count * sizeof(uint32_t); + (void)memcpy_s(appUidList->appUid, uidListSize, replyBlob->data + offset, uidListSize); + } + appUidList->appUidCount = count; + return CM_SUCCESS; +} + +int32_t CmClientGrantAppCertificate(const struct CmBlob *keyUri, uint32_t appUid, struct CmBlob *authUri) +{ + if (CmCheckBlob(keyUri) != CM_SUCCESS || CmCheckBlob(authUri) != CM_SUCCESS) { + CM_LOG_E("invalid keyUri or authUri"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri }, + { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = appUid }, + }; + + int32_t ret = ClientSerializationAndSend(CM_MSG_GRANT_APP_CERT, params, CM_ARRAY_SIZE(params), authUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("grant app serialization and send failed, ret = %d", ret); + } + return ret; +} + +int32_t CmClientGetAuthorizedAppList(const struct CmBlob *keyUri, struct CmAppUidList *appUidList) +{ + if (CmCheckBlob(keyUri) != CM_SUCCESS) { + CM_LOG_E("invalid keyUri"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (appUidList->appUidCount > MAX_OUT_BLOB_SIZE) { /* ensure not out of bounds */ + CM_LOG_E("invalid app uid list count[%u]", appUidList->appUidCount); + return CMR_ERROR_INVALID_ARGUMENT; + } + + uint32_t outLen = sizeof(uint32_t) + appUidList->appUidCount * sizeof(uint32_t); + uint8_t *outData = CmMalloc(outLen); + if (outData == NULL) { + CM_LOG_E("malloc out data failed"); + return CMR_ERROR_MALLOC_FAIL; + } + (void)memset_s(outData, outLen, 0, outLen); + struct CmBlob outBlob = { outLen, outData }; + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri }, + }; + + int32_t ret = ClientSerializationAndSend(CM_MSG_GET_AUTHED_LIST, params, CM_ARRAY_SIZE(params), &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("get authed list serialization and send failed, ret = %d", ret); + CmFree(outData); + return ret; + } + + ret = FormatAppUidList(&outBlob, appUidList); + CmFree(outData); + return ret; +} + +int32_t CmClientIsAuthorizedApp(const struct CmBlob *authUri) +{ + if (CmCheckBlob(authUri) != CM_SUCCESS) { + CM_LOG_E("invalid authUri"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *authUri }, + }; + + struct CmBlob outBlob = { 0, NULL }; + int32_t ret = ClientSerializationAndSend(CM_MSG_CHECK_IS_AUTHED_APP, params, CM_ARRAY_SIZE(params), &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("check is authed serialization and send failed, ret = %d", ret); + } + return ret; +} + +int32_t CmClientRemoveGrantedApp(const struct CmBlob *keyUri, uint32_t appUid) +{ + if (CmCheckBlob(keyUri) != CM_SUCCESS) { + CM_LOG_E("invalid keyUri"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri }, + { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = appUid }, + }; + + struct CmBlob outBlob = { 0, NULL }; + int32_t ret = ClientSerializationAndSend(CM_MSG_REMOVE_GRANT_APP, params, CM_ARRAY_SIZE(params), &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("remove granted app serialization and send failed, ret = %d", ret); + } + return ret; +} + +int32_t CmClientInit(const struct CmBlob *authUri, const struct CmSignatureSpec *spec, struct CmBlob *handle) +{ + if (CmCheckBlob(authUri) != CM_SUCCESS || CmCheckBlob(handle) != CM_SUCCESS) { + CM_LOG_E("invalid handle or inData"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmBlob signSpec = { sizeof(struct CmSignatureSpec), (uint8_t *)spec }; + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *authUri }, + { .tag = CM_TAG_PARAM1_BUFFER, .blob = signSpec }, + }; + + int32_t ret = ClientSerializationAndSend(CM_MSG_INIT, params, CM_ARRAY_SIZE(params), handle); + if (ret != CM_SUCCESS) { + CM_LOG_E("update serialization and send failed, ret = %d", ret); + } + return ret; +} + +int32_t CmClientUpdate(const struct CmBlob *handle, const struct CmBlob *inData) +{ + if (CmCheckBlob(handle) != CM_SUCCESS || CmCheckBlob(inData) != CM_SUCCESS) { + CM_LOG_E("invalid handle or inData"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle }, + { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData }, + }; + + struct CmBlob outBlob = { 0, NULL }; + int32_t ret = ClientSerializationAndSend(CM_MSG_UPDATE, params, CM_ARRAY_SIZE(params), &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("update serialization and send failed, ret = %d", ret); + } + return ret; +} + +int32_t CmClientFinish(const struct CmBlob *handle, const struct CmBlob *inData, struct CmBlob *outData) +{ + if (CmCheckBlob(handle) != CM_SUCCESS) { /* finish: inData and outData can be {0, NULL} */ + CM_LOG_E("invalid handle"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle }, + { .tag = CM_TAG_PARAM1_BUFFER, .blob = *inData }, + }; + + int32_t ret = ClientSerializationAndSend(CM_MSG_FINISH, params, CM_ARRAY_SIZE(params), outData); + if (ret != CM_SUCCESS) { + CM_LOG_E("finish serialization and send failed, ret = %d", ret); + } + return ret; +} + +int32_t CmClientAbort(const struct CmBlob *handle) +{ + if (CmCheckBlob(handle) != CM_SUCCESS) { + CM_LOG_E("invalid handle"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = *handle }, + }; + + struct CmBlob outBlob = { 0, NULL }; + int32_t ret = ClientSerializationAndSend(CM_MSG_ABORT, params, CM_ARRAY_SIZE(params), &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("abort serialization and send failed, ret = %d", ret); + } + return ret; +} + +static const uint8_t g_certPwd[] = "123456"; +static const uint8_t g_rsaP12Certinfo[] = { + 0x30, 0x82, 0x0b, 0xc1, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0b, 0x87, 0x06, 0x09, 0x2a, 0x86, 0x48, +}; + +static const uint8_t g_eccP12Certinfo[] = { + 0x30, 0x82, 0x04, 0x6a, 0x02, 0x01, 0x03, 0x30, 0x82, 0x04, 0x30, 0x06, 0x09, 0x2a, 0x86, 0x48, +}; + +#define CERT_KEY_ALG_RSA 1 +#define CERT_KEY_ALG_ECC 2 + +int32_t TestGenerateAppCert(const struct CmBlob *alias, uint32_t alg, uint32_t store) +{ + struct CmBlob appCert = { 0, NULL }; + if (alg == CERT_KEY_ALG_RSA) { + appCert.size = sizeof(g_rsaP12Certinfo); + appCert.data = (uint8_t *)g_rsaP12Certinfo; + } else if (alg == CERT_KEY_ALG_ECC) { + appCert.size = sizeof(g_eccP12Certinfo); + appCert.data = (uint8_t *)g_eccP12Certinfo; + } else { + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmBlob appCertPwd = { sizeof(g_certPwd), (uint8_t *)g_certPwd }; + return CmInstallAppCert(&appCert, &appCertPwd, alias, store); +} diff --git a/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.h b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.h new file mode 100644 index 0000000..d4b27fb --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_MANAGER_IPC_H +#define AUTH_MANAGER_IPC_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int32_t CmClientGrantAppCertificate(const struct CmBlob *keyUri, uint32_t appUid, struct CmBlob *authUri); + +int32_t CmClientGetAuthorizedAppList(const struct CmBlob *keyUri, struct CmAppUidList *appUidList); + +int32_t CmClientIsAuthorizedApp(const struct CmBlob *authUri); + +int32_t CmClientRemoveGrantedApp(const struct CmBlob *keyUri, uint32_t appUid); + +int32_t CmClientInit(const struct CmBlob *authUri, const struct CmSignatureSpec *spec, struct CmBlob *handle); + +int32_t CmClientUpdate(const struct CmBlob *handle, const struct CmBlob *inData); + +int32_t CmClientFinish(const struct CmBlob *handle, const struct CmBlob *inData, struct CmBlob *outData); + +int32_t CmClientAbort(const struct CmBlob *handle); + +int32_t TestGenerateAppCert(const struct CmBlob *alias, uint32_t alg, uint32_t store); + +#ifdef __cplusplus +} +#endif + +#endif /* AUTH_MANAGER_IPC_H */ diff --git a/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.c b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.c new file mode 100644 index 0000000..e2265ca --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_manager_ipc_service.h" + +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_response.h" + +#include "cert_manager_service.h" + +static int32_t GetInputParams(const struct CmBlob *paramSetBlob, struct CmParamSet **paramSet, + struct CmContext *cmContext, struct CmParamOut *params, uint32_t paramsCount) +{ + int32_t ret = CmGetProcessInfoForIPC(cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("get ipc info failed, ret = %d", ret); + return ret; + } + + /* The paramSet blob pointer needs to be refreshed across processes. */ + ret = CmGetParamSet((struct CmParamSet *)paramSetBlob->data, paramSetBlob->size, paramSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("get paramSet failed, ret = %d", ret); + return ret; + } + + ret = CmParamSetToParams(*paramSet, params, paramsCount); + if (ret != CM_SUCCESS) { + CM_LOG_E("get params from paramSet failed, ret = %d", ret); + CmFreeParamSet(paramSet); /* if success no need free paramSet */ + } + + return ret; +} + +static int32_t GetAuthedList(const struct CmContext *context, const struct CmBlob *keyUri, struct CmBlob *outData) +{ + if (outData->size < sizeof(uint32_t)) { /* appUidCount size */ + CM_LOG_E("invalid outData size[%u]", outData->size); + return CMR_ERROR_INVALID_ARGUMENT; + } + + uint32_t count = (outData->size - sizeof(uint32_t)) / sizeof(uint32_t); + struct CmAppUidList appUidList = { count, NULL }; + if (count != 0) { + appUidList.appUid = (uint32_t *)(outData->data + sizeof(uint32_t)); + } + + int32_t ret = CmServiceGetAuthorizedAppList(context, keyUri, &appUidList); + if (ret != CM_SUCCESS) { + CM_LOG_E("service get authed list failed, ret = %d", ret); + return ret; + } + + /* refresh outData: 1.refresh appUidCount; 2.appUidCount is no bigger than count */ + (void)memcpy_s(outData->data, sizeof(uint32_t), &appUidList.appUidCount, sizeof(uint32_t)); + outData->size = sizeof(uint32_t) + sizeof(uint32_t) * appUidList.appUidCount; + + return CM_SUCCESS; +} + +void CmIpcServiceGrantAppCertificate(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + + int32_t ret; + do { + struct CmBlob keyUri = { 0, NULL }; + uint32_t appUid = 0; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &keyUri }, + { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = &appUid }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + ret = CmServiceGrantAppCertificate(&cmContext, &keyUri, appUid, outData); + if (ret != CM_SUCCESS) { + CM_LOG_E("service grant app failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceGrantAppCertificate end:%d", ret); + CmSendResponse(context, ret, outData); + CmFreeParamSet(¶mSet); +} + +void CmIpcServiceGetAuthorizedAppList(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + + int32_t ret; + do { + struct CmBlob keyUri = { 0, NULL }; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &keyUri }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + ret = GetAuthedList(&cmContext, &keyUri, outData); + if (ret != CM_SUCCESS) { + CM_LOG_E("get authed app list failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceGetAuthorizedAppList end:%d", ret); + CmSendResponse(context, ret, outData); + CmFreeParamSet(¶mSet); +} + +void CmIpcServiceIsAuthorizedApp(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + (void)outData; + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + + int32_t ret; + do { + struct CmBlob authUri = { 0, NULL }; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &authUri }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + ret = CmServiceIsAuthorizedApp(&cmContext, &authUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("service check is authed app failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceIsAuthorizedApp end:%d", ret); + CmSendResponse(context, ret, NULL); + CmFreeParamSet(¶mSet); +} + +void CmIpcServiceRemoveGrantedApp(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + (void)outData; + + int32_t ret; + do { + uint32_t appUid = 0; + struct CmBlob keyUri = { 0, NULL }; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &keyUri }, + { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = &appUid }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + ret = CmServiceRemoveGrantedApp(&cmContext, &keyUri, appUid); + if (ret != CM_SUCCESS) { + CM_LOG_E("service remove grant app failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceRemoveGrantedApp end:%d", ret); + CmSendResponse(context, ret, NULL); + CmFreeParamSet(¶mSet); +} + +void CmIpcServiceInit(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + + int32_t ret; + do { + struct CmBlob authUri = { 0, NULL }; + struct CmBlob specBlob = { 0, NULL }; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &authUri }, + { .tag = CM_TAG_PARAM1_BUFFER, .blob = &specBlob }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + struct CmSignatureSpec spec = { 0 }; + if (specBlob.size < sizeof(struct CmSignatureSpec)) { + CM_LOG_E("invalid input spec size"); + ret = CMR_ERROR_INVALID_ARGUMENT; + break; + } + (void)memcpy_s(&spec, sizeof(struct CmSignatureSpec), specBlob.data, sizeof(struct CmSignatureSpec)); + + ret = CmServiceInit(&cmContext, &authUri, &spec, outData); + if (ret != CM_SUCCESS) { + CM_LOG_E("service init failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceInit end:%d", ret); + CmSendResponse(context, ret, outData); + CmFreeParamSet(¶mSet); +} + +void CmIpcServiceUpdate(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + (void)outData; + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + + int32_t ret; + do { + struct CmBlob handleUpdate = { 0, NULL }; + struct CmBlob inDataUpdate = { 0, NULL }; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &handleUpdate }, + { .tag = CM_TAG_PARAM1_BUFFER, .blob = &inDataUpdate }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + ret = CmServiceUpdate(&cmContext, &handleUpdate, &inDataUpdate); + if (ret != CM_SUCCESS) { + CM_LOG_E("service update failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceUpdate end:%d", ret); + CmSendResponse(context, ret, NULL); + CmFreeParamSet(¶mSet); +} + +void CmIpcServiceFinish(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + + int32_t ret; + do { + struct CmBlob handleFinish = { 0, NULL }; + struct CmBlob inDataFinish = { 0, NULL }; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &handleFinish }, + { .tag = CM_TAG_PARAM1_BUFFER, .blob = &inDataFinish }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + ret = CmServiceFinish(&cmContext, &handleFinish, &inDataFinish, outData); + if (ret != CM_SUCCESS) { + CM_LOG_E("service finish failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceFinish end:%d", ret); + CmSendResponse(context, ret, outData); + CmFreeParamSet(¶mSet); +} + +void CmIpcServiceAbort(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + (void)outData; + struct CmContext cmContext = { 0, 0, {0} }; + struct CmParamSet *paramSet = NULL; + + int32_t ret; + do { + struct CmBlob handle = { 0, NULL }; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, .blob = &handle }, + }; + ret = GetInputParams(paramSetBlob, ¶mSet, &cmContext, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("get input params failed, ret = %d", ret); + break; + } + + ret = CmServiceAbort(&cmContext, &handle); + if (ret != CM_SUCCESS) { + CM_LOG_E("service abort failed, ret = %d", ret); + break; + } + } while (0); + + CM_LOG_I("CmIpcServiceAbort end:%d", ret); + CmSendResponse(context, ret, NULL); + CmFreeParamSet(¶mSet); +} diff --git a/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.h b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.h new file mode 100644 index 0000000..ce86892 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/auth_manager_ipc_service.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_IPC_SERVICE_H +#define AUTH_IPC_SERVICE_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void CmIpcServiceGrantAppCertificate(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceGetAuthorizedAppList(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceIsAuthorizedApp(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceRemoveGrantedApp(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceInit(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceUpdate(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceFinish(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceAbort(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.c b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.c new file mode 100644 index 0000000..df4928b --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.c @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_auth_list_mgr.h" + +#include "cert_manager.h" +#include "cert_manager_file_operator.h" +#include "cert_manager_mem.h" +#include "cert_manager_uri.h" + +#include "cm_log.h" +#include "cm_type.h" + +#include "securec.h" + +#define MAX_PATH_LEN 512 +#define MAX_AUTH_COUNT 256 +#define AUTH_LIST_VERSON 0 + +static int32_t GetUidFromUri(const struct CmBlob *uri, uint32_t *uid) +{ + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + int32_t ret = CertManagerUriDecode(&uriObj, (char *)uri->data); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + if (uriObj.app == NULL) { + CM_LOG_E("uri app invalid"); + (void)CertManagerFreeUri(&uriObj); + return CMR_ERROR_INVALID_ARGUMENT; + } + + *uid = atoi(uriObj.app); + (void)CertManagerFreeUri(&uriObj); + return CM_SUCCESS; +} + +static int32_t GetRootPath(uint32_t store, char *rootPath, uint32_t pathLen) +{ + errno_t ret; + + /* keep \0 at end */ + switch (store) { + case CERT_MANAGER_CREDENTIAL_STORE: + ret = memcpy_s(rootPath, pathLen - 1, CREDNTIAL_STORE, strlen(CREDNTIAL_STORE)); + break; + default: + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (ret != EOK) { + CM_LOG_E("copy path failed, store = %u", store); + return CMR_ERROR_BAD_STATE; + } + + return CM_SUCCESS; +} + +static int32_t ConstructUserIdPath(const struct CmContext *context, uint32_t store, + char *userIdPath, uint32_t pathLen) +{ + char rootPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = GetRootPath(store, rootPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + if (snprintf_s(userIdPath, pathLen, pathLen - 1, "%s/%u", rootPath, context->userId) < 0) { + CM_LOG_E("construct user id path failed"); + return CMR_ERROR_BAD_STATE; + } + + ret = CmMakeDir(userIdPath); + if (ret == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("mkdir userId path failed"); + return ret; + } /* ret may be CMR_ERROR_ALREADY_EXISTS */ + + return CM_SUCCESS; +} + +static int32_t ConstructUidPath(const struct CmContext *context, uint32_t store, + char *uidPath, uint32_t pathLen) +{ + char userIdPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = ConstructUserIdPath(context, store, userIdPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + if (snprintf_s(uidPath, pathLen, pathLen - 1, "%s/%u", userIdPath, context->uid) < 0) { + CM_LOG_E("construct uid path failed"); + return CMR_ERROR_BAD_STATE; + } + + ret = CmMakeDir(uidPath); + if (ret == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("mkdir uid path failed"); + return ret; + } /* ret may be CMR_ERROR_ALREADY_EXISTS */ + + return CM_SUCCESS; +} + +static int32_t ConstructAuthListPath(const struct CmContext *context, uint32_t store, + char *authListPath, uint32_t pathLen) +{ + char uidPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = ConstructUidPath(context, store, uidPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + if (snprintf_s(authListPath, pathLen, pathLen - 1, "%s/%s", uidPath, "authlist") < 0) { + CM_LOG_E("construct authlist failed"); + return CMR_ERROR_BAD_STATE; + } + + ret = CmMakeDir(authListPath); + if (ret == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("mkdir auth list path failed"); + return ret; + } /* ret may be CMR_ERROR_ALREADY_EXISTS */ + + return CM_SUCCESS; +} + +static int32_t GetAuthListBuf(const char *path, const char *fileName, struct CmBlob *authList) +{ + uint32_t fileSize = CmFileSize(path, fileName); + if (fileSize == 0 || fileSize > MAX_OUT_BLOB_SIZE) { + CM_LOG_E("file size[%u] invalid", fileSize); + return CMR_ERROR_BAD_STATE; + } + + uint8_t *data = (uint8_t *)CMMalloc(fileSize); + if (data == NULL) { + CM_LOG_E("malloc file buffer failed"); + return CMR_ERROR_MALLOC_FAIL; + } + + uint32_t readSize = CmFileRead(path, fileName, 0, data, fileSize); + if (readSize == 0) { + CM_LOG_E("read file size 0 invalid"); + CMFree(data); + return CMR_ERROR_BAD_STATE; + } + + authList->data = data; + authList->size = fileSize; + return CM_SUCCESS; +} + +static int32_t CheckAuthListFileSizeValid(const struct CmBlob *originList, uint32_t *authCount) +{ + if (originList->size < (sizeof(uint32_t) + sizeof(uint32_t))) { /* version and count size */ + CM_LOG_E("invalid authlist size[%u]", originList->size); + return CMR_ERROR_BAD_STATE; + } + + uint32_t count = 0; + (void)memcpy_s(&count, sizeof(count), originList->data + sizeof(uint32_t), sizeof(count)); + if (count > MAX_OUT_BLOB_SIZE) { + CM_LOG_E("invalid auth count[%u]", count); + return CMR_ERROR_BAD_STATE; + } + + uint32_t size = sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) * count; + if (originList->size != size) { + CM_LOG_E("invalid auth list file size[%u], count[%u]", originList->size, count); + return CMR_ERROR_BAD_STATE; + } + + *authCount = count; + return CM_SUCCESS; +} + +static bool IsUidExist(const struct CmBlob *list, uint32_t count, uint32_t targetUid, uint32_t *position) +{ + uint32_t uid; + uint32_t offset = sizeof(uint32_t) + sizeof(uint32_t); + for (uint32_t i = 0; i < count; ++i) { + (void)memcpy_s(&uid, sizeof(uint32_t), list->data + offset, sizeof(uint32_t)); + offset += sizeof(uint32_t); + if (uid == targetUid) { + *position = offset; + return true; + } + } + return false; +} + +static int32_t CopyBlob(const struct CmBlob *originList, struct CmBlob *outList) +{ + uint8_t *data = (uint8_t *)CMMalloc(originList->size); + if (data == NULL) { + CM_LOG_E("out data malloc failed"); + return CMR_ERROR_MALLOC_FAIL; + } + + (void)memcpy_s(data, originList->size, originList->data, originList->size); + + outList->data = data; + outList->size = originList->size; + return CM_SUCCESS; +} + +static int32_t InsertUid(const struct CmBlob *originList, uint32_t uid, struct CmBlob *addedList) +{ + uint32_t count = 0; + int32_t ret = CheckAuthListFileSizeValid(originList, &count); + if (ret != CM_SUCCESS) { + return ret; + } + + uint32_t position = 0; + bool isUidExist = IsUidExist(originList, count, uid, &position); + if (isUidExist) { + /* exist then copy origin */ + return CopyBlob(originList, addedList); + } + + if (count >= MAX_AUTH_COUNT) { + return CMR_ERROR_INSUFFICIENT_MEMORY; + } + + uint32_t size = originList->size + sizeof(uint32_t); /* add one uid */ + uint8_t *data = (uint8_t *)CMMalloc(size); + if (data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + + do { + ret = CMR_ERROR_BAD_STATE; + if (memcpy_s(data, size, originList->data, originList->size) != EOK) { + CM_LOG_E("copy origin list failed"); + break; + } + if (memcpy_s(data + originList->size, size - originList->size, &uid, sizeof(uint32_t)) != EOK) { + CM_LOG_E("copy inserted uid failed"); + break; + } + + /* refresh count after add */ + uint32_t countAfterAdd = count + 1; + if (memcpy_s(data + sizeof(uint32_t), sizeof(countAfterAdd), &countAfterAdd, sizeof(countAfterAdd)) != EOK) { + CM_LOG_E("refresh count after add failed"); + break; + } + ret = CM_SUCCESS; + } while (0); + if (ret != CM_SUCCESS) { + CM_FREE_PTR(data); + return ret; + } + + addedList->data = data; + addedList->size = size; + return CM_SUCCESS; +} + +static int32_t RemoveUid(const struct CmBlob *originList, uint32_t uid, struct CmBlob *removedList) +{ + uint32_t count = 0; + int32_t ret = CheckAuthListFileSizeValid(originList, &count); + if (ret != CM_SUCCESS) { + return ret; + } + + uint32_t position = 0; + bool isUidExist = IsUidExist(originList, count, uid, &position); + if (!isUidExist) { + /* not exist then copy origin */ + return CopyBlob(originList, removedList); + } + + uint32_t size = originList->size - sizeof(uint32_t); /* delete one uid */ + uint8_t *data = (uint8_t *)CMMalloc(size); + if (data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + + do { + ret = CMR_ERROR_BAD_STATE; + uint32_t beforeSize = position - sizeof(uint32_t); /* positon > 12 */ + if (memcpy_s(data, size, originList->data, beforeSize) != EOK) { + CM_LOG_E("copy origin list before uid failed"); + break; + } + + if (size > beforeSize) { /* has buffer after uid */ + if (memcpy_s(data + beforeSize, size - beforeSize, originList->data + position, + originList->size - position) != EOK) { + CM_LOG_E("copy origin list after uid failed"); + break; + } + } + + /* refresh count after remove */ + uint32_t countAfterRemove = count - 1; /* count > 1 */ + if (memcpy_s(data + sizeof(uint32_t), sizeof(countAfterRemove), + &countAfterRemove, sizeof(countAfterRemove)) != EOK) { + CM_LOG_E("refresh count after delete failed"); + break; + } + ret = CM_SUCCESS; + } while (0); + if (ret != CM_SUCCESS) { + CM_FREE_PTR(data); + return ret; + } + + removedList->data = data; + removedList->size = size; + return CM_SUCCESS; +} + +static int32_t RefreshAuthListBuf(const char *path, const char *fileName, uint32_t uid, bool isAdd, + struct CmBlob *authList) +{ + struct CmBlob list = { 0, NULL }; + int32_t ret = GetAuthListBuf(path, fileName, &list); + if (ret != CM_SUCCESS) { + return ret; + } + + if (isAdd) { + ret = InsertUid(&list, uid, authList); + } else { + ret = RemoveUid(&list, uid, authList); + } + CM_FREE_PTR(list.data); + return ret; +} + +/* + * auth list buffer format: + * |--version--|--uidCount(n)--|--uid0--|--uid1--|...|--uid(n-1)--| + * | 4Byte | 4Byte | 4Byte | 4Byte |...| 4Byte | + */ +static int32_t InitAuthListBuf(uint32_t uid, struct CmBlob *authList) +{ + uint32_t count = 1; + uint32_t version = AUTH_LIST_VERSON; + uint32_t size = sizeof(version) + sizeof(count) + sizeof(uid) * count; + uint8_t *data = (uint8_t *)CMMalloc(size); + if (data == NULL) { + CM_LOG_E("malloc file buffer failed"); + return CMR_ERROR_MALLOC_FAIL; + } + (void)memset_s(data, size, 0, size); + + int32_t ret = CM_SUCCESS; + uint32_t offset = 0; + do { + if (memcpy_s(data + offset, size - offset, &version, sizeof(version)) != EOK) { + CM_LOG_E("copy count failed"); + ret = CMR_ERROR_BAD_STATE; + break; + } + offset += sizeof(version); + + if (memcpy_s(data + offset, size - offset, &count, sizeof(count)) != EOK) { + CM_LOG_E("copy count failed"); + ret = CMR_ERROR_BAD_STATE; + break; + } + offset += sizeof(count); + + if (memcpy_s(data + offset, size - offset, &uid, sizeof(uid)) != EOK) { + CM_LOG_E("copy uid failed"); + ret = CMR_ERROR_BAD_STATE; + break; + } + } while (0); + if (ret != CM_SUCCESS) { + CM_FREE_PTR(data); + return ret; + } + + authList->data = data; + authList->size = size; + return CM_SUCCESS; +} + +static int32_t RefreshAuthList(const char *path, const char *fileName, uint32_t uid, bool isAdd) +{ + bool isAuthListExist = false; + int32_t ret = CmIsFileExist(path, fileName); + if (ret == CM_SUCCESS) { + isAuthListExist = true; + } + + if (!isAuthListExist && !isAdd) { + CM_LOG_I("auth list file not exit when delete uid"); + return CM_SUCCESS; /* auth list file not exit when delete uid */ + } + + struct CmBlob authList = { 0, NULL }; + if (isAuthListExist) { + ret = RefreshAuthListBuf(path, fileName, uid, isAdd, &authList); + } else { /* auth list file not exit when add uid */ + ret = InitAuthListBuf(uid, &authList); + } + if (ret != CM_SUCCESS) { + return ret; + } + + ret = CmFileWrite(path, fileName, 0, authList.data, authList.size); + if (ret != CM_SUCCESS) { + CM_LOG_E("write file failed"); + } + CM_FREE_PTR(authList.data); + return ret; +} + +static int32_t FormatAppUidList(const struct CmBlob *list, struct CmAppUidList *appUidList) +{ + uint32_t count = 0; + int32_t ret = CheckAuthListFileSizeValid(list, &count); + if (ret != CM_SUCCESS) { + return ret; + } + + if (count == 0) { + appUidList->appUidCount = 0; + ret = CM_SUCCESS; + return ret; /* has no auth uid */ + } + + uint8_t *data = (uint8_t *)CMMalloc(count * sizeof(uint32_t)); + if (data == NULL) { + CM_LOG_E("malloc app uid buffer failed"); + return ret = CMR_ERROR_MALLOC_FAIL; + } + + uint32_t offsetOut = 0; + uint32_t offset = sizeof(uint32_t) + sizeof(uint32_t); + for (uint32_t i = 0; i < count; ++i) { + (void)memcpy_s(data + offsetOut, sizeof(uint32_t), list->data + offset, sizeof(uint32_t)); + offset += sizeof(uint32_t); + offsetOut += sizeof(uint32_t); + } + + appUidList->appUidCount = count; + appUidList->appUid = (uint32_t *)data; + return CM_SUCCESS; +} + +int32_t CmAddAuthUid(const struct CmContext *context, const struct CmBlob *uri, uint32_t uid) +{ + int32_t ret = CmCheckCredentialExist(context, uri); + if (ret != CM_SUCCESS) { + return ret; + } + + char authListPath[MAX_PATH_LEN] = { 0 }; + ret = ConstructAuthListPath(context, CERT_MANAGER_CREDENTIAL_STORE, authListPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + ret = RefreshAuthList(authListPath, (char *)uri->data, uid, true); + if (ret != CM_SUCCESS) { + CM_LOG_E("refresh auth list failed, ret = %d", ret); + } + return ret; +} + +int32_t CmRemoveAuthUid(const struct CmContext *context, const struct CmBlob *uri, uint32_t uid) +{ + char authListPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = ConstructAuthListPath(context, CERT_MANAGER_CREDENTIAL_STORE, authListPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + ret = RefreshAuthList(authListPath, (char *)uri->data, uid, false); + if (ret != CM_SUCCESS) { + CM_LOG_E("refresh auth list failed, ret = %d", ret); + } + return ret; +} + +int32_t CmGetAuthList(const struct CmContext *context, const struct CmBlob *uri, struct CmAppUidList *appUidList) +{ + char authListPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = ConstructAuthListPath(context, CERT_MANAGER_CREDENTIAL_STORE, authListPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + /* auth list file not exist */ + ret = CmIsFileExist(authListPath, (char *)uri->data); + if (ret != CM_SUCCESS) { + appUidList->appUidCount = 0; + return CM_SUCCESS; + } + + struct CmBlob list = { 0, NULL }; + ret = GetAuthListBuf(authListPath, (char *)uri->data, &list); + if (ret != CM_SUCCESS) { + return ret; + } + + ret = FormatAppUidList(&list, appUidList); + CM_FREE_PTR(list.data); + return ret; +} + +int32_t CmDeleteAuthListFile(const struct CmContext *context, const struct CmBlob *uri) +{ + char authListPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = ConstructAuthListPath(context, CERT_MANAGER_CREDENTIAL_STORE, authListPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + ret = CmIsFileExist(authListPath, (char *)uri->data); + if (ret != CM_SUCCESS) { /* auth list file not exist */ + return CM_SUCCESS; + } + + ret = CmFileRemove(authListPath, (char *)uri->data); + if (ret != CM_SUCCESS) { + CM_LOG_E("remove file failed, ret = %d", ret); + } + return ret; +} + +int32_t CmCheckIsAuthUidExist(const struct CmContext *context, const struct CmBlob *uri, + uint32_t targetUid, bool *isInAuthList) +{ + *isInAuthList = false; + + char authListPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = ConstructAuthListPath(context, CERT_MANAGER_CREDENTIAL_STORE, authListPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + ret = CmIsFileExist(authListPath, (char *)uri->data); + if (ret != CM_SUCCESS) { /* auth list file not exist */ + return CM_SUCCESS; + } + + struct CmBlob list = { 0, NULL }; + ret = GetAuthListBuf(authListPath, (char *)uri->data, &list); + if (ret != CM_SUCCESS) { + return ret; + } + + uint32_t count = 0; + ret = CheckAuthListFileSizeValid(&list, &count); + if (ret != CM_SUCCESS) { + CM_FREE_PTR(list.data); + return ret; + } + + uint32_t position = 0; + *isInAuthList = IsUidExist(&list, count, targetUid, &position); + CM_FREE_PTR(list.data); + + return CM_SUCCESS; +} + +int32_t CmRemoveAuthUidByUserId(uint32_t userId, uint32_t targetUid, const struct CmBlob *uri) +{ + uint32_t uid = 0; + int32_t ret = GetUidFromUri(uri, &uid); + if (ret != CM_SUCCESS) { + return ret; + } + + struct CmContext context = { userId, uid, { 0 } }; + return CmRemoveAuthUid(&context, uri, targetUid); +} + +int32_t CmGetAuthListByUserId(uint32_t userId, const struct CmBlob *uri, struct CmAppUidList *appUidList) +{ + uint32_t uid = 0; + int32_t ret = GetUidFromUri(uri, &uid); + if (ret != CM_SUCCESS) { + return ret; + } + + struct CmContext context = { userId, uid, { 0 } }; + return CmGetAuthList(&context, uri, appUidList); +} + +int32_t CmDeleteAuthListFileByUserId(uint32_t userId, const struct CmBlob *uri) +{ + uint32_t uid = 0; + int32_t ret = GetUidFromUri(uri, &uid); + if (ret != CM_SUCCESS) { + return ret; + } + + struct CmContext context = { userId, uid, { 0 } }; + return CmDeleteAuthListFile(&context, uri); +} + +int32_t CmCheckIsAuthUidExistByUserId(uint32_t userId, uint32_t targetUid, + const struct CmBlob *uri, bool *isInAuthList) +{ + uint32_t uid = 0; + int32_t ret = GetUidFromUri(uri, &uid); + if (ret != CM_SUCCESS) { + return ret; + } + + struct CmContext context = { userId, uid, { 0 } }; + return CmCheckIsAuthUidExist(&context, uri, targetUid, isInAuthList); +} + +int32_t CmCheckCredentialExist(const struct CmContext *context, const struct CmBlob *uri) +{ + char uidPath[MAX_PATH_LEN] = { 0 }; + int32_t ret = ConstructUidPath(context, CERT_MANAGER_CREDENTIAL_STORE, uidPath, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + return ret; + } + + char *fileName = (char *)uri->data; + ret = CmIsFileExist(uidPath, fileName); + if (ret != HKS_SUCCESS) { + CM_LOG_E("Credential file not exist."); + } + return ret; +} + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.h b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.h new file mode 100644 index 0000000..3bd47ff --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_list_mgr.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_AUTH_LIST_MGR_H +#define CERT_MANAGER_AUTH_LIST_MGR_H + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmAddAuthUid(const struct CmContext *context, const struct CmBlob *uri, uint32_t uid); + +int32_t CmRemoveAuthUid(const struct CmContext *context, const struct CmBlob *uri, uint32_t uid); + +int32_t CmGetAuthList(const struct CmContext *context, const struct CmBlob *uri, struct CmAppUidList *appUidList); + +int32_t CmDeleteAuthListFile(const struct CmContext *context, const struct CmBlob *uri); + +int32_t CmCheckIsAuthUidExist(const struct CmContext *context, const struct CmBlob *uri, + uint32_t targetUid, bool *isInAuthList); + +int32_t CmRemoveAuthUidByUserId(uint32_t userId, uint32_t targetUid, const struct CmBlob *uri); + +int32_t CmGetAuthListByUserId(uint32_t userId, const struct CmBlob *uri, struct CmAppUidList *appUidList); + +int32_t CmDeleteAuthListFileByUserId(uint32_t userId, const struct CmBlob *uri); + +int32_t CmCheckIsAuthUidExistByUserId(uint32_t userId, uint32_t targetUid, + const struct CmBlob *uri, bool *isInAuthList); + +int32_t CmCheckCredentialExist(const struct CmContext *context, const struct CmBlob *uri); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANAGER_AUTH_LIST_MGR_H */ + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.c b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.c new file mode 100644 index 0000000..c44561f --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.c @@ -0,0 +1,733 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_auth_mgr.h" + +#include "cert_manager_auth_list_mgr.h" +#include "cert_manager_key_operation.h" +#include "cert_manager_mem.h" +#include "cert_manager_session_mgr.h" +#include "cert_manager_uri.h" +#include "cm_log.h" + +#include "hks_api.h" +#include "hks_type.h" + +#include "securec.h" + +#define MAX_UINT32_LEN 11 +#define MAC_SHA256_LEN 32 + +#define NUMBER_9_IN_DECIMAL 9 +#define BYTE_TO_HEX_OPER_LENGTH 2 +#define OUT_OF_HEX 16 +#define DEC 10 + +static char HexToChar(uint8_t hex) +{ + return (hex > NUMBER_9_IN_DECIMAL) ? (hex + 0x37) : (hex + 0x30); /* Convert to the corresponding character */ +} + +static uint8_t CharToHex(char c) +{ + if ((c >= 'A') && (c <= 'F')) { + return (c - 'A' + DEC); + } else if ((c >= 'a') && (c <= 'f')) { + return (c - 'a' + DEC); + } else if ((c >= '0') && (c <= '9')) { + return (c - '0'); + } else { + return OUT_OF_HEX; + } +} + +static int32_t ByteToHexString(const uint8_t *byte, uint32_t byteLen, char *hexStr, uint32_t hexLen) +{ + if (hexLen < (byteLen * BYTE_TO_HEX_OPER_LENGTH + 1)) { /* The terminator('\0') needs 1 bit */ + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + for (uint32_t i = 0; i < byteLen; ++i) { + hexStr[i * BYTE_TO_HEX_OPER_LENGTH] = HexToChar((byte[i] & 0xF0) >> 4); /* 4: shift right for filling */ + hexStr[i * BYTE_TO_HEX_OPER_LENGTH + 1] = HexToChar(byte[i] & 0x0F); /* get low four bits */ + } + hexStr[byteLen * BYTE_TO_HEX_OPER_LENGTH] = '\0'; + + return CM_SUCCESS; +} + +static int32_t HexStringToByte(const char *hexStr, uint8_t *byte, uint32_t byteLen) +{ + uint32_t realHexLen = strlen(hexStr); + /* odd number or len too small */ + if ((realHexLen % BYTE_TO_HEX_OPER_LENGTH != 0) || (byteLen < realHexLen / BYTE_TO_HEX_OPER_LENGTH)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + for (uint32_t i = 0; i < realHexLen / BYTE_TO_HEX_OPER_LENGTH; ++i) { + uint8_t high = CharToHex(hexStr[i * BYTE_TO_HEX_OPER_LENGTH]); + uint8_t low = CharToHex(hexStr[i * BYTE_TO_HEX_OPER_LENGTH + 1]); + if ((high == OUT_OF_HEX) || (low == OUT_OF_HEX)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + byte[i] = high << 4; /* 4: Set the high nibble */ + byte[i] |= low; /* Set the low nibble */ + } + return CM_SUCCESS; +} + +static int32_t GetAndCheckUriObj(struct CMUri *uriObj, const struct CmBlob *uri) +{ + int32_t ret = CertManagerUriDecode(uriObj, (char *)uri->data); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + if ((uriObj->object == NULL) || + (uriObj->user == NULL) || + (uriObj->app == NULL) || + (uriObj->type != CM_URI_TYPE_APP_KEY)) { + CM_LOG_E("uri format invalid"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + return CM_SUCCESS; +} + +static int32_t CheckCallerIsProducer(const struct CmContext *context, const struct CMUri *uriObj) +{ + /* check caller is Producer: user and app has been checked not null */ + uint32_t userId = atoi(uriObj->user); + uint32_t uid = atoi(uriObj->app); + if ((userId == context->userId) && (uid == context->uid)) { + CM_LOG_I("caller is producer."); + return CM_SUCCESS; + } + + return CMR_ERROR_PERMISSION_DENIED; +} + +static int32_t UintToString(uint32_t input, char *out, uint32_t outLen) +{ + if (snprintf_s(out, outLen, outLen - 1, "%u", input) < 0) { + return CMR_ERROR_BAD_STATE; + } + return CM_SUCCESS; +} + +static int32_t ConstructUri(const struct CMUri *uriObj, struct CmBlob *outUri) +{ + uint32_t outLen = 0; + int32_t ret = CertManagerUriEncode(NULL, &outLen, uriObj); + if (ret != CM_SUCCESS) { + CM_LOG_E("get uriObj len failed, ret = %d", ret); + return ret; + } + + if ((outLen == 0) || (outLen > MAX_OUT_BLOB_SIZE)) { + CM_LOG_E("invalid outLen[%u]", outLen); + return CMR_ERROR_BAD_STATE; + } + + char *data = (char *)CMMalloc(outLen); + if (data == NULL) { + CM_LOG_E("malloc uri buf failed"); + return CMR_ERROR_BAD_STATE; + } + (void)memset_s(data, outLen, 0, outLen); + outUri->size = outLen; /* include 1 byte: the terminator('\0') */ + + ret = CertManagerUriEncode(data, &outLen, uriObj); /* outLen not include '\0' */ + if (ret != CM_SUCCESS) { + CM_LOG_E("encord uri failed"); + outUri->size = 0; + CMFree(data); + return ret; + } + + CM_LOG_I("urilen = %u, uir:%s", outLen, data); + outUri->data = (uint8_t *)data; + return CM_SUCCESS; +} + +static int32_t ConstructToBeAuthedUri(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *toBeAuthedUri) +{ + struct CMUri uri; + (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri)); + + char uidStr[MAX_UINT32_LEN] = { 0 }; + int32_t ret = UintToString(clientUid, uidStr, MAX_UINT32_LEN); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct client uid to string failed"); + return ret; + } + + uri.clientApp = uidStr; + uri.clientUser = NULL; + uri.mac = NULL; + + return ConstructUri(&uri, toBeAuthedUri); +} + +static int32_t ConstructMacKeyUri(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *macKeyUri) +{ + struct CMUri uri; + (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri)); + + char uidStr[MAX_UINT32_LEN] = { 0 }; + int32_t ret = UintToString(clientUid, uidStr, MAX_UINT32_LEN); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct client uid to string failed"); + return ret; + } + + uri.type = CM_URI_TYPE_MAC_KEY; /* type is 'm' */ + uri.clientApp = uidStr; + uri.clientUser = NULL; + uri.mac = NULL; + + return ConstructUri(&uri, macKeyUri); +} + +static int32_t ConstructCommonUri(const struct CMUri *uriObj, struct CmBlob *commonUri) +{ + struct CMUri uri; + (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri)); + + uri.type = CM_URI_TYPE_APP_KEY; /* type is 'ak' */ + uri.clientApp = NULL; + uri.clientUser = NULL; + uri.mac = NULL; + + return ConstructUri(&uri, commonUri); +} +static int32_t CalcUriMac(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *mac, bool isNeedGenKey) +{ + struct CmBlob toBeAuthedUri = { 0, NULL }; + struct CmBlob macKeyUri = { 0, NULL }; + int32_t ret; + + do { + /* construct to be authed URI */ + ret = ConstructToBeAuthedUri(uriObj, clientUid, &toBeAuthedUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct to be authed uri failed, ret = %d", ret); + break; + } + + /* construc mac key URI */ + ret = ConstructMacKeyUri(uriObj, clientUid, &macKeyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct mac key uri, ret = %d", ret); + break; + } + + if (isNeedGenKey) { + ret = CmKeyOpGenMacKey(&macKeyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("generate mac key failed, ret = %d", ret); + break; + } + } + + ret = CmKeyOpCalcMac(&macKeyUri, &toBeAuthedUri, mac); + if (ret != CM_SUCCESS) { + CM_LOG_E("calc mac failed, ret = %d", ret); + break; + } + } while (0); + + CM_FREE_PTR(toBeAuthedUri.data); + CM_FREE_PTR(macKeyUri.data); + return ret; +} + +static int32_t DeleteMacKey(const struct CMUri *uriObj, uint32_t clientUid) +{ + struct CmBlob macKeyUri = { 0, NULL }; + int32_t ret; + + do { + /* construc mac key URI */ + ret = ConstructMacKeyUri(uriObj, clientUid, &macKeyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct mac key uri, ret = %d", ret); + break; + } + + struct HksBlob keyAlias = { macKeyUri.size, macKeyUri.data }; + ret = HksDeleteKey(&keyAlias, NULL); + if ((ret != HKS_SUCCESS) && (ret != HKS_ERROR_NOT_EXIST)) { + CM_LOG_E("delete mac key failed, ret = %d", ret); + break; + } + ret = CM_SUCCESS; /* ret is success if key not exist */ + } while (0); + + CM_FREE_PTR(macKeyUri.data); + return ret; +} + + +static int32_t ConstructAuthUri(const struct CMUri *uriObj, uint32_t clientUid, const struct CmBlob *mac, + struct CmBlob *authUri) +{ + struct CMUri uri; + (void)memcpy_s(&uri, sizeof(uri), uriObj, sizeof(uri)); + + char uidStr[MAX_UINT32_LEN] = { 0 }; + int32_t ret = UintToString(clientUid, uidStr, MAX_UINT32_LEN); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct client uid to string failed"); + return ret; + } + + uint32_t macHexLen = mac->size * BYTE_TO_HEX_OPER_LENGTH + 1; + char *macHex = (char *)CMMalloc(macHexLen); + if (macHex == NULL) { + CM_LOG_E("malloc mac hex buffer failed"); + return CMR_ERROR_MALLOC_FAIL; + } + + ret = ByteToHexString(mac->data, mac->size, macHex, macHexLen); + if (ret != CM_SUCCESS) { + CM_LOG_E("byte to hex string failed, ret = %d", ret); + CMFree(macHex); + return ret; + } + + uri.clientApp = uidStr; + uri.clientUser = NULL; + uri.mac = macHex; + + ret = ConstructUri(&uri, authUri); + CMFree(macHex); + return ret; +} + +static int32_t GenerateAuthUri(const struct CMUri *uriObj, uint32_t clientUid, struct CmBlob *authUri) +{ + struct CmBlob tempAuthUri = { 0, NULL }; + int32_t ret; + do { + /* calc uri mac */ + uint8_t macData[MAC_SHA256_LEN] = {0}; + struct CmBlob mac = { sizeof(macData), macData }; + ret = CalcUriMac(uriObj, clientUid, &mac, true); + if (ret != CM_SUCCESS) { + CM_LOG_E("calc uri mac failed, ret = %d", ret); + break; + } + + /* construct auth URI */ + ret = ConstructAuthUri(uriObj, clientUid, &mac, &tempAuthUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct auth uri failed, ret = %d", ret); + break; + } + + if (authUri->size < tempAuthUri.size) { + CM_LOG_E("auth uri out size too small"); + ret = CMR_ERROR_BUFFER_TOO_SMALL; + break; + } + if (memcpy_s(authUri->data, authUri->size, tempAuthUri.data, tempAuthUri.size) != EOK) { + CM_LOG_E("copy auth uri failed"); + ret = CMR_ERROR_BAD_STATE; + break; + } + authUri->size = tempAuthUri.size; + ret = CM_SUCCESS; + } while (0); + + CM_FREE_PTR(tempAuthUri.data); + return ret; +} + +int32_t CmAuthGrantAppCertificate(const struct CmContext *context, const struct CmBlob *keyUri, + uint32_t appUid, struct CmBlob *authUri) +{ + int32_t ret = CmCheckCredentialExist(context, keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("credential not exist when grant auth, ret = %d", ret); + return ret; + } + + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + ret = GetAndCheckUriObj(&uriObj, keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + do { + ret = CheckCallerIsProducer(context, &uriObj); + if (ret != CM_SUCCESS) { + CM_LOG_E("check caller userId/uid failed when grant, ret = %d", ret); + break; + } + + /* auth URI */ + ret = GenerateAuthUri(&uriObj, appUid, authUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct auth URI failed, ret = %d", ret); + break; + } + + /* add auth uid */ + ret = CmAddAuthUid(context, keyUri, appUid); + if (ret != CM_SUCCESS) { + CM_LOG_E("add auth uid to auth list failed, ret = %d", ret); + break; + } + } while (0); + + if (ret != CM_SUCCESS) { + (void)CmAuthRemoveGrantedApp(context, keyUri, appUid); /* clear auth info */ + } + (void)CertManagerFreeUri(&uriObj); + return ret; +} + +int32_t CmAuthGetAuthorizedAppList(const struct CmContext *context, const struct CmBlob *keyUri, + struct CmAppUidList *appUidList) +{ + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + int32_t ret = GetAndCheckUriObj(&uriObj, keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + struct CmAppUidList tempAppUidList = { 0, NULL }; + do { + ret = CheckCallerIsProducer(context, &uriObj); + if (ret != CM_SUCCESS) { + CM_LOG_E("check caller userId/uid failed, ret = %d", ret); + break; + } + + ret = CmGetAuthList(context, keyUri, &tempAppUidList); + if (ret != CM_SUCCESS) { + CM_LOG_E("get auth list failed, ret = %d", ret); + break; + } + + if (tempAppUidList.appUidCount != 0) { + if (appUidList->appUidCount < tempAppUidList.appUidCount) { + CM_LOG_E("out auth list buffer too small, input[%u] < expect[%u]", + appUidList->appUidCount, tempAppUidList.appUidCount); + ret = CMR_ERROR_BUFFER_TOO_SMALL; + break; + } + if (memcpy_s(appUidList->appUid, appUidList->appUidCount * sizeof(uint32_t), + tempAppUidList.appUid, tempAppUidList.appUidCount * sizeof(uint32_t)) != EOK) { + ret = CMR_ERROR_BAD_STATE; + break; + } + } + appUidList->appUidCount = tempAppUidList.appUidCount; + ret = CM_SUCCESS; + } while (0); + + CM_FREE_PTR(tempAppUidList.appUid); + (void)CertManagerFreeUri(&uriObj); + return ret; +} + +static int32_t GetMacByteFromString(const char *macString, struct CmBlob *macByte) +{ + uint32_t size = strlen(macString) / BYTE_TO_HEX_OPER_LENGTH; + if ((size == 0) || (size > MAX_OUT_BLOB_SIZE)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + uint8_t *data = (uint8_t *)CMMalloc(size); + if (data == NULL) { + CM_LOG_E("malloc mac in byte failed"); + return CMR_ERROR_MALLOC_FAIL; + } + + int32_t ret = HexStringToByte(macString, data, size); + if (ret != CM_SUCCESS) { + CM_LOG_E("mac hex string to byte failed, ret = %d", ret); + CM_FREE_PTR(data); + return ret; + } + + macByte->data = data; + macByte->size = size; + return CM_SUCCESS; +} + +static int32_t CheckIsAuthorizedApp(const struct CMUri *uriObj) +{ + if ((uriObj->clientApp == NULL) || (uriObj->mac == NULL)) { + CM_LOG_E("invalid input auth uri"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct CmBlob macByte = { 0, NULL }; + int32_t ret = GetMacByteFromString(uriObj->mac, &macByte); + if (ret != CM_SUCCESS) { + CM_LOG_E("get mac byte from string failed, ret = %d", ret); + return ret; + } + + /* calc uri mac */ + uint8_t macData[MAC_SHA256_LEN] = {0}; + struct CmBlob mac = { sizeof(macData), macData }; + uint32_t clientUid = atoi(uriObj->clientApp); + ret = CalcUriMac(uriObj, clientUid, &mac, false); + if (ret != CM_SUCCESS) { + CM_LOG_E("calc uri mac failed, ret = %d", ret); + CM_FREE_PTR(macByte.data); + return ret; + } + + if ((macByte.size != mac.size) || (memcmp(macByte.data, mac.data, macByte.size) != 0)) { + CM_LOG_E("mac size[%u] invalid or mac check failed", macByte.size); + CM_FREE_PTR(macByte.data); + return CMR_ERROR_AUTH_CHECK_FAILED; + } + + CM_FREE_PTR(macByte.data); + return CM_SUCCESS; +} + +int32_t CmAuthIsAuthorizedApp(const struct CmContext *context, const struct CmBlob *authUri) +{ + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + int32_t ret = GetAndCheckUriObj(&uriObj, authUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + ret = CheckIsAuthorizedApp(&uriObj); + if (ret != CM_SUCCESS) { + CM_LOG_E("check is authed app failed, ret = %d", ret); + } + (void)CertManagerFreeUri(&uriObj); + return ret; +} + +int32_t CmAuthRemoveGrantedApp(const struct CmContext *context, const struct CmBlob *keyUri, uint32_t appUid) +{ + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + int32_t ret = GetAndCheckUriObj(&uriObj, keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + do { + ret = CheckCallerIsProducer(context, &uriObj); + if (ret != CM_SUCCESS) { + CM_LOG_E("check caller userId/uid failed when remove grant, ret = %d", ret); + break; + } + + /* delete mac key */ + ret = DeleteMacKey(&uriObj, appUid); + if (ret != CM_SUCCESS) { + CM_LOG_E("delete mac key failed, ret = %d", ret); + break; + } + + /* remove auth uid */ + ret = CmRemoveAuthUid(context, keyUri, appUid); + if (ret != CM_SUCCESS) { + CM_LOG_E("remove auth uid from auth list failed, ret = %d", ret); + break; + } + + /* remove session node */ + struct CmSessionNodeInfo info = { context->userId, context->uid, *keyUri }; + CmDeleteSessionByNodeInfo(DELETE_SESSION_BY_ALL, &info); + } while (0); + + (void)CertManagerFreeUri(&uriObj); + return ret; +} + +static int32_t DeleteAuthInfo(uint32_t userId, const struct CmBlob *uri, const struct CmAppUidList *appUidList) +{ + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + int32_t ret = GetAndCheckUriObj(&uriObj, uri); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + do { + for (uint32_t i = 0; i < appUidList->appUidCount; ++i) { + ret = DeleteMacKey(&uriObj, appUidList->appUid[i]); + if (ret != CM_SUCCESS) { + CM_LOG_E("delete mac key failed, ret = %d", ret); + break; + } + } + } while (0); + + (void)CertManagerFreeUri(&uriObj); + return ret; +} + +/* 删除凭据时调用 */ +int32_t CmAuthDeleteAuthInfo(const struct CmContext *context, const struct CmBlob *uri) +{ + struct CmAppUidList appUidList = { 0, NULL }; + int32_t ret; + do { + ret = CmGetAuthList(context, uri, &appUidList); + if (ret != CM_SUCCESS) { + CM_LOG_E("get auth list failed, ret = %d", ret); + break; + } + + ret = DeleteAuthInfo(context->userId, uri, &appUidList); + if (ret != CM_SUCCESS) { + CM_LOG_E("delete auth failed, ret = %d", ret); + break; + } + + ret = CmDeleteAuthListFile(context, uri); + if (ret != CM_SUCCESS) { + CM_LOG_E("delete auth list file failed, ret = %d", ret); + break; + } + + /* remove session node by uri */ + struct CmSessionNodeInfo info = { context->userId, 0, *uri }; + CmDeleteSessionByNodeInfo(DELETE_SESSION_BY_URI, &info); + } while (0); + + CM_FREE_PTR(appUidList.appUid); + return ret; +} + +/* 用户删除时调用 */ +int32_t CmAuthDeleteAuthInfoByUserId(uint32_t userId, const struct CmBlob *uri) +{ + struct CmAppUidList appUidList = { 0, NULL }; + int32_t ret; + do { + ret = CmGetAuthListByUserId(userId, uri, &appUidList); + if (ret != CM_SUCCESS) { + CM_LOG_E("get auth list by user id failed, ret = %d", ret); + break; + } + + ret = DeleteAuthInfo(userId, uri, &appUidList); + if (ret != CM_SUCCESS) { + CM_LOG_E("delete auth failed, ret = %d", ret); + break; + } + + ret = CmDeleteAuthListFileByUserId(userId, uri); + if (ret != CM_SUCCESS) { + CM_LOG_E("delete auth list file failed, ret = %d", ret); + break; + } + } while (0); + + CM_FREE_PTR(appUidList.appUid); + return ret; +} + +/* 应用卸载时调用 */ +int32_t CmAuthDeleteAuthInfoByUid(uint32_t userId, uint32_t targetUid, const struct CmBlob *uri) +{ + bool isInAuthList = false; + int32_t ret = CmCheckIsAuthUidExistByUserId(userId, targetUid, uri, &isInAuthList); + if (ret != CM_SUCCESS) { + CM_LOG_E("check is in auth list failed, ret = %d", ret); + return ret; + } + + if (!isInAuthList) { + return CM_SUCCESS; + } + + uint32_t appUid[] = { targetUid }; + struct CmAppUidList appUidList = { sizeof(appUid) / sizeof(uint32_t), appUid }; + ret = DeleteAuthInfo(userId, uri, &appUidList); + if (ret != CM_SUCCESS) { + CM_LOG_E("delete mac key info failed, ret = %d", ret); + return ret; + } + + ret = CmRemoveAuthUidByUserId(userId, targetUid, uri); + if (ret != CM_SUCCESS) { + CM_LOG_E("remove auth uid by user id failed, ret = %d", ret); + } + return ret; +} + +static int32_t CheckCommonPermission(const struct CmContext *context, const struct CMUri *uriObj) +{ + int32_t ret = CheckCallerIsProducer(context, uriObj); + if (ret == CM_SUCCESS) { + return ret; + } + + if (uriObj->clientApp == NULL) { + CM_LOG_E("invalid uri client app"); + return CMR_ERROR_PERMISSION_DENIED; + } + + uint32_t clientUid = atoi(uriObj->clientApp); + if (clientUid != context->uid) { + CM_LOG_E("caller uid not match client uid"); + return CMR_ERROR_PERMISSION_DENIED; + } + + CM_LOG_I("caller may be authed app, need check"); + return CheckIsAuthorizedApp(uriObj); +} + +int32_t CmCheckAndGetCommonUri(const struct CmContext *context, const struct CmBlob *uri, struct CmBlob *commonUri) +{ + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + int32_t ret = GetAndCheckUriObj(&uriObj, uri); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + do { + ret = CheckCommonPermission(context, &uriObj); + if (ret != CM_SUCCESS) { + break; + } + + ret = ConstructCommonUri(&uriObj, commonUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct common uri failed, ret = %d", ret); + break; + } + } while (0); + + (void)CertManagerFreeUri(&uriObj); + return ret; +} diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.h b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.h new file mode 100644 index 0000000..0ca733c --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_auth_mgr.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_AUTH_MGR_H +#define CERT_MANAGER_AUTH_MGR_H + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmAuthGrantAppCertificate(const struct CmContext *context, const struct CmBlob *keyUri, + uint32_t appUid, struct CmBlob *authUri); + +int32_t CmAuthGetAuthorizedAppList(const struct CmContext *context, const struct CmBlob *keyUri, + struct CmAppUidList *appUidList); + +int32_t CmAuthIsAuthorizedApp(const struct CmContext *context, const struct CmBlob *authUri); + +int32_t CmAuthRemoveGrantedApp(const struct CmContext *context, const struct CmBlob *keyUri, uint32_t appUid); + +int32_t CmAuthDeleteAuthInfo(const struct CmContext *context, const struct CmBlob *uri); + +int32_t CmAuthDeleteAuthInfoByUserId(uint32_t userId, const struct CmBlob *uri); + +int32_t CmAuthDeleteAuthInfoByUid(uint32_t userId, uint32_t targetUid, const struct CmBlob *uri); + +int32_t CmCheckAndGetCommonUri(const struct CmContext *context, const struct CmBlob *uri, struct CmBlob *commonUri); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANAGER_AUTH_MGR_H */ + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.c b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.c new file mode 100644 index 0000000..711576a --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_double_list.h" + +#ifndef NULL +#define NULL ((void *)0) +#endif + +void CmInitList(struct DoubleList *listNode) +{ + if (listNode == NULL) { + return; + } + + listNode->prev = listNode; + listNode->next = listNode; +} + +void CmAddNodeAfterListHead(struct DoubleList *listHead, struct DoubleList *listNode) +{ + if ((listHead == NULL) || (listNode == NULL)) { + return; + } + + if (listHead->next == NULL) { + listHead->next = listHead; + } + + listHead->next->prev = listNode; + listNode->next = listHead->next; + listNode->prev = listHead; + listHead->next = listNode; +} + +void CmAddNodeAtListTail(struct DoubleList *listHead, struct DoubleList *listNode) +{ + if ((listHead == NULL) || (listNode == NULL)) { + return; + } + + if (listHead->prev == NULL) { + listHead->prev = listHead; + } + + listHead->prev->next = listNode; + listNode->next = listHead; + listNode->prev = listHead->prev; + listHead->prev = listNode; +} + +void CmRemoveNodeFromList(struct DoubleList *listNode) +{ + if (listNode == NULL) { + return; + } + + if (listNode->next != NULL) { + listNode->next->prev = listNode->prev; + } + + if (listNode->prev != NULL) { + listNode->prev->next = listNode->next; + } + + listNode->prev = NULL; + listNode->next = NULL; +} + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.h b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.h new file mode 100644 index 0000000..ec96bba --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_double_list.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_DOUBLE_LIST_H +#define CERT_MANAGER_DOUBLE_LIST_H + +#include "cm_type.h" + +struct DoubleList { + struct DoubleList *prev; + struct DoubleList *next; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void CmInitList(struct DoubleList *listNode); + +void CmAddNodeAfterListHead(struct DoubleList *listHead, struct DoubleList *listNode); + +void CmAddNodeAtListTail(struct DoubleList *listHead, struct DoubleList *listNode); + +void CmRemoveNodeFromList(struct DoubleList *listNode); + +#ifdef __cplusplus +} +#endif + +/* + * CM_DLIST_ITER - iterate over double list of struct st, double list should be the first member of struct st + * @st: the struct in the double list + * @head: the head for double list. + */ +#define CM_DLIST_ITER(st, head) \ + struct DoubleList *p = NULL; \ + for (p = (head)->next, (st) = (__typeof__(st))p; p != (head); p = p->next, (st) = (__typeof__(st))p) + +#define CM_DLIST_SAFT_ITER(st, head) \ + struct DoubleList *p = NULL; \ + struct DoubleList tmp = { NULL, NULL }; \ + for (p = (head)->next, (st) = (__typeof__(st))p, tmp = *p; p != (head); \ + p = tmp.next, tmp = *p, (st) = (__typeof__(st))p) + +#endif /* CERT_MANAGER_DOUBLE_LIST_H */ + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.c b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.c new file mode 100644 index 0000000..5d9cd79 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_key_operation.h" + +#include "cert_manager_mem.h" +#include "cert_manager_session_mgr.h" +#include "cm_log.h" +#include "cm_type.h" + +#include "hks_api.h" +#include "hks_param.h" +#include "hks_type.h" + +#define DEFAULT_LEN_USED_FOR_MALLOC 1024 + +struct CmKeyProperties { + uint32_t algType; + uint32_t keySize; + uint32_t padding; + uint32_t digest; + uint32_t purpose; +}; + +static int32_t ConstructParamSet(const struct HksParam *params, uint32_t paramCount, struct HksParamSet **outParamSet) +{ + struct HksParamSet *paramSet = NULL; + int32_t ret = HksInitParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("init paramset failed"); + return ret; + } + + ret = HksAddParams(paramSet, params, paramCount); + if (ret != HKS_SUCCESS) { + CM_LOG_E("add params failed"); + HksFreeParamSet(¶mSet); + return ret; + } + + ret = HksBuildParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("build paramSet failed"); + HksFreeParamSet(¶mSet); + return ret; + } + + *outParamSet = paramSet; + return CM_SUCCESS; +} + +int32_t CmKeyOpGenMacKey(const struct CmBlob *alias) +{ + struct HksParam genMacKeyParams[] = { + { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_HMAC }, + { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 }, + { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_MAC }, + { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 }, + }; + + struct HksParamSet *paramSet = NULL; + int32_t ret = ConstructParamSet(genMacKeyParams, sizeof(genMacKeyParams) / sizeof(struct HksParam), + ¶mSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct gen mac key paramSet failed"); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + + struct HksBlob keyAlias = { alias->size, alias->data }; + ret = HksGenerateKey(&keyAlias, paramSet, NULL); + HksFreeParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("hks generate key failed, ret = %d", ret); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + return CM_SUCCESS; +} + +int32_t CmKeyOpCalcMac(const struct CmBlob *alias, const struct CmBlob *srcData, struct CmBlob *mac) +{ + struct HksParam macParams[] = { + { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_HMAC }, + { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 }, + { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_MAC }, + { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 }, + }; + + struct HksParamSet *paramSet = NULL; + int32_t ret = ConstructParamSet(macParams, sizeof(macParams) / sizeof(struct HksParam), ¶mSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct mac init paramSet failed"); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + + do { + uint64_t handleValue = 0; + struct HksBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + struct HksBlob keyAlias = { alias->size, alias->data }; + ret = HksInit(&keyAlias, paramSet, &handle, NULL); + if (ret != HKS_SUCCESS) { + CM_LOG_E("mac calc init failed, ret = %d", ret); + break; + } + + struct HksBlob inData = { srcData->size, srcData->data }; + struct HksBlob outMac = { mac->size, mac->data }; + ret = HksFinish(&handle, paramSet, &inData, &outMac); + if (ret != HKS_SUCCESS) { + CM_LOG_E("mac calc finish failed, ret = %d", ret); + break; + } + mac->size = outMac.size; + } while (0); + + HksFreeParamSet(¶mSet); + return (ret == HKS_SUCCESS) ? CM_SUCCESS : CMR_ERROR_KEY_OPERATION_FAILED; +} + +static void FillKeySpec(const struct HksParamSet *paramSet, struct CmKeyProperties *spec) +{ + for (uint32_t i = 0; i < paramSet->paramsCnt; ++i) { + switch (paramSet->params[i].tag) { + case HKS_TAG_ALGORITHM: + spec->algType = paramSet->params[i].uint32Param; + break; + case HKS_TAG_KEY_SIZE: + spec->keySize = paramSet->params[i].uint32Param; + break; + case HKS_TAG_PURPOSE: + spec->purpose = paramSet->params[i].uint32Param; + break; + case HKS_TAG_DIGEST: + spec->digest = paramSet->params[i].uint32Param; + break; + case HKS_TAG_PADDING: + spec->padding = paramSet->params[i].uint32Param; + break; + default: + break; + } + } +} + +static int32_t TranslateToHksPurpose(const uint32_t inputPurpose, uint32_t *hksPurpose) +{ + if (inputPurpose == CM_KEY_PURPOSE_SIGN) { + *hksPurpose = HKS_KEY_PURPOSE_SIGN; + } else if (inputPurpose == CM_KEY_PURPOSE_VERIFY) { + *hksPurpose = HKS_KEY_PURPOSE_VERIFY; + } else { + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +static int32_t AddParamsToParamSet(const struct CmBlob *commonUri, const struct CmSignatureSpec *spec, + struct HksParamSet *paramSet) +{ + uint32_t purpose; + int32_t ret = TranslateToHksPurpose(spec->purpose, &purpose); + if (ret != CM_SUCCESS) { + CM_LOG_E("invalid input purpose[%u]", spec->purpose); + return ret; + } + + struct HksParamSet *outParamSet = (struct HksParamSet*)CMMalloc(DEFAULT_LEN_USED_FOR_MALLOC); + if (outParamSet == NULL) { + CM_LOG_E("malloc failed"); + return CMR_ERROR_MALLOC_FAIL; + } + outParamSet->paramSetSize = DEFAULT_LEN_USED_FOR_MALLOC; + + do { + ret = HksGetKeyParamSet((const struct HksBlob *)commonUri, NULL, outParamSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("get paramSet from huks failed, ret = %d", ret); + break; + } + + struct CmKeyProperties keySpec = {0}; + FillKeySpec(outParamSet, &keySpec); + struct HksParam params[] = { + { .tag = HKS_TAG_ALGORITHM, .uint32Param = keySpec.algType }, + { .tag = HKS_TAG_KEY_SIZE, .uint32Param = keySpec.keySize }, + { .tag = HKS_TAG_PURPOSE, .uint32Param = purpose }, + { .tag = HKS_TAG_DIGEST, .uint32Param = keySpec.digest }, + { .tag = HKS_TAG_PADDING, .uint32Param = keySpec.padding }, + }; + + ret = HksAddParams(paramSet, params, sizeof(params) / sizeof(struct HksParam)); + if (ret != HKS_SUCCESS) { + CM_LOG_E("add params failed"); + break; + } + } while (0); + + CM_FREE_PTR(outParamSet); + return (ret == HKS_SUCCESS) ? CM_SUCCESS : CMR_ERROR_KEY_OPERATION_FAILED; +} + +static int32_t ConstructInitParamSet(const struct CmBlob *commonUri, const struct CmSignatureSpec *spec, + struct HksParamSet **outParamSet) +{ + struct HksParamSet *paramSet = NULL; + int32_t ret = HksInitParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("init paramSet failed, ret = %d", ret); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + + ret = AddParamsToParamSet(commonUri, spec, paramSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("add params failed"); + HksFreeParamSet(¶mSet); + return ret; + } + + ret = HksBuildParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("build params failed, ret = %d", ret); + HksFreeParamSet(¶mSet); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + + *outParamSet = paramSet; + return CM_SUCCESS; +} + +static int32_t ServiceSignVerifyUpdate(const struct CmBlob *handle, const struct HksParamSet *paramSet, + const struct CmBlob *inData) +{ + uint32_t temp = 0; + struct HksBlob tempOut = { sizeof(uint32_t), (uint8_t *)&temp }; + + struct HksBlob handleHks = { handle->size, handle->data }; + struct HksBlob inDataHks = { inData->size, inData->data }; + + int32_t ret = HksUpdate(&handleHks, paramSet, &inDataHks, &tempOut); + if (ret != HKS_SUCCESS) { + CM_LOG_E("huks update fail, ret = %d", ret); + CmDeleteSession(handle); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + return CM_SUCCESS; +} + +static int32_t ServiceSignVerifyFinish(const struct CmBlob *handle, const struct HksParamSet *paramSet, + const struct CmBlob *inData, struct CmBlob *outData) +{ + struct HksBlob handleHks = { handle->size, handle->data }; + struct HksBlob inDataHks = { inData->size, inData->data }; + struct HksBlob outDataHks = { outData->size, outData->data }; + + int32_t ret = HksFinish(&handleHks, paramSet, &inDataHks, &outDataHks); + CmDeleteSession(handle); + if (ret != HKS_SUCCESS) { + CM_LOG_E("huks finish fail, ret = %d", ret); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + outData->size = outDataHks.size; + return CM_SUCCESS; +} + +static int32_t ServiceSignVerifyAbort(const struct CmBlob *handle, const struct HksParamSet *paramSet) +{ + struct HksBlob handleHks = { handle->size, handle->data }; + + int32_t ret = HksAbort(&handleHks, paramSet); + CmDeleteSession(handle); + if (ret != HKS_SUCCESS) { + CM_LOG_E("huks abort fail, ret = %d", ret); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + return CM_SUCCESS; +} + +int32_t CmKeyOpInit(const struct CmContext *context, const struct CmBlob *alias, const struct CmSignatureSpec *spec, + struct CmBlob *handle) +{ + struct HksParamSet *paramSet = NULL; + int32_t ret = ConstructInitParamSet(alias, spec, ¶mSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct init paramSet failed, ret = %d", ret); + return ret; + } + + do { + struct HksBlob keyAlias = { alias->size, alias->data }; + struct HksBlob handleOut = { handle->size, handle->data }; + ret = HksInit(&keyAlias, paramSet, &handleOut, NULL); + if (ret != HKS_SUCCESS) { + CM_LOG_E("Huks init failed, ret = %d", ret); + break; + } + handle->size = handleOut.size; + + struct CmSessionNodeInfo info = { context->userId, context->uid, *alias }; + ret = CmCreateSession(&info, handle, true); + if (ret != CM_SUCCESS) { + CM_LOG_E("create session failed, ret = %d", ret); + break; + } + } while (0); + + HksFreeParamSet(¶mSet); + return (ret == HKS_SUCCESS) ? CM_SUCCESS : CMR_ERROR_KEY_OPERATION_FAILED; +} + +int32_t CmKeyOpProcess(enum CmSignVerifyCmd cmdId, const struct CmContext *context, const struct CmBlob *handle, + const struct CmBlob *inData, struct CmBlob *outData) +{ + struct CmSessionNodeInfo info = { context->userId, context->uid, { 0, NULL } }; + if (CmQuerySession(&info, handle) == NULL) { + CM_LOG_E("session handle not exist"); + return (cmdId == SIGN_VERIFY_CMD_ABORT) ? CM_SUCCESS : CMR_ERROR_NOT_EXIST; + } + + struct HksParamSet *paramSet = NULL; + int32_t ret = HksInitParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + CM_LOG_E("init paramset failed"); + CmDeleteSession(handle); + return CMR_ERROR_KEY_OPERATION_FAILED; + } + + switch (cmdId) { + case SIGN_VERIFY_CMD_UPDATE: + ret = ServiceSignVerifyUpdate(handle, paramSet, inData); + break; + case SIGN_VERIFY_CMD_FINISH: + ret = ServiceSignVerifyFinish(handle, paramSet, inData, outData); + break; + case SIGN_VERIFY_CMD_ABORT: + ret = ServiceSignVerifyAbort(handle, paramSet); + break; + default: + ret = CMR_ERROR_INVALID_ARGUMENT; + break; + } + + HksFreeParamSet(¶mSet); + return ret; +} + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.h b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.h new file mode 100644 index 0000000..f282012 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_key_operation.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_KEY_OPERATION_H +#define CERT_MANAGER_KEY_OPERATION_H + +#include "cm_type.h" + +enum CmSignVerifyCmd { + SIGN_VERIFY_CMD_UPDATE, + SIGN_VERIFY_CMD_FINISH, + SIGN_VERIFY_CMD_ABORT, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmKeyOpGenMacKey(const struct CmBlob *alias); + +int32_t CmKeyOpCalcMac(const struct CmBlob *alias, const struct CmBlob *srcData, struct CmBlob *mac); + +int32_t CmKeyOpInit(const struct CmContext *context, const struct CmBlob *alias, const struct CmSignatureSpec *spec, + struct CmBlob *handle); + +int32_t CmKeyOpProcess(enum CmSignVerifyCmd cmdId, const struct CmContext *context, const struct CmBlob *handle, + const struct CmBlob *inData, struct CmBlob *outData); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANAGER_KEY_OPERATION_H */ + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.cpp b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.cpp new file mode 100644 index 0000000..53fe066 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_permission_check.h" + +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" + +#include "cm_log.h" + +static bool HasPermission(const std::string &permissionName) +{ + OHOS::Security::AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + + int result = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName); + if (result == OHOS::Security::AccessToken::PERMISSION_GRANTED) { + return true; + } + + return false; +} + +bool CmHasPrivilegedPermission(void) +{ + return HasPermission("ohos.permission.ACCESS_CERT_MANAGER_PRIVILEGED"); +} + +bool CmHasCommonPermission(void) +{ + return HasPermission("ohos.permission.ACCESS_CERT_MANAGER"); +} + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.h b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.h new file mode 100644 index 0000000..9521328 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_permission_check.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_PERMISSION_CHECK_H +#define CERT_MANAGER_PERMISSION_CHECK_H + +#ifdef __cplusplus +extern "C" { +#endif + +bool CmHasPrivilegedPermission(void); + +bool CmHasCommonPermission(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANAGER_PERMISSION_CHECK_H */ diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.c b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.c new file mode 100644 index 0000000..0ff5b22 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_service.h" + +#include "cert_manager_auth_mgr.h" +#include "cert_manager_key_operation.h" +#include "cert_manager_mem.h" +#include "cert_manager_permission_check.h" +#include "cm_log.h" +#include "cm_type.h" + +static int32_t CheckUri(const struct CmBlob *keyUri) +{ + if (CmCheckBlob(keyUri) != CM_SUCCESS) { + CM_LOG_E("invalid uri"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + for (uint32_t i = 1; i < keyUri->size; ++i) { /* from index 1 has '\0' */ + if (keyUri->data[i] == 0) { + return CM_SUCCESS; + } + } + return CMR_ERROR_INVALID_ARGUMENT; +} + +int32_t CmServiceGrantAppCertificate(const struct CmContext *context, const struct CmBlob *keyUri, + uint32_t appUid, struct CmBlob *authUri) +{ + if (CheckUri(keyUri) != CM_SUCCESS || CmCheckBlob(authUri) != CM_SUCCESS) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasPrivilegedPermission() || !CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + return CmAuthGrantAppCertificate(context, keyUri, appUid, authUri); +} + +int32_t CmServiceGetAuthorizedAppList(const struct CmContext *context, const struct CmBlob *keyUri, + struct CmAppUidList *appUidList) +{ + if (CheckUri(keyUri) != CM_SUCCESS) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasPrivilegedPermission() || !CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + return CmAuthGetAuthorizedAppList(context, keyUri, appUidList); +} + +int32_t CmServiceIsAuthorizedApp(const struct CmContext *context, const struct CmBlob *authUri) +{ + if (CheckUri(authUri) != CM_SUCCESS) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + return CmAuthIsAuthorizedApp(context, authUri); +} + +int32_t CmServiceRemoveGrantedApp(const struct CmContext *context, const struct CmBlob *keyUri, uint32_t appUid) +{ + if (CheckUri(keyUri) != CM_SUCCESS) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasPrivilegedPermission() || !CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + return CmAuthRemoveGrantedApp(context, keyUri, appUid); +} + +int32_t CmServiceInit(const struct CmContext *context, const struct CmBlob *authUri, + const struct CmSignatureSpec *spec, struct CmBlob *handle) +{ + if (CheckUri(authUri) != CM_SUCCESS || CmCheckBlob(handle) != CM_SUCCESS) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + struct CmBlob commonUri = { 0, NULL }; + int32_t ret = CmCheckAndGetCommonUri(context, authUri, &commonUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("check and get common uri failed, ret = %d"); + return ret; + } + + ret = CmKeyOpInit(context, &commonUri, spec, handle); + CM_FREE_PTR(commonUri.data); + return ret; +} + +int32_t CmServiceUpdate(const struct CmContext *context, const struct CmBlob *handle, + const struct CmBlob *inData) +{ + if (CmCheckBlob(handle) != CM_SUCCESS || CmCheckBlob(inData) != CM_SUCCESS) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + return CmKeyOpProcess(SIGN_VERIFY_CMD_UPDATE, context, handle, inData, NULL); +} + +int32_t CmServiceFinish(const struct CmContext *context, const struct CmBlob *handle, + const struct CmBlob *inData, struct CmBlob *outData) +{ + if (CmCheckBlob(handle) != CM_SUCCESS) { /* inData.data and outData.data can be null */ + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + return CmKeyOpProcess(SIGN_VERIFY_CMD_FINISH, context, handle, inData, outData); +} + +int32_t CmServiceAbort(const struct CmContext *context, const struct CmBlob *handle) +{ + if (CmCheckBlob(handle) != CM_SUCCESS) { + CM_LOG_E("invalid input arguments"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!CmHasCommonPermission()) { + CM_LOG_E("permission check failed"); + return CMR_ERROR_PERMISSION_DENIED; + } + + return CmKeyOpProcess(SIGN_VERIFY_CMD_ABORT, context, handle, NULL, NULL); +} + diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.h b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.h new file mode 100644 index 0000000..cc55a82 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_service.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_SERVICE_H +#define CERT_MANAGER_SERVICE_H + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmServiceGrantAppCertificate(const struct CmContext *context, const struct CmBlob *keyUri, + uint32_t appUid, struct CmBlob *authUri); + +int32_t CmServiceGetAuthorizedAppList(const struct CmContext *context, const struct CmBlob *keyUri, + struct CmAppUidList *appUidList); + +int32_t CmServiceIsAuthorizedApp(const struct CmContext *context, const struct CmBlob *authUri); + +int32_t CmServiceRemoveGrantedApp(const struct CmContext *context, const struct CmBlob *keyUri, uint32_t appUid); + +int32_t CmServiceInit(const struct CmContext *context, const struct CmBlob *authUri, + const struct CmSignatureSpec *spec, struct CmBlob *handle); + +int32_t CmServiceUpdate(const struct CmContext *context, const struct CmBlob *handle, + const struct CmBlob *inData); + +int32_t CmServiceFinish(const struct CmContext *context, const struct CmBlob *handle, + const struct CmBlob *inData, struct CmBlob *outData); + +int32_t CmServiceAbort(const struct CmContext *context, const struct CmBlob *handle); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANAGER_SERVICE_H */ diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.c b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.c new file mode 100644 index 0000000..32a09a3 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.c @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_session_mgr.h" +#include "cert_manager_mem.h" +#include "cm_log.h" + +#include +#include + +#include "hks_api.h" +#include "hks_param.h" +#include "hks_type.h" + +#include "securec.h" + +#define MAX_OPERATIONS_COUNT 15 + +static struct DoubleList g_sessionList = { &g_sessionList, &g_sessionList }; +static uint32_t g_sessionCount = 0; +static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; + +static void DeleteHuksInitInfo(const struct CmBlob *handle) +{ + struct HksParamSet *paramSet = NULL; + if (HksInitParamSet(¶mSet) != HKS_SUCCESS) { + return; + } + + (void)HksAbort((const struct HksBlob *)handle, paramSet); + HksFreeParamSet(¶mSet); +} + +static void FreeSessionNode(struct CmSessionNode **node) +{ + if ((node == NULL) || (*node == NULL)) { + return; + } + + CM_FREE_PTR((*node)->handle.data); + CM_FREE_PTR((*node)->info.uri.data); + CM_FREE_PTR(*node); +} + +/* Need to lock before calling RemoveAndFreeSessionNode */ +static void RemoveAndFreeSessionNode(struct CmSessionNode **sessionNode) +{ + if ((sessionNode == NULL) || (*sessionNode == NULL)) { + return; + } + + CmRemoveNodeFromList(&(*sessionNode)->listHead); + FreeSessionNode(sessionNode); +} + +/* Need to lock before calling DeleteFirstAbortableSession */ +static int32_t DeleteFirstAbortableSession(void) +{ + struct CmSessionNode *sessionNode = NULL; + + CM_DLIST_ITER(sessionNode, &g_sessionList) { + if (sessionNode->abortable) { + DeleteHuksInitInfo(&(sessionNode->handle)); + RemoveAndFreeSessionNode(&sessionNode); + --g_sessionCount; + CM_LOG_I("delete session count: %u", g_sessionCount); + return CM_SUCCESS; + } + } + + return CMR_ERROR_NOT_FOUND; +} + +static int32_t AddSessionNode(struct CmSessionNode *sessionNode) +{ + pthread_mutex_lock(&g_lock); + + if (g_sessionCount >= MAX_OPERATIONS_COUNT) { + CM_LOG_I("maximum number of sessions reached: delete oldest session."); + if (DeleteFirstAbortableSession() != CM_SUCCESS) { + pthread_mutex_unlock(&g_lock); + CM_LOG_E("not found abortable session"); + return CMR_ERROR_SESSION_REACHED_LIMIT; + } + } + + CmAddNodeAtListTail(&g_sessionList, &sessionNode->listHead); + ++g_sessionCount; + CM_LOG_I("add session count:%u", g_sessionCount); + pthread_mutex_unlock(&g_lock); + + return HKS_SUCCESS; +} + +static int32_t ConstructSessionInfo(const struct CmSessionNodeInfo *info, struct CmSessionNode *node) +{ + uint32_t size = info->uri.size; + uint8_t *data = (uint8_t *)CMMalloc(size); + if (data == NULL) { + CM_LOG_E("malloc uri data failed"); + return CMR_ERROR_MALLOC_FAIL; + } + (void)memcpy_s(data, size, info->uri.data, size); + + node->info.userId = info->userId; + node->info.uid = info->uid; + node->info.uri.data = data; + node->info.uri.size = size; + return CM_SUCCESS; +} + +static int32_t ConstructHandle(const struct CmBlob *handle, struct CmSessionNode *node) +{ + uint32_t size = handle->size; + uint8_t *data = (uint8_t *)CMMalloc(size); + if (data == NULL) { + CM_LOG_E("malloc handle data failed"); + return CMR_ERROR_MALLOC_FAIL; + } + (void)memcpy_s(data, size, handle->data, size); + + node->handle.data = data; + node->handle.size = size; + return CM_SUCCESS; +} + +int32_t CmCreateSession(const struct CmSessionNodeInfo *info, const struct CmBlob *handle, bool abortable) +{ + struct CmSessionNode *node = (struct CmSessionNode *)CMMalloc(sizeof(struct CmSessionNode)); + if (node == NULL) { + CM_LOG_E("malloc session node failed"); + return CMR_ERROR_MALLOC_FAIL; + } + (void)memset_s(node, sizeof(struct CmSessionNode), 0, sizeof(struct CmSessionNode)); + + int32_t ret; + do { + ret = ConstructSessionInfo(info, node); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct session info failed, ret = %d", ret); + break; + } + + ret = ConstructHandle(handle, node); + if (ret != CM_SUCCESS) { + CM_LOG_E("construct handle failed, ret = %d", ret); + break; + } + + node->abortable = abortable; + + ret = AddSessionNode(node); + if (ret != CM_SUCCESS) { + CM_LOG_E("add session node failed, ret = %d", ret); + break; + } + } while (0); + if (ret != CM_SUCCESS) { + FreeSessionNode(&node); + } + + return ret; +} + +static bool IsSameBlob(const struct CmBlob *blob1, const struct CmBlob *blob2) +{ + if (blob1->size != blob2->size) { + return false; + } + if (memcmp(blob1->data, blob2->data, blob1->size) != 0) { + return false; + } + return true; +} + +static bool IsSameCaller(const struct CmSessionNodeInfo *info, const struct CmSessionNode *node) +{ + return (info->uid == node->info.uid) && (info->userId == node->info.userId); +} + +struct CmSessionNode *CmQuerySession(const struct CmSessionNodeInfo *info, const struct CmBlob *handle) +{ + struct CmSessionNode *node = NULL; + pthread_mutex_lock(&g_lock); + CM_DLIST_ITER(node, &g_sessionList) { + if (IsSameBlob(handle, &(node->handle)) && IsSameCaller(info, node)) { + pthread_mutex_unlock(&g_lock); + return node; + } + } + pthread_mutex_unlock(&g_lock); + + return NULL; +} + +void CmDeleteSession(const struct CmBlob *handle) +{ + struct CmSessionNode *node = NULL; + pthread_mutex_lock(&g_lock); + CM_DLIST_ITER(node, &g_sessionList) { + if (IsSameBlob(handle, &(node->handle))) { + RemoveAndFreeSessionNode(&node); + --g_sessionCount; + CM_LOG_I("delete session count: %u", g_sessionCount); + pthread_mutex_unlock(&g_lock); + return; + } + } + pthread_mutex_unlock(&g_lock); +} + +static bool IsNeedDelete(enum CmSessionDeleteType deleteType, const struct CmSessionNodeInfo *info, + const struct CmSessionNode *node) +{ + switch (deleteType) { + case DELETE_SESSION_BY_USERID: + return info->userId == node->info.userId; + case DELETE_SESSION_BY_UID: + return IsSameCaller(info, node); + case DELETE_SESSION_BY_URI: + return IsSameBlob(&(info->uri), &(node->info.uri)); + case DELETE_SESSION_BY_ALL: + return IsSameCaller(info, node) && IsSameBlob(&(info->uri), &(node->info.uri)); + default: + return false; + } +} + +static void DeleteSessionNode(enum CmSessionDeleteType deleteType, const struct CmSessionNodeInfo *info, + struct CmSessionNode **nodeSession) +{ + struct CmSessionNode *node = *nodeSession; + if (IsNeedDelete(deleteType, info, node)) { + DeleteHuksInitInfo(&(node->handle)); + RemoveAndFreeSessionNode(nodeSession); + --g_sessionCount; + CM_LOG_I("delete session count = %u", g_sessionCount); + } +} + +void CmDeleteSessionByNodeInfo(enum CmSessionDeleteType deleteType, const struct CmSessionNodeInfo *info) +{ + struct CmSessionNode *node = NULL; + + pthread_mutex_lock(&g_lock); + CM_DLIST_SAFT_ITER(node, &g_sessionList) { + if (node != NULL) { + DeleteSessionNode(deleteType, info, &node); + } + } + pthread_mutex_unlock(&g_lock); +} diff --git a/frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.h b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.h new file mode 100644 index 0000000..9396c4f --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/cert_manager_session_mgr.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_SESSION_MGR_H +#define CERT_MANAGER_SESSION_MGR_H + +#include +#include + +#include "cert_manager_double_list.h" +#include "cm_type.h" + +struct CmSessionNodeInfo { + uint32_t userId; + uint32_t uid; + struct CmBlob uri; /* origin uri */ +}; + +struct CmSessionNode { + struct DoubleList listHead; + struct CmSessionNodeInfo info; + struct CmBlob handle; + bool abortable; +}; + +enum CmSessionDeleteType { + DELETE_SESSION_BY_USERID, + DELETE_SESSION_BY_UID, + DELETE_SESSION_BY_URI, + DELETE_SESSION_BY_ALL, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmCreateSession(const struct CmSessionNodeInfo *info, const struct CmBlob *handle, bool abortable); + +struct CmSessionNode *CmQuerySession(const struct CmSessionNodeInfo *info, const struct CmBlob *handle); + +void CmDeleteSession(const struct CmBlob *handle); + +void CmDeleteSessionByNodeInfo(enum CmSessionDeleteType deleteType, const struct CmSessionNodeInfo *info); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANAGER_SESSION_MGR_H */ diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_abort_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_abort_test.cpp new file mode 100644 index 0000000..8b53bba --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_abort_test.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cm_test_common.h" + +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { + +class CmAbortTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmAbortTest::SetUpTestCase(void) +{ +} + +void CmAbortTest::TearDownTestCase(void) +{ +} + +void CmAbortTest::SetUp() +{ +} + +void CmAbortTest::TearDown() +{ +} + +/** +* @tc.name: CmAbortTest001 +* @tc.desc: Test CmIsAuthorizedApp handle is null +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmAbortTest, CmAbortTest001, TestSize.Level0) +{ + struct CmBlob *handle = nullptr; + int32_t ret = CmAbort(handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmAbortTest002 + * @tc.desc: Test CmIsAuthorizedApp handle size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmAbortTest, CmAbortTest002, TestSize.Level0) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { 0, (uint8_t *)&handleValue }; + int32_t ret = CmAbort(&handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmAbortTest003 + * @tc.desc: Test CmIsAuthorizedApp handle data is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmAbortTest, CmAbortTest003, TestSize.Level0) +{ + struct CmBlob handle = { sizeof(uint64_t), nullptr }; + int32_t ret = CmAbort(&handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmAbortTest004 +* @tc.desc: Test CmIsAuthorizedApp handle not exist +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmAbortTest, CmAbortTest004, TestSize.Level0) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + int32_t ret = CmAbort(&handle); + EXPECT_EQ(ret, CM_SUCCESS); +} + +/** +* @tc.name: CmAbortTest005 +* @tc.desc: Test CmIsAuthorizedApp handle exist then abort +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmAbortTest, CmAbortTest005, TestSize.Level0) +{ + uint8_t aliasData[] = "CmAbortTest005"; + struct CmBlob alias = { sizeof(aliasData), aliasData }; + int32_t ret = TestGenerateAppCert(&alias, CERT_KEY_ALG_ECC, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert failed, retcode:" << ret; + + uint8_t uriData[] = "oh:t=ak;o=CmAbortTest005;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + + ret = CmInit(&keyUri, &spec, &handle); + EXPECT_EQ(ret, CM_SUCCESS) << "CmInit failed, retcode:" << ret; + + ret = CmAbort(&handle); + EXPECT_EQ(ret, CM_SUCCESS) << "CmAbort failed, retcode:" << ret; + + ret = CmUninstallAppCert(&keyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert failed, retcode:" << ret; +} +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_finish_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_finish_test.cpp new file mode 100644 index 0000000..25a640b --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_finish_test.cpp @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cm_test_common.h" + +#include "cert_manager_api.h" + +#include "cm_log.h" +#include "cm_mem.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { + +static constexpr uint32_t DEFAULT_SIGNATURE_LEN = 1024; +static constexpr uint32_t MAX_SESSION_NUM_MORE_1 = 16; + +class CmFinishTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmFinishTest::SetUpTestCase(void) +{ +} + +void CmFinishTest::TearDownTestCase(void) +{ +} + +void CmFinishTest::SetUp() +{ +} + +void CmFinishTest::TearDown() +{ +} + +static const uint8_t g_uriData[] = "oh:t=ak;o=TestFinishSignVerify;u=0;a=0"; +static const CmBlob g_keyUri = { sizeof(g_uriData), (uint8_t *)g_uriData }; + +static const uint8_t g_messageData[] = "This_is_test_message_for_test_sign_and_verify"; + +static void TestInstallAppCert(uint32_t alg) +{ + uint8_t aliasData[] = "TestFinishSignVerify"; + struct CmBlob alias = { sizeof(aliasData), aliasData }; + + int32_t ret = TestGenerateAppCert(&alias, alg, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert failed, retcode:" << ret; +} + +static void TestUninstallAppCert(void) +{ + int32_t ret = CmUninstallAppCert(&g_keyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert failed, retcode:" << ret; +} + +static void TestSign(const struct CmBlob *keyUri, const struct CmBlob *message, struct CmBlob *signature) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(uint64_t), (uint8_t *)&handleValue }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + + int32_t ret = CmInit(keyUri, &spec, &handle); + EXPECT_EQ(ret, CM_SUCCESS) << "TestSign CmInit test failed"; + + ret = CmUpdate(&handle, message); + EXPECT_EQ(ret, CM_SUCCESS) << "TestSign CmUpdate test failed"; + + struct CmBlob inDataFinish = { 0, nullptr }; + ret = CmFinish(&handle, &inDataFinish, signature); + EXPECT_EQ(ret, CM_SUCCESS) << "TestSign CmFinish test failed"; + + ret = CmAbort(&handle); + EXPECT_EQ(ret, CM_SUCCESS) << "TestSign CmAbort test failed"; +} + +static void TestVerify(const struct CmBlob *keyUri, const struct CmBlob *message, const struct CmBlob *signature, + bool isValidSignature) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(uint64_t), (uint8_t *)&handleValue }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_VERIFY }; + + int32_t ret = CmInit(keyUri, &spec, &handle); + EXPECT_EQ(ret, CM_SUCCESS) << "TestVerify CmInit test failed"; + + ret = CmUpdate(&handle, message); + EXPECT_EQ(ret, CM_SUCCESS) << "TestVerify CmUpdate test failed"; + + struct CmBlob inDataFinish = { signature->size, signature->data }; + if (!isValidSignature && signature->size > 0) { + signature->data[0] += 0x01; /* change the first byte of signature, ignore data flipping */ + } + + struct CmBlob outDataFinish = { 0, nullptr }; + ret = CmFinish(&handle, &inDataFinish, &outDataFinish); + if (isValidSignature) { + EXPECT_EQ(ret, CM_SUCCESS) << "TestVerify CmFinish test failed"; + } else { + EXPECT_EQ(ret, CMR_ERROR_KEY_OPERATION_FAILED) << "TestVerify CmFinish test failed"; + } + + ret = CmAbort(&handle); + EXPECT_EQ(ret, CM_SUCCESS) << "TestVerify CmAbort test failed"; +} + +static void TestSignVerify(uint32_t alg, bool isValidSignature) +{ + /* install credential */ + TestInstallAppCert(alg); + + struct CmBlob message = { sizeof(g_messageData), (uint8_t *)g_messageData }; + uint8_t signData[DEFAULT_SIGNATURE_LEN] = {0}; + struct CmBlob signature = { DEFAULT_SIGNATURE_LEN, signData }; + + /* sign */ + TestSign(&g_keyUri, &message, &signature); + + /* verify */ + TestVerify(&g_keyUri, &message, &signature, isValidSignature); + + /* uninstall rsa credential */ + TestUninstallAppCert(); +} + +static void ProducerSessionMaxTest(void) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handle[MAX_SESSION_NUM_MORE_1]; + int32_t ret; + + for (uint32_t i = 0; i < MAX_SESSION_NUM_MORE_1; ++i) { + struct CmBlob handleBlob = { sizeof(uint64_t), (uint8_t *)&handle[i] }; + ret = CmInit(&g_keyUri, &spec, &handleBlob); + EXPECT_EQ(ret, CM_SUCCESS) << "cm init failed, index[" << i << "]"; + } + + for (uint32_t i = 0; i < MAX_SESSION_NUM_MORE_1; ++i) { + uint8_t tmpInput[] = "thisIstestForSessionMaxTestInData"; + struct CmBlob updateInput = { sizeof(tmpInput), tmpInput }; + struct CmBlob handleBlob = { sizeof(uint64_t), (uint8_t *)&handle[i] }; + + int32_t expectRet = CM_SUCCESS; + if (i == 0) { + expectRet = CMR_ERROR_NOT_EXIST; + } + + ret = CmUpdate(&handleBlob, &updateInput); + EXPECT_EQ(ret, expectRet) << "update failed, i:" << i; + + uint8_t tmpOutput[DEFAULT_SIGNATURE_LEN] = {0}; + struct CmBlob finishInput = { 0, nullptr }; + struct CmBlob finishOutput = { sizeof(tmpOutput), tmpOutput }; + ret = CmFinish(&handleBlob, &finishInput, &finishOutput); + EXPECT_EQ(ret, expectRet) << "finish failed, i:" << i; + } + + for (uint32_t i = 0; i < MAX_SESSION_NUM_MORE_1; ++i) { + struct CmBlob handleBlob = { sizeof(uint64_t), (uint8_t *)&handle[i] }; + ret = CmAbort(&handleBlob); + EXPECT_EQ(ret, CM_SUCCESS) << "abort failed, i:" << i; + } +} + + +/** +* @tc.name: CmFinishTest001 +* @tc.desc: Test CmIsAuthorizedApp handle is null +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest001, TestSize.Level0) +{ + struct CmBlob *handle = nullptr; + struct CmBlob inData = { 0, nullptr }; + struct CmBlob outData = { 0, nullptr }; + + int32_t ret = CmFinish(handle, &inData, &outData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmFinishTest002 + * @tc.desc: Test CmIsAuthorizedApp handle size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmFinishTest, CmFinishTest002, TestSize.Level0) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { 0, (uint8_t *)&handleValue }; + struct CmBlob inData = { 0, nullptr }; + struct CmBlob outData = { 0, nullptr }; + + int32_t ret = CmFinish(&handle, &inData, &outData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmFinishTest003 + * @tc.desc: Test CmIsAuthorizedApp handle data is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmFinishTest, CmFinishTest003, TestSize.Level0) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), nullptr }; + struct CmBlob inData = { 0, nullptr }; + struct CmBlob outData = { 0, nullptr }; + + int32_t ret = CmFinish(&handle, &inData, &outData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmFinishTest004 +* @tc.desc: Test CmIsAuthorizedApp inData is null +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest004, TestSize.Level0) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + struct CmBlob *inData = nullptr; + struct CmBlob outData = { 0, nullptr }; + + int32_t ret = CmFinish(&handle, inData, &outData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmFinishTest005 + * @tc.desc: Test CmIsAuthorizedApp outData is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmFinishTest, CmFinishTest005, TestSize.Level0) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + struct CmBlob inData = { 0, nullptr }; + struct CmBlob *outData = nullptr; + + int32_t ret = CmFinish(&handle, &inData, outData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmFinishTest006 +* @tc.desc: Test CmIsAuthorizedApp handle not exist +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest006, TestSize.Level0) +{ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + struct CmBlob inData = { 0, nullptr }; + struct CmBlob outData = { 0, nullptr }; + + int32_t ret = CmFinish(&handle, &inData, &outData); + EXPECT_EQ(ret, CMR_ERROR_NOT_EXIST); +} + +/** +* @tc.name: CmFinishTest007 +* @tc.desc: Test CmIsAuthorizedApp normal case: caller is producer, rsa sign verify +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest007, TestSize.Level0) +{ + TestSignVerify(CERT_KEY_ALG_RSA, true); +} + +/** +* @tc.name: CmFinishTest008 +* @tc.desc: Test CmIsAuthorizedApp normal case: caller is producer, ecc sign verify +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest008, TestSize.Level0) +{ + TestSignVerify(CERT_KEY_ALG_ECC, true); +} + +/** +* @tc.name: CmFinishTest009 +* @tc.desc: Test CmIsAuthorizedApp abnormal case: caller is producer, rsa sign verify(sign invalid) +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest009, TestSize.Level0) +{ + TestSignVerify(CERT_KEY_ALG_RSA, false); +} + +/** +* @tc.name: CmFinishTest010 +* @tc.desc: Test CmIsAuthorizedApp abnormal case: caller is producer, ecc sign verify(sign invalid) +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest010, TestSize.Level0) +{ + TestSignVerify(CERT_KEY_ALG_ECC, false); +} + +/** +* @tc.name: CmFinishTest011 +* @tc.desc: Test CmIsAuthorizedApp normal case: normal case: caller is producer, max times + 1(first fail) +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmFinishTest, CmFinishTest011, TestSize.Level0) +{ + TestInstallAppCert(CERT_KEY_ALG_ECC); + ProducerSessionMaxTest(); + TestUninstallAppCert(); +} +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_get_auth_list_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_get_auth_list_test.cpp new file mode 100644 index 0000000..f998829 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_get_auth_list_test.cpp @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cm_test_common.h" + +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { + +static constexpr uint32_t DEFAULT_AUTH_URI_LEN = 256; +static constexpr uint32_t DEFAULT_BASE_APP_ID = 1000; +static constexpr uint32_t APP_UID_COUNT_ONE = 1; +static constexpr uint32_t APP_UID_COUNT_MULTI = 10; +static constexpr uint32_t APP_UID_REMOVE_COUNT = 4; +static constexpr uint32_t DEFAULT_APP_UID_COUNT = 256; + +class CmGetAuthListTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmGetAuthListTest::SetUpTestCase(void) +{ +} + +void CmGetAuthListTest::TearDownTestCase(void) +{ +} + +static const uint8_t g_uriData[] = "oh:t=ak;o=GetAuthList;u=0;a=0"; +static const CmBlob g_keyUri = { sizeof(g_uriData), (uint8_t *)g_uriData }; + +void CmGetAuthListTest::SetUp() +{ + uint8_t aliasData[] = "GetAuthList"; + struct CmBlob alias = { sizeof(aliasData), aliasData }; + + int32_t ret = TestGenerateAppCert(&alias, CERT_KEY_ALG_RSA, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert failed, retcode:" << ret; + + uint32_t appId = DEFAULT_BASE_APP_ID; + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + ret = CmGrantAppCertificate(&g_keyUri, appId, &authUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGrantAppCertificate failed, retcode:" << ret; +} + +void CmGetAuthListTest::TearDown() +{ + int32_t ret = CmUninstallAppCert(&g_keyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert failed, retcode:" << ret; + + uint32_t appUid[DEFAULT_APP_UID_COUNT] = {0}; + struct CmAppUidList appUidList = { DEFAULT_APP_UID_COUNT, appUid }; + ret = CmGetAuthorizedAppList(&g_keyUri, &appUidList); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAuthorizedAppList failed, retcode:" << ret; + + uint32_t expectCount = 0; + EXPECT_EQ(appUidList.appUidCount, expectCount); +} + +static void TestRemoveGrant(uint32_t count, uint32_t baseAppId) +{ + int32_t ret; + uint32_t appId; + for (uint32_t i = 0; i < count; ++i) { + appId = baseAppId + i; + ret = CmRemoveGrantedApp(&g_keyUri, appId); + EXPECT_EQ(ret, CM_SUCCESS) << "CmRemoveGrantedApp failed, retcode:" << ret; + } +} + +static void TestGrant(uint32_t count, uint32_t baseAppId) +{ + uint32_t appId; + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + int32_t ret; + for (uint32_t i = 0; i < count; ++i) { + appId = baseAppId + i; + authUri.size = DEFAULT_AUTH_URI_LEN; + ret = CmGrantAppCertificate(&g_keyUri, appId, &authUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGrantAppCertificate failed, retcode:" << ret; + ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmIsAuthorizedApp failed, retcode:" << ret; + } +} + +static void CheckGetAuthedList(uint32_t count, uint32_t baseAppId) +{ + uint32_t appUid[DEFAULT_APP_UID_COUNT] = {0}; + struct CmAppUidList appUidList = { DEFAULT_APP_UID_COUNT, appUid }; + int32_t ret = CmGetAuthorizedAppList(&g_keyUri, &appUidList); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAuthorizedAppList failed, retcode:" << ret; + + EXPECT_EQ(appUidList.appUidCount, count); + + uint32_t uidValidCount = 0; + for (uint32_t i = 0; i < count; ++i) { + for (uint32_t j = 0; j < appUidList.appUidCount; ++j) { + if ((baseAppId + i) == appUidList.appUid[j]) { + uidValidCount++; + } + } + } + EXPECT_EQ(uidValidCount, count); +} + +/* caller make sure grantCount is no smaller than removeCount */ +static void TestGetAuthList(uint32_t grantCount, uint32_t removeCount) +{ + TestGrant(grantCount, DEFAULT_BASE_APP_ID); + CheckGetAuthedList(grantCount, DEFAULT_BASE_APP_ID); + + uint32_t remainCount = grantCount - removeCount; + uint32_t remainBaseAppId = DEFAULT_BASE_APP_ID + removeCount; + + if (removeCount != 0) { + TestRemoveGrant(removeCount, DEFAULT_BASE_APP_ID); + CheckGetAuthedList(remainCount, remainBaseAppId); + } + + /* clear environment */ + TestRemoveGrant(remainCount, remainBaseAppId); + CheckGetAuthedList(0, 0); +} + +/** + * @tc.name: CmGetAuthListTest001 + * @tc.desc: Test CmGetAuthListTest keyUri is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest001, TestSize.Level0) +{ + struct CmBlob *keyUri = nullptr; /* keyUri is NULL */ + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest002 + * @tc.desc: Test CmGetAuthListTest keyUri size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest002, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { 0, uriData }; /* keyUri size is 0 */ + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest003 + * @tc.desc: Test CmGetAuthListTest keyUri data is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest003, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), nullptr }; /* keyUri data is null */ + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest004 + * @tc.desc: Test CmGetAuthListTest keyUri data not end of '\0' + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest004, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { strlen((char *)uriData), uriData }; /* keyUri data not end of '\0' */ + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest005 + * @tc.desc: Test CmGetAuthListTest keyUri data has no app + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest005, TestSize.Level0) +{ + /* keyUri data has no app */ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest006 + * @tc.desc: Test CmGetAuthListTest keyUri data has no user + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest006, TestSize.Level0) +{ + /* keyUri data has no user */ + uint8_t uriData[] = "oh:t=ak;o=keyA;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest007 + * @tc.desc: Test CmGetAuthListTest keyUri data has no object + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest007, TestSize.Level0) +{ + /* keyUri data has no object */ + uint8_t uriData[] = "oh:t=ak;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest008 + * @tc.desc: Test CmGetAuthListTest keyUri data type not ak + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest008, TestSize.Level0) +{ + /* keyUri data type not ak */ + uint8_t uriData[] = "oh:t=m;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest009 + * @tc.desc: Test CmGetAuthListTest authUriList is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest009, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + struct CmAppUidList *appUidList = nullptr; /* authUriList is NULL */ + int32_t ret = CmGetAuthorizedAppList(&keyUri, appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest010 + * @tc.desc: Test CmGetAuthListTest authlist count too small + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest010, TestSize.Level0) +{ + struct CmAppUidList appUidList = { 0, nullptr }; + int32_t ret = CmGetAuthorizedAppList(&g_keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_BUFFER_TOO_SMALL); +} + +/** + * @tc.name: CmGetAuthListTest011 + * @tc.desc: Test CmGetAuthListTest authlist data NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest011, TestSize.Level0) +{ + struct CmAppUidList appUidList = { APP_UID_COUNT_ONE, nullptr }; /* setup has granted 1 app uid */ + int32_t ret = CmGetAuthorizedAppList(&g_keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest012 + * @tc.desc: Test CmGetAuthListTest authlist count too big > MAX_OUT_BLOB_SIZE + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest012, TestSize.Level0) +{ + struct CmAppUidList appUidList = { MAX_OUT_BLOB_SIZE + 1, nullptr }; /* count too big */ + int32_t ret = CmGetAuthorizedAppList(&g_keyUri, &appUidList); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGetAuthListTest013 + * @tc.desc: Test CmGetAuthListTest not grant, get grant list { 0, NULL } + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest013, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + struct CmAppUidList appUidList = { 0, nullptr }; + + int32_t ret = CmGetAuthorizedAppList(&keyUri, &appUidList); /* auth uid not exist */ + EXPECT_EQ(ret, CM_SUCCESS); + + uint32_t expectCount = 0; + EXPECT_EQ(appUidList.appUidCount, expectCount); +} + +/** +* @tc.name: CmGetAuthListTest014 +* @tc.desc: Test CmGetAuthListTest grant 1, get authlist +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest014, TestSize.Level0) +{ + uint32_t tempUid = 0; + struct CmAppUidList appUidList = { APP_UID_COUNT_ONE, &tempUid }; + + int32_t ret = CmGetAuthorizedAppList(&g_keyUri, &appUidList); + EXPECT_EQ(ret, CM_SUCCESS); + EXPECT_EQ(appUidList.appUidCount, APP_UID_COUNT_ONE); + EXPECT_EQ(*(appUidList.appUid), DEFAULT_BASE_APP_ID); +} + +/** + * @tc.name: CmGetAuthListTest015 + * @tc.desc: Test CmGetAuthListTest grant 10, get authlist + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest015, TestSize.Level0) +{ + TestGetAuthList(APP_UID_COUNT_MULTI, 0); +} + +/** + * @tc.name: CmGetAuthListTest016 + * @tc.desc: Test CmGetAuthListTest grant 10, remove grant 4, get authlist + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGetAuthListTest, CmGetAuthListTest016, TestSize.Level0) +{ + TestGetAuthList(APP_UID_COUNT_MULTI, APP_UID_REMOVE_COUNT); +} + +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_grant_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_grant_test.cpp new file mode 100644 index 0000000..e2aa996 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_grant_test.cpp @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cm_test_common.h" + +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { + +static constexpr uint32_t DEFAULT_AUTH_URI_LEN = 256; +static constexpr uint32_t INVALID_AUTH_URI_LEN = 100; +static constexpr uint32_t DEFAULT_APP_ID = 1000; +static constexpr uint32_t GRANT_ONE_APP_ID = 1; +static constexpr uint32_t GRANT_MULTIPLE_APP_ID = 10; + +class CmGrantTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmGrantTest::SetUpTestCase(void) +{ +} + +void CmGrantTest::TearDownTestCase(void) +{ +} + +void CmGrantTest::SetUp() +{ +} + +void CmGrantTest::TearDown() +{ +} + +static void TestNormalGrant(uint32_t count, bool isSameUid) +{ + uint8_t aliasData[] = "TestNormalGrant"; + struct CmBlob alias = { sizeof(aliasData), aliasData }; + int32_t ret = TestGenerateAppCert(&alias, CERT_KEY_ALG_RSA, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert failed, retcode:" << ret; + + uint8_t uriData[] = "oh:t=ak;o=TestNormalGrant;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + uint32_t appId = DEFAULT_APP_ID; + + for (uint32_t i = 0; i < count; ++i) { + if (!isSameUid) { + appId += i; + } + authUri.size = DEFAULT_AUTH_URI_LEN; /* clear authUri size */ + ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGrantAppCertificate failed, retcode:" << ret; + } + + ret = CmUninstallAppCert(&keyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert failed, retcode:" << ret; +} + +/** + * @tc.name: CmGrantTest001 + * @tc.desc: Test CmGrantTest keyUri is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest001, TestSize.Level0) +{ + struct CmBlob *keyUri = nullptr; /* keyUri is NULL */ + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGrantTest002 + * @tc.desc: Test CmGrantTest keyUri size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest002, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { 0, uriData }; /* keyUri size is 0 */ + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGrantTest003 + * @tc.desc: Test CmGrantTest keyUri data is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest003, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), nullptr }; /* keyUri data is null */ + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGrantTest004 + * @tc.desc: Test CmGrantTest keyUri data not end of '\0' + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest004, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { strlen((char *)uriData), uriData }; /* keyUri data not end of '\0' */ + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGrantTest005 + * @tc.desc: Test CmGrantTest keyUri data has no app: can't find cert + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest005, TestSize.Level0) +{ + /* keyUri data has no app */ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_NOT_EXIST); +} + +/** + * @tc.name: CmGrantTest006 + * @tc.desc: Test CmGrantTest keyUri data has no user: can't find cert + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest006, TestSize.Level0) +{ + /* keyUri data has no user */ + uint8_t uriData[] = "oh:t=ak;o=keyA;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_NOT_EXIST); +} + +/** + * @tc.name: CmGrantTest007 + * @tc.desc: Test CmGrantTest keyUri data has no object: can't find cert + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest007, TestSize.Level0) +{ + /* keyUri data has no object */ + uint8_t uriData[] = "oh:t=ak;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_NOT_EXIST); +} + +/** + * @tc.name: CmGrantTest008 + * @tc.desc: Test CmGrantTest keyUri data type not ak: can't find cert + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest008, TestSize.Level0) +{ + /* keyUri data type not ak */ + uint8_t uriData[] = "oh:t=m;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_NOT_EXIST); +} + +/** + * @tc.name: CmGrantTest009 + * @tc.desc: Test CmGrantTest authUri null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest009, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint32_t appId = DEFAULT_APP_ID; + struct CmBlob *authUri = nullptr; /* authUri nullptr */ + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGrantTest010 + * @tc.desc: Test CmGrantTest authUri size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest010, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { 0, authUriData }; /* authUri size is 0 */ + + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGrantTest011 + * @tc.desc: Test CmGrantTest authUri data is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest011, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, nullptr }; /* authUri data is NULL */ + uint32_t appId = DEFAULT_APP_ID; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmGrantTest012 + * @tc.desc: Test CmGrantTest normal case: grant 1 app id + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest012, TestSize.Level0) +{ + TestNormalGrant(GRANT_ONE_APP_ID, true); /* grant 1 app id */ +} + +/** + * @tc.name: CmGrantTest013 + * @tc.desc: Test CmGrantTest normal case: grant 10 same app id + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest013, TestSize.Level0) +{ + TestNormalGrant(GRANT_MULTIPLE_APP_ID, true); /* grant 10 same app id */ +} + +/** + * @tc.name: CmGrantTest014 + * @tc.desc: Test CmGrantTest normal case: grant 10 different app id + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest014, TestSize.Level0) +{ + TestNormalGrant(GRANT_MULTIPLE_APP_ID, false); /* grant 10 different app id */ +} + +/** + * @tc.name: CmGrantTest015 + * @tc.desc: Test CmGrantTest authUri size too small + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmGrantTest, CmGrantTest015, TestSize.Level0) +{ + uint8_t aliasData[] = "CmGrantTest014"; + struct CmBlob alias = { sizeof(aliasData), aliasData }; + int32_t ret = TestGenerateAppCert(&alias, CERT_KEY_ALG_RSA, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert failed, retcode:" << ret; + + uint8_t uriData[] = "oh:t=ak;o=CmGrantTest014;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint8_t authUriData[INVALID_AUTH_URI_LEN] = {0}; /* size too small */ + struct CmBlob authUri = { INVALID_AUTH_URI_LEN, authUriData }; + uint32_t appId = DEFAULT_APP_ID; + + ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CMR_ERROR_BUFFER_TOO_SMALL) << "CmGrantAppCertificate failed, retcode:" << ret; + + ret = CmUninstallAppCert(&keyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert failed, retcode:" << ret; +} + +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_init_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_init_test.cpp new file mode 100644 index 0000000..13addac --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_init_test.cpp @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cm_test_common.h" + +#include "cert_manager_api.h" + +#include "cm_log.h" +#include "cm_mem.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { + +static constexpr uint32_t INIT_COUNT_MULTI = 16; + +class CmInitTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmInitTest::SetUpTestCase(void) +{ +} + +void CmInitTest::TearDownTestCase(void) +{ +} + +static const uint8_t g_rsaUriData[] = "oh:t=ak;o=TestInitRsa;u=0;a=0"; +static const uint8_t g_eccUriData[] = "oh:t=ak;o=TestInitEcc;u=0;a=0"; +static const CmBlob g_rsaKeyUri = { sizeof(g_rsaUriData), (uint8_t *)g_rsaUriData }; +static const CmBlob g_eccKeyUri = { sizeof(g_eccUriData), (uint8_t *)g_eccUriData }; + +void CmInitTest::SetUp() +{ + uint8_t aliasRsaData[] = "TestInitRsa"; + uint8_t aliasEccData[] = "TestInitEcc"; + struct CmBlob aliasRsa = { sizeof(aliasRsaData), aliasRsaData }; + struct CmBlob aliasEcc = { sizeof(aliasEccData), aliasEccData }; + + int32_t ret = TestGenerateAppCert(&aliasRsa, CERT_KEY_ALG_RSA, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert rsa failed, retcode:" << ret; + ret = TestGenerateAppCert(&aliasEcc, CERT_KEY_ALG_ECC, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert ecc failed, retcode:" << ret; +} + +void CmInitTest::TearDown() +{ + int32_t ret = CmUninstallAppCert(&g_rsaKeyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert rsa failed, retcode:" << ret; + ret = CmUninstallAppCert(&g_eccKeyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert ecc failed, retcode:" << ret; +} + +/** +* @tc.name: CmInitTest001 +* @tc.desc: Test CmIsAuthorizedApp authUri is NULL +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest001, TestSize.Level0) +{ + struct CmBlob *authUri = nullptr; /* authUri is NULL */ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmInitTest002 + * @tc.desc: Test CmIsAuthorizedApp authUri size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest002, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob authUri = { 0, uriData }; /* authUri size is 0 */ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmInitTest003 +* @tc.desc: Test CmIsAuthorizedApp authUri data is null +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest003, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob authUri = { sizeof(uriData), nullptr }; /* authUri data is null */ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmInitTest004 + * @tc.desc: Test CmIsAuthorizedApp authUri data not end of '\0' + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest004, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob authUri = { strlen((char *)uriData), uriData }; /* authUri data not end of '\0' */ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmInitTest005 +* @tc.desc: Test CmIsAuthorizedApp authUri data has no app +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest005, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0"; /* authUri data has no app */ + struct CmBlob authUri = { sizeof(uriData), uriData }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmInitTest006 + * @tc.desc: Test CmIsAuthorizedApp authUri data has no user + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest006, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;a=0"; /* authUri data has no user */ + struct CmBlob authUri = { sizeof(uriData), uriData }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmInitTest007 +* @tc.desc: Test CmIsAuthorizedApp authUri data has no object +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest007, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;u=0;a=0"; /* authUri data has no object */ + struct CmBlob authUri = { sizeof(uriData), uriData }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmInitTest008 + * @tc.desc: Test CmIsAuthorizedApp authUri data type not ak + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest008, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=m;o=keyA;u=0;a=0"; /* authUri data type not ak */ + struct CmBlob authUri = { sizeof(uriData), uriData }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmInitTest009 +* @tc.desc: Test CmIsAuthorizedApp spec is NULL +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest009, TestSize.Level0) +{ + struct CmSignatureSpec *spec = nullptr; /* spec is NULL */ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&g_rsaKeyUri, spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmInitTest010 + * @tc.desc: Test CmIsAuthorizedApp spec->purpose is not CM_KEY_PURPOSE_SIGN/VERIFY + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest010, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_AGREE }; /* purpose is not CM_KEY_PURPOSE_SIGN/VERIFY */ + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&g_rsaKeyUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmInitTest011 + * @tc.desc: Test CmIsAuthorizedApp handle is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest011, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + struct CmBlob *handle = nullptr; /* handle is NULL */ + + int32_t ret = CmInit(&g_rsaKeyUri, &spec, handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmInitTest012 +* @tc.desc: Test CmIsAuthorizedApp handle size is 0 +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest012, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { 0, (uint8_t *)&handleValue }; /* handle size is 0 */ + + int32_t ret = CmInit(&g_rsaKeyUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmInitTest013 + * @tc.desc: Test CmIsAuthorizedApp handle data is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest013, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + struct CmBlob handle = { sizeof(uint64_t), nullptr }; /* handle data is NULL */ + + int32_t ret = CmInit(&g_rsaKeyUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmInitTest014 +* @tc.desc: Test CmIsAuthorizedApp handle size smaller than sizeof(uint64_t) +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest014, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint32_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; /* size smaller than sizeof(uint64_t) */ + + int32_t ret = CmInit(&g_rsaKeyUri, &spec, &handle); + EXPECT_EQ(ret, CMR_ERROR_KEY_OPERATION_FAILED); +} + +/** + * @tc.name: CmInitTest015 + * @tc.desc: Test CmIsAuthorizedApp huks key not exist + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest015, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob authUri = { sizeof(uriData), uriData }; + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&authUri, &spec, &handle); /* key not exist */ + EXPECT_EQ(ret, CMR_ERROR_KEY_OPERATION_FAILED); +} + +/** +* @tc.name: CmInitTest016 +* @tc.desc: Test CmIsAuthorizedApp normal case: caller is producer, init once rsa +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmInitTest, CmInitTest016, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&g_rsaKeyUri, &spec, &handle); + EXPECT_EQ(ret, CM_SUCCESS); +} + +/** + * @tc.name: CmInitTest017 + * @tc.desc: Test CmIsAuthorizedApp normal case: caller is producer, init once ecc + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest017, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_VERIFY }; + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&g_eccKeyUri, &spec, &handle); + EXPECT_EQ(ret, CM_SUCCESS); +} + +/** + * @tc.name: CmInitTest018 + * @tc.desc: Test CmIsAuthorizedApp normal case: caller is producer, init max times + 1 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmInitTest, CmInitTest018, TestSize.Level0) +{ + struct CmSignatureSpec spec = { CM_KEY_PURPOSE_VERIFY }; + + for (uint32_t i = 0; i < INIT_COUNT_MULTI; ++i) { + uint64_t handleValue = 0; + struct CmBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue }; + + int32_t ret = CmInit(&g_eccKeyUri, &spec, &handle); + EXPECT_EQ(ret, CM_SUCCESS); + } +} +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_is_authed_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_is_authed_test.cpp new file mode 100644 index 0000000..222e356 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_is_authed_test.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cm_test_common.h" + +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { + +static constexpr uint32_t DEFAULT_AUTH_URI_LEN = 256; + +class CmIsAuthedTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmIsAuthedTest::SetUpTestCase(void) +{ +} + +void CmIsAuthedTest::TearDownTestCase(void) +{ +} + +void CmIsAuthedTest::SetUp() +{ + uint8_t aliasData[] = "TestNormalGrant"; + struct CmBlob alias = { sizeof(aliasData), aliasData }; + + int32_t ret = TestGenerateAppCert(&alias, CERT_KEY_ALG_RSA, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert failed, retcode:" << ret; +} + +void CmIsAuthedTest::TearDown() +{ + uint8_t uriData[] = "oh:t=ak;o=TestNormalGrant;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + + int32_t ret = CmUninstallAppCert(&keyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert failed, retcode:" << ret; +} + +static void TestGrantApp(struct CmBlob *authUri) +{ + uint32_t appId = 0; + uint8_t uriData[] = "oh:t=ak;o=TestNormalGrant;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + + int32_t ret = CmGrantAppCertificate(&keyUri, appId, authUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGrantAppCertificate failed, retcode:" << ret; +} + +/** + * @tc.name: CmIsAuthedTest001 + * @tc.desc: Test CmIsAuthorizedApp authUri is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest001, TestSize.Level0) +{ + struct CmBlob *authUri = nullptr; /* authUri is NULL */ + int32_t ret = CmIsAuthorizedApp(authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest002 + * @tc.desc: Test CmIsAuthorizedApp authUri size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest002, TestSize.Level0) +{ + uint8_t uriData[] = + "oh:t=ak;o=keyA;u=0;a=0?ca=1000&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { 0, uriData }; /* authUri size is 0 */ + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest003 + * @tc.desc: Test CmIsAuthorizedApp authUri data is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest003, TestSize.Level0) +{ + uint8_t uriData[] = + "oh:t=ak;o=keyA;u=0;a=0?ca=1000&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { sizeof(uriData), nullptr }; /* authUri data is null */ + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest004 + * @tc.desc: Test CmIsAuthorizedApp authUri data not end of '\0' + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest004, TestSize.Level0) +{ + uint8_t uriData[] = + "oh:t=ak;o=keyA;u=0;a=0?ca=1000&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { strlen((char *)uriData), uriData }; /* authUri data not end of '\0' */ + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest005 + * @tc.desc: Test CmIsAuthorizedApp authUri data has no app + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest005, TestSize.Level0) +{ + /* authUri data has no app */ + uint8_t uriData[] = + "oh:t=ak;o=keyA;u=0?ca=1000&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { sizeof(uriData), uriData }; + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest006 + * @tc.desc: Test CmIsAuthorizedApp authUri data has no user + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest006, TestSize.Level0) +{ + /* authUri data has no user */ + uint8_t uriData[] = + "oh:t=ak;o=keyA;a=0?ca=1000&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { sizeof(uriData), uriData }; + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest007 + * @tc.desc: Test CmIsAuthorizedApp authUri data has no object + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest007, TestSize.Level0) +{ + /* authUri data has no object */ + uint8_t uriData[] = + "oh:t=ak;u=0;a=0?ca=1000&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { sizeof(uriData), uriData }; + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest008 + * @tc.desc: Test CmIsAuthorizedApp authUri data type not ak + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest008, TestSize.Level0) +{ + /* authUri data type not ak */ + uint8_t uriData[] = + "oh:t=m;o=keyA;u=0;a=0?ca=1000&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { sizeof(uriData), uriData }; + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest009 + * @tc.desc: Test CmIsAuthorizedApp authUri data has no clientapp + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest009, TestSize.Level0) +{ + /* authUri data has no clientapp */ + uint8_t uriData[] = + "oh:t=ak;o=keyA;u=0;a=0?m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUri = { sizeof(uriData), uriData }; + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest010 + * @tc.desc: Test CmIsAuthorizedApp authUri data has no macData + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest010, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0?ca=1000"; /* authUri data has no macData */ + struct CmBlob authUri = { sizeof(uriData), uriData }; + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest011 + * @tc.desc: Test CmIsAuthorizedApp normal test + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest011, TestSize.Level0) +{ + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + TestGrantApp(&authUri); + + int32_t ret = CmIsAuthorizedApp(&authUri); + EXPECT_EQ(ret, CM_SUCCESS); +} + +/** + * @tc.name: CmIsAuthedTest012 + * @tc.desc: Test CmIsAuthorizedApp authUri macData size not 32 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest012, TestSize.Level0) +{ + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + TestGrantApp(&authUri); + + /* authUri macData size 31 */ + uint8_t uriDataFail[] = + "oh:t=ak;o=TestNormalGrant;u=0;a=0?ca=0&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FA"; + struct CmBlob authUriFail = { sizeof(uriDataFail), uriDataFail }; + int32_t ret = CmIsAuthorizedApp(&authUriFail); + EXPECT_EQ(ret, CMR_ERROR_AUTH_CHECK_FAILED); +} + +/** + * @tc.name: CmIsAuthedTest013 + * @tc.desc: Test CmIsAuthorizedApp mac invalid + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest013, TestSize.Level0) +{ + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + TestGrantApp(&authUri); + + /* authUri macData invalid */ + uint8_t uriDataFail[] = + "oh:t=ak;o=TestNormalGrant;u=0;a=0?ca=0&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUriFail = { sizeof(uriDataFail), uriDataFail }; + int32_t ret = CmIsAuthorizedApp(&authUriFail); + EXPECT_EQ(ret, CMR_ERROR_AUTH_CHECK_FAILED); +} + +/** + * @tc.name: CmIsAuthedTest014 + * @tc.desc: Test CmIsAuthorizedApp mac size is odd number + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest014, TestSize.Level0) +{ + /* authUri mac size is odd number */ + uint8_t uriDataFail[] = + "oh:t=ak;o=TestNormalGrant;u=0;a=0?ca=0&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAF"; + struct CmBlob authUriFail = { sizeof(uriDataFail), uriDataFail }; + int32_t ret = CmIsAuthorizedApp(&authUriFail); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest015 + * @tc.desc: Test CmIsAuthorizedApp mac data can not change to hex + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest015, TestSize.Level0) +{ + /* authUri mac data can not change to hex */ + uint8_t uriDataFail[] = + "oh:t=ak;o=TestNormalGrant;u=0;a=0?ca=0&m=BA632421B76F1059BC28184FB9E50D57mm232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUriFail = { sizeof(uriDataFail), uriDataFail }; + int32_t ret = CmIsAuthorizedApp(&authUriFail); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmIsAuthedTest016 + * @tc.desc: Test CmIsAuthorizedApp can find mac key + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmIsAuthedTest, CmIsAuthedTest016, TestSize.Level0) +{ + uint8_t uriDataFail[] = + "oh:t=ak;o=keyA;u=0;a=0?ca=0&m=BA632421B76F1059BC28184FB9E50D5795232B6D5C535E0DCAC0114A7AD8FAFE"; + struct CmBlob authUriFail = { sizeof(uriDataFail), uriDataFail }; + int32_t ret = CmIsAuthorizedApp(&authUriFail); + EXPECT_EQ(ret, CMR_ERROR_KEY_OPERATION_FAILED); +} +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_remove_grant_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_remove_grant_test.cpp new file mode 100644 index 0000000..396073f --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_remove_grant_test.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cm_test_common.h" + +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { + +static constexpr uint32_t DEFAULT_AUTH_URI_LEN = 256; +static constexpr uint32_t DEFAULT_APP_ID = 1000; +static constexpr uint32_t REMOVE_TWICE = 2; +static constexpr uint32_t REMOVE_ONCE = 1; +static constexpr uint32_t REMOVE_NOT_EXIST_ID = 1001; + +class CmRemoveGrantTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmRemoveGrantTest::SetUpTestCase(void) +{ +} + +void CmRemoveGrantTest::TearDownTestCase(void) +{ +} + +void CmRemoveGrantTest::SetUp() +{ +} + +void CmRemoveGrantTest::TearDown() +{ +} + +static void TestRemoveGrant(uint32_t removeAppUid, uint32_t removeCount) +{ + uint8_t aliasData[] = "TestRemoveGrant"; + struct CmBlob alias = { sizeof(aliasData), aliasData }; + int32_t ret = TestGenerateAppCert(&alias, CERT_KEY_ALG_RSA, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "TestGenerateAppCert failed, retcode:" << ret; + + uint8_t uriData[] = "oh:t=ak;o=TestRemoveGrant;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint8_t authUriData[DEFAULT_AUTH_URI_LEN] = {0}; + struct CmBlob authUri = { DEFAULT_AUTH_URI_LEN, authUriData }; + uint32_t appId = DEFAULT_APP_ID; + + ret = CmGrantAppCertificate(&keyUri, appId, &authUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGrantAppCertificate failed, retcode:" << ret; + + for (uint32_t i = 0; i < removeCount; ++i) { + ret = CmRemoveGrantedApp(&keyUri, removeAppUid); + EXPECT_EQ(ret, CM_SUCCESS) << "CmRemoveGrantedApp failed, index:" << i << ", retcode:" << ret; + } + + ret = CmUninstallAppCert(&keyUri, CERT_MANAGER_CREDENTIAL_STORE); + EXPECT_EQ(ret, CM_SUCCESS) << "CmUninstallAppCert failed, retcode:" << ret; +} + +/** + * @tc.name: CmRemoveGrantTest001 + * @tc.desc: Test CmRemoveGrantTest keyUri is NULL + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest001, TestSize.Level0) +{ + struct CmBlob *keyUri = nullptr; /* keyUri is NULL */ + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest002 + * @tc.desc: Test CmRemoveGrantTest keyUri size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest002, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { 0, uriData }; /* keyUri size is 0 */ + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest003 + * @tc.desc: Test CmRemoveGrantTest keyUri data is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest003, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), nullptr }; /* keyUri data is null */ + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest004 + * @tc.desc: Test CmRemoveGrantTest keyUri data not end of '\0' + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest004, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { strlen((char *)uriData), uriData }; /* keyUri data not end of '\0' */ + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest005 + * @tc.desc: Test CmRemoveGrantTest keyUri data has no app + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest005, TestSize.Level0) +{ + /* keyUri data has no app */ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest006 + * @tc.desc: Test CmRemoveGrantTest keyUri data has no user + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest006, TestSize.Level0) +{ + /* keyUri data has no user */ + uint8_t uriData[] = "oh:t=ak;o=keyA;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest007 + * @tc.desc: Test CmRemoveGrantTest keyUri data has no object + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest007, TestSize.Level0) +{ + /* keyUri data has no object */ + uint8_t uriData[] = "oh:t=ak;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest008 + * @tc.desc: Test CmRemoveGrantTest keyUri data type not ak + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest008, TestSize.Level0) +{ + /* keyUri data type not ak */ + uint8_t uriData[] = "oh:t=m;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint32_t appId = 0; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmRemoveGrantTest009 + * @tc.desc: Test CmRemoveGrantTest remove while keyUri not exist + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest009, TestSize.Level0) +{ + uint8_t uriData[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { sizeof(uriData), uriData }; + uint32_t appId = DEFAULT_APP_ID; + int32_t ret = CmRemoveGrantedApp(&keyUri, appId); + EXPECT_EQ(ret, CM_SUCCESS); +} + +/** + * @tc.name: CmRemoveGrantTest010 + * @tc.desc: Test CmRemoveGrantTest remove while app uid not exist + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest010, TestSize.Level0) +{ + TestRemoveGrant(REMOVE_NOT_EXIST_ID, REMOVE_ONCE); /* remove not exist app uid */ +} + +/** + * @tc.name: CmRemoveGrantTest011 + * @tc.desc: Test CmRemoveGrantTest remove while app uid exist + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest011, TestSize.Level0) +{ + TestRemoveGrant(DEFAULT_APP_ID, REMOVE_ONCE); /* remove exist app uid */ +} + +/** + * @tc.name: CmRemoveGrantTest012 + * @tc.desc: Test CmRemoveGrantTest remove same app uid twice + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmRemoveGrantTest, CmRemoveGrantTest012, TestSize.Level0) +{ + TestRemoveGrant(DEFAULT_APP_ID, REMOVE_TWICE); /* remove same app uid twice */ +} +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/auth_manager/test/cm_update_test.cpp b/frameworks/cert_manager_standard/main/auth_manager/test/cm_update_test.cpp new file mode 100644 index 0000000..da7d7f3 --- /dev/null +++ b/frameworks/cert_manager_standard/main/auth_manager/test/cm_update_test.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cert_manager_api.h" + +using namespace testing::ext; +namespace { + +static constexpr uint32_t DEFAULT_INDATA_SIZE = 10; +static constexpr uint32_t DEFAULT_HANDLE_SIZE = 8; + +class CmUpdateTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void CmUpdateTest::SetUpTestCase(void) +{ +} + +void CmUpdateTest::TearDownTestCase(void) +{ +} + +void CmUpdateTest::SetUp() +{ +} + +void CmUpdateTest::TearDown() +{ +} + +static const uint8_t g_inDataBuf[DEFAULT_INDATA_SIZE] = {0}; +static const uint8_t g_handleBuf[DEFAULT_HANDLE_SIZE] = {0}; +static const struct CmBlob g_inData = { DEFAULT_INDATA_SIZE, (uint8_t *)g_inDataBuf }; +static const struct CmBlob g_handle = { DEFAULT_HANDLE_SIZE, (uint8_t *)g_handleBuf }; + +/** +* @tc.name: CmUpdateTest001 +* @tc.desc: Test CmIsAuthorizedApp handle is null +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmUpdateTest, CmUpdateTest001, TestSize.Level0) +{ + struct CmBlob *handle = nullptr; + int32_t ret = CmUpdate(handle, &g_inData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmUpdateTest002 + * @tc.desc: Test CmIsAuthorizedApp handle size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmUpdateTest, CmUpdateTest002, TestSize.Level0) +{ + struct CmBlob handle = { 0, (uint8_t *)g_handleBuf }; + int32_t ret = CmUpdate(&handle, &g_inData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmUpdateTest003 + * @tc.desc: Test CmIsAuthorizedApp handle data is null + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmUpdateTest, CmUpdateTest003, TestSize.Level0) +{ + struct CmBlob handle = { DEFAULT_HANDLE_SIZE, nullptr }; + int32_t ret = CmUpdate(&handle, &g_inData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmUpdateTest004 +* @tc.desc: Test CmIsAuthorizedApp inData is null +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmUpdateTest, CmUpdateTest004, TestSize.Level0) +{ + struct CmBlob *inData = nullptr; + int32_t ret = CmUpdate(&g_handle, inData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** + * @tc.name: CmUpdateTest005 + * @tc.desc: Test CmIsAuthorizedApp inData size is 0 + * @tc.type: FUNC + * @tc.require: AR000H0MIA /SR000H09NA + */ +HWTEST_F(CmUpdateTest, CmUpdateTest005, TestSize.Level0) +{ + struct CmBlob inData = { 0, (uint8_t *)g_inDataBuf }; + int32_t ret = CmUpdate(&g_handle, &inData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmUpdateTest006 +* @tc.desc: Test CmIsAuthorizedApp inData data is null +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmUpdateTest, CmUpdateTest006, TestSize.Level0) +{ + struct CmBlob inData = { DEFAULT_INDATA_SIZE, nullptr }; + int32_t ret = CmUpdate(&g_handle, &inData); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT); +} + +/** +* @tc.name: CmUpdateTest007 +* @tc.desc: Test CmIsAuthorizedApp handle not exist +* @tc.type: FUNC +* @tc.require: AR000H0MIA /SR000H09NA +*/ +HWTEST_F(CmUpdateTest, CmUpdateTest007, TestSize.Level0) +{ + int32_t ret = CmUpdate(&g_handle, &g_inData); + EXPECT_EQ(ret, CMR_ERROR_NOT_EXIST); +} +} // end of namespace diff --git a/frameworks/cert_manager_standard/main/common/BUILD.gn b/frameworks/cert_manager_standard/main/common/BUILD.gn new file mode 100644 index 0000000..2871494 --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("cert_manager_config") { + include_dirs = [ "include" ] +} + +ohos_static_library("libcert_manager_common_standard_static") { + subsystem_name = "security" + part_name = "certificate_manager" + defines = [ + "L2_STANDARD", + "_CM_LOG_ENABLE_", + ] + public_configs = + [ ":cert_manager_config" ] # Share include files for other gn when deps. + + include_dirs = [ + "//commonlibrary/c_utils/base/include", + "//third_party/openssl/include", + ] + + sources = [ + "src/cm_param.c", + "src/cm_pfx.c", + "src/cm_x509.c", + ] + + deps = [ "//third_party/openssl:libcrypto_shared" ] + external_deps = [ + "c_utils:utils", + "huks:libhukssdk", + ] + cflags = [ + "-DHILOG_ENABLE", + "-Wall", + "-Werror", + ] + complete_static_lib = true +} diff --git a/frameworks/cert_manager_standard/main/common/include/cm_config.h b/frameworks/cert_manager_standard/main/common/include/cm_config.h new file mode 100644 index 0000000..c6c41e7 --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_config.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_CONFIG_H +#define CM_CONFIG_H + +#define CM_SUPPORT_POSIX + +#define CM_SUPPORT_THREAD + +#define CM_SUPPORT_API_ATTEST_KEY + +/* AES */ +#define CM_SUPPORT_AES_C +#define CM_SUPPORT_AES_GENERATE_KEY +#define CM_SUPPORT_AES_CBC_NOPADDING +#define CM_SUPPORT_AES_CBC_PKCS7 +#define CM_SUPPORT_AES_GCM +#define CM_SUPPORT_AES_CTR_NOPADDING +#define CM_SUPPORT_AES_ECB_NOPADDING +#define CM_SUPPORT_AES_ECB_PKCS7PADDING + +/* BN */ +#define CM_SUPPORT_BN_C + +/* ECC */ +#define CM_SUPPORT_ECC_C +#define CM_SUPPORT_ECC_GENERATE_KEY +#define CM_SUPPORT_ECC_GET_PUBLIC_KEY + +#define CM_SUPPORT_ECDH_C +#define CM_SUPPORT_ECDH_AGREE_KEY + +#define CM_SUPPORT_ECDSA_C +#define CM_SUPPORT_ECDSA_SIGN_VERIFY + +/* ED25519 */ +#define CM_SUPPORT_ED25519_C +#define CM_SUPPORT_ED25519_GENERATE_KEY +#define CM_SUPPORT_ED25519_SIGN_VERIFY +#define CM_SUPPORT_ED2519_GET_PUBLIC_KEY + +/* HASH */ +#define CM_SUPPORT_HASH_C +#define CM_SUPPORT_HASH_SHA1 +#define CM_SUPPORT_HASH_SHA224 +#define CM_SUPPORT_HASH_SHA256 +#define CM_SUPPORT_HASH_SHA384 +#define CM_SUPPORT_HASH_SHA512 +#define CM_SUPPORT_HASH_MD5 + +/* HMAC */ +#define CM_SUPPORT_HMAC_C +#define CM_SUPPORT_HMAC_GENERATE_KEY +#define CM_SUPPORT_HMAC_SHA1 +#define CM_SUPPORT_HMAC_SHA224 +#define CM_SUPPORT_HMAC_SHA256 +#define CM_SUPPORT_HMAC_SHA384 +#define CM_SUPPORT_HMAC_SHA512 + +/* KDF */ +#define CM_SUPPORT_KDF_C +#define CM_SUPPORT_KDF_PBKDF2 +#define CM_SUPPORT_KDF_HKDF + +/* RSA */ +#define CM_SUPPORT_RSA_C +#define CM_SUPPORT_RSA_GENERATE_KEY +#define CM_SUPPORT_RSA_CRYPT +#define CM_SUPPORT_RSA_SIGN_VERIFY +#define CM_SUPPORT_RSA_GET_PUBLIC_KEY +#define CM_SUPPORT_RSA_ECB_NOPADDING +#define CM_SUPPORT_RSA_ECB_PKCS1PADDING +#define CM_SUPPORT_RSA_ECB_OAEPPADDING_SHA1MGF1 +#define CM_SUPPORT_RSA_ECB_OAEPPADDING_SHA224MGF1 +#define CM_SUPPORT_RSA_ECB_OAEPPADDING_SHA256MGF1 +#define CM_SUPPORT_RSA_ECB_OAEPPADDING_SHA384MGF1 +#define CM_SUPPORT_RSA_ECB_OAEPPADDING_SHA512MGF1 +#define CM_SUPPORT_RSA_ECB_OEAPPADDING +#define CM_SUPPORT_RSA_PSS + +/* DH */ +#define CM_SUPPORT_DH_C +#define CM_SUPPORT_DH_GENERATE_KEY +#define CM_SUPPORT_DH_AGREE_KEY +#define CM_SUPPORT_DH_GET_PUBLIC_KEY + +/* DSA */ +#define CM_SUPPORT_DSA_C +#define CM_SUPPORT_DSA_GENERATE_KEY +#define CM_SUPPORT_DSA_SIGN_VERIFY +#define CM_SUPPORT_DSA_GET_PUBLIC_KEY + +/* X25519 */ +#define CM_SUPPORT_X25519_C +#define CM_SUPPORT_X25519_GENERATE_KEY +#define CM_SUPPORT_X25519_AGREE_KEY +#define CM_SUPPORT_X25519_GET_PUBLIC_KEY + +#define CM_SUPPORT_ED25519_TO_X25519 + +#if defined(CM_SUPPORT_AES_GENERATE_KEY) || defined(CM_SUPPORT_DH_GENERATE_KEY) || \ + defined(CM_SUPPORT_DSA_GENERATE_KEY) || defined(CM_SUPPORT_ECC_GENERATE_KEY) || \ + defined(CM_SUPPORT_ED25519_GENERATE_KEY) || defined(CM_SUPPORT_HMAC_GENERATE_KEY) || \ + defined(CM_SUPPORT_RSA_GENERATE_KEY) || defined(CM_SUPPORT_X25519_GENERATE_KEY) +#define CM_SUPPORT_API_GENERATE_KEY +#define CM_SUPPORT_API_DELETE_KEY +#define CM_SUPPORT_API_GET_KEY_PARAM_SET +#define CM_SUPPORT_API_KEY_EXIST +#endif + +#if defined(CM_SUPPORT_ECC_C) || defined(CM_SUPPORT_RSA_C) || defined(CM_SUPPORT_ED25519_C) || \ + defined(CM_SUPPORT_X25519_C) || defined(CM_SUPPORT_AES_C) || defined(CM_SUPPORT_DSA_C) || \ + defined(CM_SUPPORT_DH_C) +#define CM_SUPPORT_API_IMPORT +#endif + +#if defined(CM_SUPPORT_ECC_C) || defined(CM_SUPPORT_RSA_C) || defined(CM_SUPPORT_ED25519_C) || \ + defined(CM_SUPPORT_X25519_C) || defined(CM_SUPPORT_AES_C) || defined(CM_SUPPORT_DSA_C) || \ + defined(CM_SUPPORT_DH_C) +#define CM_SUPPORT_API_EXPORT +#endif + +#define CM_SUPPORT_API_GENERATE_RANDOM + +#if defined(CM_SUPPORT_ECDSA_SIGN_VERIFY) || defined(CM_SUPPORT_ED25519_SIGN_VERIFY) || \ + defined(CM_SUPPORT_RSA_SIGN_VERIFY) || defined(CM_SUPPORT_DSA_SIGN_VERIFY) +#define CM_SUPPORT_API_SIGN_VERIFY +#endif + +#if defined(CM_SUPPORT_AES_C) || defined(CM_SUPPORT_RSA_CRYPT) +#define CM_SUPPORT_API_CIPHER +#endif + +#if defined(CM_SUPPORT_X25519_AGREE_KEY) || defined(CM_SUPPORT_ECDH_AGREE_KEY) || defined(CM_SUPPORT_DH_AGREE_KEY) +#define CM_SUPPORT_API_AGREE_KEY +#endif + +#ifdef CM_SUPPORT_KDF_C +#define CM_SUPPORT_API_DERIVE_KEY +#endif + +#ifdef CM_SUPPORT_HMAC_C +#define CM_SUPPORT_API_MAC +#endif + +#ifdef CM_SUPPORT_HASH_C +#define CM_SUPPORT_API_HASH +#endif + +#ifdef CM_SUPPORT_BN_C +#define CM_SUPPORT_API_BN_EXP_MOD +#endif + +#ifndef CM_SUPPORT_LITE_HEAP +#define CM_SUPPORT_API_GET_KEY_INFO_LIST +#endif + +#endif /* CM_CONFIG_H */ diff --git a/frameworks/cert_manager_standard/main/common/include/cm_log.h b/frameworks/cert_manager_standard/main/common/include/cm_log.h new file mode 100644 index 0000000..7628a0e --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_log.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_LOG_H +#define CM_LOG_H + +#include "cm_type.h" + +#ifdef _CM_LOG_ENABLE_ +#undef LOG_TAG +#define LOG_TAG "CM" +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD002F00 /* Security subsystem's domain id */ +#endif + +enum CmLogLevel { + CM_LOG_LEVEL_I, + CM_LOG_LEVEL_E, + CM_LOG_LEVEL_W, + CM_LOG_LEVEL_D, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _CM_LOG_ENABLE_ +void CmLog(uint32_t logLevel, const char *funcName, uint32_t lineNo, const char *format, ...); + +#define CM_LOG_I(...) CmLog(CM_LOG_LEVEL_I, __func__, __LINE__, __VA_ARGS__) +#define CM_LOG_W(...) CmLog(CM_LOG_LEVEL_W, __func__, __LINE__, __VA_ARGS__) +#define CM_LOG_E(...) CmLog(CM_LOG_LEVEL_E, __func__, __LINE__, __VA_ARGS__) +#define CM_LOG_D(...) CmLog(CM_LOG_LEVEL_D, __func__, __LINE__, __VA_ARGS__) +#else +#define CM_LOG_I(...) +#define CM_LOG_W(...) +#define CM_LOG_E(...) +#define CM_LOG_D(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CM_LOG_H */ diff --git a/frameworks/cert_manager_standard/main/common/include/cm_mem.h b/frameworks/cert_manager_standard/main/common/include/cm_mem.h new file mode 100644 index 0000000..867da4f --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_mem.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_MEM_H +#define CM_MEM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void *CmMalloc(size_t size); +void CmFree(void *ptr); + +#define SELF_FREE_PTR(PTR, FREE_FUNC) \ +{ \ + if ((PTR) != NULL) { \ + FREE_FUNC(PTR); \ + (PTR) = NULL; \ + } \ +} + +#define CM_FREE_PTR(p) SELF_FREE_PTR(p, CmFree) + +#define CM_FREE_BLOB(blob) do { \ + if ((blob).data != NULL) { \ + CmFree((blob).data); \ + (blob).data = NULL; \ + } \ + (blob).size = 0; \ +} while (0) + +#define CMMUTABLE_FREE_BLOB(blob) do { \ + if ((blob).data != NULL) { \ + CmFree((blob).data); \ + (blob).data = NULL; \ + } \ + (blob).size = 0; \ +} while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* CM_MEM_H */ diff --git a/frameworks/cert_manager_standard/main/common/include/cm_param.h b/frameworks/cert_manager_standard/main/common/include/cm_param.h new file mode 100644 index 0000000..610eaec --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_param.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_PARAM_H +#define CM_PARAM_H + +#include "cm_type.h" + +#define CM_PARAM_SET_MAX_SIZE (4 * 1024 * 1024) +#define CM_DEFAULT_PARAM_SET_SIZE 512 +#define CM_DEFAULT_PARAM_CNT ((uint32_t)((CM_DEFAULT_PARAM_SET_SIZE - sizeof(struct CmParamSet)) / \ + sizeof(struct HksParam))) +#define CM_TAG_TYPE_MASK (0xF << 28) + +#ifdef __cplusplus +extern "C" { +#endif + +enum CmTagType GetTagType(enum CmTag tag); + +int32_t CmInitParamSet(struct CmParamSet **paramSet); + +int32_t CmBuildParamSet(struct CmParamSet **paramSet); + +void CmFreeParamSet(struct CmParamSet **paramSet); + +int32_t CmGetParam(const struct CmParamSet *paramSet, uint32_t tag, struct CmParam **param); + +int32_t CmGetParamSet(const struct CmParamSet *inParamSet, uint32_t inParamSetSize, struct CmParamSet **outParamSet); + +int32_t CmAddParams(struct CmParamSet *paramSet, const struct CmParam *params, uint32_t paramCnt); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/frameworks/cert_manager_standard/main/common/include/cm_pfx.h b/frameworks/cert_manager_standard/main/common/include/cm_pfx.h new file mode 100644 index 0000000..405172c --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_pfx.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_PFX_H +#define CERT_MANAGER_PFX_H + +#include "cm_x509.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmParsePkcs12Cert(const struct CmBlob *p12Cert, char *passWd, EVP_PKEY **pkey, struct AppCert *appCert); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/frameworks/cert_manager_standard/main/common/include/cm_type.h b/frameworks/cert_manager_standard/main/common/include/cm_type.h new file mode 100644 index 0000000..43bce8b --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_type.h @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_TYPE_H +#define CM_TYPE_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +#ifndef CM_API_PUBLIC + #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__ICCARM__) /* __ICCARM__ for iar */ + #define CM_API_EXPORT + #else + #define CM_API_EXPORT __attribute__ ((visibility("default"))) + #endif +#else + #define CM_API_EXPORT __attribute__ ((visibility("default"))) +#endif + +#define MAX_LEN_CERTIFICATE 8196 + +#define MAX_LEN_CERTIFICATE_CHAIN (3 * MAX_LEN_CERTIFICATE) + +#define MAX_SUFFIX_LEN 8 +#define MAX_COUNT_CERTIFICATE 256 +#define MAX_LEN_URI 64 +#define MAX_LEN_CERT_ALIAS 64 +#define MAX_LEN_SUBJECT_NAME 256 +#define MAX_LEN_PACKGE_NAME 64 + +#define MAX_LEN_ISSUER_NAME 128 +#define MAX_LEN_SERIAL 64 +#define MAX_LEN_NOT_BEFORE 32 +#define MAX_LEN_NOT_AFTER 32 +#define MAX_LEN_FINGER_PRINT_SHA256 128 +#define MAX_LEN_APP_CERT 20480 +#define MAX_LEN_APP_CERT_PASSWD 16 + +#define MAX_BUF_LEN 64 +#define CM_ARRAY_SIZE(arr) ((sizeof(arr)) / (sizeof((arr)[0]))) +#define EOK (0) + +/* + * Align to 4-tuple + * Before calling this function, ensure that the size does not overflow after 3 is added. + */ +#define ALIGN_SIZE(size) ((((uint32_t)(size) + 3) >> 2) << 2) +#define DEFAULT_ALIGN_MASK_SIZE 3 + +#define CM_AE_TAG_LEN 16 +#define CM_BITS_PER_BYTE 8 +#define MAX_KEY_SIZE 2048 +#define CM_AE_TAG_LEN 16 +#define CM_AE_NONCE_LEN 12 +#define CM_MAX_KEY_ALIAS_LEN 64 +#define CM_MAX_PROCESS_NAME_LEN 50 +#define CM_MAX_RANDOM_LEN 1024 +#define CM_KEY_BYTES(keySize) (((keySize) + CM_BITS_PER_BYTE - 1) / CM_BITS_PER_BYTE) +#define CM_SIGNATURE_MIN_SIZE 64 +#define CM_ARRAY_SIZE(arr) ((sizeof(arr)) / (sizeof((arr)[0]))) +#define MAX_OUT_BLOB_SIZE (5 * 1024 * 1024) + +#define CM_CREDENTIAL_STORE 0 +#define CM_SYSTEM_TRUSTED_STORE 1 +#define CM_USER_TRUSTED_STORE 2 +#define CM_PRI_CREDENTIAL_STORE 3 + +enum CmKeyDigest { + CM_DIGEST_NONE = 0, + CM_DIGEST_MD5 = 1, + CM_DIGEST_SHA1 = 10, + CM_DIGEST_SHA224 = 11, + CM_DIGEST_SHA256 = 12, + CM_DIGEST_SHA384 = 13, + CM_DIGEST_SHA512 = 14, +}; + +enum CmKeyPurpose { + CM_KEY_PURPOSE_ENCRYPT = 1, /* Usable with RSA, EC, AES, and SM4 keys. */ + CM_KEY_PURPOSE_DECRYPT = 2, /* Usable with RSA, EC, AES, and SM4 keys. */ + CM_KEY_PURPOSE_SIGN = 4, /* Usable with RSA, EC keys. */ + CM_KEY_PURPOSE_VERIFY = 8, /* Usable with RSA, EC keys. */ + CM_KEY_PURPOSE_DERIVE = 16, /* Usable with EC keys. */ + CM_KEY_PURPOSE_WRAP = 32, /* Usable with wrap key. */ + CM_KEY_PURPOSE_UNWRAP = 64, /* Usable with unwrap key. */ + CM_KEY_PURPOSE_MAC = 128, /* Usable with mac. */ + CM_KEY_PURPOSE_AGREE = 256, /* Usable with agree. */ +}; + +enum CmErrorCode { + CM_SUCCESS = 0, + CM_FAILURE = -1, + + CMR_ERROR_NOT_PERMITTED = -2, + CMR_ERROR_NOT_SUPPORTED = -3, + CMR_ERROR_STORAGE = -4, + CMR_ERROR_NOT_FOUND = -5, + CMR_ERROR_NULL_POINTER = -6, + CMR_ERROR_INVALID_ARGUMENT = -7, + CMR_ERROR_MAKE_DIR_FAIL = -8, + CMR_ERROR_INVALID_OPERATION = -9, + CMR_ERROR_OPEN_FILE_FAIL = -10, + CMR_ERROR_READ_FILE_ERROR = -11, + CMR_ERROR_WRITE_FILE_FAIL = -12, + CMR_ERROR_REMOVE_FILE_FAIL = -13, + CMR_ERROR_CLOSE_FILE_FAIL = -14, + CMR_ERROR_MALLOC_FAIL = -15, + CMR_ERROR_NOT_EXIST = -16, + CMR_ERROR_ALREADY_EXISTS = -17, + CMR_ERROR_INSUFFICIENT_DATA = -18, + CMR_ERROR_BUFFER_TOO_SMALL = -19, + CMR_ERROR_INVALID_CERT_FORMAT = -20, + CMR_ERROR_PARAM_NOT_EXIST = -21, +}; + +enum CmTagType { + CM_TAG_TYPE_INVALID = 0 << 28, + CM_TAG_TYPE_INT = 1 << 28, + CM_TAG_TYPE_UINT = 2 << 28, + CM_TAG_TYPE_ULONG = 3 << 28, + CM_TAG_TYPE_BOOL = 4 << 28, + CM_TAG_TYPE_BYTES = 5 << 28, +}; + +enum CmTag { + /* Inner-use TAGS used for ipc serialization */ + CM_TAG_PARAM0_BUFFER = CM_TAG_TYPE_BYTES | 30001, + CM_TAG_PARAM1_BUFFER = CM_TAG_TYPE_BYTES | 30002, + CM_TAG_PARAM2_BUFFER = CM_TAG_TYPE_BYTES | 30003, + CM_TAG_PARAM3_BUFFER = CM_TAG_TYPE_BYTES | 30004, + CM_TAG_PARAM4_BUFFER = CM_TAG_TYPE_BYTES | 30005, + CM_TAG_PARAM0_UINT32 = CM_TAG_TYPE_UINT | 30006, + CM_TAG_PARAM1_UINT32 = CM_TAG_TYPE_UINT | 30007, + CM_TAG_PARAM2_UINT32 = CM_TAG_TYPE_UINT | 30008, + CM_TAG_PARAM3_UINT32 = CM_TAG_TYPE_UINT | 30009, + CM_TAG_PARAM4_UINT32 = CM_TAG_TYPE_UINT | 30010, + CM_TAG_PARAM0_BOOL = CM_TAG_TYPE_BOOL | 30011, + CM_TAG_PARAM1_BOOL = CM_TAG_TYPE_BOOL | 30012, + CM_TAG_PARAM2_BOOL = CM_TAG_TYPE_BOOL | 30013, + CM_TAG_PARAM3_BOOL = CM_TAG_TYPE_BOOL | 30014, + CM_TAG_PARAM4_BOOL = CM_TAG_TYPE_BOOL | 30015, + CM_TAG_PARAM0_NULL = CM_TAG_TYPE_BYTES | 30016, + CM_TAG_PARAM1_NULL = CM_TAG_TYPE_BYTES | 30017, + CM_TAG_PARAM2_NULL = CM_TAG_TYPE_BYTES | 30018, + CM_TAG_PARAM3_NULL = CM_TAG_TYPE_BYTES | 30019, + CM_TAG_PARAM4_NULL = CM_TAG_TYPE_BYTES | 30020, +}; + +#define CM_PARAM_BUFFER_NULL_INTERVAL ((CM_TAG_PARAM0_NULL) - (CM_TAG_PARAM0_BUFFER)) + +enum CmSendType { + CM_SEND_TYPE_ASYNC = 0, + CM_SEND_TYPE_SYNC, +}; + +struct CmMutableBlob { + uint32_t size; + uint8_t *data; +}; + +struct CmContext { + uint32_t userId; + uint32_t uid; + char packageName[MAX_LEN_PACKGE_NAME]; +}; + +struct CmBlob { + uint32_t size; + uint8_t *data; +}; + +struct CertBlob { + struct CmBlob uri[MAX_COUNT_CERTIFICATE]; + struct CmBlob certAlias[MAX_COUNT_CERTIFICATE]; + struct CmBlob subjectName[MAX_COUNT_CERTIFICATE]; +}; + +struct CertAbstract { + char uri[MAX_LEN_URI]; + char certAlias[MAX_LEN_CERT_ALIAS]; + bool status; + char subjectName[MAX_LEN_SUBJECT_NAME]; +}; + +struct CertList { + uint32_t certsCount; + struct CertAbstract *certAbstract; +}; + +struct CertInfo { + char uri[MAX_LEN_URI]; + char certAlias[MAX_LEN_CERT_ALIAS]; + bool status; + char issuerName[MAX_LEN_ISSUER_NAME]; + char subjectName[MAX_LEN_SUBJECT_NAME]; + char serial[MAX_LEN_SERIAL]; + char notBefore[MAX_LEN_NOT_BEFORE]; + char notAfter[MAX_LEN_NOT_AFTER]; + char fingerprintSha256[MAX_LEN_FINGER_PRINT_SHA256]; + struct CmBlob certInfo; +}; + +struct CmProcessInfo { + struct CmBlob userId; + struct CmBlob processName; +}; + +struct CertFile { + const struct CmBlob *fileName; + const struct CmBlob *path; +}; + +struct CMApp { + uint32_t userId; + uint32_t uid; + const char *packageName; + struct CmBlob *appId; // for attestation +}; + +struct Credential { + uint32_t isExist; + char type[MAX_LEN_SUBJECT_NAME]; + char alias[MAX_LEN_CERT_ALIAS]; + char keyUri[MAX_LEN_URI]; + uint32_t certNum; + uint32_t keyNum; + struct CmBlob credData; +}; + +struct CredentialAbstract { + char type[MAX_LEN_SUBJECT_NAME]; + char alias[MAX_LEN_CERT_ALIAS]; + char keyUri[MAX_LEN_URI]; +}; + +struct CredentialList { + uint32_t credentialCount; + struct CredentialAbstract *credentialAbstract; +}; + +struct AppCert { + uint32_t certCount; + uint32_t keyCount; + uint32_t certSize; + uint8_t appCertdata[MAX_LEN_CERTIFICATE_CHAIN]; +}; + +struct CmParam { + uint32_t tag; + union { + bool boolParam; + int32_t int32Param; + uint32_t uint32Param; + uint64_t uint64Param; + struct CmBlob blob; + }; +}; + +struct CmParamOut { + uint32_t tag; + union { + bool *boolParam; + int32_t *int32Param; + uint32_t *uint32Param; + uint64_t *uint64Param; + struct CmBlob *blob; + }; +}; + +struct CmParamSet { + uint32_t paramSetSize; + uint32_t paramsCnt; + struct CmParam params[]; +}; + +struct CmKeySpec { + uint32_t algType; + uint32_t keyLen; + void *algParam; /* for example : struct HksKeyDerivationParam */ +}; + +#define CM_DERIVE_DEFAULT_SALT_LEN 16 +#define CM_HMAC_DIGEST_SHA512_LEN 64 +#define CM_DEFAULT_RANDOM_LEN 16 +#define CM_MAX_KEY_AUTH_ID_LEN 64 +#define CM_KEY_MATERIAL_NUM 3 +#define CM_MAX_KEY_LEN (CM_KEY_BYTES(CM_RSA_KEY_SIZE_4096) * CM_KEY_MATERIAL_NUM) + +struct CmStoreHeaderInfo { + uint16_t version; + uint16_t keyCount; + uint32_t totalLen; /* key buffer total len */ + uint32_t sealingAlg; + uint8_t salt[CM_DERIVE_DEFAULT_SALT_LEN]; + uint8_t hmac[CM_HMAC_DIGEST_SHA512_LEN]; +}; + +struct CmStoreKeyInfo { + uint16_t keyInfoLen; /* current keyinfo len */ + uint16_t keySize; /* keySize of key from crypto hal after encrypted */ + uint8_t random[CM_DEFAULT_RANDOM_LEN]; + uint8_t flag; /* import or generate key */ + uint8_t keyAlg; + uint8_t keyMode; + uint8_t digest; + uint8_t padding; + uint8_t rsv; + uint16_t keyLen; /* keyLen from paramset, e.g. aes-256 */ + uint32_t purpose; + uint32_t role; + uint16_t domain; + uint8_t aliasSize; + uint8_t authIdSize; +}; + +struct Cm25519KeyPair { + uint32_t publicBufferSize; + uint32_t privateBufferSize; +}; + +static inline bool CmIsAdditionOverflow(uint32_t a, uint32_t b) +{ + return (UINT32_MAX - a) < b; +} + +static inline bool CmIsInvalidLength(uint32_t length) +{ + return (length == 0) || (length > MAX_OUT_BLOB_SIZE); +} + +static inline int32_t CmCheckBlob(const struct CmBlob *blob) +{ + if ((blob == NULL) || (blob->data == NULL) || (blob->size == 0)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +#endif /* CM_TYPE_H */ diff --git a/frameworks/cert_manager_standard/main/common/include/cm_type_inner.h b/frameworks/cert_manager_standard/main/common/include/cm_type_inner.h new file mode 100644 index 0000000..6ab7782 --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_type_inner.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_TYPE_INNER_H +#define CM_TYPE_INNER_H + +#include "cm_type.h" +#include "securec.h" + +#endif /* CM_TYPE_INNER_H */ diff --git a/frameworks/cert_manager_standard/main/common/include/cm_x509.h b/frameworks/cert_manager_standard/main/common/include/cm_x509.h new file mode 100644 index 0000000..7c34ec3 --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/include/cm_x509.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_X509_H +#define CERT_MANAGER_X509_H + +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +#define SN_MAX_SIZE 64 +#define TIME_FORMAT_MAX_SIZE 16 +#define NAME_MAX_SIZE 256 +#define FINGERPRINT_MAX_SIZE 128 +#define NAME_LONGFORMAT_MAX_SIZE 1024 +#define NAME_DELIMITER_SIZE 2 +#define NAME_ANS1TIME_LEN 12 + +#define CM_COMMON_NAME "CN" +#define CM_SURNAME "SN" +#define CM_COUNTRY_NAME "C" +#define CM_LOCALITY_NAME "L" +#define CM_STATE_OR_PROVINCE_NAME "ST" +#define CM_STREET_ADDRESS "street" +#define CM_ORGANIZATION_NAME "O" +#define CM_ORGANIZATION_UNIT_NAME "OU" + + +#define ASN1_TAG_TYPE_SEQ 0x30 +enum CmCertFormat { + CM_CERT_FORMAT_PEM, + CM_CERT_FORMAT_DER +}; + +struct DataTime { + uint32_t year; + uint32_t month; + uint32_t day; + uint32_t hour; + uint32_t min; + uint32_t second; +}; + +X509 *InitCertContext(const uint8_t *certBuf, uint32_t size); + +int32_t GetX509Version(X509 *x509cert); + +int32_t GetX509SerialNumber(X509 *x509cert, char *outBuf, uint32_t outBufMaxSize); + +int32_t GetX509SubjectName(const X509 *x509cert, const char *subjectObjName, char* outBuf, uint32_t outBufMaxSize); + +int32_t GetX509SubjectNameLongFormat(const X509 *x509cert, char* outBuf, uint32_t outBufMaxSize); +int32_t GetX509IssueNameLongFormat(const X509 *x509cert, char* outBuf, uint32_t outBufMaxSize); + +int32_t GetX509NotBefore(const X509 *x509cert, char* outBuf, uint32_t outBufMaxSize); +int32_t GetX509NotAfter(const X509 *x509cert, char* outBuf, uint32_t outBufMaxSize); + +int32_t GetX509Fingerprint(const X509 *x509cert, char* outBuf, uint32_t outBufMaxSize); + +void FreeCertContext(X509 *x509cert); +#ifdef __cplusplus +} +#endif +#endif diff --git a/frameworks/cert_manager_standard/main/common/src/cm_param.c b/frameworks/cert_manager_standard/main/common/src/cm_param.c new file mode 100644 index 0000000..738f12a --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/src/cm_param.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "hks_type.h" + +#include "cm_type_inner.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_pfx.h" +#include "cm_param.h" + +enum CmTagType GetTagType(enum CmTag tag) +{ + return (enum CmTagType)((uint32_t)tag & CM_TAG_TYPE_MASK); +} + +int32_t CmInitParamSet(struct CmParamSet **paramSet) +{ + if (paramSet == NULL) { + CM_LOG_E("invalid init params!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + *paramSet = (struct CmParamSet *)CmMalloc(CM_DEFAULT_PARAM_SET_SIZE); + if (*paramSet == NULL) { + CM_LOG_E("malloc init param set failed!"); + return CMR_ERROR_MALLOC_FAIL; + } + (*paramSet)->paramsCnt = 0; + (*paramSet)->paramSetSize = sizeof(struct CmParamSet); + return CM_SUCCESS; +} + +static int32_t CmCheckParamSet(const struct CmParamSet *paramSet, uint32_t size) +{ + if (paramSet == NULL) { + return CMR_ERROR_NULL_POINTER; + } + + if ((size < sizeof(struct CmParamSet)) || (size > CM_PARAM_SET_MAX_SIZE) || + (paramSet->paramSetSize != size) || + (paramSet->paramsCnt > ((size - sizeof(struct CmParamSet)) / sizeof(struct CmParam)))) { + CM_LOG_E("invalid param set!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +static int32_t CmFreshParamSet(struct CmParamSet *paramSet, bool isCopy) +{ + if (paramSet == NULL) { + CM_LOG_E("invalid NULL paramSet"); + return CMR_ERROR_NULL_POINTER; + } + int32_t ret = CmCheckParamSet(paramSet, paramSet->paramSetSize); + if (ret != CM_SUCCESS) { + CM_LOG_E("invalid fresh paramSet"); + return ret; + } + + uint32_t size = paramSet->paramSetSize; + uint32_t offset = sizeof(struct CmParamSet) + sizeof(struct CmParam) * paramSet->paramsCnt; + + for (uint32_t i = 0; i < paramSet->paramsCnt; i++) { + if (offset > size) { + CM_LOG_E("invalid param set offset!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + if (GetTagType(paramSet->params[i].tag) == CM_TAG_TYPE_BYTES) { + if (IsAdditionOverflow(offset, paramSet->params[i].blob.size)) { + CM_LOG_E("blob size overflow!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (isCopy && (memcpy_s((uint8_t *)paramSet + offset, size - offset, + paramSet->params[i].blob.data, paramSet->params[i].blob.size) != EOK)) { + CM_LOG_E("copy param blob failed!"); + return CMR_ERROR_INVALID_OPERATION; + } + paramSet->params[i].blob.data = (uint8_t *)paramSet + offset; + offset += paramSet->params[i].blob.size; + } + } + + if (paramSet->paramSetSize != offset) { + CM_LOG_E("invalid param set size!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +static int32_t BuildParamSet(struct CmParamSet **paramSet) +{ + struct CmParamSet *freshParamSet = *paramSet; + uint32_t size = freshParamSet->paramSetSize; + uint32_t offset = sizeof(struct CmParamSet) + sizeof(struct CmParam) * freshParamSet->paramsCnt; + + if (size > CM_DEFAULT_PARAM_SET_SIZE) { + freshParamSet = (struct CmParamSet *)CmMalloc(size); + if (freshParamSet == NULL) { + CM_LOG_E("malloc params failed!"); + return CMR_ERROR_MALLOC_FAIL; + } + if (memcpy_s(freshParamSet, size, *paramSet, offset) != EOK) { + CM_FREE_PTR(freshParamSet); + CM_LOG_E("copy params failed!"); + return CMR_ERROR_INVALID_OPERATION; + } + CM_FREE_PTR(*paramSet); + *paramSet = freshParamSet; + } + + return CmFreshParamSet(freshParamSet, true); +} + +int32_t CmBuildParamSet(struct CmParamSet **paramSet) +{ + if ((paramSet == NULL) || (*paramSet == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int ret = CmCheckParamSet(*paramSet, (*paramSet)->paramSetSize); + if (ret != CM_SUCCESS) { + CM_LOG_E("invalid build params!"); + return ret; + } + + return BuildParamSet(paramSet); +} + +void CmFreeParamSet(struct CmParamSet **paramSet) +{ + if (paramSet == NULL) { + CM_LOG_E("invalid free paramset!"); + return; + } + CM_FREE_PTR(*paramSet); +} + +int32_t CmGetParam(const struct CmParamSet *paramSet, uint32_t tag, struct CmParam **param) +{ + if ((paramSet == NULL) || (param == NULL)) { + CM_LOG_E("invalid params!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (CmCheckParamSet(paramSet, paramSet->paramSetSize) != CM_SUCCESS) { + CM_LOG_E("invalid paramSet!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + for (uint32_t i = 0; i < paramSet->paramsCnt; i++) { + if (tag == paramSet->params[i].tag) { + *param = (struct CmParam *)¶mSet->params[i]; + return CM_SUCCESS; + } + } + + return CMR_ERROR_PARAM_NOT_EXIST; +} + +static int32_t FreshParamSet(struct CmParamSet *paramSet, bool isCopy) +{ + uint32_t size = paramSet->paramSetSize; + uint32_t offset = sizeof(struct CmParamSet) + sizeof(struct CmParam) * paramSet->paramsCnt; + + for (uint32_t i = 0; i < paramSet->paramsCnt; i++) { + if (offset > size) { + CM_LOG_E("FreshParamSet invalid param set offset!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + if (GetTagType(paramSet->params[i].tag) == CM_TAG_TYPE_BYTES) { + if (CmIsAdditionOverflow(offset, paramSet->params[i].blob.size)) { + CM_LOG_E("FreshParamSet blob size overflow!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + if (isCopy && memcpy_s((uint8_t *)paramSet + offset, size - offset, + paramSet->params[i].blob.data, paramSet->params[i].blob.size)) { + CM_LOG_E("FreshParamSet copy param blob failed!"); + return CMR_ERROR_INVALID_OPERATION; + } + paramSet->params[i].blob.data = (uint8_t *)paramSet + offset; + offset += paramSet->params[i].blob.size; + } + } + + if (paramSet->paramSetSize != offset) { + CM_LOG_E("FreshParamSet invalid param set size!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +int32_t CmGetParamSet(const struct CmParamSet *inParamSet, uint32_t inParamSetSize, struct CmParamSet **outParamSet) +{ + int32_t ret = CmCheckParamSet(inParamSet, inParamSetSize); + if (ret != CM_SUCCESS) { + return ret; + } + + uint32_t size = inParamSet->paramSetSize; + struct CmParamSet *buf = (struct CmParamSet *)CmMalloc(size); + if (buf == NULL) { + CM_LOG_E("malloc from param set failed!"); + return CMR_ERROR_MALLOC_FAIL; + } + + if (memcpy_s(buf, size, inParamSet, size) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + + ret = FreshParamSet(buf, false); + if (ret != CM_SUCCESS) { + CM_FREE_PTR(buf); + return ret; + } + *outParamSet = buf; + return CM_SUCCESS; +} + +static int32_t CheckBeforeAddParams(const struct CmParamSet *paramSet, const struct CmParam *params, + uint32_t paramCnt) +{ + if ((params == NULL) || (paramSet == NULL) || (paramSet->paramSetSize > CM_PARAM_SET_MAX_SIZE) || + (paramCnt > CM_DEFAULT_PARAM_CNT) || ((paramSet->paramsCnt + paramCnt) > CM_DEFAULT_PARAM_CNT)) { + CM_LOG_E("invalid params or paramset!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + for (uint32_t i = 0; i < paramCnt; i++) { + if ((GetTagType(params[i].tag) == CM_TAG_TYPE_BYTES) && + (params[i].blob.data == NULL)) { + CM_LOG_E("invalid blob param!"); + return CMR_ERROR_INVALID_ARGUMENT; + } + } + return CM_SUCCESS; +} + +int32_t CmAddParams(struct CmParamSet *paramSet, const struct CmParam *params, uint32_t paramCnt) +{ + int32_t ret = CheckBeforeAddParams(paramSet, params, paramCnt); + if (ret != CM_SUCCESS) { + return ret; + } + + for (uint32_t i = 0; i < paramCnt; i++) { + paramSet->paramSetSize += sizeof(struct CmParam); + if (GetTagType(params[i].tag) == CM_TAG_TYPE_BYTES) { + if (CmIsAdditionOverflow(paramSet->paramSetSize, params[i].blob.size)) { + CM_LOG_E("params size overflow!"); + paramSet->paramSetSize -= sizeof(struct CmParam); + return CMR_ERROR_INVALID_ARGUMENT; + } + paramSet->paramSetSize += params[i].blob.size; + } + (void)memcpy_s(¶mSet->params[paramSet->paramsCnt++], sizeof(struct CmParam), ¶ms[i], + sizeof(struct CmParam)); + } + return CM_SUCCESS; +} diff --git a/frameworks/cert_manager_standard/main/common/src/cm_pfx.c b/frameworks/cert_manager_standard/main/common/src/cm_pfx.c new file mode 100644 index 0000000..3b5f8c9 --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/src/cm_pfx.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "hks_type.h" +#include "cm_type_inner.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_pfx.h" + +static int32_t CmGetAppCertChain(X509 *cert, STACK_OF(X509) *caCert, struct AppCert *appCert) +{ + int32_t ret = CM_SUCCESS; uint32_t certCount = 0; + X509 *xCert = NULL; char *data = NULL; BIO *out = NULL; + + if (cert == NULL) { + CM_LOG_E("app terminal cert is null"); + return CM_FAILURE; + } + + do { + out = BIO_new(BIO_s_mem()); + if (out == NULL) { + CM_LOG_E("BIO_new_mem_buf faild"); + ret = CM_FAILURE; + break; + } + /* copy app terminal cert to bio */ + if (PEM_write_bio_X509(out, cert) == 0) { + CM_LOG_E("Copy app cert to bio faild"); + ret = CM_FAILURE; + break; + } + /* copy app ca cert to bio */ + for (int32_t i = 0; i < sk_X509_num(caCert); i++) { + xCert = sk_X509_value(caCert, i); + if (PEM_write_bio_X509(out, xCert) == 0) { + CM_LOG_E("Copy app ca cert to bio faild"); + ret = CM_FAILURE; + break; + } + certCount++; + } + + long len = BIO_get_mem_data(out, &data); + if (len <= 0) { + CM_LOG_E("BIO_get_mem_data faild"); + ret = CM_FAILURE; + break; + } + if (memcpy_s(appCert->appCertdata, MAX_LEN_CERTIFICATE_CHAIN, data, len) != EOK) { + CM_LOG_E("Copy appCert->appCertdata faild"); + ret = CM_FAILURE; + break; + } + /* default certificate chain is packaged as a whole */ + appCert->certCount = certCount; + appCert->certSize = (uint32_t)len; + } while (0); + + if (out != NULL) { + BIO_free(out); + } + return ret; +} + +int32_t CmParsePkcs12Cert(const struct CmBlob *p12Cert, char *passWd, EVP_PKEY **pkey, struct AppCert *appCert) +{ + BIO *bio = NULL; + X509 *cert = NULL; + PKCS12 *p12 = NULL; + int32_t ret = CM_SUCCESS; + STACK_OF(X509) *caCert = NULL; + + if (p12Cert == NULL || p12Cert->data == NULL || p12Cert->size > MAX_LEN_CERTIFICATE_CHAIN) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + do { + bio = BIO_new_mem_buf(p12Cert->data, p12Cert->size); + if (bio == NULL) { + ret = CM_FAILURE; + CM_LOG_E("BIO_new_mem_buf faild"); + break; + } + + p12 = d2i_PKCS12_bio(bio, NULL); + if (p12 == NULL) { + ret = CM_FAILURE; + CM_LOG_E("D2i_PKCS12_bio faild:%s", ERR_error_string(ERR_get_error(), NULL)); + break; + } + /* 1 the return value of PKCS12_parse 1 is success */ + if (PKCS12_parse(p12, passWd, pkey, &cert, &caCert) != 1) { + ret = CM_FAILURE; + CM_LOG_E("Parsing PKCS#12 file faild:%s", ERR_error_string(ERR_get_error(), NULL)); + break; + } + + ret = CmGetAppCertChain(cert, caCert, appCert); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetAppCertChain failed"); + break; + } + } while (0); + + if (bio != NULL) { + BIO_free(bio); + } + if (p12 != NULL) { + PKCS12_free(p12); + } + if (caCert != NULL) { + sk_X509_pop_free(caCert, X509_free); + } + return ret; +} \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/common/src/cm_x509.c b/frameworks/cert_manager_standard/main/common/src/cm_x509.c new file mode 100644 index 0000000..9d9774c --- /dev/null +++ b/frameworks/cert_manager_standard/main/common/src/cm_x509.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "cm_x509.h" +#include "cm_log.h" + +typedef X509_NAME *(FUNC)(const X509 *); +typedef ASN1_TIME *(TIME_FUNC)(const X509 *); +#define CONVERT(p) (((p)[0] - '0') * 10 + (p)[1] - '0') + +X509 *InitCertContext(const uint8_t *certBuf, uint32_t size) +{ + X509 *x509 = NULL; + if (certBuf == NULL || size > MAX_LEN_CERTIFICATE) { + return NULL; + } + BIO *bio = BIO_new_mem_buf(certBuf, (int)size); + if (!bio) { + return NULL; + } + if (certBuf[0] == '-') { + // PEM format + x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); + } else if (certBuf[0] == ASN1_TAG_TYPE_SEQ) { + // Der format + x509 = d2i_X509_bio(bio, NULL); + } else { + CM_LOG_E("invalid certificate format."); + } + BIO_free(bio); + return x509; +} + +int32_t GetX509Version(X509 *x509cert) +{ + if (x509cert == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + return (int32_t)X509_get_version(x509cert) + 1; +} + +int32_t GetX509SerialNumber(X509 *x509cert, char *outBuf, uint32_t outBufMaxSize) +{ + if (outBuf == NULL || x509cert == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + ASN1_INTEGER *serial = X509_get_serialNumber(x509cert); + if (serial == NULL) { + return CMR_ERROR_INVALID_CERT_FORMAT; + } + BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL); + if (bn == NULL) { + return CMR_ERROR_INVALID_CERT_FORMAT; + } + + char *hex = BN_bn2hex(bn); + if (hex == NULL) { + BN_free(bn); + return CMR_ERROR_INVALID_CERT_FORMAT; + } + + uint32_t len = (uint32_t)strlen(hex); + if (len >= outBufMaxSize) { + OPENSSL_free(hex); + BN_free(bn); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + if (strncpy_s(outBuf, outBufMaxSize, hex, len) != EOK) { + OPENSSL_free(hex); + BN_free(bn); + return CMR_ERROR_INVALID_OPERATION; + } + + OPENSSL_free(hex); + BN_free(bn); + return (int32_t)len; +} +static int32_t ToStringName(FUNC func, const X509 *x509cert, const char *objname, char *outBuf, uint32_t outBufMaxSize) +{ + int32_t length = 0; + if (func == NULL || x509cert == NULL || outBuf == NULL || outBufMaxSize == 0) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + X509_NAME *name = func(x509cert); + if (name == NULL) { + return CMR_ERROR_INVALID_CERT_FORMAT; + } + + for (int i = 0; i < X509_NAME_entry_count(name); ++i) { + X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); + const char *strname = OBJ_nid2sn(OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry))); + + if (strcmp(objname, strname) == 0) { + char *data = NULL; + length = ASN1_STRING_to_UTF8((unsigned char **)&data, X509_NAME_ENTRY_get_data(entry)); + if (length < 0) { + return CMR_ERROR_INVALID_CERT_FORMAT; + } else if ((uint32_t)length >= outBufMaxSize) { + OPENSSL_free(data); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + if (strncpy_s(outBuf, outBufMaxSize, data, length) != EOK) { + OPENSSL_free(data); + return CMR_ERROR_INVALID_OPERATION; + } + OPENSSL_free(data); + break; + } + } + return length; +} + +static int32_t GetX509IssueName(const X509 *x509cert, const char *issuerObjName, char *outBuf, uint32_t outBufMaxSize) +{ + return ToStringName(X509_get_issuer_name, x509cert, issuerObjName, outBuf, outBufMaxSize); +} + +int32_t GetX509SubjectName(const X509 *x509cert, const char *subjectObjName, char *outBuf, uint32_t outBufMaxSize) +{ + return ToStringName(X509_get_subject_name, x509cert, subjectObjName, outBuf, outBufMaxSize); +} + +int32_t GetX509SubjectNameLongFormat(const X509 *x509cert, char *outBuf, uint32_t outBufMaxSize) +{ + if (outBuf == NULL || outBufMaxSize == 0) { + return CMR_ERROR_INVALID_ARGUMENT; + } + uint32_t offset = 0; + const char *subjectNameList[] = {CM_COMMON_NAME, CM_ORGANIZATION_UNIT_NAME, CM_ORGANIZATION_NAME}; + uint32_t sizeList = sizeof(subjectNameList) / sizeof(subjectNameList[0]); + for (uint32_t j = 0; j < sizeList; ++j) { + char subjectName[NAME_MAX_SIZE] = {0}; + int32_t length = GetX509SubjectName(x509cert, subjectNameList[j], subjectName, NAME_MAX_SIZE); + if (length < 0) { + return length; + } + if (snprintf_s(outBuf + offset, NAME_LONGFORMAT_MAX_SIZE - offset, + NAME_LONGFORMAT_MAX_SIZE - offset - 1, "%s=%s%c", + subjectNameList[j], subjectName, (char)(((j + 1) == sizeList) ? '\0' : ',')) < 0) { + return CMR_ERROR_INVALID_OPERATION; + } + offset += strlen(subjectNameList[j]) + strlen(subjectName) + NAME_DELIMITER_SIZE; + } + return (int32_t)strlen(outBuf); +} + +int32_t GetX509IssueNameLongFormat(const X509 *x509cert, char *outBuf, uint32_t outBufMaxSize) +{ + if (outBuf == NULL || outBufMaxSize == 0) { + return CMR_ERROR_INVALID_ARGUMENT; + } + uint32_t offset = 0; + + const char *issueNameList[] = {CM_COMMON_NAME, CM_ORGANIZATION_UNIT_NAME, CM_ORGANIZATION_NAME}; + uint32_t sizeList = sizeof(issueNameList) / sizeof(issueNameList[0]); + for (uint32_t j = 0; j < sizeList; ++j) { + char issueName[NAME_MAX_SIZE] = {0}; + int32_t length = GetX509IssueName(x509cert, issueNameList[j], issueName, NAME_MAX_SIZE); + if (length < 0) { + return length; + } + if (snprintf_s(outBuf + offset, NAME_LONGFORMAT_MAX_SIZE - offset, + NAME_LONGFORMAT_MAX_SIZE - offset - 1, "%s=%s%c", + issueNameList[j], issueName, (char)(((j + 1) == sizeList) ? '\0' : ',')) < 0) { + return CMR_ERROR_INVALID_OPERATION; + } + offset += strlen(issueNameList[j]) + strlen(issueName) + NAME_DELIMITER_SIZE; + } + return (int32_t)strlen(outBuf); +} + +static int32_t GetX509Time(TIME_FUNC fuc, const X509 *x509cert, struct DataTime *pDataTime) +{ + if (x509cert == NULL || fuc == NULL || pDataTime == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + ASN1_TIME *bufTime = fuc(x509cert); + if (!bufTime) { + return CMR_ERROR_INVALID_CERT_FORMAT; + } + + if (bufTime->length < NAME_ANS1TIME_LEN) { + return CMR_ERROR_INVALID_CERT_FORMAT; + } + + /* Convent the asn1 time to the readable time */ + pDataTime->year = CONVERT(bufTime->data); + if (pDataTime->year < 50) { /* 50 is used for the readable time */ + pDataTime->year += 100; /* 100 is used for the readable time */ + } + pDataTime->year += 1900; /* 1900 is used for the readable time */ + pDataTime->month = CONVERT(bufTime->data + 2); + pDataTime->day = CONVERT(bufTime->data + 4); + pDataTime->hour = CONVERT(bufTime->data + 6); + pDataTime->min = CONVERT(bufTime->data + 8); + pDataTime->second = CONVERT(bufTime->data + 10); + return 0; +} + +static int32_t GetX509TimeFormat(TIME_FUNC fuc, const X509 *x509cert, char *outBuf, uint32_t outBufMaxSize) +{ + if (x509cert == NULL || outBuf == NULL || outBufMaxSize == 0) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + struct DataTime dataTime; + int32_t ret = GetX509Time(fuc, x509cert, &dataTime); + if (CM_SUCCESS != ret) { + return ret; + } + + char buf[TIME_FORMAT_MAX_SIZE] = {0}; + if (snprintf_s(buf, TIME_FORMAT_MAX_SIZE, TIME_FORMAT_MAX_SIZE - 1, + "%d-%d-%d", (int)dataTime.year, (int)dataTime.month, (int)dataTime.day) < 0) { + return CMR_ERROR_INVALID_OPERATION; + } + + uint32_t length = (uint32_t)strlen(buf); + if (length >= outBufMaxSize) { + CM_LOG_E("GetX509TimeFormat buffer too small"); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + if (strncpy_s(outBuf, outBufMaxSize, buf, length) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + return (int32_t)length; +} +int32_t GetX509NotBefore(const X509 *x509cert, char *outBuf, uint32_t outBufMaxSize) +{ + return GetX509TimeFormat(X509_getm_notBefore, x509cert, outBuf, outBufMaxSize); +} + +int32_t GetX509NotAfter(const X509 *x509cert, char *outBuf, uint32_t outBufMaxSize) +{ + return GetX509TimeFormat(X509_getm_notAfter, x509cert, outBuf, outBufMaxSize); +} + +int32_t GetX509Fingerprint(const X509 *x509cert, char *outBuf, uint32_t outBufMaxSize) +{ + uint32_t size = 0; + uint8_t md[EVP_MAX_MD_SIZE] = {0}; + if (x509cert == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t res = X509_digest(x509cert, EVP_sha256(), md, &size); + if (res < 0) { + return CMR_ERROR_INVALID_CERT_FORMAT; + } + char buf[FINGERPRINT_MAX_SIZE] = {0}; + for (uint32_t i = 0; i < size; ++i) { + if (snprintf_s(buf + 3 * i, FINGERPRINT_MAX_SIZE - 3 * i, /* 3 is array index */ + FINGERPRINT_MAX_SIZE - 3 * i - 1, /* 3 is array index */ + "%02X%c", md[i], (char)(((i + 1) == size) ? '\0' : ':')) < 0) { + return CMR_ERROR_INVALID_OPERATION; + } + } + uint32_t length = (uint32_t)strlen(buf); + if (length >= outBufMaxSize) { + CM_LOG_E("GetX509Fingerprint buffer too small"); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + if (strncpy_s(outBuf, outBufMaxSize, buf, length) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + return (int32_t)length; +} + +void FreeCertContext(X509 *x509cert) +{ + if (!x509cert) { + return; + } + X509_free(x509cert); +} diff --git a/frameworks/cert_manager_standard/main/os_dependency/BUILD.gn b/frameworks/cert_manager_standard/main/os_dependency/BUILD.gn new file mode 100644 index 0000000..0cbbff8 --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/BUILD.gn @@ -0,0 +1,61 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("cert_manager_config") { + include_dirs = [ + "include", + "cm_ipc/include", + ] +} + +ohos_static_library("libcert_manager_os_dependency_standard_static") { + subsystem_name = "security" + part_name = "certificate_manager" + public_configs = [ ":cert_manager_config" ] + include_dirs = [ + "log", + "//commonlibrary/c_utils/base/include", + "//utils/system/safwk/native/include", + ] + defines = [ + "L2_STANDARD", + "_CM_LOG_ENABLE_", + ] + sources = [ + "./cm_ipc/src/cm_ipc_check.c", + "./cm_ipc/src/cm_ipc_client.c", + "./cm_ipc/src/cm_ipc_serialization.c", + "./cm_ipc/src/cm_load_sa.cpp", + "./cm_ipc/src/cm_request.cpp", + "./log/cm_log.c", + "./posix/cm_mem.c", + ] + deps = [ + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/common:libcert_manager_common_standard_static", + "//third_party/openssl:libcrypto_shared", + ] + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "samgr:samgr_proxy", + ] + cflags_cc = [ + "-DHILOG_ENABLE", + "-Wall", + "-Werror", + ] + cflags = cflags_cc + complete_static_lib = true +} diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_client_ipc.h b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_client_ipc.h new file mode 100644 index 0000000..526acdb --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_client_ipc.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_CLIENT_IPC_H +#define CM_CLIENT_IPC_H + +#include "cm_request.h" +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int32_t CmClientGetCertList(const struct CmContext *cmContext, const uint32_t store, + struct CertList *certificateList); + +int32_t CmClientGetCertInfo(const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store, struct CertInfo *certificateList); + +int32_t CmClientSetCertStatus(const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store, const uint32_t status); + +int32_t CmClientInstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd, + const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri); + +int32_t CmClientUninstallAppCert(const struct CmBlob *keyUri, const uint32_t store); + +int32_t CmClientUninstallAllAppCert(enum CmMessage type); + +int32_t CmClientGetAppCertList(const uint32_t store, struct CredentialList *certificateList); + +int32_t CmClientGetAppCert(const struct CmBlob *keyUri, const uint32_t store, struct Credential *certificate); + +#ifdef __cplusplus +} +#endif + +#endif /* CM_CLIENT_IPC_H */ diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_check.h b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_check.h new file mode 100644 index 0000000..ba8bb1b --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_check.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_CRYPTO_CHECK_H +#define CM_CRYPTO_CHECK_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CopyUint32ToBuffer(uint32_t value, const struct CmBlob *destBlob, uint32_t *destOffset); + +int32_t GetUint32FromBuffer(uint32_t *value, const struct CmBlob *srcBlob, uint32_t *srcOffset); + +int32_t CmGetBlobFromBuffer(struct CmBlob *blob, const struct CmBlob *srcBlob, uint32_t *srcOffset); + +int32_t CopyBlobToBuffer(const struct CmBlob *blob, const struct CmBlob *destBlob, uint32_t *destOffset); + +int32_t CheckCertificateListPara(struct CmBlob *inBlob, struct CmBlob *outBlob, const struct CmContext *cmContext, + const uint32_t store, struct CertList *certificateList); + +int32_t CheckCertificateInfoPara(struct CmBlob *inBlob, struct CmBlob *outBlob, const struct CmContext *cmContext, + const uint32_t store, struct CertInfo *certificateInfo); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_serialization.h b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_serialization.h new file mode 100644 index 0000000..9a40f41 --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_ipc_serialization.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_IPC_SERIALIZATION_H +#define CM_IPC_SERIALIZATION_H + +#include "cm_type_inner.h" + +#define MAX_IPC_BUF_SIZE 0x10000 /* Maximun IPC message buffer size. */ +#define MAX_IPC_RSV_SIZE 0x400 /* Reserve IPC message buffer size */ +#define MAX_PROCESS_SIZE (MAX_IPC_BUF_SIZE - MAX_IPC_RSV_SIZE) + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmCertificateListPack(struct CmBlob *inData, const struct CmContext *cmContext, const uint32_t store); + +int32_t CmCertificateInfoPack(struct CmBlob *inData, const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store); + +int32_t CmCertificateListUnpackFromService(const struct CmBlob *outData, bool needEncode, + const struct CmContext *context, struct CertList *certificateList); + +int32_t CmCertificateInfoUnpackFromService(const struct CmBlob *outData, const struct CmContext *context, + struct CertInfo *certificateInfo, const struct CmBlob *certUri); + +int32_t CmCertificateStatusPack(struct CmBlob *inData, const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store, const uint32_t status); + +int32_t CmParamsToParamSet(const struct CmParam *params, uint32_t cnt, struct CmParamSet **outParamSet); + +#ifdef __cplusplus +} +#endif + +#endif /* CM_IPC_SERIALIZATION_H */ \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_load_sa.h b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_load_sa.h new file mode 100644 index 0000000..e5faead --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_load_sa.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_LOAD_SA_H +#define CM_LOAD_SA_H + +#include +#include "system_ability_load_callback_stub.h" + +class OnDemandLoadCertManagerCallback : public OHOS::SystemAbilityLoadCallbackStub { +private: + std::string servers; +public: + OnDemandLoadCertManagerCallback(std::string servers); + void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const OHOS::sptr& remoteObject) override; + void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; +}; + +#endif /* CM_LOAD_SA_H */ \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_request.h b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_request.h new file mode 100644 index 0000000..a3b098d --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include/cm_request.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_REQUEST_H +#define CM_REQUEST_H + +#include "cm_type_inner.h" + +enum CmMessage { +#ifndef _CM_L1_TEE_ + CM_MSG_BASE = 0x3a400, /* range of message value defined by router. globally unique */ +#else + CM_MSG_BASE = 1000, /* range of message value defined by SmartLock. Max 65535 */ +#endif + CM_MSG_GEN_KEY = CM_MSG_BASE, + CM_MSG_GET_CERTIFICATE_LIST, + CM_MSG_GET_CERTIFICATE_INFO, + CM_MSG_SET_CERTIFICATE_STATUS, + CM_MSG_INSTALL_APP_CERTIFICATE, + CM_MSG_UNINSTALL_APP_CERTIFICATE, + CM_MSG_UNINSTALL_ALL_APP_CERTIFICATE, + CM_MSG_GET_APP_CERTIFICATE_LIST, + CM_MSG_GET_APP_CERTIFICATE, + CM_MSG_UPDATA_APP_CERTIFICATE, + + CM_MSG_MAX, /* new cmd type must be added before CM_MSG_MAX */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * SendRequest - Send the request message to target module by function call or ipc or other ways. + * @type: the request message type. + * @inBlob: the input serialized data blob. + * @outBlob: the output serialized data blob, can be null. + */ + +int32_t SendRequest(enum CmMessage type, const struct CmBlob *inBlob, + struct CmBlob *outBlob); + +#ifdef __cplusplus +} +#endif + +#endif /* CM_REQUEST_H */ diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_check.c b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_check.c new file mode 100644 index 0000000..8d7ae89 --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_check.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_ipc_check.h" +#include "cm_ipc_serialization.h" + +#include "cm_log.h" + +int32_t CheckCertificateListPara(struct CmBlob *inBlob, struct CmBlob *outBlob, const struct CmContext *cmContext, + const uint32_t store, struct CertList *certificateList) +{ + if ((inBlob == NULL) || (outBlob == NULL) || (cmContext == NULL) || (certificateList == NULL)) { + CM_LOG_E("CheckCertificateListPara arg error"); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +int32_t CheckCertificateInfoPara(struct CmBlob *inBlob, struct CmBlob *outBlob, const struct CmContext *cmContext, + const uint32_t store, struct CertInfo *certificateInfo) +{ + if ((inBlob == NULL) || (outBlob == NULL) || (cmContext == NULL) || (certificateInfo == NULL)) { + CM_LOG_E("CmCertificateInfoPack arg error"); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_client.c b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_client.c new file mode 100644 index 0000000..5cf152c --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_client.c @@ -0,0 +1,660 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_client_ipc.h" +#include "cm_ipc_check.h" + +#include "cm_ipc_serialization.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_x509.h" +#include "cm_param.h" + +#include "cm_request.h" + +static int32_t CertificateInfoInitBlob(struct CmBlob *inBlob, struct CmBlob *outBlob, + const struct CmContext *cmContext, struct CertInfo *CertificateInfo) +{ + uint32_t buffSize; + int32_t ret = CM_SUCCESS; + buffSize = sizeof(cmContext->userId) + sizeof(cmContext->uid) + + sizeof(uint32_t) + sizeof(cmContext->packageName) + sizeof(uint32_t) + MAX_LEN_URI + sizeof(uint32_t); + inBlob->data = (uint8_t *)CmMalloc(buffSize); + if (inBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + goto err; + } + inBlob->size = buffSize; + + buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t); + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + goto err; + } + outBlob->size = buffSize; + + CertificateInfo->certInfo.data = (uint8_t *)CmMalloc(MAX_LEN_CERTIFICATE); + if (CertificateInfo->certInfo.data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + goto err; + } + CertificateInfo->certInfo.size = MAX_LEN_CERTIFICATE; + return ret; +err: + CM_FREE_BLOB(*inBlob); + CM_FREE_BLOB(*outBlob); + + return ret; +} + +static int32_t CertificateListInitBlob(struct CmBlob *inBlob, struct CmBlob *outBlob, const struct CmContext *cmContext, + const uint32_t store, struct CertList *certificateList) +{ + uint32_t buffSize; + int32_t ret = CM_SUCCESS; + + buffSize = sizeof(cmContext->userId) + sizeof(cmContext->uid) + + sizeof(uint32_t) + sizeof(cmContext->packageName) + sizeof(uint32_t); + inBlob->data = (uint8_t *)CmMalloc(buffSize); + if (inBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + goto err; + } + inBlob->size = buffSize; + + buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) + sizeof(uint32_t) + + MAX_LEN_URI + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE; + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + goto err; + } + outBlob->size = buffSize; + + buffSize = (MAX_COUNT_CERTIFICATE * sizeof(struct CertAbstract)); + certificateList->certAbstract = (struct CertAbstract *)CmMalloc(buffSize); + if (certificateList->certAbstract == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + goto err; + } + certificateList->certsCount = MAX_COUNT_CERTIFICATE; + + if (memset_s(certificateList->certAbstract, buffSize, 0, buffSize) != EOK) { + CM_LOG_E("init certAbstract failed"); + ret = CMR_ERROR_INVALID_OPERATION; + goto err; + } + return ret; +err: + CM_FREE_BLOB(*inBlob); + CM_FREE_BLOB(*outBlob); + CmFree(certificateList->certAbstract); + + return ret; +} + +static int32_t GetCertificateList(enum CmMessage type, const struct CmContext *cmContext, const uint32_t store, + struct CertList *certificateList) +{ + struct CmBlob inBlob = {0, NULL}; + struct CmBlob outBlob = {0, NULL}; + const struct CmContext context = {0}; + int32_t ret = CheckCertificateListPara(&inBlob, &outBlob, cmContext, store, certificateList); + if (ret != CM_SUCCESS) { + CM_LOG_E("CheckCertificateListPara fail"); + return ret; + } + + ret = CertificateListInitBlob(&inBlob, &outBlob, cmContext, store, certificateList); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertificateListInitBlob fail"); + return ret; + } + + do { + ret = CmCertificateListPack(&inBlob, cmContext, store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertificateListPack fail"); + break; + } + ret = SendRequest(type, &inBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertificateList request fail"); + break; + } + + ret = CmCertificateListUnpackFromService(&outBlob, false, &context, certificateList); + } while (0); + CM_FREE_BLOB(inBlob); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientGetCertList(const struct CmContext *cmContext, const uint32_t store, + struct CertList *certificateList) +{ + return GetCertificateList(CM_MSG_GET_CERTIFICATE_LIST, cmContext, store, certificateList); +} + +static int32_t GetCertificateInfo(enum CmMessage type, const struct CmContext *cmContext, + const struct CmBlob *certUri, const uint32_t store, struct CertInfo *certificateInfo) +{ + struct CmBlob inBlob = {0, NULL}; + struct CmBlob outBlob = {0, NULL}; + const struct CmContext context = {0}; + + int32_t ret = CheckCertificateInfoPara(&inBlob, &outBlob, cmContext, store, certificateInfo); + if (ret != CM_SUCCESS) { + CM_LOG_E("CheckCertificateInfoPara fail"); + return ret; + } + + ret = CertificateInfoInitBlob(&inBlob, &outBlob, cmContext, certificateInfo); + if (ret != CM_SUCCESS) { + CM_LOG_E("CheckCertificateInfoPara fail"); + return ret; + } + + do { + ret = CmCertificateInfoPack(&inBlob, cmContext, certUri, store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertificateInfoPack fail"); + break; + } + + ret = SendRequest(type, &inBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertificateInfo request fail"); + break; + } + + ret = CmCertificateInfoUnpackFromService(&outBlob, &context, certificateInfo, certUri); + } while (0); + + CM_FREE_BLOB(inBlob); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientGetCertInfo(const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store, struct CertInfo *certificateInfo) +{ + return GetCertificateInfo(CM_MSG_GET_CERTIFICATE_INFO, cmContext, certUri, store, certificateInfo); +} + +static int32_t CertificateStatusInitBlob(struct CmBlob *inBlob, const struct CmContext *cmContext, + const struct CmBlob *certUri, const uint32_t store, const uint32_t status) +{ + int32_t ret = CM_SUCCESS; + uint32_t buffSize = sizeof(cmContext->userId) + sizeof(cmContext->uid) + + sizeof(uint32_t) + sizeof(cmContext->packageName) + sizeof(certUri->size) + + ALIGN_SIZE(certUri->size) + sizeof(store) + sizeof(status); + inBlob->data = (uint8_t *)CmMalloc(buffSize); + if (inBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + goto err; + } + inBlob->size = buffSize; + return ret; +err: + CM_FREE_BLOB(*inBlob); + return ret; +} + +static int32_t SetCertificateStatus(enum CmMessage type, const struct CmContext *cmContext, + const struct CmBlob *certUri, const uint32_t store, const uint32_t status) +{ + struct CmBlob inBlob = {0, NULL}; + int32_t ret = CM_SUCCESS; + + if ((cmContext == NULL) || certUri == NULL) { + CM_LOG_E("SetCertificateStatus invalid agrument"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + ret = CertificateStatusInitBlob(&inBlob, cmContext, certUri, store, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertificateStatusInitBlob fail"); + return ret; + } + + do { + ret = CmCertificateStatusPack(&inBlob, cmContext, certUri, store, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertificateStatusPack fail"); + break; + } + ret = SendRequest(type, &inBlob, NULL); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertificateStatusPack request fail"); + break; + } + } while (0); + CM_FREE_BLOB(inBlob); + return ret; +} + +int32_t CmClientSetCertStatus(const struct CmContext *cmContext, const struct CmBlob *certUri, const uint32_t store, + const uint32_t status) +{ + return SetCertificateStatus(CM_MSG_SET_CERTIFICATE_STATUS, cmContext, certUri, store, status); +} + +static int32_t CmInstallAppCertUnpackFromService(const struct CmBlob *outData, struct CmBlob *keyUri) +{ + uint32_t offset = 0; + if ((outData == NULL) || (keyUri == NULL) || (outData->data == NULL) || + (keyUri->data == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = CmGetBlobFromBuffer(keyUri, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get keyUri failed"); + return ret; + } + + return CM_SUCCESS; +} + +static int32_t InstallAppCertInitBlob(struct CmBlob *outBlob) +{ + int32_t ret = CM_SUCCESS; + + uint32_t buffSize = sizeof(uint32_t) + MAX_LEN_URI; + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + } + outBlob->size = buffSize; + + return ret; +} + +static int32_t InstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd, + const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri) +{ + int32_t ret; + struct CmBlob outBlob = { 0, NULL }; + struct CmParamSet *sendParamSet = NULL; + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = *appCert }, + { .tag = CM_TAG_PARAM1_BUFFER, + .blob = *appCertPwd }, + { .tag = CM_TAG_PARAM2_BUFFER, + .blob = *certAlias }, + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = store }, + }; + do { + ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmParamSetPack fail"); + break; + } + + struct CmBlob parcelBlob = { + .size = sendParamSet->paramSetSize, + .data = (uint8_t *)sendParamSet + }; + + ret = InstallAppCertInitBlob(&outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("InstallAppCertInitBlob fail"); + break; + } + + ret = SendRequest(CM_MSG_INSTALL_APP_CERTIFICATE, &parcelBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmParamSet send fail"); + break; + } + + ret = CmInstallAppCertUnpackFromService(&outBlob, keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmAppCertListUnpackFromService fail"); + break; + } + } while (0); + + CmFreeParamSet(&sendParamSet); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientInstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd, + const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri) +{ + return InstallAppCert(appCert, appCertPwd, certAlias, store, keyUri); +} + +static int32_t UninstallAppCert(enum CmMessage type, const struct CmBlob *keyUri, const uint32_t store) +{ + int32_t ret; + struct CmParamSet *sendParamSet = NULL; + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = *keyUri }, + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = store }, + }; + + do { + ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("UninstallAppCert CmParamSetPack fail"); + break; + } + + struct CmBlob parcelBlob = { + .size = sendParamSet->paramSetSize, + .data = (uint8_t *)sendParamSet + }; + + ret = SendRequest(type, &parcelBlob, NULL); + if (ret != CM_SUCCESS) { + CM_LOG_E("UninstallAppCert CmParamSet send fail"); + break; + } + } while (0); + + CmFreeParamSet(&sendParamSet); + return ret; +} + +int32_t CmClientUninstallAppCert(const struct CmBlob *keyUri, const uint32_t store) +{ + return UninstallAppCert(CM_MSG_UNINSTALL_APP_CERTIFICATE, keyUri, store); +} + +int32_t CmClientUninstallAllAppCert(enum CmMessage type) +{ + int32_t ret; + char tempBuff[] = "uninstall all app cert"; + struct CmBlob parcelBlob = { + .size = sizeof(tempBuff), + .data = (uint8_t *)tempBuff + }; + + ret = SendRequest(type, &parcelBlob, NULL); + if (ret != CM_SUCCESS) { + CM_LOG_E("UninstallAllAppCert request fail"); + } + + return ret; +} + +static int32_t GetAppCertListInitBlob(struct CmBlob *outBlob) +{ + uint32_t buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) + + MAX_LEN_URI + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE; + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + outBlob->size = buffSize; + + return CM_SUCCESS; +} + +static int32_t CmAppCertListUnpackFromService(const struct CmBlob *outData, + struct CredentialList *certificateList) +{ + uint32_t offset = 0; + struct CmBlob blob = { 0, NULL }; + if ((outData == NULL) || (certificateList == NULL) || + (outData->data == NULL) || (certificateList->credentialAbstract == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = GetUint32FromBuffer(&(certificateList->credentialCount), outData, &offset); + if (ret != CM_SUCCESS || certificateList->credentialCount == 0) { + CM_LOG_E("certificateList->credentialCount ret:%d, cont:%d", ret, certificateList->credentialCount); + return ret; + } + for (uint32_t i = 0; i < certificateList->credentialCount; i++) { + ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get type blob failed"); + return ret; + } + if (memcpy_s(certificateList->credentialAbstract[i].type, MAX_LEN_SUBJECT_NAME, blob.data, blob.size) != EOK) { + CM_LOG_E("copy type failed"); + return CMR_ERROR_INVALID_OPERATION; + } + + ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get keyUri blob failed"); + return ret; + } + if (memcpy_s(certificateList->credentialAbstract[i].keyUri, MAX_LEN_URI, blob.data, blob.size) != EOK) { + CM_LOG_E("copy keyUri failed"); + return CMR_ERROR_INVALID_OPERATION; + } + + ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get alias blob failed"); + return ret; + } + if (memcpy_s(certificateList->credentialAbstract[i].alias, MAX_LEN_CERT_ALIAS, blob.data, blob.size) != EOK) { + CM_LOG_E("copy alias failed"); + return CMR_ERROR_INVALID_OPERATION; + } + } + return CM_SUCCESS; +} + +static int32_t GetAppCertList(enum CmMessage type, const uint32_t store, struct CredentialList *certificateList) +{ + int32_t ret; + struct CmBlob outBlob = { 0, NULL }; + struct CmParamSet *sendParamSet = NULL; + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = store }, + }; + + do { + ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertList CmParamSetPack fail"); + break; + } + + struct CmBlob parcelBlob = { + .size = sendParamSet->paramSetSize, + .data = (uint8_t *)sendParamSet + }; + + ret = GetAppCertListInitBlob(&outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertListInitBlob fail"); + break; + } + + ret = SendRequest(type, &parcelBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertList request fail"); + break; + } + + ret = CmAppCertListUnpackFromService(&outBlob, certificateList); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmAppCertListUnpackFromService fail"); + break; + } + } while (0); + + CmFreeParamSet(&sendParamSet); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientGetAppCertList(const uint32_t store, struct CredentialList *certificateList) +{ + return GetAppCertList(CM_MSG_GET_APP_CERTIFICATE_LIST, store, certificateList); +} + +static int32_t GetAppCertInitBlob(struct CmBlob *outBlob) +{ + uint32_t buffSize = sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS + sizeof(uint32_t) + MAX_LEN_URI + + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_CERTIFICATE_CHAIN; + + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + outBlob->size = buffSize; + + return CM_SUCCESS; +} + +static int32_t CmGetAppCertFromBuffer(struct Credential *certificateInfo, + const struct CmBlob *outData, uint32_t *offset) +{ + struct CmBlob blob; + int32_t ret = CmGetBlobFromBuffer(&blob, outData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get type blob failed"); + return ret; + } + if (memcpy_s(certificateInfo->type, MAX_LEN_SUBJECT_NAME, blob.data, blob.size) != EOK) { + CM_LOG_E("copy type failed"); + return CMR_ERROR_INVALID_OPERATION; + } + + ret = CmGetBlobFromBuffer(&blob, outData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get keyUri blob failed"); + return ret; + } + if (memcpy_s(certificateInfo->keyUri, MAX_LEN_URI, blob.data, blob.size) != EOK) { + CM_LOG_E("copy keyUri failed"); + return CMR_ERROR_INVALID_OPERATION; + } + + ret = CmGetBlobFromBuffer(&blob, outData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get alias blob failed"); + return ret; + } + if (memcpy_s(certificateInfo->alias, MAX_LEN_CERT_ALIAS, blob.data, blob.size) != EOK) { + CM_LOG_E("copy alias failed"); + return CMR_ERROR_INVALID_OPERATION; + } + + return ret; +} + +static int32_t CmAppCertInfoUnpackFromService(const struct CmBlob *outData, struct Credential *certificateInfo) +{ + uint32_t offset = 0; + if ((outData == NULL) || (certificateInfo == NULL) || (outData->data == NULL) || + (certificateInfo->credData.data == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = GetUint32FromBuffer(&certificateInfo->isExist, outData, &offset); + if (ret != CM_SUCCESS || certificateInfo->isExist == 0) { + CM_LOG_E("Get certificateInfo->isExist failed ret:%s, is exist:%d", ret, certificateInfo->isExist); + return ret; + } + + ret = CmGetAppCertFromBuffer(certificateInfo, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get AppCert failed"); + return ret; + } + + ret = GetUint32FromBuffer(&certificateInfo->certNum, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get certificateInfo->certNum failed"); + return ret; + } + + ret = GetUint32FromBuffer(&certificateInfo->keyNum, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get certificateInfo->keyNum failed"); + return ret; + } + + ret = CmGetBlobFromBuffer(&certificateInfo->credData, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get certificateInfo->credData failed"); + return ret; + } + + return CM_SUCCESS; +} + +static int32_t GetAppCert(enum CmMessage type, const struct CmBlob *certUri, const uint32_t store, + struct Credential *certificate) +{ + int32_t ret; + struct CmBlob outBlob = { 0, NULL }; + struct CmParamSet *sendParamSet = NULL; + + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = *certUri }, + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = store }, + }; + do { + ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCert CmParamSetPack fail"); + break; + } + + struct CmBlob parcelBlob = { + .size = sendParamSet->paramSetSize, + .data = (uint8_t *)sendParamSet + }; + + ret = GetAppCertInitBlob(&outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertInitBlob fail"); + break; + } + + ret = SendRequest(type, &parcelBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCert request fail"); + break; + } + + ret = CmAppCertInfoUnpackFromService(&outBlob, certificate); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmAppCertInfoUnpackFromService fail"); + } + } while (0); + + CmFreeParamSet(&sendParamSet); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientGetAppCert(const struct CmBlob *keyUri, const uint32_t store, struct Credential *certificate) +{ + return GetAppCert(CM_MSG_GET_APP_CERTIFICATE, keyUri, store, certificate); +} diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_serialization.c b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_serialization.c new file mode 100644 index 0000000..2ff0711 --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_ipc_serialization.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_ipc_serialization.h" + +#include "cm_log.h" +#include "cm_mem.h" + +#include "cm_param.h" +#include "cm_x509.h" + +int32_t CopyUint32ToBuffer(uint32_t value, const struct CmBlob *destBlob, uint32_t *destOffset) +{ + if ((*destOffset > destBlob->size) || ((destBlob->size - *destOffset) < sizeof(value))) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, &value, sizeof(value)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + *destOffset += sizeof(value); + return CM_SUCCESS; +} + +int32_t CopyBlobToBuffer(const struct CmBlob *blob, const struct CmBlob *destBlob, uint32_t *destOffset) +{ + if ((*destOffset > destBlob->size) || + ((destBlob->size - *destOffset) < (sizeof(blob->size) + ALIGN_SIZE(blob->size)))) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, + &(blob->size), sizeof(blob->size)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + *destOffset += sizeof(blob->size); + + if (memcpy_s(destBlob->data + *destOffset, destBlob->size - *destOffset, blob->data, blob->size) != EOK) { + *destOffset -= sizeof(blob->size); + return CMR_ERROR_INVALID_OPERATION; + } + *destOffset += ALIGN_SIZE(blob->size); + return CM_SUCCESS; +} + +int32_t GetUint32FromBuffer(uint32_t *value, const struct CmBlob *srcBlob, uint32_t *srcOffset) +{ + if ((*srcOffset > srcBlob->size) || (srcBlob->size - *srcOffset < sizeof(uint32_t))) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + if (memcpy_s(value, sizeof(uint32_t), srcBlob->data + *srcOffset, sizeof(uint32_t)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + + *srcOffset += sizeof(uint32_t); + return CM_SUCCESS; +} + +int32_t CmGetBlobFromBuffer(struct CmBlob *blob, const struct CmBlob *srcBlob, uint32_t *srcOffset) +{ + if ((*srcOffset > srcBlob->size) || ((srcBlob->size - *srcOffset) < sizeof(uint32_t))) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + uint32_t size = *((uint32_t *)(srcBlob->data + *srcOffset)); + if (ALIGN_SIZE(size) > srcBlob->size - *srcOffset - sizeof(uint32_t)) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + blob->size = size; + *srcOffset += sizeof(blob->size); + blob->data = (uint8_t *)(srcBlob->data + *srcOffset); + *srcOffset += ALIGN_SIZE(blob->size); + return CM_SUCCESS; +} + +static int32_t CmCopyCmContextToBuffer(const struct CmContext *cmContext, struct CmBlob *inData, uint32_t *offset) +{ + int32_t ret; + ret = CopyUint32ToBuffer(cmContext->userId, inData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy cmContext->userId failed"); + return ret; + } + + ret = CopyUint32ToBuffer(cmContext->uid, inData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy cmContext->uid failed"); + return ret; + } + + struct CmBlob packageName = {MAX_LEN_PACKGE_NAME, (uint8_t *)cmContext->packageName}; + ret = CopyBlobToBuffer(&packageName, inData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy cmContext->packageName failed"); + return ret; + } + return ret; +} + +int32_t CmCertificateInfoPack(struct CmBlob *inData, const struct CmContext *cmContext, + const struct CmBlob *certUri, const uint32_t store) +{ + int32_t ret; + uint32_t offset = 0; + + ret = CmCopyCmContextToBuffer(cmContext, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy cmContext failed"); + return ret; + } + + ret = CopyBlobToBuffer(certUri, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy certUri failed"); + return ret; + } + + ret = CopyUint32ToBuffer(store, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy store failed"); + return ret; + } + return ret; +} + +int32_t CmCertificateListPack(struct CmBlob *inData, const struct CmContext *cmContext, const uint32_t store) +{ + int32_t ret; + uint32_t offset = 0; + + ret = CmCopyCmContextToBuffer(cmContext, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy cmContext failed"); + return ret; + } + + ret = CopyUint32ToBuffer(store, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy store failed"); + return ret; + } + return ret; +} + +int32_t CmCertificateListUnpackFromService(const struct CmBlob *outData, bool needEncode, + const struct CmContext *context, struct CertList *certificateList) +{ + uint32_t offset = 0, status = 0; + struct CmBlob blob = {0}; + if ((outData == NULL) || (context == NULL) || (certificateList == NULL) || + (outData->data == NULL) || (certificateList->certAbstract == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = GetUint32FromBuffer(&(certificateList->certsCount), outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get certificateList->certsCount failed"); + return ret; + } + for (uint32_t i = 0; i < certificateList->certsCount; i++) { + ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get subjectNameBlob FromBuffer"); + return ret; + } + if (memcpy_s(certificateList->certAbstract[i].subjectName, MAX_LEN_SUBJECT_NAME, blob.data, blob.size) != EOK) { + CM_LOG_E("copy subjectName failed"); + return CMR_ERROR_INVALID_OPERATION; + } + ret = GetUint32FromBuffer(&status, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy status failed"); + return ret; + } + certificateList->certAbstract[i].status = (status >= 1) ? false : true; + ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy uri failed"); + return ret; + } + + if (memcpy_s(certificateList->certAbstract[i].uri, MAX_LEN_URI, blob.data, blob.size) != EOK) { + CM_LOG_E("copy uri failed"); + return CMR_ERROR_INVALID_OPERATION; + } + + ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy certAlias failed"); + return ret; + } + if (memcpy_s(certificateList->certAbstract[i].certAlias, MAX_LEN_CERT_ALIAS, blob.data, blob.size) != EOK) { + CM_LOG_E("copy certAlias failed"); + return CMR_ERROR_INVALID_OPERATION; + } + } + return CM_SUCCESS; +} + +int32_t CmCertificateInfoUnpackFromService(const struct CmBlob *outData, + const struct CmContext *context, struct CertInfo *certificateInfo, const struct CmBlob *certUri) +{ + struct CmBlob blob; + uint32_t offset = 0, status = 0; + + if ((outData == NULL) || (context == NULL) || (certificateInfo == NULL) || + (outData->data == NULL) || (certificateInfo->certInfo.data == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertificateInfo get certInfo faild"); + return ret; + } + certificateInfo->certInfo.size = blob.size; + if (memcpy_s(certificateInfo->certInfo.data, MAX_LEN_CERTIFICATE, blob.data, blob.size) != EOK) { + CM_LOG_E("copy cert data failed"); + return CMR_ERROR_INVALID_OPERATION; + } + + ret = GetUint32FromBuffer(&(status), outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy status failed"); + return ret; + } + certificateInfo->status = (status >= 1) ? false : true; + + X509 *x509cert = InitCertContext(certificateInfo->certInfo.data, certificateInfo->certInfo.size); + + GetX509SubjectNameLongFormat(x509cert, certificateInfo->subjectName, MAX_LEN_SUBJECT_NAME); + GetX509IssueNameLongFormat(x509cert, certificateInfo->issuerName, MAX_LEN_ISSUER_NAME); + GetX509SerialNumber(x509cert, certificateInfo->serial, MAX_LEN_SERIAL); + GetX509NotBefore(x509cert, certificateInfo->notBefore, MAX_LEN_NOT_BEFORE); + GetX509NotAfter(x509cert, certificateInfo->notAfter, MAX_LEN_NOT_AFTER); + GetX509Fingerprint(x509cert, certificateInfo->fingerprintSha256, MAX_LEN_FINGER_PRINT_SHA256); + GetX509SubjectName(x509cert, CM_ORGANIZATION_NAME, certificateInfo->certAlias, MAX_LEN_CERT_ALIAS); + + FreeCertContext(x509cert); + + if (memset_s(certificateInfo->uri, MAX_LEN_URI, 0, MAX_LEN_URI) != EOK) { + CM_LOG_E("init uri failed"); + return CMR_ERROR_INVALID_OPERATION; + } + if (memcpy_s(certificateInfo->uri, MAX_LEN_URI, certUri->data, certUri->size) != EOK) { + CM_LOG_E("copy uri failed"); + return CMR_ERROR_INVALID_OPERATION; + } + return CM_SUCCESS; +} + +int32_t CmCertificateStatusPack(struct CmBlob *inData, const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store, const uint32_t status) +{ + int32_t ret; + uint32_t offset = 0; + + ret = CmCopyCmContextToBuffer(cmContext, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertificateStatus copy cmContext failed"); + return ret; + } + + ret = CopyBlobToBuffer(certUri, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertificateStatus copy certUri failed"); + return ret; + } + + ret = CopyUint32ToBuffer(store, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertificateStatus copy store failed"); + return ret; + } + + ret = CopyUint32ToBuffer(status, inData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertificateStatus copy store failed"); + return ret; + } + return ret; +} + +static int32_t AddParams(struct CmParam *params, uint32_t cnt, struct CmParamSet *paramSet) +{ + uint8_t tmpData = 0; + struct CmBlob tmpBlob = { sizeof(tmpData), &tmpData }; + + for (uint32_t i = 0; i < cnt; ++i) { + if ((GetTagType(params[i].tag) == CM_TAG_TYPE_BYTES) && + (params[i].blob.size == 0 || params[i].blob.data == NULL)) { + params[i].tag += CM_PARAM_BUFFER_NULL_INTERVAL; + params[i].blob = tmpBlob; + } + } + return CmAddParams(paramSet, params, cnt); +} + +int32_t CmParamsToParamSet(const struct CmParam *params, uint32_t cnt, struct CmParamSet **outParamSet) +{ + struct CmParamSet *newParamSet = NULL; + + int32_t ret = CmInitParamSet(&newParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("init param set failed"); + return ret; + } + + do { + ret = AddParams((struct CmParam *)params, cnt, newParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("add in params failed"); + break; + } + + ret = CmBuildParamSet(&newParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("build paramset failed!"); + break; + } + } while (0); + if (ret != CM_SUCCESS) { + CmFreeParamSet(&newParamSet); + return ret; + } + + *outParamSet = newParamSet; + + return ret; +} diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_load_sa.cpp b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_load_sa.cpp new file mode 100644 index 0000000..132e733 --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_load_sa.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cm_load_sa.h" +#include "cm_log.h" + +using namespace std; + +OnDemandLoadCertManagerCallback::OnDemandLoadCertManagerCallback(string servers) : servers(servers) +{ + CM_LOG_E("Servers %s on demand Callback constructor success", servers.c_str()); +} diff --git a/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_request.cpp b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_request.cpp new file mode 100644 index 0000000..1d51743 --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/src/cm_request.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_request.h" +#include "cm_load_sa.h" +#include +#include "iservice_registry.h" +#include "cm_log.h" +#include +#include +#include + +using namespace std; +using namespace OHOS; + +#define MAX_SA_BOOT_DELAY_TIME 30 + +static int32_t CmLoadSystemAbility(); + +static sptr cmProxy; + +namespace { + constexpr int SA_ID_KEYSTORE_SERVICE = 3512; + const std::u16string SA_KEYSTORE_SERVICE_DESCRIPTOR = u"ohos.security.cm.service"; + int32_t g_isLoadSystemAbility = CmLoadSystemAbility(); + sptr loadCallBack = nullptr; +} + +static int32_t CmLoadSystemAbility() +{ + if (cmProxy != nullptr) { + CM_LOG_D("GetCmProxy cmProxy already exist."); + return CM_SUCCESS; + } + + sptr saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (saManager == nullptr) { + CM_LOG_E("GetCmProxy registry is null"); + return CM_FAILURE; + } + + string servers = "CertManager"; + loadCallBack = new OnDemandLoadCertManagerCallback(servers); + if (loadCallBack == nullptr) { + CM_LOG_E("new OnDemandLoadCertManagerCallback failed"); + return CM_FAILURE; + } + + int32_t ret = saManager->LoadSystemAbility(SA_ID_KEYSTORE_SERVICE, loadCallBack); + if (ret != ERR_OK) { + CM_LOG_E("systemAbilityId:%d load failed,result code:%d", SA_ID_KEYSTORE_SERVICE, ret); + return CM_SUCCESS; + } + + return ret; +} + +static int32_t CmReadRequestReply(MessageParcel &reply, struct CmBlob *outBlob) +{ + int32_t ret = reply.ReadInt32(); + if (ret != CM_SUCCESS) { + CM_LOG_I("CmReadRequestReply start"); + return ret; + } + + size_t outLen = reply.ReadUint32(); + if (outLen == 0) { + if (outBlob != nullptr) { + outBlob->size = 0; + } + return ret; + } + if (CmCheckBlob(outBlob) != CM_SUCCESS) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + const uint8_t *outData = reply.ReadBuffer(outLen); + if (outData == nullptr) { + return CMR_ERROR_NULL_POINTER; + } + if (outBlob->size < outLen) { + CM_LOG_E("outBlob->size smaller than outLen.outBlob.siza[%d]", outBlob->size); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + if (memcpy_s(outBlob->data, outBlob->size, outData, outLen) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + outBlob->size = outLen; + return CM_SUCCESS; +} + +int32_t SendRequest(enum CmMessage type, const struct CmBlob *inBlob, + struct CmBlob *outBlob) +{ + uint32_t i = 0; + if (CmLoadSystemAbility() != CM_SUCCESS) { + CM_LOG_E("LoadSystemAbility success."); + return CMR_ERROR_INVALID_OPERATION; + } + + while ((cmProxy == nullptr) && i < MAX_SA_BOOT_DELAY_TIME) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); /* 100 is time */ + i++; + } + + if (cmProxy == nullptr) { + CM_LOG_E("Certtificate manager Proxy is null."); + return CMR_ERROR_NULL_POINTER; + } + + enum CmSendType sendType = CM_SEND_TYPE_SYNC; + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (sendType == CM_SEND_TYPE_SYNC) { + option = MessageOption::TF_SYNC; + } else { + option = MessageOption::TF_ASYNC; + } + + data.WriteInterfaceToken(SA_KEYSTORE_SERVICE_DESCRIPTOR); + if (outBlob == nullptr) { + data.WriteUint32(0); + } else { + data.WriteUint32(outBlob->size); + } + data.WriteUint32(inBlob->size); + data.WriteBuffer(inBlob->data, (size_t)inBlob->size); + + int error = cmProxy->SendRequest(type, data, reply, option); + if (error != 0) { + CM_LOG_E("SendRequest error:%d", error); + return error; + } + return CmReadRequestReply(reply, outBlob); +} + +void OnDemandLoadCertManagerCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, + const sptr& remoteObject) +{ + cmProxy = remoteObject; + CM_LOG_I("OnLoadSystemAbility Success systemAbilityId: %d, IRemoteObject result:%s", + systemAbilityId, ((remoteObject != nullptr) ? "succeed" : "failed")); +} + +void OnDemandLoadCertManagerCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId) +{ + cmProxy = nullptr; + CM_LOG_E("OnLoadSystemAbility Fail systemAbilityId: %d", systemAbilityId); +} \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/os_dependency/log/cm_log.c b/frameworks/cert_manager_standard/main/os_dependency/log/cm_log.c new file mode 100644 index 0000000..f4ac423 --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/log/cm_log.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_log.h" + +#include "securec.h" + +#include "hilog/log.h" +#include "cm_mem.h" + +#undef LOG_DOMAIN +#undef LOG_TAG +static const unsigned int LOG_DOMAIN = 0xD002F01; +static const char* LOG_TAG = "CertManager"; + +#define MAX_LOG_BUFF_LEN 512 + +void CmLog(uint32_t logLevel, const char *funcName, uint32_t lineNo, const char *format, ...) +{ + char *buf = (char *)CmMalloc(MAX_LOG_BUFF_LEN); + if (buf == NULL) { + HILOG_ERROR(LOG_CORE, "certificate manager log malloc fail"); + return; + } + (void)memset_s(buf, MAX_LOG_BUFF_LEN, 0, MAX_LOG_BUFF_LEN); + + va_list ap; + va_start(ap, format); + int32_t ret = vsnprintf_s(buf, MAX_LOG_BUFF_LEN, MAX_LOG_BUFF_LEN - 1, format, ap); + va_end(ap); + if (ret < 0) { + HILOG_ERROR(LOG_CORE, "certificate manager log concatenate error."); + CM_FREE_PTR(buf); + return; + } + + switch (logLevel) { + case CM_LOG_LEVEL_I: + HILOG_INFO(LOG_CORE, "%{public}s[%{public}u]: %{public}s\n", funcName, lineNo, buf); + break; + case CM_LOG_LEVEL_E: + HILOG_ERROR(LOG_CORE, "%{public}s[%{public}u]: %{public}s\n", funcName, lineNo, buf); + break; + case CM_LOG_LEVEL_W: + HILOG_WARN(LOG_CORE, "%{public}s[%{public}u]: %{public}s\n", funcName, lineNo, buf); + break; + case CM_LOG_LEVEL_D: + HILOG_DEBUG(LOG_CORE, "%{public}s[%{public}u]: %{private}s\n", funcName, lineNo, buf); + break; + default: + CM_FREE_PTR(buf); + return; + } + + CM_FREE_PTR(buf); +} diff --git a/frameworks/cert_manager_standard/main/os_dependency/posix/cm_mem.c b/frameworks/cert_manager_standard/main/os_dependency/posix/cm_mem.c new file mode 100644 index 0000000..991b74a --- /dev/null +++ b/frameworks/cert_manager_standard/main/os_dependency/posix/cm_mem.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_mem.h" + +#include + +#ifdef CM_SUPPORT_PRODUCT_GT_WATCH +#include "ohos_mem_pool.h" + +void *CmMalloc(size_t size) +{ + return OhosMalloc(MEM_TYPE_HICHAIN, size); +} + +void CmFree(void *ptr) +{ + OhosFree(ptr); +} +#else +void *CmMalloc(size_t size) +{ + return malloc(size); +} + +void CmFree(void *ptr) +{ + free(ptr); +} +#endif \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.c b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.c new file mode 100644 index 0000000..9d7dceb --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef CM_CONFIG_FILE +#include CM_CONFIG_FILE +#else +#include "cm_config.h" +#endif + +#include "cert_manager_api_user_trusted_cert.h" + +#include "cm_ipc_client_user_trusted_cert.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" + +#include "cm_request.h" + +CM_API_EXPORT int32_t CmGetCertList01(uint32_t store, struct CertList *certificateList) +{ + CM_LOG_I("enter get certificate list"); + if (certificateList == NULL) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = CmClientGetCertList01(store, certificateList); + CM_LOG_I("leave get certificate list, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmGetCertInfo01(const struct CmBlob *certUri, uint32_t store, struct CertInfo *certificateInfo) +{ + CM_LOG_I("enter get certificate info"); + if ((certUri == NULL) || (certificateInfo == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = CmClientGetCertInfo01(certUri, store, certificateInfo); + CM_LOG_I("leave get certificate info, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmSetCertStatus01(const struct CmBlob *certUri, uint32_t store, const bool status) +{ + CM_LOG_I("enter set certificate status"); + if (certUri == NULL) { + return CMR_ERROR_NULL_POINTER; + } + + uint32_t uStatus = status? 0: 1; // 0 indicates the certificate enabled status + + int32_t ret = CmClientSetCertStatus01(certUri, store, uStatus); + CM_LOG_I("leave set certificate status, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmInstallUserTrustedCert(const struct CmBlob *userCert, const struct CmBlob *certAlias, + struct CmBlob *certUri) +{ + CM_LOG_I("enter install user certificate"); + if ((userCert == NULL) || (certAlias == NULL) || (certUri == NULL)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientInstallUserTrustedCert(userCert, certAlias, certUri); + CM_LOG_I("leave install user certificate, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmUninstallUserTrustedCert(const struct CmBlob *certUri) +{ + CM_LOG_I("enter uninstall user certificate"); + if (certUri == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientUninstallUserTrustedCert(certUri); + CM_LOG_I("leave uninstall user certificate, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmUninstallAllUserTrustedCert(void) +{ + CM_LOG_I("enter uninstall user all certificate"); + + int32_t ret = CmClientUninstallAllUserTrustedCert(void); + CM_LOG_I("leave uninstall all user certificate, result = %d", ret); + return ret; +} diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.h b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.h new file mode 100644 index 0000000..effc3a9 --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_api_user_trusted_cert.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANGAGER_API_H +#define CERT_MANGAGER_API_H + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +CM_API_EXPORT int32_t CmGetCertList01(uint32_t store, struct CertList *certificateList); + +CM_API_EXPORT int32_t CmGetCertInfo01(const struct CmBlob *certUri, uint32_t store, + struct CertInfo *certificateInfo); + +CM_API_EXPORT int32_t CmSetCertStatus01(const struct CmBlob *certUri, uint32_t store, + const bool status); + +CM_API_EXPORT int32_t CmInstallUserTrustedCert(const struct CmBlob *userCert, + const struct CmBlob *certAlias, struct CmBlob *certUri); + +CM_API_EXPORT int32_t CmUninstallUserTrustedCert(const struct CmBlob *certUri); + +CM_API_EXPORT int32_t CmUninstallAllUserTrustedCert(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANGAGER_API_H */ \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.c b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.c new file mode 100644 index 0000000..f3ca2a4 --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdio.h" +#include "stdbool.h" +#include "stdint.h" +#include "cert_manager_user_trusted_cert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmFreeCertPaths(struct CmMutableBlob *certPaths) +{ + uint32_t i; + int32_t ret = 0; + struct CmMutableBlob *cPaths; + + if (certPaths == NULL) { + CM_LOG_E("Failed to free memory for certificate paths"); + return -1; + } + cPaths = (struct CmMutableBlob *)certPaths->data; + + for (i = 0; i < certPaths->size; i++) { + if (cPaths[i].data == NULL) { + CM_LOG_E("Failed to free memory for certificate name: %d", i); + ret = -1; + } else { + if (memset_s(cPaths[i].data, MAX_PATH_LEN, 0, cPaths[i].size) != EOK) { + return CMR_ERROR; + } + cPaths[i].size = 0; + CMFree(cPaths[i].data); + } + } + CMFree(cPaths); + certPaths->size = 0; + + return ret; +} + +int32_t CmGetCertFilePath(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathBlob) +{ + char pathPtr[MAX_PATH_LEN] = {0}; + + if ((pathBlob == NULL) || (pathBlob->data == NULL)) { + CM_LOG_E("Null pointer failure"); + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = ConstructUidPath(context, store, pathPtr, MAX_PATH_LEN); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get file path faild"); + return CM_FAILURE; + } + + char *path = (char *)pathBlob->data; + if (sprintf_s(path, MAX_PATH_LEN, "%s", pathPtr) < 0) { + return CM_FAILURE; + } + pathBlob->size = strlen(path) + 1; + if (CmMakeDir(path) == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("Failed to create folder %s", path); + return CMR_FILE_WRITE_ERROR; + } + return CM_SUCCESS; +} + +static int32_t CmGetUserIdPath(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathBlob) +{ + char pathPtr[MAX_PATH_LEN] = {0}; + + if ((pathBlob == NULL) || (pathBlob->data == NULL)) { + CM_LOG_E("Null pointer failure"); + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = ConstructUserIdPath(context, store, pathPtr, MAX_PATH_LEN); + if (ret != CMR_OK) { + CM_LOG_E("Get file path faild"); + return CMR_ERROR; + } + + char *useridpath = (char *)pathBlob->data; + if (sprintf_s(useridpath, MAX_PATH_LEN, "%s", pathPtr) < 0) { + return CM_FAILURE; + } + pathBlob->size = strlen(path) + 1; + if (CmMakeDir(useridpath) == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("Failed to create folder %s", useridpath); + return CMR_FILE_WRITE_ERROR; + } + return CMR_OK; +} + +static int32_t CreateCertPathList(char *useridPath, struct CmMutableBlob *certPathList) +{ + ASSERT_ARGS(useridPath && certPathList); + int32_t ret = CM_SUCCESS; + uint32_t i = 0; + uint32_t uidCount = 0; + struct CmMutableBlob *cPaths = NULL; + + if (MallocFileNames(certPathList, useridPath, &cPaths, &uidCount) != 0) { + CM_LOG_E("Failed to malloc memory for certPath List"); + return CM_FAILURE; + } + do { + void *d = CmOpenDir(useridPath); + if (d == NULL) { + CM_LOG_E("Failed to open directory: %s", useridPath); + ret = CM_FAILURE; + break; + } + + struct CmFileDirentInfo dire = {0}; + while (CmGetSubDir(d, &dire) == CMR_OK) { + char pathBuf[CERT_MAX_PATH_LEN] = {0}; + if (snprintf_s(pathBuf, MAX_PATH_LEN, MAX_PATH_LEN - 1, "%s/%s", useridPath, dire.fileName) < 0) { + CM_LOG_E("mkdir uid path failed"); + ret = CM_FAILURE; + break; + } + + cPaths[i].size = strlen(pathBuf) + 1; + cPaths[i].data = (uint8_t *)CmMalloc(cPaths[i].size); + char *path = (char *)cPaths[i].data; + if (sprintf_s(path, MAX_PATH_LEN, "%s", pathBuf) < 0) { + ret = CM_FAILURE; + break; + } + i++; + } + + if (i != uidCount) { + ret = CM_FAILURE; + break; + } + } while (0); + (void) CmCloseDir(d); + FreeFileNames(cPaths, i); + return ret; +} + +int32_t CmGetCertPathList(const struct CmContext *context, uint32_t store, + struct CmMutableBlob *certPathList) +{ + int32_t ret = CM_SUCCESS; + uint8_t userPathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob userPathBlob = { sizeof(userPathBuf), userPathBuf }; + + do { + ret = CmGetUserIdPath(context, store, &userPathBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed obtain userpath for store %u", store); + break; + } + + ret = CreateCertPathList((char *)userPathBlob.data, certPathList); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed create certPathList for userid %u", context->userId); + break; + } + } while (0); + return ret; +} + +int32_t CmRemoveUserCert(struct CmMutableBlob *pathBlob, + const struct CmBlob *certUri) +{ + return CertManagerFileRemove((char *)pathBlob->data, (char *)certUri->data); +} + +static int32_t RemoveAllUserCert(const struct CmContext *context, uint32_t store, const char* path) +{ + ASSERT_ARGS(path); + int32_t ret = CM_SUCCESS; + struct CmMutableBlob fileNames = { 0, NULL }; + struct CmMutableBlob *fNames = NULL; + struct CmBlob uri[MAX_LEN_URI]; + struct CmMutableBlob pathBlob = { sizeof(path), path }; + + uint32_t uriArraryLen = MAX_LEN_URI * sizeof(struct CmMutableBlob); + (void)memset_s(uri, uriArraryLen, 0, uriArraryLen); + if (CertManagerGetFilenames(&fileNames, path, uri) < 0) { + CM_LOG_E("Failed obtain filenames from path: %s", path); + (void)CmFreeCaFileNames(&fileNames); + return CM_FAILURE; + } + + fNames = (struct CmMutableBlob *)fileNames.data; + for (uint32_t i = 0; i < fileNames.size; i++) { + ret = CertManagerFileRemove(path, (char *)fNames[i].data); + if (ret != CMR_OK) { + CM_LOG_E("User Cert %d remove failed, ret: %d", i, ret); + continue; + } + ret = CmSetStatusEnable(context, &pathBlob, &uri[i], store); + if (ret != CM_SUCCESS) { + CM_LOG_E("Update StatusFile %d fail, ret = %d", i, ret); + continue; + } + } + (void)CmFreeCaFileNames(&fileNames); + return ret; +} + +static int32_t RemoveAllUidDir(const char* path) +{ + return CM_ERROR(CmDirRemove(path)); +} + +int32_t CmRemoveAllUserCert(const struct CmContext *context, uint32_t store, const struct CmMutableBlob *certPathList) +{ + ASSERT_ARGS(certPathList && certPathList->data && certPathList->size); + int32_t ret = CM_SUCCESS; + struct CmMutableBlob *path = (struct CmMutableBlob *)certPathList.data; + + for (uint32_t i = 0; i < certPathList->size; i++) { + ret = RemoveAllUserCert(context, store, (char *)path[i].data); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed remove usercert of path %s", (char *)path[i].data); + continue; + } + ret = RemoveAllUidDir((char *)path[i].data); + if (ret != CM_SUCCESS) { + CM_LOG_E("Remove UidPath %s fail, ret = %d", (char *)path[i].data, ret); + continue; + } + } + return ret; +} + +static int32_t NameHashFromUri(const char *fName, struct CmMutableBlob *nameDigest) +{ + uint32_t buffsize = (uint32_t)strlen(fName) + 1; + struct HksBlob certName = {buffsize, (uint8_t *)fName}; + + return NameHash(&certName, nameDigest); +} + +static int32_t CreateCertFile(struct CertFile *certFile, const char *path, uint32_t *certCount) +{ + ASSERT_ARGS(path); + int32_t ret = CM_SUCCESS; + uint32_t i = *certCount; + uint32_t fileNums = GetNumberOfFiles(path); + + void *d = CmOpenDir(path); + if (d == NULL) { + CM_LOG_E("Failed to open directory: %s", path); + return CM_FAILURE; + } + + struct CmFileDirentInfo dire = {0}; + while (CmGetDirFile(d, &dire) == CMR_OK) { + uint32_t pathSize = strlen(path); + certFile[i].path->size = pathSize; + certFile[i].path->data = (uint8_t *) strdup(path); + + uint32_t fNameSize = strlen(dire.fileName); + certFile[i].fileName->size = fNameSize; + certFile[i].fileName->data = (uint8_t *) strdup(dire.fileName); + + i++; + } + + if (i != fileNums) { + return CM_FAILURE; + } + (void) CmCloseDir(d); + *certCount += fileNums; + return ret; +} + +static int CmGetCertSubAndAlias(const char *fName, const char *path, + struct CmBlob *subjectName, struct CmBlob *certAlias) +{ + int32_t ret = CM_SUCCESS; + X509 *x509cert = NULL; + int32_t subjectNameLen = 0; + int32_t certAliasLen = 0; + uint32_t certBuffSize = CertManagerFileSize(path, fName); + struct CmMutableBlob certData = { 0, NULL }; + + certData.data = CmMalloc(certBuffSize); + if (certDataList[i].data == NULL) { + CM_LOG_E("Failed to allocate memory for certificate: %s", fName); + return CM_FAILURE; + } + certData->size = certBuffSize; + if (CertManagerFileRead(path, fName, 0, certData.data, certBuffSize) != certBuffSize) { + CM_LOG_E("Failed to read file: %s", fName); + return CM_FAILURE; + } + + x509cert = InitCertContext(certData.data, certData.size); + subjectNameLen = GetX509SubjectNameLongFormat(x509cert, (char *)subjectName->data, + MAX_LEN_SUBJECT_NAME); + if (subjectNameLen == 0) { + CM_LOG_E("Failed to get cert subjectName"); + return CM_FAILURE; + } + subjectName->.size = (uint32_t)subjectNameLen; + + certAliasLen = GetX509SubjectName(x509cert, CM_ORGANIZATION_NAME, (char *)certAlias->data, + MAX_LEN_CERT_ALIAS); + if (certAliasLen == 0) { + certAliasLen = GetX509SubjectName(x509cert, CM_COMMON_NAME, (char *)certAlias->data, + MAX_LEN_CERT_ALIAS); + } + if (certAliasLen == 0) { + CM_LOG_E("Failed to get cert CN name"); + return CM_FAILURE; + } + if (certAliasLen < 0) { + return certAliasLen; + } + FreeCertContext(x509cert); + certAlias->size = (uint32_t)certAliasLen; + return ret; +} + +int32_t CmGetCertListInfo(const struct CmContext *context, uint32_t store, + const struct CmMutableBlob *certFileList, struct CertBlob *certBlob, uint32_t *status) +{ + int32_t ret = CM_SUCCESS; + struct CertFile *certFile = (struct CertFile *)certFileList->data; + + ret = CmMallocCertInfo01(certBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmMallocCertInfo fail"); + return ret; + } + + for (uint32_t i = 0; i < certFileList->size; i++) { + /* status */ + ret = CertManagerStatusFile(context, certFile[i], store, CERT_STATUS_INVALID, &status[i]); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get cert status"); + return CM_FAILURE; + } + + /* uri */ + certBlob->uri[i].size = certFile[i].fileName->size; + if (memcpy_s(certBlob->uri[i].data, MAX_LEN_URI, certFile[i].fileName->data, + certFile[i].fileName->size) != EOK) { + CM_LOG_E("Failed to get cert uri"); + return CM_FAILURE; + } + + /* subjectName + certAlias */ + ret = CmGetCertSubAndAlias((char *)certFile[i].fileName->data, (char *)certFile[i].path->data, + &(certBlob->subjectName[i]), &(certBlob->certAlias[i])); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get cert data"); + return CM_FAILURE; + } + } + return ret; +} + +static int32_t CreateCertFileList(const struct CmMutableBlob *certPathList, struct CmMutableBlob *certFileList) +{ + ASSERT_ARGS(certPathList && certPathList->data && certPathList->size); + int32_t ret = CM_SUCCESS; + struct CmMutableBlob *path = (struct CmMutableBlob *)certPathList.data; + struct CertFile *certFile = (struct CertFile *)CmMalloc(sizeof(struct CertFile) * MAX_COUNT_CERTIFICATE); + certFileList->data = (uint8_t *)certFile; + uint32_t certCount = 0; + + for (uint32_t i = 0; i < certPathList->size; i++) { + ret = CreateCertFile(certFile, path[i].data, &certCount); + if (ret != CM_SUCCESS) { + CM_LOG_E("CreateCertFile fail of %s", path[i].data); + continue; + } + } + certFileList->size = certCount; + return ret; +} + +int32_t CmServiceGetCertList(const struct CmContext *context, uint32_t store, struct CmMutableBlob *certFileList) +{ + int32_t ret = CM_SUCCESS; + struct CmMutableBlob certPathList = { 0, NULL }; + + do { + ret = CmCheckCallerPermission(context); + if (ret != CM_SUCCESS) { + CM_LOG_E("Check caller permission fail"); + break; + } + + /* get path of every uid */ + ret = CmGetCertPathList(context, store, &certPathList); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertPathList fail, ret = %d", ret); + (void)CmFreeCertPaths(&certPathList); + break; + } + + /* create certFile(path + name) list from every uid */ + ret = CreateCertFileList(&certPathList, certFileList); + if (ret != CM_SUCCESS) { + CM_LOG_E("CreateCertFileList fail, ret = %d", ret); + (void)CmFreeCertPaths(&certPathList); + break; + } + } while (0); + + (void)CmFreeCertPaths(&certPathList); + return ret; +} + +static int32_t CmGetCertData(const char *fName, const char *path, struct CmBlob *certificateData) +{ + int32_t ret = CM_SUCCESS; + uint32_t certBuffSize = CertManagerFileSize(path, fName); + + certificateData->data = (uint8_t *)CmMalloc(certBuffSize); + if (fName == NULL) { + CM_LOG_E("Failed to allocate memory for certificate: %s", fName); + return CM_FAILURE; + } + certificateData->size = certBuffSize; + if (CertManagerFileRead(path, fName, 0, certificateData->data, certBuffSize) != certBuffSize) { + CM_LOG_E("Failed to read file: %s", fName); + return CM_FAILURE; + } + return ret; +} + +static int32_t CmGetMatchedCertIndex(const struct CmMutableBlob *certFileList, const struct CmBlob *certUri) +{ + struct CertFile *certFile = (struct CertFile *)certFileList->data; + uint32_t matchIndex = certFileList->size; + + for (uint32_t i = 0; i < certFileList->size; i++) { + if (certFile[i].fileName->data == NULL) { + CM_LOG_E("Corrupted file name at index: %d.\n", i); + ret = CMR_ERROR_STORAGE; + continue; + } + + if ((certUri->size <= certFile[i].fileName->data) && + (memcmp(certUri->data, certFile[i].fileName->data, certUri->size) == 0)) { + matchIndex = i; + break; + } + } + return matchIndex; +} + +int32_t CmGetServiceCertInfo(const struct CmContext *context, const struct CmBlob *certUri, + uint32_t store, struct CmBlob *certificateData, uint32_t *status) +{ + int32_t ret = CM_SUCCESS; + struct CmMutableBlob certFileList = { 0, NULL }; + uint32_t matchIndex = 0; + + do { + ret = CmCheckCallerPermission(context); + if (ret != CM_SUCCESS) { + CM_LOG_E("Check caller permission fail"); + break; + } + + ret = CmServiceGetCertList(context, store, &certFileList); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertList fail, ret = %d", ret); + break; + } + + matchIndex = CmGetMatchedCertIndex(&certFileList, certUri); + if (matchIndex == certFileList.size) { + CM_LOG_E("certFile of certUri don't matched"); + return CM_FAILURE; + } + + ret = CertManagerStatusFile(context, certFile[matchIndex], store, CERT_STATUS_INVALID, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get cert status"); + return CM_FAILURE; + } + + ret = CmGetCertData((char *)certFile[matchIndex].fileName->data, + (char *)certFile[matchIndex].path->data, certificateData); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get cert data"); + return CM_FAILURE; + } + } while (0); + + (void)CmFreeCertPaths(&certPathList); + return ret; +} + +int32_t BuildUserUri(char **userUri, const char *aliasName, uint32_t type, const struct CmContext *context) +{ + int32_t rc = CM_SUCCESS; + struct CMUri uri = {0}; + uri.object = strdup(aliasName); + uri.type = type; + + TRY_FUNC(UriSetIdStr(&uri.user, context->userId), rc); + TRY_FUNC(UriSetIdStr(&uri.app, context->uid), rc); + TRY_FUNC(EncodeUri(userUri, &uri), rc); + +finally: + CertManagerFreeUri(&uri); + return rc; +} + +static int32_t DirRemove(const char *path) +{ + if (access(path, F_OK) != 0) { + return CMR_ERROR_NOT_EXIST; + } + + struct stat tmp; + if (stat(path, &tmp) != 0) { + return CMR_ERROR_INTERNAL_ERROR; + } + + DIR *dirp; + struct dirent *dire; + if (S_ISDIR(tmp.st_mode)) { + uint32_t i = 0; + dirp = opendir(path); + while ((dire = readdir(dirp)) != NULL)) { + if ((strcmp(dire->d_name, ".") == 0) || (strcmp(dire->d_name, "..") == 0)) { + continue; + } + i++; + } + closedir(path); + + if (i != 0) { + CM_LOG_E("Dir is not empty"); + return CMR_ERROR_INVALID_ARGUMENT; + } + rmdir(path); + return CMR_OK; + } + return CMR_ERROR_INVALID_ARGUMENT; +} + +int32_t CmDirRemove(const char *path) +{ + if (path == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + return DirRemove(path); +} + +int32_t CmGetSubDir(DIR *dirp, struct CmFileDirentInfo *direntInfo) +{ + DIR *dir = (DIR *)dirp; + struct dirent *dire = readdir(dir); + + while (dire != NULL) { + if ((dire->d_type != DT_DIR) || (strcmp(dire->d_name, ".") == 0) || + (strcmp(dire->d_name, "..") == 0)) { + dire = readdir(dir); + continue; + } + + uint32_t dirLen = strlen(dire->d_name); + if (memcpy_s(direntInfo->fileName, sizeof(direntInfo->fileName) - 1, dire->d_name, dirLen) != EOK) { + return CMR_ERROR_BAD_STATE; + } + direntInfo->fileName[dirLen] = '\0'; + return CMR_OK; + } + + return CMR_ERROR_NOT_EXIST; +} + +static RbTreeKey GetRbTreeKey(uint32_t store, char *fn) +{ + uint8_t buff[MAX_NAME_DIGEST_LEN]; + struct CmMutableBlob nameDigest = {sizeof(buff), buff}; + if (store == CM_SYSTEM_TRUSTED_STORE) { + RbTreeKey key = GetRbTreeKeyFromName(fn); + } else { + rc = NameHashFromUri(fn, &nameDigest); + if (rc != CMR_OK) { + return rc; + } + RbTreeKey key = GetRbTreeKeyFromName((char *)nameDigest.data); + } + return key; +} + +int32_t CmSetStatusEnable(const struct CmContext *context, struct CmMutableBlob *pathBlob, + const struct CmBlob *certUri, uint32_t store) +{ + struct CertFile certFile = { 0, 0 }; + certFile.path = &(CM_BLOB(pathBlob)); + certFile.fileName = &(CM_BLOB(certUri)); + + return CertManagerStatusFile(context, certFile, store, CERT_STATUS_ENANLED, NULL); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.h b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.h new file mode 100644 index 0000000..d090ece --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cert_manager_user_trusted_cert.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CERT_MANAGER_H +#define CERT_MANAGER_H + +#include "cert_manager_type.h" +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t BuildUserUri(char **userUri, const char *aliasName, uint32_t type, const struct CmContext *ipcInfo); + +int32_t CmGetCertFilePath(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathBlob); + +int32_t CmRemoveUserCert(struct CmMutableBlob *pathBlob, const struct CmBlob *certUri); + +int32_t CmFreeCertPaths(struct CmMutableBlob *certPaths); + +int32_t CmGetCertPathList(const struct CmContext *context, uint32_t store, struct CmMutableBlob *certPathList); + +int32_t CmRemoveAllUserCert(uint32_t store, const struct CmMutableBlob *certPathList); + +int32_t CmServiceGetCertList(const struct CmContext *context, uint32_t store, struct CmMutableBlob *certFileList); + +int32_t CmGetCertListInfo(const struct CmContext *context, uint32_t store, + const struct CmMutableBlob *certFileList, struct CertBlob *certBlob, uint32_t *status) + +int32_t CmGetServiceCertInfo(const struct CmContext *context, const struct CmBlob *certUri, + uint32_t store, struct CmBlob *certificateData, uint32_t *status); + +int32_t CmDirRemove(const char *path); + +int32_t CmGetSubDir(DIR *dirp, struct CmFileDirentInfo *direntInfo); + +int32_t CmSetStatusEnable(const struct CmContext *ipcInfo, struct CmMutableBlob *pathBlob, + const struct CmBlob *certUri, uint32_t store); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.c b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.c new file mode 100644 index 0000000..e65dc3d --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.c @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_ipc_client_user_trusted_cert.h" +#include "cm_ipc_check.h" + +#include "cm_ipc_serialization.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_x509.h" +#include "cm_param.h" + +#include "cm_request_user_trusted_cert.h" + +static int32_t GetCertListInitBlob(const struct CmBlob *outBlob, struct CertList *certificateList) +{ + uint32_t buffSize; + int32_t ret = CM_SUCCESS; + buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) + sizeof(uint32_t) + + MAX_LEN_URI + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE; + + do { + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + CM_FREE_BLOB(*outBlob); + break; + } + outBlob->size = buffSize; + + buffSize = (MAX_COUNT_CERTIFICATE * sizeof(struct CertAbstract)); + certificateList->certAbstract = (struct CertAbstract *)CmMalloc(buffSize); + if (certificateList->certAbstract == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + CM_FREE_BLOB(*outBlob); + CmFree(certificateList->certAbstract); + break; + } + certificateList->certsCount = MAX_COUNT_CERTIFICATE; + + if (memset_s(certificateList->certAbstract, buffSize, 0, buffSize) != EOK) { + CM_LOG_E("init certAbstract failed"); + ret = CMR_ERROR_BAD_STATE; + CM_FREE_BLOB(*outBlob); + CmFree(certificateList->certAbstract); + break; + } + } while (0); + + return ret; +} + +static int32_t CmSendParcelInit(const struct CmParam *params, uint32_t cnt, + struct CmParamSet *sendParamSet, struct CmBlob *parcelBlob) +{ + int32_t ret = CmParamsToParamSet(params, CM_ARRAY_SIZE(params), &sendParamSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("install CmParamSetPack fail"); + break; + } + + parcelBlob->size = sendParamSet->paramSetSize; + parcelBlob->data = (uint8_t *)sendParamSet; + return ret; +} + +static int32_t GetCertificateList01(enum CmMessage type, const uint32_t store, + struct CertList *certificateList) +{ + struct CmBlob outBlob = {0, NULL}; + struct CmBlob parcelBlob = {0, NULL}; + const struct CmContext context = {0}; + struct CmParamSet *sendParamSet = NULL; + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = store }, + }; + + do { + int32_t ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &sendParamSet, &parcelBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("install CmParamSetPack fail"); + break; + } + + ret = GetCertListInitBlob(&outBlob, certificateList); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertListInitBlob fail"); + break; + } + + ret = SendRequest(type, &parcelBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertList request fail"); + break; + } + + ret = CmCertificateListUnpackFromService(&outBlob, false, &context, certificateList); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertificatetListUnpackFromService fail"); + break; + } + } while (0); + + CmFreeParamSet(&sendParamSet); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientGetCertList01(const uint32_t store, struct CertList *certificateList) +{ + return GetCertificateList01(CM_MSG_GET_CERTIFICATE_LIST, store, certificateList); +} + +static int32_t GetCertInfoInitBlob(struct CmBlob *outBlob, struct CertInfo *certificateInfo) +{ + int32_t ret = CM_SUCCESS; + uint32_t buffSize; + buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t); + + do { + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + CM_FREE_BLOB(*outBlob); + break; + } + outBlob->size = buffSize; + + certificateInfo->certInfo.data = (uint8_t *)CmMalloc(MAX_LEN_CERTIFICATE); + if (certificateInfo->certInfo.data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + CM_FREE_BLOB(*outBlob); + break; + } + certificateInfo->certInfo.size = MAX_LEN_CERTIFICATE; + } while (0); + + return ret; +} + +static int32_t GetCertificateInfo01(enum CmMessage type, const struct CmBlob *certUri, + const uint32_t store, struct CertInfo *certificateInfo) +{ + struct CmBlob outBlob = {0, NULL}; + struct CmBlob parcelBlob = {0, NULL}; + const struct CmContext context = {0}; + struct CmParamSet *sendParamSet = NULL; + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = *certUri }, + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = store }, + }; + + do { + int32_t ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &sendParamSet, &parcelBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("install CmParamSetPack fail"); + break; + } + + ret = GetCertInfoInitBlob(&outBlob, certificateInfo); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertListInitBlob fail"); + break; + } + + ret = SendRequest(type, &parcelBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertList request fail"); + break; + } + + ret = CmCertificateInfoUnpackFromService(&outBlob, &context, certificateInfo, certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertificatetListUnpackFromService fail"); + break; + } + } while (0); + + CmFreeParamSet(&sendParamSet); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientGetCertInfo01(const struct CmBlob *certUri, const uint32_t store, + struct CertInfo *certificateInfo) +{ + return GetCertificateInfo01(CM_MSG_GET_CERTIFICATE_INFO, certUri, store, certificateInfo); +} + +static int32_t SetCertificateStatus01(enum CmMessage type, const struct CmBlob *certUri, + const uint32_t store, const uint32_t status) +{ + struct CmBlob parcelBlob = {0, NULL}; + struct CmParamSet *sendParamSet = NULL; + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = *certUri }, + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = store }, + { .tag = CM_TAG_PARAM1_UINT32, + .uint32Param = status }, + }; + + do { + int32_t ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &sendParamSet, &parcelBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("install CmParamSetPack fail"); + break; + } + + ret = SendRequest(type, &parcelBlob, NULL); + if (ret != CM_SUCCESS) { + CM_LOG_E("SetCertStatus CmParamSet send fail"); + break; + } + } while (0); + + CmFreeParamSet(&sendParamSet); + return ret; +} + +int32_t CmClientSetCertStatus01(const struct CmBlob *certUri, const uint32_t store, + const uint32_t status) +{ + return SetCertificateStatus01(CM_MSG_SET_CERTIFICATE_STATUS, certUri, store, status); +} + +static int32_t InstallUserCertInitBlob(struct CmBlob *outBlob, struct CmBlob *certUri) +{ + int32_t ret = CM_SUCCESS; + uint32_t buffSize; + + do { + buffSize = sizeof(uint32_t) + MAX_LEN_URI; + outBlob->data = (uint8_t *)CmMalloc(buffSize); + if (outBlob->data == NULL) { + CM_LOG_E("InstallUserCert malloc OutBlob fail"); + ret = CMR_ERROR_MALLOC_FAIL; + break; + } + outBlob->size = buffsize; + + certUri->data = (uint8_t *)CMMalloc(MAX_LEN_URI); + if (certUri->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + CM_LOG_E("InstallUserCert malloc certUri fail"); + break; + } + certUri->size = MAX_LEN_URI; + if (memset_s(certUri->data, MAX_LEN_URI, 0, MAX_LEN_URI) != EOK) { + CM_LOG_E("init certUri fail"); + ret = CMR_ERROR_BAD_STATE; + break; + } + } while (0); + if (certUri->data != NULL) { + CM_FREE_BLOB(certUri); + } + return ret; +} + +int32_t CmInstallUserCertUnpackFromService(const struct CmBlob *outData, + struct CmBlob *certUri) +{ + uint32_t offset = 0; + struct CmBlob blob; + if ((outData == NULL) || (certUri == NULL) || (outData->data == NULL) || + (certUri->data == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = CmGetBlobFromBuffer(&blob, outData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmInstallUserCert get certUri faild"); + return ret; + } + certUri->size = blob.size; + if (memcpy_s(certUri->data, MAX_LEN_URI, blob.data, blob.size) != EOK) { + CM_LOG_E("copy certuri failed"); + return CMR_ERROR_BAD_STATE; + } + + return CM_SUCCESS; +} + +static int32_t InstallUserCert(enum CmMessage type, const struct CmBlob *userCert, const struct CmBlob *certAlias, + struct CmBlob *certUri) +{ + struct CmBlob parcelBlob = {0, NULL}; + struct CmParamSet *sendParamSet = NULL; + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = *userCert }, + { .tag = CM_TAG_PARAM1_BUFFER, + .blob = *certAlias }, + }; + struct CmBlob outBlob = {0, NULL}; + + do { + int32_t ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &sendParamSet, &parcelBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("install CmParamSetPack fail"); + break; + } + + ret = InstallUserCertInitBlob(&outBlob, certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("init blob fail"); + break; + } + + ret = SendRequest(type, &parcelBlob, &outBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("install CmParamSet send fail"); + break; + } + + ret = CmInstallUserCertUnpackFromService(&outBlob, certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmInstallUserCertUnpackFromService fail"); + break; + } + } while (0); + CmFreeParamSet(&sendParamSet); + CM_FREE_BLOB(outBlob); + return ret; +} + +int32_t CmClientInstallUserTrustedCert(const struct CmBlob *userCert, const struct CmBlob *certAlias, + struct CmBlob *certUri) +{ + return InstallUserCert(CM_MSG_INSTALL_USER_CERTIFICATE, userCert, certAlias, certUri); +} + +static int32_t UninstallUserCert(enum CmMessage type, const struct CmBlob *certUri) +{ + struct CmParamSet *sendParamSet = NULL; + struct CmParam params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = *certUri }, + }; + struct CmBlob parcelBlob = {0, NULL}; + + do { + int32_t ret = CmSendParcelInit(params, CM_ARRAY_SIZE(params), &sendParamSet, &parcelBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("install CmParamSetPack fail"); + break; + } + + ret = SendRequest(type, &parcelBlob, NULL); + if (ret != CM_SUCCESS) { + CM_LOG_E("uninstall CmParamSet send fail"); + break; + } + } while (0); + CmFreeParamSet(&sendParamSet); + return ret; +} + +int32_t CmClientUninstallUserTrustedCert(const struct CmBlob *certUri) +{ + return UninstallUserCert(CM_MSG_UNINSTALL_USER_CERTIFICATE, certUri); +} + +static int32_t UninstallAllUserCert(enum CmMessage type) +{ + struct CmParamSet *sendParamSet = NULL; + struct CmBlob parcelBlob = { + .size = sendParamSet->paramSetSize, + .data = (uint8_t *)sendParamSet + }; + + ret = SendRequest(type, &parcelBlob, NULL); + if (ret != CM_SUCCESS) { + CM_LOG_E("uninstall all CmParamSet send fail"); + break; + } + CmFreeParamSet(&sendParamSet); + return ret; +} + +int32_t CmClientUninstallAllUserTrustedCert(void) +{ + return UninstallAllUserCert(CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE); +} diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.h b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.h new file mode 100644 index 0000000..62eb359 --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_client_user_trusted_cert.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_CLIENT_IPC_H +#define CM_CLIENT_IPC_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int32_t CmClientGetCertList01(const uint32_t store, struct CertList *certificateList); + +int32_t CmClientGetCertInfo01(const struct CmBlob *certUri, const uint32_t store, + struct CertInfo *certificateInfo); + +int32_t CmClientSetCertStatus01(const struct CmBlob *certUri, const uint32_t store, + const uint32_t status); + +int32_t CmClientInstallUserTrustedCert(const struct CmBlob *userCert, const struct CmBlob *certAlias, + struct CmBlob *certUri); + +int32_t CmClientUninstallUserTrustedCert(const struct CmBlob *certUri); + +int32_t CmClientUninstallAllUserTrustedCert(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CM_CLIENT_IPC_H */ diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.c b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.c new file mode 100644 index 0000000..fb41732 --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.c @@ -0,0 +1,589 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_ipc_service_user_trusted_cert.h" + +static int32_t CmMallocCertInfo01(struct CertBlob *certInfoBlob) +{ + uint32_t i; + + if (certInfoBlob == NULL) { + return CMR_INVALID_ARGUMENT; + } + + for (i = 0; i < MAX_COUNT_CERTIFICATE; i++) { + certInfoBlob->uri[i].size = MAX_LEN_CERTIFICATE; + certInfoBlob->uri[i].data = (uint8_t *)CmMalloc(MAX_LEN_URI); + if (certInfoBlob->uri[i].data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + ASSERT_FUNC(memset_s(certInfoBlob->uri[i].data, MAX_LEN_URI, 0, MAX_LEN_URI)); + + certInfoBlob->subjectName[i].size = MAX_LEN_CERTIFICATE; + certInfoBlob->subjectName[i].data = (uint8_t *)CmMalloc(MAX_LEN_SUBJECT_NAME); + if (certInfoBlob->subjectName[i].data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + ASSERT_FUNC(memset_s(certInfoBlob->subjectName[i].data, MAX_LEN_SUBJECT_NAME, 0, MAX_LEN_SUBJECT_NAME)); + + certInfoBlob->certAlias[i].size = MAX_LEN_CERTIFICATE; + certInfoBlob->certAlias[i].data = (uint8_t *)CmMalloc(MAX_LEN_CERT_ALIAS); + if (certInfoBlob->certAlias[i].data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + ASSERT_FUNC(memset_s(certInfoBlob->certAlias[i].data, MAX_LEN_CERT_ALIAS, 0, MAX_LEN_CERT_ALIAS)); + } + return CM_SUCCESS; +} + +static int32_t CmServiceGetCertListPack01(const struct CmContext *context, uint32_t store, + const struct CmMutableBlob *certFileList, struct CmBlob *certificateList) +{ + int32_t ret = CM_SUCCESS; + uint32_t offset = 0; + uint32_t buffSize; + uint32_t status[MAX_COUNT_CERTIFICATE] = {0}; + struct CertBlob certBlob; + + ret = CmGetCertListInfo(context, store, certFileList, &certBlob, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetCertListInfo fail"); + return ret; + } + + /* buff struct: cert count + (cert subjectname + cert status + cert uri + cert alias) * MAX_CERT_COUNT */ + buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) + sizeof(uint32_t) + + MAX_LEN_URI + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE; + certificateList->data = (uint8_t *)CmMalloc(buffSize); + if (certificateList->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + return ret; + } + certificateList->size = buffSize; + + ret = CopyUint32ToBuffer(certFileList->size, certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy cert count failed"); + return ret; + } + + for (uint32_t i = 0; i < certFileList->size; i++) { + ret = CopyBlobToBuffer(&(certBlob->subjectName[i]), certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate subject failed"); + return ret; + } + ret = CopyUint32ToBuffer(status[i], certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate status failed"); + return ret; + } + ret = CopyBlobToBuffer(&(certBlob->uri[i]), certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate uri failed"); + return ret; + } + ret = CopyBlobToBuffer(&(certBlob->certAlias[i]), certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate certAlias failed"); + return ret; + } + } + return ret; +} + +static int32_t CmParsesInputParcel(const struct CmBlob *paramSetBlob, const struct CmParam *params, + struct CmContext *cmContext) +{ + struct CmParamSet *paramSet = NULL; + + do { + int ret = CmGetParamSet((struct CmParamSet *)paramSetBlob->data, paramSetBlob->size, ¶mSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertList CmGetParamSet fail, ret = %d", ret); + break; + } + + ret = CmParamSetToParams(paramSet, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertList CmParamSetToParams fail, ret = %d", ret); + break; + } + + ret = CmGetProcessInfoForIPC(cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetProcessInfoForIPC fail, ret = %d", ret); + break; + } + } while (0); + CmFreeParamSet(¶mSet); + return ret; +} + +void CmIpcServiceGetCertificateList01(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply) +{ + uint32_t store; + (void)outData; + struct CmContext cmContext = {0}; + struct CmBlob certificateList = { 0, NULL }; + struct CmMutableBlob certFileList = { 0, NULL }; + struct CmParamOut params[] = { + { + .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = &store + }, + }; + + do { + int ret = CmParsesInputParcel(paramSetBlob, params, &cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertList CmParsesParcel fail, ret = %d", ret); + break; + } + + ret = CmServiceGetCertList(&cmContext, store, &certFileList); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertList fail, ret = %d", ret); + break; + } + + ret = CmServiceGetCertListPack01(&cmContext, store, &certFileList, &certificateList); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmServiceGetCertListPack pack fail, ret = %d", ret); + break; + } + + CmSendResponse(contextReply, ret, &certificateList); + } while (0); + if (ret != CM_SUCCESS) { + CmSendResponse(contextReply, ret, NULL); + } + CM_FREE_BLOB(certificateList); + CM_FREE_BLOB(certFileList); +} + +static int32_t CmServiceGetCertInfoPack(const struct CmBlob *certificateData, uint32_t status, + struct CmBlob *certificateInfo) +{ + int32_t retVal = CM_SUCCESS; + uint32_t offset = 0; + uint32_t buffSize; + + const struct CmBlob *tempBlob = &(((const struct CmBlob *)certificateData->data)[0]); + + /* buff struct: cert len + cert data + cert staus */ + buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t); + certificateInfo->data = (uint8_t *)CmMalloc(buffSize); + if (certificateInfo->data == NULL) { + retVal = CMR_ERROR_MALLOC_FAIL; + return retVal; + } + certificateInfo->size = buffSize; + + retVal = CopyBlobToBuffer(tempBlob, certificateInfo, &offset); + if (retVal != CM_SUCCESS) { + CM_LOG_E("copy certificateInfo failed"); + return retVal; + } + + retVal = CopyUint32ToBuffer(status, certificateInfo, &offset); + if (retVal != CM_SUCCESS) { + CM_LOG_E("Copy certificate count failed"); + return retVal; + } + + return retVal; +} + +void CmIpcServiceGetCertificateInfo01(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply) +{ + (void)outData; + uint32_t store; + uint32_t status = 0; + struct CmBlob certUri = { 0, NULL }; + struct CmBlob certificateData = { 0, NULL }; + struct CmBlob certificateInfo = { 0, NULL }; + struct CmContext cmContext = {0}; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = &certUri}, + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = &store}, + }; + + do { + int ret = CmParsesInputParcel(paramSetBlob, params, &cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertInfo CmParsesParcel fail, ret = %d", ret); + break; + } + + ret = CmGetServiceCertInfo(&cmContext, &certUri, store, &certificateData, &status); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertInfo fail, ret = %d", ret); + break; + } + + ret = CmServiceGetCertInfoPack(&certificateData, status, &certificateInfo); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmServiceGetCertInfoPack pack fail, ret = %d", ret); + break; + } + CmSendResponse(contextReply, ret, &certificateInfo); + } while (0); + if (ret != CM_SUCCESS) { + CmSendResponse(contextReply, ret, NULL); + } + CM_FREE_BLOB(certificateInfo); + CM_FREE_BLOB(certificateData); +} + +void CmIpcServiceSetCertStatus01(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply) +{ + (void)outData; + uint32_t store; + uint32_t status; + struct CmBlob certUri = { 0, NULL }; + struct CmContext cmContext = {0}; + struct CmParamOut params[] = { + { .tag = CM_TAG_PARAM0_BUFFER, + .blob = &certUri}, + { .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = &store}, + { .tag = CM_TAG_PARAM1_UINT32, + .uint32Param = &status}, + }; + + do { + int ret = CmParsesInputParcel(paramSetBlob, params, &cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("SetCertStatus CmParsesParcel fail, ret = %d", ret); + break; + } + + ret = CertManagerSetCertificatesStatus(&cmContext, certUri, store, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("set cert status fail, ret = %d", ret); + break; + } + } while (0); + CmSendResponse(contextReply, ret, NULL); +} + +static int32_t CmWriteUserCert(const struct CmContext *context, struct CmMutableBlob *pathBlob, + const struct CmBlob *userCert, const struct CmBlob *certAlias, struct CmBlob *certUri) +{ + int32_t ret = CM_SUCCESS; + char *userUri = NULL; + + do { + ret = BuildUserUri(&userUri, (char *)certAlias->data, CM_URI_TYPE_CERTIFICATE, context); + if (ret != CM_SUCCESS || userUri == NULL) { + CM_LOG_E("BuildUserUri failed"); + break; + } + + certUri->data = (uint8_t *)CMMalloc(MAX_LEN_URI); + if (certUri->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + break; + } + if (memset_s(certUri->data, MAX_LEN_URI, 0, MAX_LEN_URI) != EOK) { + ret = CMR_ERROR; + break; + } + certUri->size = (uint32_t)strlen(userUri) + 1; + if (memcpy_s(certUri->data, MAX_LEN_URI, (uint8_t *)userUri, certUri->size) != EOK) { + ret = CMR_ERROR; + break; + } + + if (CmFileWrite((char*)pathBlob.data, userUri, 0, userCert->data, userCert->size) != CMR_OK) { + CM_LOG_E("Failed to write certificate: %s in to %s", certAlias->data, pathBlob.data); + ret = CMR_FILE_WRITE_ERROR; + break; + } + } while (0); + + if (userUri != NULL) { + CmFree(userUri); + } + return ret; +} + +static int32_t CmCheckCallerPermission(const struct CmContext *ipcInfo) +{ + (void)ipcInfo; + + return CM_SUCCESS; +} + +static int32_t CmInstallUserCert(const struct CmContext *context, const struct CmBlob *userCert, + const struct CmBlob *certAlias, struct CmBlob *certUri) +{ + int32_t ret = CM_SUCCESS; + uint8_t pathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob pathBlob = { sizeof(pathBuf), pathBuf }; + uint32_t store = CM_USER_TRUSTED_STORE; + + do { + ret = CmCheckCallerPermission(context); + if (ret != CM_SUCCESS) { + CM_LOG_E("Check caller permission fail"); + break; + } + + X509 *userCertX509 = InitCertContext(userCert->data, userCert->size); + if (userCertX509 == NULL) { + CM_LOG_E("Parse X509 cert fail"); + ret = CM_FAILURE; + break; + } + + ret = CmGetCertFilePath(context, store, &pathBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed obtain path for store:%d path:%s", store, pathBuf); + break; + } + + ret = CmWriteUserCert(context, &pathBlob, userCert, certAlias, certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertManagerWriteUserCert fail"); + ret = CM_FAILURE; + break; + } + + ret = CmSetStatusEnable(context, &pathBlob, certUri, store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertManagerUpdateStatusFile fail"); + ret = CM_FAILURE; + break; + } + } while (0); + + if (userCertX509 != NULL) { + FreeCertContext(userCertX509); + } + return ret; +} + +void CmIpcServiceInstallUserCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply) +{ + (void)outData; + struct CmBlob userCert = { 0, NULL }; + struct CmBlob certAlias = { 0, NULL }; + struct CmBlob certUri = { 0, NULL }; + struct CmContext cmContext = {0}; + struct CmParamOut params[] = { + { + .tag = CM_TAG_PARAM0_BUFFER, + .blob = &userCert + }, { + .tag = CM_TAG_PARAM1_BUFFER, + .blob = &certAlias + }, + }; + + do { + int ret = CmParsesInputParcel(paramSetBlob, params, &cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("InstallUserCert CmParsesParcel fail, ret = %d", ret); + break; + } + + ret = CmInstallUserCert(&cmContext, &userCert, &certAlias, &certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertManagerInstallUserCert fail, ret = %d", ret); + } + + CmSendResponse(contextReply, ret, &certUri); + } while (0); + + if (ret != CM_SUCCESS) { + CmSendResponse(contextReply, ret, NULL); + } + CM_FREE_BLOB(certUri); +} + +static int32_t CmComparisonCallerIdWithUri(const struct CmContext *context, + const struct CmBlob *certUri) +{ + uint32_t useridObj; + uint32_t uidObj; + struct CMUri uriObj; + (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj)); + + int32_t ret = CertManagerUriDecode(&uriObj, (char *)uri->data); + if (ret != CM_SUCCESS) { + CM_LOG_E("uri decode failed, ret = %d", ret); + return ret; + } + + if (uriObj.user == NULL) { + CM_LOG_E("uri user invalid"); + (void)CertManagerFreeUri(&uriObj); + return CMR_ERROR_INVALID_ARGUMENT; + } + useridObj = atoi(uriObj.user); + + if (uriObj.app == NULL) { + CM_LOG_E("uri app invalid"); + (void)CertManagerFreeUri(&uriObj); + return CMR_ERROR_INVALID_ARGUMENT; + } + uidObj = atoi(uriObj.app); + if ((context->userId == useridObj) && (context->uid == uidObj)) { + ret = CM_SUCCESS; + } else { + (void)CertManagerFreeUri(&uriObj); + return CMR_ERROR_INVALID_ARGUMENT; + } + + (void)CertManagerFreeUri(&uriObj); + return ret; +} + +static int32_t CmUninstallUserCert(const struct CmContext *context, const struct CmBlob *certUri) +{ + int32_t ret = CM_SUCCESS; + ASSERT_ARGS(context && certUri && certUri->data && certUri->size); + uint8_t pathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob pathBlob = { sizeof(pathBuf), pathBuf }; + uint32_t store = CM_USER_TRUSTED_STORE; + + do { + ret = CmCheckCallerPermission(&context); + if (ret != CM_SUCCESS) { + CM_LOG_E("Caller haven't permission, ret = %d", ret); + break; + } + + ret = CmComparisonCallerIdWithUri(&context, certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CallerId don't match uri, ret = %d", ret); + break; + } + + ret = CmGetCertFilePath(context, store, &pathBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed obtain path for store %d", store); + break; + } + + ret = CmRemoveUserCert(&pathBlob, certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("RemoveUserCertFile fail, ret = %d", ret); + break; + } + + ret = CmSetStatusEnable(context, &pathBlob, certUri, store); + if (ret != CM_SUCCESS) { + CM_LOG_E("UpdateStatusFile fail, ret = %d", ret); + break; + } + } while (0); + + return ret; +} + +void CmIpcServiceUninstallUserCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply) +{ + (void)outData; + struct CmBlob certUri = { 0, NULL }; + struct CmContext cmContext = {0}; + struct CmParamOut params[] = { + { + .tag = CM_TAG_PARAM0_BUFFER, + .blob = &certUri + }, + }; + + do { + int ret = CmParsesInputParcel(paramSetBlob, params, &cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("UninstallUserCert CmParsesParcel fail, ret = %d", ret); + break; + } + + ret = CmUninstallUserCert(&cmContext, &certUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertManagerUninstallUserCert fail, ret = %d", ret); + break; + } + } while (0); + + CmSendResponse(contextReply, ret, NULL); +} + +static int32_t CmUninstallAllUserCert(const struct CmContext *context) +{ + int32_t ret = CM_SUCCESS; + uint32_t store = CERT_MANAGER_USER_TRUSTED_STORE; + struct CmMutableBlob certPathList = { 0, NULL }; + + do { + ret = CmCheckCallerPermission(context); + if (ret != CM_SUCCESS) { + CM_LOG_E("Caller haven't permission, ret = %d", ret); + break; + } + + ret = CmGetCertPathList(context, store, &certPathList); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetCertPathList fail, ret = %d", ret); + (void)CmFreeCertPaths(&certPathList); + break; + } + + ret = CmRemoveAllUserCert(context, store, &certPathList); + if (ret != CM_SUCCESS) { + CM_LOG_E("RemoveAllUserCert fail, ret = %d", ret); + (void)CmFreeCertPaths(&certPathList); + break; + } + } while (0); + if (uidPathList.data != NULL) { + (void)CmFreeCertPaths(&certPathList); + } + return ret; +} + +void CmIpcServiceUninstallAllUserCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply) +{ + (void)outData; + struct CmContext cmContext = {0}; + + do { + int32_t ret = CmGetProcessInfoForIPC(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetProcessInfoForIPC fail, ret = %d", ret); + break; + } + + ret = CmUninstallAllUserCert(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertManagerUninstallAllUserCert fail, ret = %d", ret); + break; + } + } while (0); + + CmSendResponse(contextReply, ret, NULL); +} diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.h b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.h new file mode 100644 index 0000000..9f81cd4 --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_ipc_service_user_trusted_cert.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_IPC_SERVICE_H +#define CM_IPC_SERVICE_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void CmIpcServiceGetCertificateList01(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply); + +void CmIpcServiceGetCertificateInfo01(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply); + +void CmIpcServiceSetCertStatus01(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply); + +void CmIpcServiceInstallUserCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply); + +void CmIpcServiceUninstallUserCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply); + +void CmIpcServiceUninstallAllUserCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *contextReply); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/frameworks/cert_manager_standard/main/user_trusted_cert/cm_sa_user_trusted_cert.cpp b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_sa_user_trusted_cert.cpp new file mode 100644 index 0000000..31b1ffb --- /dev/null +++ b/frameworks/cert_manager_standard/main/user_trusted_cert/cm_sa_user_trusted_cert.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_sa.h" + +enum CmMessage { + CM_MSG_INSTALL_USER_CERTIFICATE, + CM_MSG_UNINSTALL_USER_CERTIFICATE, + CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE, +}; + +static struct CmIpcPoint g_cmIpcHandler[] = { + { CM_MSG_INSTALL_USER_CERTIFICATE, CmIpcServiceInstallUserCert }, + { CM_MSG_UNINSTALL_USER_CERTIFICATE, CmIpcServiceUninstallUserCert }, + { CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE, CmIpcServiceUninstallAllUserCert }, + { CM_MSG_GET_CERTIFICATE_LIST, CmIpcServiceGetCertificateList01 }, + { CM_MSG_GET_CERTIFICATE_INFO, CmIpcServiceGetCertificateInfo01 }, + { CM_MSG_SET_CERTIFICATE_STATUS, CmIpcServiceSetCertStatus01 }, +}; + diff --git a/interfaces/innerkits/cert_manager_standard/main/BUILD.gn b/interfaces/innerkits/cert_manager_standard/main/BUILD.gn new file mode 100644 index 0000000..3264a8e --- /dev/null +++ b/interfaces/innerkits/cert_manager_standard/main/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("cert_manager_config") { + include_dirs = [ "include" ] +} + +if (os_level == "standard") { + ohos_shared_library("cert_manager_sdk") { + subsystem_name = "security" + part_name = "certificate_manager" + public_configs = [ ":cert_manager_config" ] + defines = [ + "L2_STANDARD", + "_HARDWARE_ROOT_KEY_", + "_CM_LOG_ENABLE_", + ] + include_dirs = [ + "//base/security/certificate_manager/utils/cm_crypto_adapter", + "//commonlibrary/c_utils/base/include", + ] + + sources = [ "src/cert_manager_api.c" ] + + cflags = [ + "-DHILOG_ENABLE", + "-Wall", + "-Werror", + ] + deps = [ "//base/security/certificate_manager/frameworks/cert_manager_standard/main:cert_manager_standard_frameworks" ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } +} +#if (os_level == "small" || os_level == "mini") { +# group("libcert_managersdk") { +# } +#} diff --git a/interfaces/innerkits/cert_manager_standard/main/include/cert_manager_api.h b/interfaces/innerkits/cert_manager_standard/main/include/cert_manager_api.h new file mode 100644 index 0000000..d7e88b0 --- /dev/null +++ b/interfaces/innerkits/cert_manager_standard/main/include/cert_manager_api.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANGAGER_API_H +#define CERT_MANGAGER_API_H + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +CM_API_EXPORT int32_t CmGetCertList(const struct CmContext *cmContext, uint32_t store, + struct CertList *certificateList); + +CM_API_EXPORT int32_t CmGetCertInfo(const struct CmContext *cmContext, const struct CmBlob *certUri, + uint32_t store, struct CertInfo *certificateInfo); + +CM_API_EXPORT int32_t CmSetCertStatus(const struct CmContext *cmContext, const struct CmBlob *certUri, + uint32_t store, const bool status); + +CM_API_EXPORT int32_t CmInstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd, + const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri); + +CM_API_EXPORT int32_t CmUninstallAppCert(const struct CmBlob *keyUri, const uint32_t store); + +CM_API_EXPORT int32_t CmUninstallAllAppCert(); + +CM_API_EXPORT int32_t CmGetAppCertList(const uint32_t store, struct CredentialList *certificateList); + +CM_API_EXPORT int32_t CmGetAppCert(const struct CmBlob *keyUri, const uint32_t store, struct Credential *certificate); + +#ifdef __cplusplus +} +#endif + +#endif /* CERT_MANGAGER_API_H */ \ No newline at end of file diff --git a/interfaces/innerkits/cert_manager_standard/main/src/cert_manager_api.c b/interfaces/innerkits/cert_manager_standard/main/src/cert_manager_api.c new file mode 100644 index 0000000..1369be0 --- /dev/null +++ b/interfaces/innerkits/cert_manager_standard/main/src/cert_manager_api.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef CM_CONFIG_FILE +#include CM_CONFIG_FILE +#else +#include "cm_config.h" +#endif + +#include "cert_manager_api.h" +#include "cm_client_ipc.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" + +#include "cm_request.h" + +CM_API_EXPORT int32_t CmGetCertList(const struct CmContext *cmContext, const uint32_t store, + struct CertList *certificateList) +{ + CM_LOG_I("enter get certificate list"); + if ((cmContext == NULL) || (certificateList == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = CmClientGetCertList(cmContext, store, certificateList); + CM_LOG_I("leave get certificate list, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmGetCertInfo(const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store, struct CertInfo *certificateInfo) +{ + CM_LOG_I("enter get certificate info"); + if ((cmContext == NULL) || (certUri == NULL) || (certificateInfo == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + int32_t ret = CmClientGetCertInfo(cmContext, certUri, store, certificateInfo); + CM_LOG_I("leave get certificate info, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmSetCertStatus(const struct CmContext *cmContext, const struct CmBlob *certUri, + const uint32_t store, const bool status) +{ + CM_LOG_I("enter set certificate status"); + if ((cmContext == NULL) || (certUri == NULL)) { + return CMR_ERROR_NULL_POINTER; + } + + uint32_t uStatus = status ? 0: 1; // 0 indicates the certificate enabled status + + int32_t ret = CmClientSetCertStatus(cmContext, certUri, store, uStatus); + CM_LOG_I("leave set certificate status, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmInstallAppCert(const struct CmBlob *appCert, const struct CmBlob *appCertPwd, + const struct CmBlob *certAlias, const uint32_t store, struct CmBlob *keyUri) +{ + CM_LOG_I("enter install app certificate"); + if (appCert == NULL || appCertPwd == NULL || certAlias == NULL || + keyUri == NULL || keyUri->data == NULL || (store != CM_CREDENTIAL_STORE && + store != CM_PRI_CREDENTIAL_STORE)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientInstallAppCert(appCert, appCertPwd, certAlias, store, keyUri); + CM_LOG_I("leave install app certificate, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmUninstallAppCert(const struct CmBlob *keyUri, const uint32_t store) +{ + CM_LOG_I("enter uninstall app certificate"); + if (keyUri == NULL || (store != CM_CREDENTIAL_STORE && + store != CM_PRI_CREDENTIAL_STORE)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientUninstallAppCert(keyUri, store); + CM_LOG_I("leave uninstall app certificate, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmUninstallAllAppCert(void) +{ + CM_LOG_I("enter uninstall all app certificate"); + + int32_t ret = CmClientUninstallAllAppCert(CM_MSG_UNINSTALL_ALL_APP_CERTIFICATE); + + CM_LOG_I("leave uninstall all app certificate, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmGetAppCertList(const uint32_t store, struct CredentialList *certificateList) +{ + CM_LOG_I("enter get app certificatelist"); + if (certificateList == NULL || (store != CM_CREDENTIAL_STORE && + store != CM_PRI_CREDENTIAL_STORE)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientGetAppCertList(store, certificateList); + CM_LOG_I("leave get app certificatelist, result = %d", ret); + return ret; +} + +CM_API_EXPORT int32_t CmGetAppCert(const struct CmBlob *keyUri, const uint32_t store, + struct Credential *certificate) +{ + CM_LOG_I("enter get app certificate"); + if (keyUri == NULL || certificate == NULL || (store != CM_CREDENTIAL_STORE && + store != CM_PRI_CREDENTIAL_STORE)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = CmClientGetAppCert(keyUri, store, certificate); + CM_LOG_I("leave get app certificate, result = %d", ret); + return ret; +} \ No newline at end of file diff --git a/interfaces/kits/js/@ohos.security.certManager.d.ts b/interfaces/kits/js/@ohos.security.certManager.d.ts new file mode 100644 index 0000000..f7127bd --- /dev/null +++ b/interfaces/kits/js/@ohos.security.certManager.d.ts @@ -0,0 +1,437 @@ +/* +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import {AsyncCallback} from './basic'; + +/** + * OpenHarmony Universal CertManager + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @permission N/A + */ +declare namespace certManager { + /** + * Get a list of system root certificates. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + */ + function getSystemTrustedCertificateList(context: CMContext, callback: AsyncCallback) : void; + function getSystemTrustedCertificateList(context: CMContext) : Promise; + + /** + * Get the detail of system root certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param certUri Indicates the certificate's name. + */ + function getSystemTrustedCertificate(context: CMContext, certUri: string, callback: AsyncCallback) : void; + function getSystemTrustedCertificate(context: CMContext, certUri: string) : Promise; + + /** + * Set the status of root certificates. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param certUri Indicates the certificate's name. + * @param store Indicates the type of certificate. + * @param context Indicates the context of the calling interface application. + * @param status Indicates the status of certificate to be set. + */ + function setCertificateStatus(context: CMContext, certUri: string, store: number, status: boolean, callback: AsyncCallback) : void; + function setCertificateStatus(context: CMContext, certUri: string, store: number, status: boolean) : Promise; + + /** + * Install the user root certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param certificate Indicates the certificate file. + */ + function installUserTrustedCertificate(context: CMContext, certificate: CMBlob, callback: AsyncCallback) : void; + function installUserTrustedCertificate(context: CMContext, certificate: CMBlob,) : Promise; + + /** + * Uninstall all user root certificates. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + */ + function uninstallAllUserTrustedCertificate(context: CMContext, callback: AsyncCallback) : void; + function uninstallAllUserTrustedCertificate(context: CMContext) : Promise; + + /** + * Uninstall the specified user root certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param certUri Indicates the certificate's name. + */ + function uninstallUserTrustedCertificate(context: CMContext, certUri: string, callback: AsyncCallback) : void; + function uninstallUserTrustedCertificate(context: CMContext, certUri: string) : Promise; + + /** + * Get a list of user root certificates. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + */ + function getUserTrustedCertificateList(context: CMContext, callback: AsyncCallback) : void; + function getUserTrustedCertificateList(context: CMContext) : Promise; + + /** + * Get the detail of user root certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param certUri Indicates the certificate's name. + */ + function getUserTrustedCertificate(context: CMContext, certUri: string, callback: AsyncCallback) : void; + function getUserTrustedCertificate(context: CMContext, certUri: string) : Promise; + + /** + * Install normal application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keystore Indicates the keystore file with key pair and certificate. + * @param keystorePwd Indicates the password of keystore file. + * @param certAlias Indicates the certificate name inputted by the user. + * @param keyProperties Indicates the properties of keys in keystore file. + */ + function installAppCertificate(context: CMContext, keystore: CMBlob, keystorePwd: string, certAlias: string, keyProperties: CMKeyProperties, callback: AsyncCallback) : void; + function installAppCertificate(context: CMContext, keystore: CMBlob, keystorePwd: string, certAlias: string, keyProperties: CMKeyProperties) : Promise; + + /** + * Install private application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keystore Indicates the keystore file with key pair and certificate. + * @param keystorePwd Indicates the password of keystore file. + * @param certAlias Indicates the certificate name inputted by the user. + * @param keyProperties Indicates the properties of keys in keystore file. + */ + function installPrivateCertificate(context: CMContext, keystore: CMBlob, keystorePwd: string, certAlias: string, keyProperties: CMKeyProperties, callback: AsyncCallback) : void; + function installPrivateCertificate(context: CMContext, keystore: CMBlob, keystorePwd: string, certAlias: string, keyProperties: CMKeyProperties) : Promise; + + /** + * Generate private application certificate locally. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyAlias Indicates the key alias inputted by the user. + * @param keyProperties Indicates the properties of keys in keystore file. + */ + function generatePrivateCertificate(context: CMContext, keyAlias: string, keyProperties: CMKeyProperties, callback: AsyncCallback) : void; + function generatePrivateCertificate(context: CMContext, keyAlias: string, keyProperties: CMKeyProperties) : Promise; + + /** + * Update private application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param type Indicates the type of the certificate used. + * @param keyUri Indicates key's name. + * @param certificate Indicates the certificate file. + */ + function updatePrivateCertificate(context: CMContext, type: string, keyUri: string, certificate: CMBlob, callback: AsyncCallback) : void; + function updatePrivateCertificate(context: CMContext, type: string, keyUri: string, certificate: CMBlob) : Promise; + + /** + * Uninstall all application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + */ + function uninstallAllAppCertificate(context: CMContext, callback: AsyncCallback) : void; + function uninstallAllAppCertificate(context: CMContext) : Promise; + + /** + * Uninstall the specified normal application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + */ + function uninstallAppCertificate(context: CMContext, keyUri: string, callback: AsyncCallback) : void; + function uninstallAppCertificate(context: CMContext, keyUri: string) : Promise; + + /** + * Uninstall the specified normal application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + */ + function uninstallPrivateCertificate(context: CMContext, keyUri: string, callback: AsyncCallback) : void; + function uninstallPrivateCertificate(context: CMContext, keyUri: string) : Promise; + + /** + * Get a list of normal application certificates. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + */ + function getAppCertificateList(context: CMContext, callback: AsyncCallback) : void; + function getAppCertificateList(context: CMContext) : Promise; + + /** + * Get a list of private application certificates. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + */ + function getPrivateCertificateList(context: CMContext, callback: AsyncCallback) : void; + function getPrivateCertificateList(context: CMContext) : Promise; + + /** + * Get the detail of normal application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + */ + function getAppCertificate(context: CMContext, keyUri: string, callback: AsyncCallback) : void; + function getAppCertificate(context: CMContext, keyUri: string, ) : Promise; + + /** + * Get the detail of private application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + */ + function getPrivateCertificate(context: CMContext, keyUri: string, callback: AsyncCallback) : void; + function getPrivateCertificate(context: CMContext, keyUri: string) : Promise; + + /** + * Authorize the specified application certificate for the specified application. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + * @param clientApp Indicates the context of the authorized application. + */ + function grantAppCertificate(context: CMContext, keyUri: string, clientApp: CMContext, callback: AsyncCallback) : void; + function grantAppCertificate(context: CMContext, keyUri: string, clientApp: CMContext) : Promise; + + /** + * Whether the current application is authorized by the specified application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + */ + function isAuthorizedApp(context: CMContext, keyUri: string, callback: AsyncCallback) : void; + function isAuthorizedApp(context: CMContext, keyUri: string) : Promise; + + /** + * Get the list of applications authorized by the specified certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + */ + function getAuthorizedAppList(context: CMContext, keyUri: string, callback: AsyncCallback) : void; + function getAuthorizedAppList(context: CMContext, keyUri: string) : Promise; + + /** + * Deauthorize the specified application from the specified application certificate. + * @since 9 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param keyUri Indicates key's name. + * @param clientApp Indicates the context of the deauthorized application. + */ + function removeGrantAppCertificate(context: CMContext, keyUri: string, clientApp: CMContext, callback: AsyncCallback) : void; + function removeGrantAppCertificate(context: CMContext, keyUri: string, clientApp: CMContext) : Promise; + + /** + * Init Operation. + * @since 8 + * @syscap SystemCapability.Security.CertManager + * @param context Indicates the context of the calling interface application. + * @param authUri Indicates the authorization relationship between application and application certificate. + * @param spec Indicates the properties of the signature and verification.. + * @return The handle of the init Operation. + */ + function init(context: CMContext, authUri: string, spec: CMSignatureSpec, callback: AsyncCallback) : void; + function init(context: CMContext, authUri: string, spec: CMSignatureSpec) : Promise; + + /** + * Update Operation. + * @since 8 + * @syscap SystemCapability.Security.Huks + * @param context Indicates the context of the calling interface application. + * @param handle Indicates the handle of the init operation. + * @param data Indicates the input value. + * @param token Indicates the value of token. + */ + function update(context: CMContext, handle: number, data: Uint8Array, callback: AsyncCallback) : void; + function update(context: CMContext, handle: number, data: Uint8Array, token: Uint8Array, callback: AsyncCallback) : void; + function update(context: CMContext, handle: number, data: Uint8Array, token?: Uint8Array) : Promise; + + + /** + * Finish Operation. + * @since 8 + * @syscap SystemCapability.Security.Huks + * @param context Indicates the context of the calling interface application. + * @param handle Indicates the handle of the init operation. + * @param signature Indicates the sign data. + */ + function finish(context: CMContext, handle: number, callback: AsyncCallback) : void; + function finish(context: CMContext, handle: number, signature: Uint8Array, callback: AsyncCallback) : void; + function finish(context: CMContext, handle: number, signature?: Uint8Array) : Promise; + + /** + * Abort Operation. + * @since 8 + * @syscap SystemCapability.Security.Huks + * @param context Indicates the context of the calling interface application. + * @param handle Indicates the handle of the init operation. + */ + function abort(context: CMContext, handle: number, callback: AsyncCallback) : void; + function abort(context: CMContext, handle: number) : Promise; + + export interface CMContext { + userId: string; + uid: string; + packageName: string; + } + + export interface CertInfo { + uri: string; + certAlias: string; + status: boolean; + issuerName: string; + subjectName: string; + serial: string; + notBefore: string; + notAfter: string; + fingerprintSha1: string; + fingerprintSha256: string; + cert: Uint8Array; + } + + export interface CertAbstract { + uri: string; + certAlias: string; + status: boolean; + subjectName: string; + } + + export interface Credential { + type: string; + alias: string; + keyUri: string; + certNum: number; + keyNum: number; + credData:Uint8Array; + } + + export interface CredentialAbstract { + type: string; + alias: string; + keyUri: string; + } + + export interface CMBlob { + readonly inData?: Uint8Array; + readonly alias?: string; + } + + export interface CMResult { + errorCode: number; + certList?: Array; + certInfo?: CertInfo; + credentialList?: Array; + credential?: Credential; + appList?: Array; + authUri?: string; + outData?: Uint8Array; + isAuth?: boolean; + } + + export interface CMKeyProperties { + type: string; + alg: string; + size: number; + padding: string; + purpose: string; + digest: string; + authType: string; + authTimeout: string; + } + + export interface CMSignatureSpec { + alg: string; + padding: string; + digest: string; + authToken: Uint8Array; + } + + export interface CMHandle { + errorCode: number; + handle: number; + token?: Uint8Array; + } + + export enum CMErrorCode { + CM_SUCCESS = 0, + CM_FAILURE = -1, + CM_ERROR_INSTALL_CERTIFICATE = -2, + CM_ERROR_SET_STATUS = -3, + CM_ERROR_INVALID_ARGUMENT = -3, + CM_ERROR_INVALID_STORE = -4, + CM_ERROR_NOT_SUPPORTED = -5, + CM_ERROR_UNINSTALL = -6, + CM_ERROR_NO_PERMISSION = -7, + CM_ERROR_INSUFFICIENT_DATA = -8, + CM_ERROR_GET_CERTIRICATE = -9, + CM_ERROR_STORAGE_FAILURE = -10, + CM_ERROR_HARDWARE_FAILURE = -11, + CM_ERROR_ALREADY_EXISTS = -12, + CM_ERROR_NOT_EXIST = -13, + CM_ERROR_NULL_POINTER = -14, + CM_ERROR_FILE_SIZE_FAIL = -15, + CM_ERROR_READ_FILE_FAIL = -16, + CM_ERROR_INVALID_PUBLIC_KEY = -17, + CM_ERROR_INVALID_PRIVATE_KEY = -18, + CM_ERROR_INVALID_KEY_INFO = -19, + CM_ERROR_REMOVE_CERTIFICATE_FAIL = -20, + CM_ERROR_OPEN_FILE_FAIL = -21, + CM_ERROR_INVALID_KEY_FILE = -22, + CM_ERROR_IPC_MSG_FAIL = -23, + CM_ERROR_REQUEST_OVERFLOWS = -24, + CM_ERROR_PARAM_NOT_EXIST = -25, + CM_ERROR_CRYPTO_ENGINE_ERROR = -26, + CM_ERROR_COMMUNICATION_TIMEOUT = -27, + CM_ERROR_IPC_INIT_FAIL = -28, + CM_ERROR_IPC_DLOPEN_FAIL = -29, + CM_ERROR_EFUSE_READ_FAIL = -30, + + CM_ERROR_CHECK_GET_ALG_FAIL = -100, + CM_ERROR_CHECK_GET_KEY_SIZE_FAIL = -101, + CM_ERROR_CHECK_GET_PADDING_FAIL = -102, + CM_ERROR_INVALID_DIGEST = -117, + + CM_ERROR_INTERNAL_ERROR = -999, + CM_ERROR_UNKNOWN_ERROR = -1000, + } +} + +export default certManager; diff --git a/interfaces/kits/napi/BUILD.gn b/interfaces/kits/napi/BUILD.gn new file mode 100644 index 0000000..d5fbf8e --- /dev/null +++ b/interfaces/kits/napi/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_shared_library("certmanager") { + defines = [ + "L2_STANDARD", + "_HARDWARE_ROOT_KEY_", + "_CM_LOG_ENABLE_", + ] + + include_dirs = [ + "//base/security/certificate_manager/interfaces/innerkits/cert_manager_standard/main/include", + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/common/include", + "include", + ] + + sources = [ + "src/cm_napi.cpp", + "src/cm_napi_common.cpp", + "src/cm_napi_get_system_cert_list.cpp", + "src/cm_napi_get_system_cert_info.cpp", + "src/cm_napi_set_cert_status.cpp", + "src/cm_napi_install_app_cert.cpp", + "src/cm_napi_uninstall_app_cert.cpp", + "src/cm_napi_uninstall_all_app_cert.cpp", + "src/cm_napi_get_app_cert_list.cpp", + "src/cm_napi_get_app_cert_info.cpp", + ] + + external_deps = [ + "certificate_manager:cert_manager_sdk", + "napi:ace_napi", + "c_utils:utils", + ] + cflags_cc = [ + "-Wall", + "-Werror", + ] + deps = [] + + relative_install_dir = "module/security" + subsystem_name = "security" + part_name = "certificate_manager" +} diff --git a/interfaces/kits/napi/include/cm_napi_common.h b/interfaces/kits/napi/include/cm_napi_common.h new file mode 100644 index 0000000..9f4dc25 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_common.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_COMMON_H +#define CM_NAPI_COMMON_H + +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +#include "cm_mem.h" +#include "cm_type.h" + +#define DATA_SIZE_64KB (1024 * 64) +#define NAPI_ASSERT_FUNC(f) if (CM_SUCCESS != (f)) { CM_LOG_W("Failed: %s\n", #f); return; } + +namespace CMNapi { +static const std::string CM_CONTEXT_PROPERTY_USERID = "userId"; +static const std::string CM_CONTEXT_PROPERTY_UID = "uid"; +static const std::string CM_CONTEXT_PROPERTY_PACKAGENAME = "packageName"; + +static const std::string CM_CERT_PROPERTY_URI = "uri"; +static const std::string CM_CERT_PROPERTY_TYPE = "type"; +static const std::string CM_CERT_PROPERTY_CREDENTIAL_ALIAS = "alias"; +static const std::string CM_CERT_PROPERTY_KEY_URI = "keyUri"; +static const std::string CM_CERT_PROPERTY_KEY_NUM = "keyNum"; +static const std::string CM_CERT_PROPERTY_CERT_NUM = "certNum"; +static const std::string CM_CERT_PROPERTY_CREDENTIAL_DATA = "credData"; + +static const std::string CM_CERT_PROPERTY_CERTALIAS = "certAlias"; +static const std::string CM_CERT_PROPERTY_ISSUERNAME = "issuerName"; +static const std::string CM_CERT_PROPERTY_SUBJECTNAME = "subjectName"; +static const std::string CM_CERT_PROPERTY_SERIAL = "serial"; +static const std::string CM_CERT_PROPERTY_BEFORE = "notBefore"; +static const std::string CM_CERT_PROPERTY_AFTER = "notAfter"; +static const std::string CM_CERT_PROPERTY_FINGERSHA1 = "fingerprintSha1"; +static const std::string CM_CERT_PROPERTY_FINGERSHA256 = "fingerprintSha256"; +static const std::string CM_CERT_PROPERTY_CERTINFO = "certInfo"; +static const std::string CM_CERT_PROPERTY_STATUS = "status"; + +static const std::string BUSINESS_ERROR_PROPERTY_CODE = "code"; +static const std::string BUSINESS_ERROR_PROPERTY_MESSAGE = "message"; + +static const size_t CM_HANDLE_OFFSET32 = 32; +static const std::string CM_OPTIONS_PROPERTY_PROPERTIES = "properties"; +static const std::string CM_OPTIONS_PROPERTY_INDATA = "inData"; + +static const std::string CM_PARAM_PROPERTY_TAG = "tag"; +static const std::string CM_PARAM_PROPERTY_VALUE = "value"; + +static const std::string CM_RESULT_PRPPERTY_CERTLIST = "certList"; +static const std::string CM_RESULT_PRPPERTY_CERTINFO = "certInfo"; +static const std::string CM_RESULT_PRPPERTY_CREDENTIAL_LIST = "credentialList"; +static const std::string CM_RESULT_PRPPERTY_CREDENTIAL = "credential"; + +static const std::string CM_HANDLE_PROPERTY_HANDLE = "handle"; + +static const int32_t CERT_MANAGER_SYS_CAP = 17500000; +static const int32_t RESULT_NUMBER = 2; +static const uint32_t APPLICATION_CERTIFICATE_STORE = 0; +static const uint32_t SYSTEM_CERTIFICATE_STORE = 1; +static const std::string PARAM_TYPE_ERROR_NUMBER = "401"; + + +napi_value ParseCmContext(napi_env env, napi_value object, CmContext *&cmContext); +napi_value ParseUint32(napi_env env, napi_value object, uint32_t &store); +napi_value ParseBoolean(napi_env env, napi_value object, bool &status); +napi_value ParseString(napi_env env, napi_value object, CmBlob *&certUri); +napi_value GetUint8Array(napi_env env, napi_value object, CmBlob &arrayBlob); + +napi_ref GetCallback(napi_env env, napi_value object); + +napi_value GenerateCertAbstractArray( + napi_env env, const struct CertAbstract *certAbstract, const uint32_t certCount); + +napi_value GenerateCredentialAbstractArray(napi_env env, + const struct CredentialAbstract *credentialAbstract, const uint32_t credentialCount); + +napi_value GenerateCertInfo(napi_env env, const struct CertInfo *certInfo); +napi_value GenerateAppCertInfo(napi_env env, const struct Credential *credential); +napi_value GenerateBusinessError(napi_env env, int32_t errorCode, const char *errorMessage); + +void DeleteNapiContext(napi_env env, napi_async_work &asyncWork, napi_ref &callback); + +void GeneratePromise(napi_env env, napi_deferred deferred, int32_t resultCode, + napi_value *result, int32_t arrLength); +void GenerateCallback(napi_env env, napi_ref callback, napi_value *result, int32_t arrLength); +void GenerateNapiPromise(napi_env env, napi_ref callback, napi_deferred *deferred, napi_value *promise); + +inline napi_value GetNull(napi_env env) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_get_null(env, &result)); + return result; +} + +inline napi_value GetInt32(napi_env env, int32_t value) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_int32(env, value, &result)); + return result; +} + +inline void FreeCmBlob(CmBlob *&blob) +{ + if (blob == nullptr) { + return; + } + + if (blob->data != nullptr) { + CmFree(blob->data); + blob->data = nullptr; + } + blob->size = 0; + + CmFree(blob); + blob = nullptr; +} + +void FreeCmContext(CmContext *&context); + +inline void FreeCertAbstract(CertAbstract *&certAbstract) +{ + if (certAbstract == nullptr) { + return; + } + + certAbstract->status = false; + + CmFree(certAbstract); + certAbstract = nullptr; +} + +inline void FreeCredentialAbstract(CredentialAbstract *&CredentialAbstract) +{ + if (CredentialAbstract == nullptr) { + return; + } + + CmFree(CredentialAbstract); + CredentialAbstract = nullptr; +} + +void FreeCertList(CertList *&certList); +void FreeCredentialList(CredentialList *&credentialList); +void FreeCertInfo(CertInfo *&certInfo); +void FreeCredential(Credential *&credential); + +enum CmErrorCode { + CM_SUCCESS = 0, + CM_FAILURE = 17500001, + + CMR_NOT_PERMITTED = 17500002, + CMR_NOT_SUPPORTED = 17500003, + CMR_INVALID_ARGUMENT = 17500004, + CMR_BUFFER_TOO_SMALL = 17500006, + CMR_MEM_ERROR = 17500007, + CMR_STORAGE_ERROR = 17500008, + CMR_NOT_FOUND = 17500009, + CMR_FILE_READ_ERROR = 17500010, + CMR_FILE_WRITE_ERROR = 17500011, + CMR_NULL_POINTER_ERROR = 17500012, + CMR_INSUFFICIENT_DATA = 17500013, + CMR_ERROR_MAKE_DIR_FAIL = 17500014, + CMR_ERROR_INTERNAL_ERROR = 17500015, + CMR_ERROR_REMOVE_FILE_FAIL = 17500016, + CMR_ERROR_INVALID_ARGUMENT = 17500017, + CMR_ERROR_WRITE_FILE_FAIL = 17500018, + CMR_ERROR_OPEN_FILE_FAIL = 17500019, + CMR_ERROR_CLOSE_FILE_FAIL = 17500020, + CMR_ERROR_BAD_STATE = 17500021, + CMR_ERROR_INVALID_KEY_FILE = 17500022, + CMR_ERROR_MALLOC_FAIL = 17500023, + CMR_ERROR_NOT_EXIST = 17500024, + CMR_ERROR_NULL_POINTER = 17500025, + CMR_ERROR_ALREADY_EXISTS = 17500026, + + CMR_ERROR_NOT_SUPPORTED = 17500027, + CMR_ERROR_INSUFFICIENT_DATA = 17500028, + CMR_ERROR_BUFFER_TOO_SMALL = 17500029, + CMR_ERROR_INSUFFICIENT_MEMORY = 17500030, + CMR_ERROR_INVALID_CERT_FORMAT = 17500031, + CMR_ERROR_NOT_FOUND = 17500032, + + CMR_ERROR_KEY_ERROR = 17500033, + CMR_ERROR_PARAM_NOT_EXIST = 17500034, + CMR_ERROR_INVALID_OPERATION = 17500035, +}; +} // namespace CertManagerNapi + +#endif diff --git a/interfaces/kits/napi/include/cm_napi_get_app_cert_info.h b/interfaces/kits/napi/include/cm_napi_get_app_cert_info.h new file mode 100644 index 0000000..e576d12 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_get_app_cert_info.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_GET_CREDENTIAL_INFO_H +#define CM_NAPI_GET_CREDENTIAL_INFO_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiGetAppCertInfo(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_GET_CREDENTIAL_INFO_H \ No newline at end of file diff --git a/interfaces/kits/napi/include/cm_napi_get_app_cert_list.h b/interfaces/kits/napi/include/cm_napi_get_app_cert_list.h new file mode 100644 index 0000000..b5b3b75 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_get_app_cert_list.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_GET_APP_CERTIFICATE_LIST_H +#define CM_NAPI_GET_APP_CERTIFICATE_LIST_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiGetAppCertList(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_GET_APP_CERTIFICATE_LIST_H \ No newline at end of file diff --git a/interfaces/kits/napi/include/cm_napi_get_system_cert_info.h b/interfaces/kits/napi/include/cm_napi_get_system_cert_info.h new file mode 100644 index 0000000..722c085 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_get_system_cert_info.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_GET_CERTIFICATE_INFO_H +#define CM_NAPI_GET_CERTIFICATE_INFO_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiGetSystemCertInfo(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_GET_CERTIFICATE_INFO_H \ No newline at end of file diff --git a/interfaces/kits/napi/include/cm_napi_get_system_cert_list.h b/interfaces/kits/napi/include/cm_napi_get_system_cert_list.h new file mode 100644 index 0000000..d420645 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_get_system_cert_list.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_GET_CERTIFICATE_LIST_H +#define CM_NAPI_GET_CERTIFICATE_LIST_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiGetSystemCertList(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_GET_CERTIFICATE_LIST_H \ No newline at end of file diff --git a/interfaces/kits/napi/include/cm_napi_install_app_cert.h b/interfaces/kits/napi/include/cm_napi_install_app_cert.h new file mode 100644 index 0000000..ff7f864 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_install_app_cert.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_INSTALL_APP_CERT_H +#define CM_NAPI_INSTALL_APP_CERT_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiInstallAppCert(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_INSTALL_APP_CERT_H \ No newline at end of file diff --git a/interfaces/kits/napi/include/cm_napi_set_cert_status.h b/interfaces/kits/napi/include/cm_napi_set_cert_status.h new file mode 100644 index 0000000..70b4613 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_set_cert_status.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_SET_CERTIFICATE_STATUS_H +#define CM_NAPI_SET_CERTIFICATE_STATUS_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiSetCertStatus(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_SET_CERTIFICATE_STATUS_H \ No newline at end of file diff --git a/interfaces/kits/napi/include/cm_napi_uninstall_all_app_cert.h b/interfaces/kits/napi/include/cm_napi_uninstall_all_app_cert.h new file mode 100644 index 0000000..a42e82b --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_uninstall_all_app_cert.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_UNINSTALL_ALL_APP_CERT_H +#define CM_NAPI_UNINSTALL_ALL_APP_CERT_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiUninstallAllAppCert(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_UNINSTALL_ALL_APP_CERT_H \ No newline at end of file diff --git a/interfaces/kits/napi/include/cm_napi_uninstall_app_cert.h b/interfaces/kits/napi/include/cm_napi_uninstall_app_cert.h new file mode 100644 index 0000000..50a3be7 --- /dev/null +++ b/interfaces/kits/napi/include/cm_napi_uninstall_app_cert.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_UNINSTALL_APP_CERT_H +#define CM_NAPI_UNINSTALL_APP_CERT_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CMNapi { +napi_value CMNapiUninstallAppCert(napi_env env, napi_callback_info info); +} // namespace CertManagerNapi + +#endif // CM_NAPI_UNINSTALL_APP_CERT_H \ No newline at end of file diff --git a/interfaces/kits/napi/src/cm_napi.cpp b/interfaces/kits/napi/src/cm_napi.cpp new file mode 100644 index 0000000..a63ef25 --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +#include "cm_napi_common.h" + +#include "cm_napi_get_system_cert_list.h" +#include "cm_napi_get_system_cert_info.h" +#include "cm_napi_set_cert_status.h" +#include "cm_napi_install_app_cert.h" +#include "cm_napi_uninstall_app_cert.h" +#include "cm_napi_uninstall_all_app_cert.h" +#include "cm_napi_get_app_cert_list.h" +#include "cm_napi_get_app_cert_info.h" + + +namespace CMNapi { + inline void AddInt32Property(napi_env env, napi_value object, const char *name, int32_t value) + { + napi_value property = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, value, &property)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name, property)); + } + + static void AddCMErrorCodePart(napi_env env, napi_value errorCode) + { + AddInt32Property(env, errorCode, "CM_SUCCESS", CM_SUCCESS); + AddInt32Property(env, errorCode, "CM_FAILURE", CM_FAILURE); + AddInt32Property(env, errorCode, "CMR_ERROR_NOT_PERMITTED", CMR_ERROR_NOT_PERMITTED); + AddInt32Property(env, errorCode, "CMR_ERROR_NOT_SUPPORTED", CMR_ERROR_NOT_SUPPORTED); + AddInt32Property(env, errorCode, "CMR_ERROR_STORAGE", CMR_ERROR_STORAGE); + AddInt32Property(env, errorCode, "CMR_ERROR_NOT_FOUND", CMR_ERROR_NOT_FOUND); + AddInt32Property(env, errorCode, "CMR_ERROR_NULL_POINTER", CMR_ERROR_NULL_POINTER); + AddInt32Property(env, errorCode, "CMR_ERROR_INVALID_ARGUMENT", CMR_ERROR_INVALID_ARGUMENT); + AddInt32Property(env, errorCode, "CMR_ERROR_MAKE_DIR_FAIL", CMR_ERROR_MAKE_DIR_FAIL); + AddInt32Property(env, errorCode, "CMR_ERROR_INVALID_OPERATION", CMR_ERROR_INVALID_OPERATION); + AddInt32Property(env, errorCode, "CMR_ERROR_OPEN_FILE_FAIL", CMR_ERROR_OPEN_FILE_FAIL); + AddInt32Property(env, errorCode, "CMR_ERROR_READ_FILE_ERROR", CMR_ERROR_READ_FILE_ERROR); + AddInt32Property(env, errorCode, "CMR_ERROR_WRITE_FILE_FAIL", CMR_ERROR_WRITE_FILE_FAIL); + AddInt32Property(env, errorCode, "CMR_ERROR_REMOVE_FILE_FAIL", CMR_ERROR_REMOVE_FILE_FAIL); + AddInt32Property(env, errorCode, "CMR_ERROR_CLOSE_FILE_FAIL", CMR_ERROR_CLOSE_FILE_FAIL); + AddInt32Property(env, errorCode, "CMR_ERROR_MALLOC_FAIL", CMR_ERROR_MALLOC_FAIL); + AddInt32Property(env, errorCode, "CMR_ERROR_NOT_EXIST", CMR_ERROR_NOT_EXIST); + AddInt32Property(env, errorCode, "CMR_ERROR_ALREADY_EXISTS", CMR_ERROR_ALREADY_EXISTS); + AddInt32Property(env, errorCode, "CMR_ERROR_INSUFFICIENT_DATA", CMR_ERROR_INSUFFICIENT_DATA); + AddInt32Property(env, errorCode, "CMR_ERROR_BUFFER_TOO_SMALL", CMR_ERROR_BUFFER_TOO_SMALL); + AddInt32Property(env, errorCode, "CMR_ERROR_INVALID_CERT_FORMAT", CMR_ERROR_INVALID_CERT_FORMAT); + AddInt32Property(env, errorCode, "CMR_ERROR_PARAM_NOT_EXIST", CMR_ERROR_PARAM_NOT_EXIST); + } + + static napi_value CreateCMErrorCode(napi_env env) + { + napi_value errorCode = nullptr; + NAPI_CALL(env, napi_create_object(env, &errorCode)); + + AddCMErrorCodePart(env, errorCode); + + return errorCode; + } +} // namespace CertManagerNapi + +using namespace CMNapi; + +extern "C" { + static napi_value CMNapiRegister(napi_env env, napi_value exports) + { + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("CMErrorCode", CreateCMErrorCode(env)), + + DECLARE_NAPI_FUNCTION("getSystemTrustedCertificateList", CMNapiGetSystemCertList), + DECLARE_NAPI_FUNCTION("getSystemTrustedCertificate", CMNapiGetSystemCertInfo), + DECLARE_NAPI_FUNCTION("setCertificateStatus", CMNapiSetCertStatus), + DECLARE_NAPI_FUNCTION("installAppCertificate", CMNapiInstallAppCert), + DECLARE_NAPI_FUNCTION("uninstallAllAppCertificate", CMNapiUninstallAllAppCert), + DECLARE_NAPI_FUNCTION("uninstallAppCertificate", CMNapiUninstallAppCert), + DECLARE_NAPI_FUNCTION("getAppCertificateList", CMNapiGetAppCertList), + DECLARE_NAPI_FUNCTION("getAppCertificate", CMNapiGetAppCertInfo), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; + } + + static napi_module g_module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = CMNapiRegister, + .nm_modname = "security.certmanager", + .nm_priv = ((void *)0), + .reserved = {0}, + }; + + __attribute__((constructor)) void CertManagerRegister(void) + { + napi_module_register(&g_module); + } +} diff --git a/interfaces/kits/napi/src/cm_napi_common.cpp b/interfaces/kits/napi/src/cm_napi_common.cpp new file mode 100644 index 0000000..df51d06 --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_common.cpp @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_common.h" + +#include "securec.h" + +#include "cm_log.h" +#include "cm_type.h" + +namespace CMNapi { +namespace { +constexpr int CM_MAX_DATA_LEN = 0x6400000; // The maximum length is 100M +constexpr int RESULT_ARG_NUMBER = 2; +} // namespace + +napi_value getCmContextAttribute(napi_env env, napi_value object, const char *type, int maxSize, char *&srcData) +{ + napi_value typeValue = nullptr; + napi_status status = napi_get_named_property(env, object, type, &typeValue); + if (status != napi_ok || typeValue == nullptr) { + GET_AND_THROW_LAST_ERROR((env)); + CM_LOG_E("could not get property %s", type); + return nullptr; + } + + size_t length = 0; + status = napi_get_value_string_utf8(env, typeValue, nullptr, 0, &length); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + CM_LOG_E("could not get string length"); + return nullptr; + } + + if ((int)length > maxSize) { + CM_LOG_E("input param length too large"); + return nullptr; + } + + srcData = (char *)CmMalloc(length + 1); + if (srcData == nullptr) { + napi_throw_error(env, NULL, "could not alloc memory"); + CM_LOG_E("could not alloc memory"); + return nullptr; + } + (void)memset_s(srcData, length + 1, 0, length + 1); + + size_t result = 0; + status = napi_get_value_string_utf8(env, typeValue, srcData, length + 1, &result); + if (status != napi_ok) { + CmFree(srcData); + GET_AND_THROW_LAST_ERROR((env)); + CM_LOG_E("could not get string"); + return nullptr; + } + + return GetInt32(env, 0); +} + +napi_value ParseCmContext(napi_env env, napi_value object, CmContext *&cmContext) +{ + char *userIdData = nullptr; + char *uidData = nullptr; + char *packageNameData = nullptr; + + napi_value userIdStatus = getCmContextAttribute(env, object, + CM_CONTEXT_PROPERTY_USERID.c_str(), CM_MAX_DATA_LEN, userIdData); + napi_value uidStatus = getCmContextAttribute(env, object, + CM_CONTEXT_PROPERTY_UID.c_str(), CM_MAX_DATA_LEN, uidData); + napi_value packageNameStatus = getCmContextAttribute(env, object, + CM_CONTEXT_PROPERTY_PACKAGENAME.c_str(), CM_MAX_DATA_LEN, packageNameData); + if (userIdStatus == nullptr || uidStatus == nullptr || packageNameStatus == nullptr) { + return nullptr; + } + + cmContext = (CmContext *)CmMalloc(sizeof(CmContext)); + if (cmContext == nullptr) { + CmFree(userIdData); + CmFree(uidData); + CmFree(packageNameData); + napi_throw_error(env, NULL, "could not alloc memory"); + CM_LOG_E("could not alloc memory"); + return nullptr; + } + + cmContext->userId = (uint32_t)atoi(userIdData); + cmContext->uid = (uint32_t)atoi(uidData); + if (strncpy_s(cmContext->packageName, sizeof(cmContext->packageName), + packageNameData, strlen(packageNameData)) != EOK) { + CM_LOG_E("copy packageName failed"); + return nullptr; + } + return GetInt32(env, 0); +} + +napi_value ParseUint32(napi_env env, napi_value object, uint32_t &store) +{ + napi_valuetype valueType; + napi_typeof(env, object, &valueType); + if (valueType != napi_number) { + CM_LOG_E("param type is not number"); + return nullptr; + } + uint32_t temp = 0; + napi_get_value_uint32(env, object, &temp); + store = temp; + return GetInt32(env, 0); +} + +napi_value ParseBoolean(napi_env env, napi_value object, bool &status) +{ + napi_valuetype valueType; + napi_typeof(env, object, &valueType); + if (valueType != napi_boolean) { + CM_LOG_E("param type is not bool"); + return nullptr; + } + bool temp = false; + napi_get_value_bool(env, object, &temp); + status = temp; + return GetInt32(env, 0); +} + +napi_value ParseString(napi_env env, napi_value object, CmBlob *&certUri) +{ + napi_valuetype valueType = napi_undefined; + NAPI_CALL(env, napi_typeof(env, object, &valueType)); + if (valueType != napi_string) { + CM_LOG_E("the type of param is not string"); + return nullptr; + } + size_t length = 0; + napi_status status = napi_get_value_string_utf8(env, object, nullptr, 0, &length); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + CM_LOG_E("could not get string length"); + return nullptr; + } + + if (length > CM_MAX_DATA_LEN) { + CM_LOG_E("input key alias length too large"); + return nullptr; + } + + char *data = (char *)CmMalloc(length + 1); + if (data == nullptr) { + napi_throw_error(env, NULL, "could not alloc memory"); + CM_LOG_E("could not alloc memory"); + return nullptr; + } + (void)memset_s(data, length + 1, 0, length + 1); + + size_t result = 0; + status = napi_get_value_string_utf8(env, object, data, length + 1, &result); + if (status != napi_ok) { + CmFree(data); + GET_AND_THROW_LAST_ERROR((env)); + CM_LOG_E("could not get string"); + return nullptr; + } + + certUri = (CmBlob *)CmMalloc(sizeof(CmBlob)); + if (certUri == nullptr) { + CmFree(data); + napi_throw_error(env, NULL, "could not alloc memory"); + CM_LOG_E("could not alloc memory"); + return nullptr; + } + certUri->data = (uint8_t *)data; + certUri->size = (uint32_t)((length + 1) & UINT32_MAX); + + return GetInt32(env, 0); +} + +napi_value GetUint8Array(napi_env env, napi_value object, CmBlob &arrayBlob) +{ + napi_typedarray_type arrayType; + napi_value arrayBuffer = nullptr; + size_t length = 0; + size_t offset = 0; + void *rawData = nullptr; + NAPI_CALL( + env, napi_get_typedarray_info(env, object, &arrayType, &length, (void **)&rawData, &arrayBuffer, &offset)); + NAPI_ASSERT(env, arrayType == napi_uint8_array, "Param is not uint8 array"); + + if (length > CM_MAX_DATA_LEN) { + CM_LOG_E("Data is too large, length = %x", length); + return nullptr; + } + if (length == 0) { + CM_LOG_I("The memory length created is only 1 Byte"); + // The memory length created is only 1 Byte + arrayBlob.data = (uint8_t *)CmMalloc(1); + } else { + arrayBlob.data = (uint8_t *)CmMalloc(length); + } + if (arrayBlob.data == nullptr) { + CM_LOG_E("Malloc failed"); + return nullptr; + } + (void)memset_s(arrayBlob.data, length, 0, length); + if (memcpy_s(arrayBlob.data, length, rawData, length) != EOK) { + return nullptr; + } + arrayBlob.size = (uint32_t)(length); + + return GetInt32(env, 0); +} + +napi_ref GetCallback(napi_env env, napi_value object) +{ + napi_valuetype valueType = napi_undefined; + napi_status status = napi_typeof(env, object, &valueType); + if (status != napi_ok) { + CM_LOG_E("could not get object type"); + return nullptr; + } + + if (valueType != napi_function) { + CM_LOG_E("invalid type"); + return nullptr; + } + + napi_ref ref = nullptr; + status = napi_create_reference(env, object, 1, &ref); + if (status != napi_ok) { + CM_LOG_E("could not create reference"); + return nullptr; + } + return ref; +} + +static napi_value GenerateAarrayBuffer(napi_env env, uint8_t *data, uint32_t size) +{ + uint8_t *buffer = (uint8_t *)CmMalloc(size); + if (buffer == nullptr) { + return nullptr; + } + + napi_value outBuffer = nullptr; + if (memcpy_s(buffer, size, data, size) != EOK) { + return nullptr; + } + + napi_status status = napi_create_external_arraybuffer( + env, buffer, size, [](napi_env env, void *data, void *hint) { CmFree(data); }, nullptr, &outBuffer); + if (status == napi_ok) { + // free by finalize callback + buffer = nullptr; + } else { + CmFree(buffer); + GET_AND_THROW_LAST_ERROR((env)); + } + + return outBuffer; +} + +napi_value GenerateCertAbstractArray(napi_env env, const struct CertAbstract *certAbstract, const uint32_t certCount) +{ + if (certCount == 0 || certAbstract == nullptr) { + return nullptr; + } + napi_value array = nullptr; + NAPI_CALL(env, napi_create_array(env, &array)); + for (uint32_t i = 0; i < certCount; i++) { + napi_value uri = nullptr; + napi_value certAlias = nullptr; + napi_value subjectName = nullptr; + napi_value status = nullptr; + + napi_create_string_latin1(env, (const char *)certAbstract[i].uri, NAPI_AUTO_LENGTH, &uri); + napi_create_string_latin1(env, (const char *)certAbstract[i].certAlias, + NAPI_AUTO_LENGTH, &certAlias); + napi_create_string_latin1(env, (const char *)certAbstract[i].subjectName, + NAPI_AUTO_LENGTH, &subjectName); + napi_get_boolean(env, certAbstract[i].status, &status); + + napi_value element = nullptr; + napi_create_object(env, &element); + napi_set_named_property (env, element, CM_CERT_PROPERTY_URI.c_str(), uri); + napi_set_named_property (env, element, CM_CERT_PROPERTY_CERTALIAS.c_str(), certAlias); + napi_set_named_property (env, element, CM_CERT_PROPERTY_STATUS.c_str(), status); + napi_set_named_property (env, element, CM_CERT_PROPERTY_SUBJECTNAME.c_str(), subjectName); + + napi_set_element(env, array, i, element); + } + return array; +} + +napi_value GenerateCredentialAbstractArray(napi_env env, + const struct CredentialAbstract *credentialAbstract, const uint32_t credentialCount) +{ + if (credentialCount == 0 || credentialAbstract == nullptr) { + return nullptr; + } + napi_value array = nullptr; + NAPI_CALL(env, napi_create_array(env, &array)); + for (uint32_t i = 0; i < credentialCount; i++) { + napi_value type = nullptr; + napi_value alias = nullptr; + napi_value keyUri = nullptr; + napi_create_string_latin1(env, (const char *)credentialAbstract[i].type, + NAPI_AUTO_LENGTH, &type); + napi_create_string_latin1(env, (const char *)credentialAbstract[i].alias, + NAPI_AUTO_LENGTH, &alias); + napi_create_string_latin1(env, (const char *)credentialAbstract[i].keyUri, + NAPI_AUTO_LENGTH, &keyUri); + + napi_value element = nullptr; + napi_create_object(env, &element); + napi_set_named_property (env, element, CM_CERT_PROPERTY_TYPE.c_str(), type); + napi_set_named_property (env, element, CM_CERT_PROPERTY_CREDENTIAL_ALIAS.c_str(), alias); + napi_set_named_property (env, element, CM_CERT_PROPERTY_KEY_URI.c_str(), keyUri); + + napi_set_element(env, array, i, element); + } + return array; +} + +napi_value GenerateCertInfo(napi_env env, const struct CertInfo *certInfo) +{ + if (certInfo == nullptr) { + return nullptr; + } + napi_value result = nullptr; + NAPI_CALL(env, napi_create_object(env, &result)); + napi_value uri = nullptr; + napi_value certAlias = nullptr; + napi_value status = nullptr; + napi_value issuerName = nullptr; + napi_value subjectName = nullptr; + napi_value serial = nullptr; + napi_value notBefore = nullptr; + napi_value notAfter = nullptr; + napi_value fingerprintSha256 = nullptr; + napi_value certInfoBlob = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->uri, NAPI_AUTO_LENGTH, &uri)); + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->certAlias, + NAPI_AUTO_LENGTH, &certAlias)); + + NAPI_CALL(env, napi_get_boolean(env, certInfo->status, &status)); + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->issuerName, + NAPI_AUTO_LENGTH, &issuerName)); + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->subjectName, + NAPI_AUTO_LENGTH, &subjectName)); + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->serial, NAPI_AUTO_LENGTH, &serial)); + + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->notBefore, + NAPI_AUTO_LENGTH, ¬Before)); + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->notAfter, + NAPI_AUTO_LENGTH, ¬After)); + + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)certInfo->fingerprintSha256, + NAPI_AUTO_LENGTH, &fingerprintSha256)); + + napi_value certBuffer = GenerateAarrayBuffer(env, certInfo->certInfo.data, certInfo->certInfo.size); + if (certBuffer != nullptr) { + NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, certInfo->certInfo.size, + certBuffer, 0, &certInfoBlob)); + } + + napi_value element = nullptr; + NAPI_CALL(env, napi_create_object(env, &element)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_URI.c_str(), uri)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CERTALIAS.c_str(), certAlias)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_STATUS.c_str(), status)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_ISSUERNAME.c_str(), issuerName)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_SUBJECTNAME.c_str(), subjectName)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_SERIAL.c_str(), serial)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_BEFORE.c_str(), notBefore)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_AFTER.c_str(), notAfter)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_FINGERSHA256.c_str(), fingerprintSha256)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CERTINFO.c_str(), certInfoBlob)); + + return element; +} + +napi_value GenerateBusinessError(napi_env env, int32_t errorCode, const char *errorMessage) +{ + napi_value businessError = nullptr; + NAPI_CALL(env, napi_create_object(env, &businessError)); + + napi_value code = nullptr; + NAPI_CALL(env, napi_create_int32(env, CERT_MANAGER_SYS_CAP - errorCode, &code)); + NAPI_CALL(env, napi_set_named_property(env, businessError, BUSINESS_ERROR_PROPERTY_CODE.c_str(), code)); + napi_value message = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, errorMessage, NAPI_AUTO_LENGTH, &message)); + NAPI_CALL(env, napi_set_named_property(env, businessError, BUSINESS_ERROR_PROPERTY_MESSAGE.c_str(), message)); + return businessError; +} + +napi_value GenerateAppCertInfo(napi_env env, const struct Credential *credential) +{ + if (credential == nullptr) { + return nullptr; + } + napi_value result = nullptr; + NAPI_CALL(env, napi_create_object(env, &result)); + napi_value type = nullptr; + napi_value alias = nullptr; + napi_value keyUri = nullptr; + napi_value certNum = nullptr; + napi_value keyNum = nullptr; + napi_value credData = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)credential->type, NAPI_AUTO_LENGTH, &type)); + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)credential->alias, NAPI_AUTO_LENGTH, &alias)); + NAPI_CALL(env, napi_create_string_latin1(env, (const char *)credential->keyUri, NAPI_AUTO_LENGTH, &keyUri)); + + NAPI_CALL(env, napi_create_int32(env, credential->certNum, &certNum)); + NAPI_CALL(env, napi_create_int32(env, credential->keyNum, &keyNum)); + + napi_value crendentialBuffer = GenerateAarrayBuffer(env, credential->credData.data, credential->credData.size); + if (crendentialBuffer != nullptr) { + NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, credential->credData.size, + crendentialBuffer, 0, &credData)); + } + + napi_value element = nullptr; + NAPI_CALL(env, napi_create_object(env, &element)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_TYPE.c_str(), type)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_ALIAS.c_str(), alias)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_KEY_URI.c_str(), keyUri)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CERT_NUM.c_str(), certNum)); + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_KEY_NUM.c_str(), keyNum)); + + NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_DATA.c_str(), credData)); + + return element; +} + +void GeneratePromise(napi_env env, napi_deferred deferred, int32_t resultCode, + napi_value *result, int32_t arrLength) +{ + if (arrLength < RESULT_NUMBER) { + return; + } + if (resultCode == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, deferred, result[1])); + } else { + NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, deferred, result[0])); + } +} + +void GenerateCallback(napi_env env, napi_ref callback, napi_value *result, int32_t arrLength) +{ + napi_value func = nullptr; + napi_value returnVal = nullptr; + if (arrLength < RESULT_NUMBER) { + return; + } + NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callback, &func)); + NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, func, RESULT_ARG_NUMBER, result, &returnVal)); +} + +void GenerateNapiPromise(napi_env env, napi_ref callback, napi_deferred *deferred, napi_value *promise) +{ + if (callback == nullptr) { + NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, deferred, promise)); + } else { + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, promise)); + } +} + +void DeleteNapiContext(napi_env env, napi_async_work &asyncWork, napi_ref &callback) +{ + if (asyncWork != nullptr) { + napi_delete_async_work(env, asyncWork); + asyncWork = nullptr; + } + + if (callback != nullptr) { + napi_delete_reference(env, callback); + callback = nullptr; + } +} + +void FreeCmContext(CmContext *&context) +{ + if (context == nullptr) { + return; + } + + context->userId = 0; + context->uid = 0; + + CmFree(context); + context = nullptr; +} + +void FreeCertList(CertList *&certList) +{ + if (certList == NULL || certList->certAbstract == NULL) { + return; + } + + FreeCertAbstract(certList->certAbstract); + certList->certAbstract = NULL; + + CmFree(certList); + certList = NULL; +} + +void FreeCredentialList(CredentialList *&credentialList) +{ + if (credentialList == NULL || credentialList->credentialAbstract == NULL) { + return; + } + + FreeCredentialAbstract(credentialList->credentialAbstract); + credentialList->credentialAbstract = NULL; + + CmFree(credentialList); + credentialList = NULL; +} + +void FreeCertInfo(CertInfo *&certInfo) +{ + if (certInfo == nullptr) { + return; + } + + certInfo->status = false; + + if (certInfo->certInfo.data != nullptr) { + CmFree(certInfo->certInfo.data); + } + + CmFree(certInfo); + certInfo = nullptr; +} + +void FreeCredential(Credential *&credential) +{ + if (credential == nullptr) { + return; + } + + if (credential->credData.data != nullptr) { + CmFree(credential->credData.data); + } + + CmFree(credential); + credential = nullptr; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_get_app_cert_info.cpp b/interfaces/kits/napi/src/cm_napi_get_app_cert_info.cpp new file mode 100644 index 0000000..a3eceaa --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_get_app_cert_info.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_get_app_cert_info.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_GET_APP_CERT_INFO_MIN_ARGS = 1; +constexpr int CM_NAPI_GET_APP_CERT_INFO_MAX_ARGS = 2; +} // namespace + +struct GetAppCertInfoAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; + + struct CmBlob *keyUri = nullptr; + uint32_t store = 0; + struct Credential *credential = nullptr; +}; +using GetAppCertInfoAsyncContext = GetAppCertInfoAsyncContextT *; + +static GetAppCertInfoAsyncContext CreateGetAppCertInfoAsyncContext() +{ + GetAppCertInfoAsyncContext context = + static_cast(CmMalloc(sizeof(GetAppCertInfoAsyncContextT))); + if (context != nullptr) { + (void)memset_s(context, sizeof(GetAppCertInfoAsyncContextT), 0, sizeof(GetAppCertInfoAsyncContextT)); + } + return context; +} + +static void DeleteGetAppCertInfoAsyncContext(napi_env env, GetAppCertInfoAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + if (context->keyUri != nullptr) { + FreeCmBlob(context->keyUri); + } + + if (context->credential != nullptr) { + FreeCredential(context->credential); + } + + CmFree(context); + context = nullptr; +} + +static napi_value GetAppCertInfoParseParams( + napi_env env, napi_callback_info info, GetAppCertInfoAsyncContext context) +{ + size_t argc = CM_NAPI_GET_APP_CERT_INFO_MAX_ARGS; + napi_value argv[CM_NAPI_GET_APP_CERT_INFO_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_GET_APP_CERT_INFO_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("CertInfo Missing parameter"); + return nullptr; + } + + size_t index = 0; + napi_value result = ParseString(env, argv[index], context->keyUri); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get key uri"); + return nullptr; + } + + index++; + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + + context->store = APPLICATION_CERTIFICATE_STORE; /* 0 is store type, indicate application certificate */ + return GetInt32(env, 0); +} + +static napi_value GetAppCertInfoWriteResult(napi_env env, GetAppCertInfoAsyncContext context) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_object(env, &result)); + napi_value certInfo = GenerateAppCertInfo(env, context->credential); + if (certInfo != nullptr) { + napi_set_named_property(env, result, CM_RESULT_PRPPERTY_CREDENTIAL.c_str(), certInfo); + } else { + NAPI_CALL(env, napi_get_undefined(env, &result)); + } + return result; +} + +static void InitAppCert(struct Credential *credential) +{ + credential->credData.data = (uint8_t *)CmMalloc(MAX_LEN_CERTIFICATE_CHAIN); + if (credential->credData.data == NULL) { + CM_LOG_E("malloc file buffer failed"); + return; + } + (void)memset_s(credential->credData.data, MAX_LEN_CERTIFICATE_CHAIN, 0, MAX_LEN_CERTIFICATE_CHAIN); + credential->credData.size = MAX_LEN_CERTIFICATE_CHAIN; +} + +static napi_value GetAppCertInfoAsyncWork(napi_env env, GetAppCertInfoAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "GetAppCertInfoAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + GetAppCertInfoAsyncContext context = static_cast(data); + + context->credential = (struct Credential *)CmMalloc(sizeof(struct Credential)); + if (context->credential != nullptr) { + (void)memset_s(context->credential, sizeof(struct Credential), 0, sizeof(struct Credential)); + InitAppCert(context->credential); + } + context->result = CmGetAppCert(context->keyUri, context->store, context->credential); + }, + [](napi_env env, napi_status status, void *data) { + GetAppCertInfoAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + result[1] = GetAppCertInfoWriteResult(env, context); + } else { + const char *errorMessage = "get app cert info error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteGetAppCertInfoAsyncContext(env, context); + }, + (void *)context, + &context->asyncWork)); + + napi_status status = napi_queue_async_work(env, context->asyncWork); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteGetAppCertInfoAsyncContext(env, context); + CM_LOG_E("could not queue async work"); + return nullptr; + } + + return promise; +} + +napi_value CMNapiGetAppCertInfo(napi_env env, napi_callback_info info) +{ + GetAppCertInfoAsyncContext context = CreateGetAppCertInfoAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + + napi_value result = GetAppCertInfoParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteGetAppCertInfoAsyncContext(env, context); + return nullptr; + } + result = GetAppCertInfoAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteGetAppCertInfoAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_get_app_cert_list.cpp b/interfaces/kits/napi/src/cm_napi_get_app_cert_list.cpp new file mode 100644 index 0000000..71ca5ca --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_get_app_cert_list.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_get_app_cert_list.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_GET_APP_CERT_LIST_MIN_ARGS = 0; +constexpr int CM_NAPI_GET_APP_CERT_LIST_MAX_ARGS = 1; +} // namespace + +struct GetAppCertListAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; + uint32_t store = 0; + struct CredentialList *credentialList = nullptr; +}; +using GetAppCertListAsyncContext = GetAppCertListAsyncContextT *; + +static GetAppCertListAsyncContext CreateGetAppCertListAsyncContext() +{ + GetAppCertListAsyncContext context = + static_cast(CmMalloc(sizeof(GetAppCertListAsyncContextT))); + if (context != nullptr) { + (void)memset_s(context, sizeof(GetAppCertListAsyncContextT), 0, sizeof(GetAppCertListAsyncContextT)); + } + return context; +} + +static void DeleteGetAppCertListAsyncContext(napi_env env, GetAppCertListAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + if (context->credentialList != nullptr) { + FreeCredentialList(context->credentialList); + } + + CmFree(context); + context = nullptr; +} + +static napi_value GetAppCertListParseParams( + napi_env env, napi_callback_info info, GetAppCertListAsyncContext context) +{ + size_t argc = CM_NAPI_GET_APP_CERT_LIST_MAX_ARGS; + napi_value argv[CM_NAPI_GET_APP_CERT_LIST_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_GET_APP_CERT_LIST_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("Missing parameter"); + return nullptr; + } + + size_t index = 0; + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + + context->store = APPLICATION_CERTIFICATE_STORE; /* 0 is store type, indicate application certificate */ + return GetInt32(env, 0); +} + +static napi_value GetAppCertListWriteResult(napi_env env, GetAppCertListAsyncContext context) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_object(env, &result)); + napi_value credentail = GenerateCredentialAbstractArray(env, + context->credentialList->credentialAbstract, context->credentialList->credentialCount); + if (credentail != nullptr) { + napi_set_named_property(env, result, CM_RESULT_PRPPERTY_CREDENTIAL_LIST.c_str(), credentail); + } else { + NAPI_CALL(env, napi_get_undefined(env, &result)); + } + return result; +} + +static void InitAppCertList(struct CredentialList *credentialList) +{ + uint32_t buffSize = (MAX_COUNT_CERTIFICATE * sizeof(struct CredentialAbstract)); + credentialList->credentialAbstract = (struct CredentialAbstract *)CmMalloc(buffSize); + if (credentialList->credentialAbstract == NULL) { + CM_LOG_E("malloc file buffer failed"); + return; + } + (void)memset_s(credentialList->credentialAbstract, buffSize, 0, buffSize); + credentialList->credentialCount = MAX_COUNT_CERTIFICATE; +} + +static napi_value GetAppCertListAsyncWork(napi_env env, GetAppCertListAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "GetAppCertListAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + GetAppCertListAsyncContext context = static_cast(data); + + context->credentialList = (struct CredentialList *)CmMalloc(sizeof(struct CredentialList)); + if (context->credentialList != nullptr) { + InitAppCertList(context->credentialList); + } + context->result = CmGetAppCertList(context->store, context->credentialList); + }, + [](napi_env env, napi_status status, void *data) { + GetAppCertListAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + result[1] = GetAppCertListWriteResult(env, context); + } else { + const char *errorMessage = "get app cert list info error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteGetAppCertListAsyncContext(env, context); + CM_LOG_I("get app cert list end"); + }, + (void *)context, + &context->asyncWork)); + + napi_status napiStatus = napi_queue_async_work(env, context->asyncWork); + if (napiStatus != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteGetAppCertListAsyncContext(env, context); + CM_LOG_E("get app cert list could not queue async work"); + return nullptr; + } + return promise; +} + +napi_value CMNapiGetAppCertList(napi_env env, napi_callback_info info) +{ + GetAppCertListAsyncContext context = CreateGetAppCertListAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + + napi_value result = GetAppCertListParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteGetAppCertListAsyncContext(env, context); + return nullptr; + } + result = GetAppCertListAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteGetAppCertListAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_get_system_cert_info.cpp b/interfaces/kits/napi/src/cm_napi_get_system_cert_info.cpp new file mode 100644 index 0000000..012408f --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_get_system_cert_info.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_get_system_cert_info.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_GET_SYSTEM_CERT_INFO_MIN_ARGS = 2; +constexpr int CM_NAPI_GET_SYSTEM_CERT_INFO_MAX_ARGS = 3; +} // namespace + +struct GetCertInfoAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; + struct CmContext *cmContext = nullptr; + struct CmBlob *certUri = nullptr; + uint32_t store = 0; + struct CertInfo *certificate = nullptr; +}; +using GetCertInfoAsyncContext = GetCertInfoAsyncContextT *; + +static GetCertInfoAsyncContext CreateGetCertInfoAsyncContext() +{ + GetCertInfoAsyncContext context = + static_cast(CmMalloc(sizeof(GetCertInfoAsyncContextT))); + if (context != nullptr) { + (void)memset_s( + context, sizeof(GetCertInfoAsyncContextT), 0, sizeof(GetCertInfoAsyncContextT)); + } + return context; +} + +static void DeleteGetCertInfoAsyncContext(napi_env env, GetCertInfoAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + if (context->cmContext != nullptr) { + FreeCmContext(context->cmContext); + } + + if (context->certUri != nullptr) { + FreeCmBlob(context->certUri); + } + + if (context->certificate != nullptr) { + FreeCertInfo(context->certificate); + } + + CmFree(context); + context = nullptr; +} + +static napi_value GetSystemCertInfoParseParams( + napi_env env, napi_callback_info info, GetCertInfoAsyncContext context) +{ + size_t argc = CM_NAPI_GET_SYSTEM_CERT_INFO_MAX_ARGS; + napi_value argv[CM_NAPI_GET_SYSTEM_CERT_INFO_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_GET_SYSTEM_CERT_INFO_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("Missing parameter"); + return nullptr; + } + + size_t index = 0; + napi_value result = ParseCmContext(env, argv[index], context->cmContext); + if (result == nullptr) { + CM_LOG_E("CertInfo could not get cert manager context"); + return nullptr; + } + + index++; + result = ParseString(env, argv[index], context->certUri); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get cert uri"); + return nullptr; + } + + index++; + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + + context->store = SYSTEM_CERTIFICATE_STORE; /* 1 is store type, indicate system trusted certificate */ + return GetInt32(env, 0); +} + +static napi_value GetCertInfoWriteResult(napi_env env, GetCertInfoAsyncContext context) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_object(env, &result)); + napi_value certInfo = GenerateCertInfo(env, context->certificate); + if (certInfo != nullptr) { + napi_set_named_property(env, result, CM_RESULT_PRPPERTY_CERTINFO.c_str(), certInfo); + } else { + NAPI_CALL(env, napi_get_undefined(env, &result)); + } + return result; +} + +static napi_value GetCertInfoAsyncWork(napi_env env, GetCertInfoAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "GetCertInfoAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + GetCertInfoAsyncContext context = static_cast(data); + + context->certificate = (struct CertInfo *)CmMalloc(sizeof(struct CertInfo)); + if (context->certificate != nullptr) { + (void)memset_s(context->certificate, sizeof(struct CertInfo), 0, sizeof(struct CertInfo)); + } + context->result = CmGetCertInfo(context->cmContext, context->certUri, context->store, context->certificate); + }, + [](napi_env env, napi_status status, void *data) { + GetCertInfoAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + result[1] = GetCertInfoWriteResult(env, context); + } else { + const char *errorMessage = "get system cert info error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteGetCertInfoAsyncContext(env, context); + CM_LOG_I("get system cert info end"); + }, + (void *)context, + &context->asyncWork)); + napi_status status = napi_queue_async_work(env, context->asyncWork); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteGetCertInfoAsyncContext(env, context); + CM_LOG_E("get system cert info could not queue async work"); + return nullptr; + } + return promise; +} + +napi_value CMNapiGetSystemCertInfo(napi_env env, napi_callback_info info) +{ + GetCertInfoAsyncContext context = CreateGetCertInfoAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + + napi_value result = GetSystemCertInfoParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteGetCertInfoAsyncContext(env, context); + return nullptr; + } + result = GetCertInfoAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteGetCertInfoAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_get_system_cert_list.cpp b/interfaces/kits/napi/src/cm_napi_get_system_cert_list.cpp new file mode 100644 index 0000000..acc0349 --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_get_system_cert_list.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_get_system_cert_list.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_GET_SYSTEM_CERT_LIST_MIN_ARGS = 1; +constexpr int CM_NAPI_GET_SYSTEM_CERT_LIST_MAX_ARGS = 2; +} // namespace + +struct GetCertListAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; + struct CmContext *cmContext = nullptr; + uint32_t store = 0; + struct CertList *certificateList = nullptr; +}; +using GetCertListAsyncContext = GetCertListAsyncContextT *; + +static GetCertListAsyncContext CreateGetCertListAsyncContext() +{ + GetCertListAsyncContext context = + static_cast(CmMalloc(sizeof(GetCertListAsyncContextT))); + if (context != nullptr) { + (void)memset_s( + context, sizeof(GetCertListAsyncContextT), 0, sizeof(GetCertListAsyncContextT)); + } + return context; +} + +static void DeleteGetCertListAsyncContext(napi_env env, GetCertListAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + if (context->cmContext != nullptr) { + FreeCmContext(context->cmContext); + } + + if (context->certificateList != nullptr) { + FreeCertList(context->certificateList); + } + + CmFree(context); + context = nullptr; +} + +static napi_value GetCertListParseParams( + napi_env env, napi_callback_info info, GetCertListAsyncContext context) +{ + size_t argc = CM_NAPI_GET_SYSTEM_CERT_LIST_MAX_ARGS; + napi_value argv[CM_NAPI_GET_SYSTEM_CERT_LIST_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_GET_SYSTEM_CERT_LIST_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("Missing parameter"); + return nullptr; + } + + size_t index = 0; + napi_value result = ParseCmContext(env, argv[index], context->cmContext); + if (result == nullptr) { + CM_LOG_E("could not get cert manager context"); + return nullptr; + } + + index++; + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + + context->store = SYSTEM_CERTIFICATE_STORE; /* 1 is store type, indicate system trusted certificate */ + return GetInt32(env, 0); +} + +static napi_value GetCertListWriteResult(napi_env env, GetCertListAsyncContext context) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_object(env, &result)); + napi_value certChains = GenerateCertAbstractArray(env, + context->certificateList->certAbstract, context->certificateList->certsCount); + if (certChains != nullptr) { + napi_set_named_property(env, result, CM_RESULT_PRPPERTY_CERTLIST.c_str(), certChains); + } else { + NAPI_CALL(env, napi_get_undefined(env, &result)); + } + return result; +} + +static napi_value GetCertListAsyncWork(napi_env env, GetCertListAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "GetCertListAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + GetCertListAsyncContext context = static_cast(data); + + context->certificateList = (struct CertList *)CmMalloc(sizeof(struct CertList)); + if (context->certificateList != nullptr) { + context->certificateList->certAbstract = nullptr; + context->certificateList->certsCount = 0; + } + context->result = CmGetCertList(context->cmContext, context->store, context->certificateList); + }, + [](napi_env env, napi_status status, void *data) { + GetCertListAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + result[1] = GetCertListWriteResult(env, context); + } else { + const char *errorMessage = "get system cert list error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteGetCertListAsyncContext(env, context); + }, + (void *)context, + &context->asyncWork)); + + napi_status status = napi_queue_async_work(env, context->asyncWork); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteGetCertListAsyncContext(env, context); + CM_LOG_E("could not queue async work"); + return nullptr; + } + return promise; +} + +napi_value CMNapiGetSystemCertList(napi_env env, napi_callback_info info) +{ + GetCertListAsyncContext context = CreateGetCertListAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + napi_value result = GetCertListParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteGetCertListAsyncContext(env, context); + return nullptr; + } + result = GetCertListAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteGetCertListAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_install_app_cert.cpp b/interfaces/kits/napi/src/cm_napi_install_app_cert.cpp new file mode 100644 index 0000000..28db760 --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_install_app_cert.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_install_app_cert.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_INSTALL_APP_CERT_MIN_ARGS = 3; +constexpr int CM_NAPI_INSTALL_APP_CERT_MAX_ARGS = 4; +} // namespace + +struct InstallAppCertAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; + struct CmBlob *keystore = nullptr; + struct CmBlob *keystorePwd = nullptr; + struct CmBlob *keyAlias = nullptr; + struct CmBlob *keyUri = nullptr; + uint32_t store = 0; +}; +using InstallAppCertAsyncContext = InstallAppCertAsyncContextT *; + +static InstallAppCertAsyncContext CreateInstallAppCertAsyncContext() +{ + InstallAppCertAsyncContext context = + static_cast(CmMalloc(sizeof(InstallAppCertAsyncContextT))); + if (context != nullptr) { + (void)memset_s(context, sizeof(InstallAppCertAsyncContextT), 0, sizeof(InstallAppCertAsyncContextT)); + } + return context; +} + +static void DeleteInstallAppCertAsyncContext(napi_env env, InstallAppCertAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + if (context->keystore != nullptr) { + FreeCmBlob(context->keystore); + } + + if (context->keystorePwd != nullptr) { + FreeCmBlob(context->keystorePwd); + } + + if (context->keyAlias != nullptr) { + FreeCmBlob(context->keyAlias); + } + + if (context->keyUri != nullptr) { + FreeCmBlob(context->keyUri); + } + + CmFree(context); + context = nullptr; +} + +static napi_value InstallAppCertParseParams( + napi_env env, napi_callback_info info, InstallAppCertAsyncContext context) +{ + size_t argc = CM_NAPI_INSTALL_APP_CERT_MAX_ARGS; + napi_value argv[CM_NAPI_INSTALL_APP_CERT_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_INSTALL_APP_CERT_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("Missing parameter"); + return nullptr; + } + + size_t index = 0; + context->keystore = (CmBlob *)CmMalloc(sizeof(CmBlob)); + if (context->keystore == nullptr) { + CM_LOG_E("could not alloc memory"); + return nullptr; + } + (void)memset_s(context->keystore, sizeof(CmBlob), 0, sizeof(CmBlob)); + + napi_value result = GetUint8Array(env, argv[index], *context->keystore); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get keystore"); + return nullptr; + } + + index++; + result = ParseString(env, argv[index], context->keystorePwd); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get keystore Pwd"); + return nullptr; + } + + index++; + result = ParseString(env, argv[index], context->keyAlias); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get uri"); + return nullptr; + } + + index++; + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + + context->store = APPLICATION_CERTIFICATE_STORE; + return GetInt32(env, 0); +} + +static void InitKeyUri(struct CmBlob *keyUri) +{ + if (keyUri == nullptr) { + return; + } + + keyUri->data = (uint8_t *)CmMalloc(MAX_LEN_URI); + if (keyUri->data == NULL) { + CM_LOG_E("malloc file buffer failed"); + return; + } + + (void)memset_s(keyUri->data, MAX_LEN_URI, 0, MAX_LEN_URI); + keyUri->size = MAX_LEN_URI; +} + +static napi_value InstallAppCertAsyncWork(napi_env env, InstallAppCertAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "InstallAppCertAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + InstallAppCertAsyncContext context = static_cast(data); + InitKeyUri(context->keyUri); + context->result = CmInstallAppCert(context->keystore, + context->keystorePwd, context->keyAlias, context->store, context->keyUri); + }, + [](napi_env env, napi_status status, void *data) { + InstallAppCertAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, true, &result[1])); + } else { + const char *errorMessage = "install app cert error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteInstallAppCertAsyncContext(env, context); + }, + (void *)context, + &context->asyncWork)); + + napi_status status = napi_queue_async_work(env, context->asyncWork); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteInstallAppCertAsyncContext(env, context); + CM_LOG_E("could not queue async work"); + return nullptr; + } + return promise; +} + +napi_value CMNapiInstallAppCert(napi_env env, napi_callback_info info) +{ + InstallAppCertAsyncContext context = CreateInstallAppCertAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + + napi_value result = InstallAppCertParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteInstallAppCertAsyncContext(env, context); + return nullptr; + } + result = InstallAppCertAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteInstallAppCertAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_set_cert_status.cpp b/interfaces/kits/napi/src/cm_napi_set_cert_status.cpp new file mode 100644 index 0000000..19cab48 --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_set_cert_status.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_set_cert_status.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_SET_CERT_STATUS_MIN_ARGS = 4; +constexpr int CM_NAPI_SET_CERT_STATUS_MAX_ARGS = 5; +} // namespace + +struct SetCertStatusAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; + struct CmContext *cmContext = nullptr; + struct CmBlob *certUri = nullptr; + uint32_t store = 0; + bool status = false; +}; +using SetCertStatusAsyncContext = SetCertStatusAsyncContextT *; + +static SetCertStatusAsyncContext CreateSetCertStatusAsyncContext() +{ + SetCertStatusAsyncContext context = + static_cast(CmMalloc(sizeof(SetCertStatusAsyncContextT))); + if (context != nullptr) { + (void)memset_s( + context, sizeof(SetCertStatusAsyncContextT), 0, sizeof(SetCertStatusAsyncContextT)); + } + return context; +} + +static void DeleteSetCertStatusAsyncContext(napi_env env, SetCertStatusAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + if (context->certUri != nullptr) { + FreeCmBlob(context->certUri); + } + + if (context->cmContext != nullptr) { + FreeCmContext(context->cmContext); + } + + CmFree(context); + context = nullptr; +} + +static napi_value SetCertStatusParseParams( + napi_env env, napi_callback_info info, SetCertStatusAsyncContext context) +{ + size_t argc = CM_NAPI_SET_CERT_STATUS_MAX_ARGS; + napi_value argv[CM_NAPI_SET_CERT_STATUS_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_SET_CERT_STATUS_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("CertStatus Missing parameter"); + return nullptr; + } + + size_t index = 0; + napi_value result = ParseString(env, argv[index], context->certUri); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("CertStatus could not get cert uri"); + return nullptr; + } + + index++; + result = ParseUint32(env, argv[index], context->store); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get store"); + return nullptr; + } + + index++; + result = ParseCmContext(env, argv[index], context->cmContext); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get cert manager context"); + return nullptr; + } + + index++; + result = ParseBoolean(env, argv[index], context->status); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get status"); + return nullptr; + } + + index++; + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + return GetInt32(env, 0); +} + +static napi_value SetCertStatusAsyncWork(napi_env env, SetCertStatusAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "SetCertStatusAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + SetCertStatusAsyncContext context = static_cast(data); + + context->result = CmSetCertStatus(context->cmContext, context->certUri, context->store, context->status); + }, + [](napi_env env, napi_status status, void *data) { + SetCertStatusAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, true, &result[1])); + } else { + const char *errorMessage = "set cert status error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteSetCertStatusAsyncContext(env, context); + }, + (void *)context, + &context->asyncWork)); + + napi_status status = napi_queue_async_work(env, context->asyncWork); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteSetCertStatusAsyncContext(env, context); + CM_LOG_E("could not queue async work"); + return nullptr; + } + return promise; +} + +napi_value CMNapiSetCertStatus(napi_env env, napi_callback_info info) +{ + SetCertStatusAsyncContext context = CreateSetCertStatusAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + + napi_value result = SetCertStatusParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteSetCertStatusAsyncContext(env, context); + return nullptr; + } + result = SetCertStatusAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteSetCertStatusAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_uninstall_all_app_cert.cpp b/interfaces/kits/napi/src/cm_napi_uninstall_all_app_cert.cpp new file mode 100644 index 0000000..f5ef134 --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_uninstall_all_app_cert.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_uninstall_all_app_cert.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_UNINSTALL_ALL_APP_CERT_MIN_ARGS = 0; +constexpr int CM_NAPI_UNINSTALL_ALL_APP_CERT_MAX_ARGS = 1; +} // namespace + +struct UninstallAllAppCertAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; +}; +using UninstallAllAppCertAsyncContext = UninstallAllAppCertAsyncContextT *; + +static UninstallAllAppCertAsyncContext CreateUinstallAllAppCertAsyncContext() +{ + UninstallAllAppCertAsyncContext context = + static_cast(CmMalloc(sizeof(UninstallAllAppCertAsyncContextT))); + if (context != nullptr) { + (void)memset_s( + context, sizeof(UninstallAllAppCertAsyncContextT), 0, sizeof(UninstallAllAppCertAsyncContextT)); + } + return context; +} + +static void DeleteUninstallAllAppCertAsyncContext(napi_env env, UninstallAllAppCertAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + CmFree(context); + context = nullptr; +} + +static napi_value UninstallAllAppCertParseParams( + napi_env env, napi_callback_info info, UninstallAllAppCertAsyncContext context) +{ + size_t argc = CM_NAPI_UNINSTALL_ALL_APP_CERT_MAX_ARGS; + napi_value argv[CM_NAPI_UNINSTALL_ALL_APP_CERT_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_UNINSTALL_ALL_APP_CERT_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("Missing parameter"); + return nullptr; + } + + size_t index = 0; + + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + + return GetInt32(env, 0); +} + +static napi_value UninstallAllAppCertAsyncWork(napi_env env, UninstallAllAppCertAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "UninstallAllAppCertAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + UninstallAllAppCertAsyncContext context = static_cast(data); + /* fix CmUninstallAllAppCert */ + context->result = 0; + }, + [](napi_env env, napi_status status, void *data) { + UninstallAllAppCertAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, true, &result[1])); + } else { + const char *errorMessage = "uninstall all app cert error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteUninstallAllAppCertAsyncContext(env, context); + }, + (void *)context, + &context->asyncWork)); + + napi_status status = napi_queue_async_work(env, context->asyncWork); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteUninstallAllAppCertAsyncContext(env, context); + CM_LOG_E("could not queue async work"); + return nullptr; + } + + return promise; +} + +napi_value CMNapiUninstallAllAppCert(napi_env env, napi_callback_info info) +{ + UninstallAllAppCertAsyncContext context = CreateUinstallAllAppCertAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + + napi_value result = UninstallAllAppCertParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteUninstallAllAppCertAsyncContext(env, context); + return nullptr; + } + result = UninstallAllAppCertAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteUninstallAllAppCertAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/cm_napi_uninstall_app_cert.cpp b/interfaces/kits/napi/src/cm_napi_uninstall_app_cert.cpp new file mode 100644 index 0000000..083c849 --- /dev/null +++ b/interfaces/kits/napi/src/cm_napi_uninstall_app_cert.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_uninstall_app_cert.h" + +#include "securec.h" + +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_napi_common.h" + +namespace CMNapi { +namespace { +constexpr int CM_NAPI_UNINSTALL_APP_CERT_MIN_ARGS = 1; +constexpr int CM_NAPI_UNINSTALL_APP_CERT_MAX_ARGS = 2; +} // namespace + +struct UninstallAppCertAsyncContextT { + napi_async_work asyncWork = nullptr; + napi_deferred deferred = nullptr; + napi_ref callback = nullptr; + + int32_t result = 0; + struct CmBlob *keyUri = nullptr; + uint32_t store = 0; +}; +using UninstallAppCertAsyncContext = UninstallAppCertAsyncContextT *; + +static UninstallAppCertAsyncContext CreateUninstallAppCertAsyncContext() +{ + UninstallAppCertAsyncContext context = + static_cast(CmMalloc(sizeof(UninstallAppCertAsyncContextT))); + if (context != nullptr) { + (void)memset_s( + context, sizeof(UninstallAppCertAsyncContextT), 0, sizeof(UninstallAppCertAsyncContextT)); + } + return context; +} + +static void DeleteUninstallAppCertAsyncContext(napi_env env, UninstallAppCertAsyncContext &context) +{ + if (context == nullptr) { + return; + } + + DeleteNapiContext(env, context->asyncWork, context->callback); + + if (context->keyUri != nullptr) { + FreeCmBlob(context->keyUri); + } + + CmFree(context); + context = nullptr; +} + +static napi_value UninstallAppCertParseParams( + napi_env env, napi_callback_info info, UninstallAppCertAsyncContext context) +{ + size_t argc = CM_NAPI_UNINSTALL_APP_CERT_MAX_ARGS; + napi_value argv[CM_NAPI_UNINSTALL_APP_CERT_MAX_ARGS] = {0}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + + if (argc < CM_NAPI_UNINSTALL_APP_CERT_MIN_ARGS) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Missing parameter"); + CM_LOG_E("Missing parameter"); + return nullptr; + } + + size_t index = 0; + napi_value result = ParseString(env, argv[index], context->keyUri); + if (result == nullptr) { + napi_throw_error(env, PARAM_TYPE_ERROR_NUMBER.c_str(), "Type error"); + CM_LOG_E("could not get cert uri"); + return nullptr; + } + + index++; + if (index < argc) { + context->callback = GetCallback(env, argv[index]); + } + + context->store = APPLICATION_CERTIFICATE_STORE; /* 0 is store type, indicate app certificate */ + return GetInt32(env, 0); +} + +static napi_value UninstallAppCertAsyncWork(napi_env env, UninstallAppCertAsyncContext context) +{ + napi_value promise = nullptr; + GenerateNapiPromise(env, context->callback, &context->deferred, &promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "UninstallAppCertAsyncWork", NAPI_AUTO_LENGTH, &resourceName)); + + NAPI_CALL(env, napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + UninstallAppCertAsyncContext context = static_cast(data); + context->result = CmUninstallAppCert(context->keyUri, context->store); + }, + [](napi_env env, napi_status status, void *data) { + UninstallAppCertAsyncContext context = static_cast(data); + napi_value result[RESULT_NUMBER] = {0}; + if (context->result == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &result[0])); + NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, true, &result[1])); + } else { + const char *errorMessage = "uninstall app cert error"; + result[0] = GenerateBusinessError(env, context->result, errorMessage); + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &result[1])); + } + if (context->deferred != nullptr) { + GeneratePromise(env, context->deferred, context->result, result, sizeof(result)); + } else { + GenerateCallback(env, context->callback, result, sizeof(result)); + } + DeleteUninstallAppCertAsyncContext(env, context); + }, + (void *)context, + &context->asyncWork)); + + napi_status status = napi_queue_async_work(env, context->asyncWork); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + DeleteUninstallAppCertAsyncContext(env, context); + CM_LOG_E("could not queue async work"); + return nullptr; + } + + return promise; +} + +napi_value CMNapiUninstallAppCert(napi_env env, napi_callback_info info) +{ + UninstallAppCertAsyncContext context = CreateUninstallAppCertAsyncContext(); + if (context == nullptr) { + CM_LOG_E("could not create context"); + return nullptr; + } + + napi_value result = UninstallAppCertParseParams(env, info, context); + if (result == nullptr) { + CM_LOG_E("could not parse params"); + DeleteUninstallAppCertAsyncContext(env, context); + return nullptr; + } + result = UninstallAppCertAsyncWork(env, context); + if (result == nullptr) { + CM_LOG_E("could not start async work"); + DeleteUninstallAppCertAsyncContext(env, context); + return nullptr; + } + return result; +} +} // namespace CertManagerNapi diff --git a/services/cert_manager_standard/BUILD.gn b/services/cert_manager_standard/BUILD.gn new file mode 100644 index 0000000..6156f20 --- /dev/null +++ b/services/cert_manager_standard/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_prebuilt_etc("cert_manager_service.rc") { + source = "cert_manager_service.cfg" + relative_install_dir = "init" + subsystem_name = "security" + part_name = "certificate_manager" +} + +ohos_shared_library("cert_manager_service") { + subsystem_name = "security" + part_name = "certificate_manager" + defines = [ + "L2_STANDARD", + "_CM_LOG_ENABLE_", + ] + deps = [ + ":cert_manager_service.rc", + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_service/main:libcert_manager_service_standard_static", + ] + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] +} diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/BUILD.gn b/services/cert_manager_standard/cert_manager_engine/main/core/BUILD.gn new file mode 100644 index 0000000..6a03768 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("cert_manager_config") { + include_dirs = [ "include" ] +} +ohos_shared_library("cert_manager_engine_core_standard") { + subsystem_name = "security" + part_name = "certificate_manager" + public_configs = [ ":cert_manager_config" ] + defines = [ + "L2_STANDARD", + "_CM_LOG_ENABLE_", + ] + include_dirs = [ + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_engine/main/core/include", + "//base/security/huks/interfaces/innerkits/huks_standard/main/include", + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/common/include", + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/os_dependency/log", + "//third_party/openssl/include", + ] + cflags = [ + "-Wall", + "-Werror", + ] + sources = [ + "src/cert_manager.c", + "src/cm_event_process.c", + "src/cert_manager_auth.c", + "src/cert_manager_file.c", + "src/cert_manager_file_operator.c", + "src/cert_manager_mem.c", + "src/cert_manager_status.c", + "src/cert_manager_uri.c", + "src/cert_manager_util.c", + "src/cm_asn1.c", + "src/cm_openssl_curve25519.c", + "src/cm_openssl_ecc.c", + "src/cm_openssl_rsa.c", + "src/rbtree.c", + ] + + deps = [ + "//base/security/certificate_manager/frameworks/cert_manager_standard/main:cert_manager_standard_frameworks", + "//third_party/openssl:libcrypto_shared", + ] + external_deps = [ + "c_utils:utils", + "huks:libhukssdk", + ] +} diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager.h new file mode 100644 index 0000000..48a28e3 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CERT_MANAGER_H +#define CERT_MANAGER_H + +#include "cert_manager_type.h" +#include "cm_type.h" + +#define CERT_MAX_PATH_LEN 256 +#define CERT_DIR "/data/service/el1/public/cert_manager_service/certificates" + +#define CREDNTIAL_STORE "/data/service/el1/public/cert_manager_service/certificates/credential/" +#define SYSTEM_CA_STORE "/system/etc/security/certificates/" +#define USER_CA_STORE "/data/service/el1/public/cert_manager_service/certificates/user/" +#define APP_CA_STORE "/data/service/el1/public/cert_manager_service/certificates/priv_credential/" + +#define CM_ERROR(rc) (int32_t) (rc) + +#define CREDENTIAL_STORE "./certificates/credential/" + +#ifdef __cplusplus +extern "C" { +#endif + +void CmCertificateListFree(struct CmMutableBlob *certListData, uint32_t certListSize); + +/** + * Initialize CertManager +*/ +int32_t CertManagerInitialize(void); + +/** + * List trusted certificates in the indicated trusted store or stores. + * Memory will be allocated and should be released by CertManagerFreeTrustedCertificatesList. + * Paras: + * [IN] context - The context of the call. + * [OUT] certificateList - The certificate list retrieved. + * [IN] store - The trusted store where the certificate is to be listed. + * Returns -CMR_OK on success. +*/ +int32_t CertManagerListTrustedCertificates( + const struct CmContext *context, + struct CmBlob *certificateList, + uint32_t store, struct CertBlob *certBlob, uint32_t *status); + +/** + * Get subjetc name form certificate. Memory should be allocate by the caller. + * If the data is in subjectName is NULL, The resulting size indicated the size of the buffer required. + * Paras: + * [IN] context - The context of the call. + * [IN] certificateList - The resulting certificate list. + * [IN] store - The trusted store to be listed. + * [OUT] subjectName - The subject name to be matched. + * Returns -CMR_OK on success. +*/ +int32_t CertManagerListCertificatesBySubjectName( + const struct CmContext *context, + struct CmBlob *certificateList, + uint32_t store, + const struct CmBlob *subjectName); + +/** + * List trusted certificates in the indicated trusted store or stores. + * Memory will be allocated and should be released by CertManagerFreeTrustedCertificatesList. + * Paras: + * [IN] context - The context of the call. + * [IN] certificate - The certificate for which the status is to set. + * [IN] store - The trusted store where the certificate is to be considered. + * [IN] status - The new status of the certificate.Must be one of CERT_STATUS* values. + * Returns -CMR_OK on success. + */ +int32_t CertManagerSetCertificatesStatus( + const struct CmContext *context, + const struct CmBlob *certificate, + uint32_t store, + uint32_t status); + +int32_t CertManagerFindCertFileName( + const struct CmContext *context, const struct CmBlob *certificate, uint32_t store, + struct CmMutableBlob *path, struct CmMutableBlob *fileName); + +int32_t CertManagerFindCertFileNameByUri( + const struct CmContext *context, const struct CmBlob *certUri, uint32_t store, struct CmMutableBlob *path); + +int32_t CmGetCertificatesByUri(const struct CmContext *context, struct CmBlob *certificateList, + uint32_t store, const struct CmBlob *nameDigest, uint32_t *status); + +/** + * Remove a trusted certificate from the indicated trusted store. + * Params: + * [IN] context - The context of the call. + * [IN] certificate - The certificate data to be removed. + * [IN] store - The trusted store where the certificate is to be removd. + * Returns CMR_OK on success. + */ +int32_t CmRemoveAppCert( + const struct CmContext *context, + const struct CmBlob *certUri, + uint32_t store); + +/** + * Import a raw key pair. + * Pfarams: + * [IN] context - The context of the call. + * [IN] keypair - The raw key pair. + * [IN] properties - Key properties for the new key pair + * [IN] name - Name of the key pair. + * The length of the name cannot exceed CM_NAME_MAX_LEN. + * Returns CMR_OK on success. + */ +int32_t CertManagerImportKeyPair( + const struct CMApp *caller, + const struct CmBlob *keypair, + const struct CMKeyProperties *properties, + const char *name); + +int32_t GetFilePath(const struct CmContext *context, uint32_t store, char *pathPtr, + char *suffix, uint32_t *suffixLen); + +int32_t CmRemoveAllAppCert(const struct CmContext *context); + +int32_t BuildObjUri(char **objUri, const char *name, uint32_t type, const struct CMApp *app); + +int32_t CmFreeCaFileNames(struct CmMutableBlob *fileNames); + +int32_t CmServiceGetAppCertList(const struct CmContext *context, uint32_t store, struct CmBlob *fileNames, + const uint32_t fileSize, uint32_t *fileCount); + +int32_t CmGetFilePath(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathBlob); + +void CmFreeFileNameUri(struct CmBlob *uri, uint32_t size); + +void CmFreeFileNames(struct CmBlob *fileNames, const uint32_t fileSize); + +int32_t CmGetUri(const char *filePath, struct CmBlob *uriBlob); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file.h new file mode 100644 index 0000000..24c9ba0 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_FILE_H +#define CERT_MANAGER_FILE_H + +#include "cert_manager_file.h" +#include "cm_type.h" + +#ifdef _cplusplus +extern "C" +#endif + +int32_t CertManagerGetFilenames(struct CmMutableBlob *fileNames, const char *path, struct CmBlob *uri); + +uint32_t CertManagerFileSize(const char *path, const char *fileName); + +uint32_t CertManagerFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len); + +int32_t CertManagerFileWrite(const char *path, const char *fileName, uint32_t offset, + const uint8_t *buf, uint32_t len); + +int32_t CertManagerFileRemove(const char *path, const char *fileName); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file_operator.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file_operator.h new file mode 100644 index 0000000..442d131 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_file_operator.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_FILE_OPERATOR_H +#define CM_FILE_OPERATOR_H + +#include "cert_manager_type.h" + +#define CM_PROCESS_INFO_LEN 128 +#define CM_MAX_FILE_NAME_LEN 512 +#define CM_MAX_DIRENT_FILE_LEN 256 + +#define CM_KEY_STORE_KEY_PATH "key" +#define CM_KEY_STORE_ROOT_KEY_PATH "info" +#define CM_KEY_STORE_CERTCHAIN_PATH "certchain" + +#ifdef _STORAGE_LITE_ + #define CM_KEY_STORE_PATH CM_CONFIG_KEY_STORE_PATH +#else + #ifdef L2_STANDARD + #define CM_KEY_STORE_PATH "/data/data/maindata" + #define CM_KEY_STORE_BAK_PATH "/data/data/bakdata" + #else + #define CM_KEY_STORE_PATH "/storage/maindata" + #define CM_KEY_STORE_BAK_PATH "/storage/bakdata" + #endif +#endif + +struct CmFileDirentInfo { + char fileName[CM_MAX_DIRENT_FILE_LEN]; /* point to dirent->d_name */ +}; + +enum CmStoragePathType { + CM_STORAGE_MAIN_PATH, + CM_STORAGE_BACKUP_PATH, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t CmFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len); + +int32_t CmFileWrite(const char *path, const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len); + +int32_t CmFileRemove(const char *path, const char *fileName); + +uint32_t CmFileSize(const char *path, const char *fileName); + +int32_t CmMakeDir(const char *path); + +void *CmOpenDir(const char *path); + +int32_t CmCloseDir(void *dirp); + +int32_t CmGetDirFile(void *dirp, struct CmFileDirentInfo *direntInfo); + +int32_t CmIsDirExist(const char *path); + +int32_t CmUserIdLayerGetFileCountAndNames(const char *path, struct CmBlob *fileNames, + const uint32_t arraySize, uint32_t *fileCount); + +#ifdef __cplusplus +} +#endif + +#endif /* CM_FILE_OPERATOR_H */ diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_mem.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_mem.h new file mode 100644 index 0000000..e6feb1e --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_mem.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_MEM_H +#define CM_MEM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void *CMMalloc(size_t size); +void CMFree(void *ptr); + +#define SELF_FREE_PTR(PTR, FREE_FUNC) \ +{ \ + if ((PTR) != NULL) { \ + FREE_FUNC(PTR); \ + (PTR) = NULL; \ + } \ +} + +#define CM_FREE_PTR(p) SELF_FREE_PTR(p, CMFree) + +#define CM_FREE_BLOB(blob) do { \ + if ((blob).data != NULL) { \ + CMFree((blob).data); \ + (blob).data = NULL; \ + } \ + (blob).size = 0; \ +} while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* CM_MEM_H */ diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_status.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_status.h new file mode 100644 index 0000000..dfad306 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_status.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_STATUS_H +#define CERT_MANAGER_STATUS_H + +#include "cert_manager_type.h" +#include "cert_manager_mem.h" + +#include "rbtree.h" +#include "cm_type.h" + +#define CERT_STATUS_ENANLED ((uint32_t) 0) +#define CERT_STATUS_DISABLED ((uint32_t) 1) +#define CERT_STATUS_MAX CERT_STATUS_DISABLED +#define CERT_STATUS_INVALID ((uint32_t)(CERT_STATUS_MAX + 1)) + +// integrity protection key for internal use only. +#define CM_INTEGRITY_KEY_URI "oh:o=ik;t=mk;a=cm" +#define CM_INTEGRITY_TAG_LEN ((uint32_t) 32) +#define CM_INTEGRITY_SALT_LEN ((uint32_t) 32) +#define VERSION_1 ((uint32_t) 0) +#define VERSION_1 ((uint32_t) 0) + +#define CERT_STATUS_ENABLED ((uint32_t) 0) +#define CERT_STATUS_DISABLED ((uint32_t) 1) + +#define DECODE_UINT32(_b) (uint32_t)(((_b)[0] << 24) | ((_b)[1] << 16) | ((_b)[2] << 8) | (_b)[3]) +#define ENCODE_UINT32(_b, _i) do { (_b)[0] = ((_i) >> 24) & 0xff; (_b)[1] = ((_i) >> 16) & 0xff; \ + (_b)[2] = ((_i) >> 8) & 0xff; (_b)[3] = (_i) & 0xff; } while (0) + +#define CERT_STATUS_DIR "/data/service/el1/public/cert_manager_service/status" +#define CERT_STATUS_SYSTEM_STORE "system" +#define CERT_STATUS_USER_STORE "user" +#define CERT_STATUS_APPLICATION_STORE "app" + +#define CM_ERROR(rc) (int32_t) (rc) + +#define ASSERT_ARGS(c) if (!(c)) { CM_LOG_W("Invalid args: %s\n", #c); return CMR_ERROR_INVALID_ARGUMENT; } +#define ASSERT_FUNC(f) if (CMR_OK != (f)) { CM_LOG_W("Failed: %s\n", #f); return CMR_ERROR; } + +#define ASSERT_CM_CALL(f) do {int32_t _rc = (f); if ((_rc) != CM_SUCCESS) { return CM_ERROR((_rc)); }} while (0) + +#define TRY_FUNC(f, rc) do { \ + (rc) = (f); if ((rc)) { CM_LOG_W("Failed: %s, %d\n", #f, (rc)); goto finally; }} while (0) + +#define FREE_PTR(p) if ((p) != NULL) { CMFree((p)); (p) = NULL; } + +#define CM_BLOB(b) (struct CmBlob) { .size = (b)->size, .data = (uint8_t *) (b)->data } + +#define HKS_BLOB(b) (struct HksBlob) { .size = (b)->size, .data = (uint8_t *) (b)->data } + +#define TRY_HKS_CALL(f, rc) do {int32_t _rc = (f); if ((_rc) != HKS_SUCCESS) { \ + CM_LOG_W("Failed: %s, %d\n", #f, (_rc)); (rc) = CM_ERROR((_rc)); goto finally; }} while (0) + +typedef int (*RbTreeValueEncoder)(RbTreeValue value, uint8_t *buf, uint32_t *size); + +#ifdef __cplusplus +extern "C" { +#endif + +struct CertStatus { + uint32_t userId; + uint32_t uid; + uint32_t status; + char *fileName; +}; + +int32_t CertManagerSetCertificatesStatus( + const struct CmContext *context, + const struct CmBlob *certUri, + uint32_t store, + uint32_t status); + +int32_t CertManagerGetCertificatesStatus( + const struct CmContext *context, + const struct CmBlob *certificate, + uint32_t store, + uint32_t *status); + +int32_t CertManagerStatusInit(void); +int32_t CertManagerStatusDestroy(void); +int32_t SetcertStatus(const struct CmContext *context, const struct CmBlob *certUri, + uint32_t store, uint32_t status, uint32_t *stp); + +#ifdef __cplusplus +} +#endif + +#endif // CERT_MANAGER_STATUS_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_type.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_type.h new file mode 100644 index 0000000..6d3ceb6 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_type.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_TYPES_H +#define CERT_MANAGER_TYPES_H + +#include +#include +#include +#include +#include "stdbool.h" + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Authentication related macros. These have to follow the definitions in HUKS. +#define CM_AUTH_TYPE_NONE 0 +#define CM_AUTH_TYPE_BIO 1 +#define CM_AUTH_TYPE_PASSCODE 2 + +enum CMErrorCode { + CMR_OK = 0, + CMR_ERROR = -1, +}; + +#define CM_AUTH_TYPE_NONE 0 +#define CM_HMAC_KEY_SIZE_256 256 + +struct CMKeyProperties { + uint32_t type; + uint32_t alg; + uint32_t size; + uint32_t padding; + uint32_t purpose; + uint32_t digest; + uint32_t authType; + uint32_t authTimeout; +}; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_uri.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_uri.h new file mode 100644 index 0000000..f89885a --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_uri.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_URI_H +#define CERT_MANAGER_URI_H + +#include "cert_manager_type.h" +#include "cert_manager_mem.h" +#include "cm_type.h" +#include "hks_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEC_LEN 10 + +// maximum length of object names for cert manager +#define CM_NAME_MAX_LEN 32 +// maximum length of URI +#define CM_URI_MAX_LEN 256 + +#define CM_URI_TYPE_CERTIFICATE ((uint32_t)0) +#define CM_URI_TYPE_MAC_KEY ((uint32_t)1) +#define CM_URI_TYPE_APP_KEY ((uint32_t)2) +#define CM_URI_TYPE_WLAN_KEY ((uint32_t)3) +#define CM_URI_TYPE_MAX CM_URI_TYPE_WLAN_KEY +#define CM_URI_TYPE_INVALID (CM_URI_TYPE_MAX+1) + +#define MALLOC CMMalloc +#define FREE CMFree + +#define ASSERT_MALLOC(p, sz) do { (p) = MALLOC(sz); if ( (p) == NULL) { \ + CM_LOG_E("Failed to allocate memory of size: %u\n", (uint32_t) (sz)); return CMR_ERROR_MALLOC_FAIL; } } while (0) + +// object types: certificate, mac-key, app-key, WLAN-key +static const char *g_types[] = { "c", "m", "ak", "wk" }; +static const uint32_t TYPE_COUNT = 4; + +struct CMUri { + // path components + char *object; + uint32_t type; + char *user; + char *app; + + // query components + char *clientUser; + char *clientApp; + char *mac; +}; + +// check if object type is a normal key type (APP_KEY or WLAN_KEY) +bool CertManagerIsKeyObjectType(uint32_t type); + +// Encode a URI to a char string. If (encoded) is NULL, only the required length is returned. +int32_t CertManagerUriEncode(char *encoded, uint32_t *encodedLen, const struct CMUri *uri); + +// Free memory allocated during CertManagerUriDecode. +int32_t CertManagerFreeUri(struct CMUri *uri); + +int32_t CertManagerUriDecode(struct CMUri *uri, const char *encoded); + +#ifdef __cplusplus +} +#endif + +#endif // CERT_MANAGER_URI_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_util.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_util.h new file mode 100644 index 0000000..6430097 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cert_manager_util.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CERT_MANAGER_UTIL_H +#define CERT_MANAGER_UTIL_H + +#include "cert_manager_type.h" +#include "cert_manager_mem.h" +#include "cm_type.h" +#include "hks_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ASSERT_HKS_CALL(f) do {int32_t _rc = (f); if ((_rc) != HKS_SUCCESS) { return (int32_t) (rc); }} while (0) +#define TRY_CM_CALL(f, rc) do {int32_t _rc = (f); if ((_rc) != HKS_SUCCESS) { \ + CM_LOG_W("Failed: %s, %d\n", #f, (_rc)); (rc) = (int32_t)(_rc); goto finally; }} while (0) + +int32_t CertManagerHmac(const char *uri, const struct CmBlob *data, struct CmMutableBlob *mac); + +int32_t CertManagerGenerateHmacKey(const char *uri); + +int32_t CertManagerBuildKeySpec(struct HksParamSet **params, const struct CMKeyProperties *properties); + +#ifdef __cplusplus +} +#endif + +#endif // CERT_MANAGER_UTIL_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_asn1.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_asn1.h new file mode 100644 index 0000000..5e04eea --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_asn1.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_ASN1_H +#define CM_ASN1_H + +#include "cm_type.h" + +#define ASN_1_TAG_TYPE_BOOL 0x01 +#define ASN_1_TAG_TYPE_INT 0x02 +#define ASN_1_TAG_TYPE_BIT_STR 0x03 +#define ASN_1_TAG_TYPE_OCT_STR 0x04 +#define ASN_1_TAG_TYPE_NULL 0x05 +#define ASN_1_TAG_TYPE_OID 0x06 +#define ASN_1_TAG_TYPE_ENUMERATED 0x0A +#define ASN_1_TAG_TYPE_UTF8_STR 0x0C +#define ASN_1_TAG_TYPE_PRINTABLE_STR 0x13 +#define ASN_1_TAG_TYPE_UTC_TIME 0x17 + +#define ASN_1_TAG_TYPE_SEQ 0x30 +#define ASN_1_TAG_TYPE_SET 0x31 + +#define ASN_1_TAG_TYPE_CTX_SPEC0 0xA0 +#define ASN_1_TAG_TYPE_CTX_SPEC3 0xA3 + +#define ASN_1_TAG_TYPE_RAW 0xff000001 + +#define ASN_1_MAX_VAL_NO_EXTRA_LEN_BYTE 0x7F +#define ASN_1_MIN_VAL_1_EXTRA_LEN_BYTE 0x80 +#define ASN_1_MIN_VAL_2_EXTRA_LEN_BYTE 0x100 + +#define ASN_1_TAG_TYPE_1_BYTE_LEN 0x81 +#define ASN_1_TAG_TYPE_2_BYTE_LEN 0x82 + +#define ASN_1_MAX_HEADER_LEN 0x5 +#define ASN_1_MIN_HEADER_LEN 0x3 + +#define ASN_1_TRUE_VALUE 0xFF + +#define ASN_1_MAX_SIZE (0x10000 - 0x100) + +struct CmAsn1Blob { + uint32_t type; + uint32_t size; + uint8_t *data; +}; + +struct CmAsn1Obj { + struct CmAsn1Blob header; + struct CmAsn1Blob value; +}; + +#define CM_ASN1_ENCODE_BYTE(ptr, value) \ +do { \ + (ptr)[0] = (uint8_t)((value) & 0xff); \ + (ptr)++; \ +} while (0) + +#define CM_ASN1_ENCODE_TWO_BYTE(ptr, value) \ +do { \ + (ptr)[0] = (uint8_t)(((value) >> 8) & 0xff); \ + (ptr)++; \ + (ptr)[0] = (uint8_t)((value) & 0xff); \ + (ptr)++; \ +} while (0) + +#define CM_ASN1_DECODE_BYTE(ptr, value) \ +do { \ + (value) = (uint32_t)((ptr)[0]); \ + (ptr)++; \ +} while (0) + +#define CM_ASN1_DECODE_TWO_BYTE(ptr, value) \ +do { \ + (value) = (uint32_t)((ptr)[0] & 0xff) << 8; \ + (ptr)++; \ + (value) |= (uint32_t)((ptr)[0] & 0xff); \ + (ptr)++; \ +} while (0) + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmAsn1GetObj(struct CmBlob *next, struct CmAsn1Obj *obj, const struct CmBlob *data); + +int32_t CmAsn1ExtractTag(struct CmBlob *next, struct CmAsn1Obj *obj, const struct CmBlob *data, + uint32_t expected_tag); + +static inline int32_t CheckAsn1Blob(const struct CmAsn1Blob *blob) +{ + if ((blob == NULL) || (blob->data == NULL) || (blob->size == 0)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +static inline int32_t CheckAsn1Obj(const struct CmAsn1Obj *obj) +{ + if ((obj == NULL) || (CheckAsn1Blob(&obj->header) != CM_SUCCESS) || + (CheckAsn1Blob(&obj->value) != CM_SUCCESS)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_event_process.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_event_process.h new file mode 100644 index 0000000..e651003 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_event_process.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + */ +#ifndef CM_CLIENT_SERVICE_H +#define CM_CLIENT_SERVICE_H + +#include + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INVALID_VALUE 0XFFFF + +int32_t CmDeleteProcessInfo(struct CmContext *context); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_curve25519.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_curve25519.h new file mode 100644 index 0000000..9978739 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_curve25519.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_OPENSSL_CURVE25519_H +#define CM_OPENSSL_CURVE25519_H + +#include +#include "cm_type.h" +#include "cm_openssl_engine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CURVE25519_KEY_LEN 32 +#define CURVE25519_KEY_BITS 256 + +struct KeyMaterial25519 { + enum CmKeyAlg keyAlg; + uint32_t keySize; + uint32_t pubKeySize; + uint32_t priKeySize; + uint32_t reserved; +}; + + +int32_t SaveCurve25519KeyMaterial(uint32_t algType, const EVP_PKEY *pKey, struct CmBlob *keyOut); + +#ifdef __cplusplus +} +#endif + +#endif /* HKS_OPENSSL_CURVE25519_H */ diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_ecc.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_ecc.h new file mode 100644 index 0000000..f332bf8 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_ecc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_OPENSSL_ECC_H +#define CM_OPENSSL_ECC_H + +#include +#include +#include "cm_type.h" +#include "cm_openssl_engine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ECC_KEYPAIR_CNT 3 + +struct KeyMaterialEcc { + enum CmKeyAlg keyAlg; + uint32_t keySize; + uint32_t xSize; + uint32_t ySize; + uint32_t zSize; +}; + +int32_t EccSaveKeyMaterial(const EC_KEY *eccKey, const struct CmKeySpec *spec, + uint8_t **output, uint32_t *outputSize); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_engine.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_engine.h new file mode 100644 index 0000000..59d991e --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_engine.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_OPENSSL_ENGINE_H +#define CM_OPENSSL_ENGINE_H + +#include +#include "cm_type.h" +#include "cm_openssl_engine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum CmKeyAlg { + CM_ALG_RSA = 1, + CM_ALG_ECC = 2, + + CM_ALG_AES = 20, + CM_ALG_HMAC = 50, + CM_ALG_HKDF = 51, + CM_ALG_PBKDF2 = 52, + + CM_ALG_ECDH = 100, + CM_ALG_X25519 = 101, + CM_ALG_ED25519 = 102, + + CM_ALG_SM2 = 150, + CM_ALG_SM3 = 151, + CM_ALG_SM4 = 152, +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_rsa.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_rsa.h new file mode 100644 index 0000000..8b89b23 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/cm_openssl_rsa.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_OPENSSL_RSA_H +#define CM_OPENSSL_RSA_H + +#include +#include "cm_type.h" +#include "cm_openssl_engine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CM_RSA_KEYPAIR_CNT 3 + +struct KeyMaterialRsa { + enum CmKeyAlg keyAlg; + uint32_t keySize; + uint32_t nSize; + uint32_t eSize; + uint32_t dSize; +}; + +int32_t RsaSaveKeyMaterial(const RSA *rsa, const uint32_t keySize, struct CmBlob *key); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/include/rbtree.h b/services/cert_manager_standard/cert_manager_engine/main/core/include/rbtree.h new file mode 100644 index 0000000..02edce2 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/include/rbtree.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RED_BLACK_TREE_H +#define RED_BLACK_TREE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t RbTreeKey; +typedef void* RbTreeValue; +typedef void (*RbTreeNodeHandler)(RbTreeKey key, RbTreeValue value, const void *context); + +typedef int (*RbTreeValueEncoder)(RbTreeValue value, uint8_t *buf, uint32_t *size); +typedef int (*RbTreeValueDecoder)(RbTreeValue *value, const uint8_t *buf, uint32_t size); + +enum TraverseOrder { + IN, PRE, POST +}; + +struct RbTreeNode { + RbTreeKey key; + RbTreeValue value; + struct RbTreeNode *p; + struct RbTreeNode *left; + struct RbTreeNode *right; +}; + +struct RbTree { + struct RbTreeNode *nil; + struct RbTreeNode *root; +}; + +int RbTreeNew(struct RbTree *t); + +RbTreeKey RbTreeNodeKey(const struct RbTreeNode *n); + +int RbTreeDelete(struct RbTree *t, struct RbTreeNode *z); + +int RbTreeInsert(struct RbTree *t, RbTreeKey key, const RbTreeValue value); + +int RbTreeDestroyEx(struct RbTree *t, RbTreeNodeHandler handler, const void *context); + +int RbTreeFindNode(struct RbTreeNode **node, RbTreeKey key, const struct RbTree *tree); + +int RbTreeDecode(struct RbTree *t, RbTreeValueDecoder dec, uint8_t *buf, uint32_t size); + +int RbTreeEncode(const struct RbTree *t, RbTreeValueEncoder enc, uint8_t *buf, uint32_t *size); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager.c new file mode 100644 index 0000000..3ba5b1c --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager.c @@ -0,0 +1,1170 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdio.h" +#include "stdbool.h" +#include "stdint.h" +#include "cert_manager.h" +#include "cert_manager_type.h" +#include "cert_manager_file.h" +#include "cert_manager_mem.h" +#include "cert_manager_status.h" +#include "cert_manager_file_operator.h" +#include "securec.h" +#include "cm_type.h" +#include "cm_asn1.h" +#include "cm_log.h" +#include "cm_x509.h" +#include "hks_type.h" +#include "hks_api.h" +#include "hks_param.h" + +#define MAX_FILES_IN_DIR 1000 +#define CERT_MANAGER_MD5_SIZE 32 +#define CERT_MANAGER_MAX_CERT_SIZE 4096 + +#define MAX_NAME_PREFIX 32 +#define MAX_NAME_DIGEST_LEN 9 + +#define MAX_PATH_LEN 256 +#define NAME_DIGEST_SIZE 4 + +#define EOK (0) + +#ifndef errno_t +typedef int errno_t; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +static bool g_hksInitialized = false; + +struct CmMathedIndexPara { + char *path; + uint32_t store; + uint32_t *status; + uint32_t *count; + uint8_t *indexes; +}; + +int32_t CertManagerInitialize(void) +{ + if (!g_hksInitialized) { + ASSERT_CM_CALL(HksInitialize()); + g_hksInitialized = true; + } + + if (CmMakeDir(CERT_DIR) == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("Failed to create folder %s\n", CERT_DIR); + return CMR_ERROR_WRITE_FILE_FAIL; + } + + ASSERT_FUNC(CertManagerStatusInit()); + + return CMR_OK; +} + +int32_t CmFreeCaFileNames(struct CmMutableBlob *fileNames) +{ + uint32_t i; + int32_t ret = 0; + struct CmMutableBlob *fNames; + + if (fileNames == NULL) { + CM_LOG_E("Failed to free memory for certificate names"); + return -1; + } + fNames = (struct CmMutableBlob *)fileNames->data; + + for (i = 0; i < fileNames->size; i++) { + if (fNames[i].data == NULL) { + CM_LOG_E("Failed to free memory for certificate name: %u", i); + ret = -1; + } else { + if (memset_s(fNames[i].data, MAX_LEN_URI, 0, fNames[i].size) != EOK) { + return CMR_ERROR; + } + fNames[i].size = 0; + CMFree(fNames[i].data); + } + } + CMFree(fNames); + fileNames->size = 0; + + return ret; +} + +int32_t GetFilePath(const struct CmContext *context, uint32_t store, char *pathPtr, + char *suffix, uint32_t *suffixLen) +{ + int32_t ret, retVal; + if (suffix == NULL || suffixLen == NULL) { + CM_LOG_E("NULL pointer failure.\n"); + return CMR_ERROR_NULL_POINTER; + } + + switch (store) { + if (context == NULL) { + CM_LOG_E("Null pointer failture.\n"); + return CMR_ERROR_NULL_POINTER; + } + case CM_CREDENTIAL_STORE: + case CM_USER_TRUSTED_STORE: + case CM_PRI_CREDENTIAL_STORE: + if (store == CM_CREDENTIAL_STORE) { + ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s%u", CREDNTIAL_STORE, context->userId); + } else if (store == CM_PRI_CREDENTIAL_STORE) { + ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s%u", APP_CA_STORE, context->userId); + } else { + ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s%u", USER_CA_STORE, context->userId); + } + + retVal = sprintf_s(suffix, MAX_SUFFIX_LEN, "%u", context->uid); + if (ret < 0 || retVal < 0) { + return CMR_ERROR; + } + break; + case CM_SYSTEM_TRUSTED_STORE: + ret = sprintf_s(pathPtr, MAX_PATH_LEN, "%s", SYSTEM_CA_STORE); + if (ret < 0) { + return CMR_ERROR; + } + break; + + default: + return CMR_ERROR_NOT_SUPPORTED; + } + *suffixLen = (uint32_t)strlen(suffix); + return CMR_OK; +} + +int32_t CmGetFilePath(const struct CmContext *context, uint32_t store, struct CmMutableBlob *pathBlob) +{ + char pathPtr[MAX_PATH_LEN] = {0}; + uint32_t suffixLen = 0; + char suffixBuf[MAX_SUFFIX_LEN] = {0}; + + if ((pathBlob == NULL) || (pathBlob->data == NULL)) { + CM_LOG_E("Null pointer failure"); + return CMR_ERROR_NULL_POINTER; + } + int32_t ret = GetFilePath(context, store, pathPtr, suffixBuf, &suffixLen); + if (ret != CMR_OK) { + CM_LOG_E("Get file path faild"); + return CMR_ERROR; + } + + /* Create folder if it does not exist */ + if (CmMakeDir(pathPtr) == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("Failed to create path folder:%s", pathPtr); + return CMR_ERROR_WRITE_FILE_FAIL; + } + + if (pathBlob->size - 1 < strlen(pathPtr) + suffixLen) { + CM_LOG_E("Failed to copy path"); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + char *path = (char *)pathBlob->data; + if (suffixLen == 0) { + if (sprintf_s(path, MAX_PATH_LEN, "%s", pathPtr) < 0) { + return CM_FAILURE; + } + } else { + if (sprintf_s(path, MAX_PATH_LEN, "%s/%s", pathPtr, suffixBuf) < 0) { + return CM_FAILURE; + } + } + + pathBlob->size = strlen(path) + 1; + if (CmMakeDir(path) == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("Failed to create folder %s", path); + return CMR_ERROR_WRITE_FILE_FAIL; + } + return CMR_OK; +} + +static int32_t CreateCertificateMalloc(const struct CmMutableBlob *fileNames, + struct CmMutableBlob **certDataList) +{ + uint32_t i; + uint32_t blobLen = sizeof(struct CmMutableBlob); + struct CmMutableBlob *certData = (struct CmMutableBlob *)CMMalloc(blobLen * (fileNames->size)); + if (certData == NULL) { + CM_LOG_E("Failed to allocate memory for certificates"); + return CMR_ERROR_MALLOC_FAIL; + } + + for (i = 0; i < fileNames->size; i++) { + certData[i].data = NULL; + certData[i].size = 0; + } + *certDataList = certData; + + return CMR_OK; +} + +void CmCertificateListFree(struct CmMutableBlob *certListData, uint32_t certListSize) +{ + if (certListData == NULL || certListSize == 0) { + return; + } + for (uint32_t i = 0; i < certListSize; i++) { + if (certListData[i].data != NULL) { + (void)memset_s(certListData[i].data, certListData[i].size, 0, certListData[i].size); + CMFree(certListData[i].data); + certListData[i].data = NULL; + certListData[i].size = 0; + } + } + + CMFree(certListData); + certListData = NULL; +} + +static int32_t CmCreateCertificateList(struct CmBlob *certList, + struct CmMutableBlob *fileNames, const char *path) +{ + uint32_t i; + char *fName = NULL; + uint32_t certBuffSize = 0; + int32_t ret; + struct CmMutableBlob *certDataList = NULL; + + if ((certList == NULL) || (fileNames == NULL) || (path == NULL) || + (fileNames->data == NULL) || (fileNames->size > MAX_FILES_IN_DIR)) { + CM_LOG_E("Bad parameters: path = %s, ileNames->size = %u", path, fileNames->size); + return CMR_ERROR_INVALID_ARGUMENT; + } + + ret = CreateCertificateMalloc(fileNames, &certDataList); + if (ret != CMR_OK) { + CM_LOG_E("Malloc failed"); + return ret; + } + + certList->data = (uint8_t *)certDataList; + certList->size = fileNames->size; + + for (i = 0; i < fileNames->size; i++) { + fName = (char *)((struct CmMutableBlob *)fileNames->data)[i].data; + certBuffSize = CertManagerFileSize(path, fName); + certDataList[i].data = CMMalloc(certBuffSize); + if (certDataList[i].data == 0) { + CM_LOG_E("Failed to allocate memory for certificate: %s", fName); + goto cleanup; + } + certDataList[i].size = certBuffSize; + + if (CertManagerFileRead(path, fName, 0, certDataList[i].data, certBuffSize) != certBuffSize) { + CM_LOG_E("Failed to read file: %s", fName); + goto cleanup; + } + } + + return CMR_OK; +cleanup: + CmCertificateListFree(certDataList, i); + return CMR_ERROR; +} + +static int32_t CmGetSubjectNameAsn1(const struct CmBlob *certificate, struct CmAsn1Obj *subjectName) +{ + ASSERT_ARGS(certificate && certificate->size && certificate->data); + ASSERT_ARGS(subjectName); + + struct CmAsn1Obj obj; + struct CmBlob next = { 0, NULL }; + struct CmBlob cert = CM_BLOB(certificate); + + (void)memset_s(&obj, sizeof(struct CmAsn1Obj), 0, sizeof(struct CmAsn1Obj)); + ASSERT_CM_CALL(CmAsn1ExtractTag(&next, &obj, &cert, ASN_1_TAG_TYPE_SEQ)); + struct CmBlob val = { obj.value.size, obj.value.data }; + + ASSERT_CM_CALL(CmAsn1ExtractTag(&val, &obj, &val, ASN_1_TAG_TYPE_SEQ)); + struct CmBlob in_val = { obj.value.size, obj.value.data }; + + ASSERT_CM_CALL(CmAsn1ExtractTag(&in_val, &obj, &in_val, ASN_1_TAG_TYPE_CTX_SPEC0)); + ASSERT_CM_CALL(CmAsn1ExtractTag(&in_val, &obj, &in_val, ASN_1_TAG_TYPE_INT)); + ASSERT_CM_CALL(CmAsn1ExtractTag(&in_val, &obj, &in_val, ASN_1_TAG_TYPE_SEQ)); + ASSERT_CM_CALL(CmAsn1ExtractTag(&in_val, subjectName, &in_val, ASN_1_TAG_TYPE_SEQ)); + + return CMR_OK; +} + +static int32_t CertMangerGetCertificateList(const struct CmContext *context, + const struct CmBlob *certificateList, uint32_t store, struct CertBlob *certBlob, uint32_t *status) +{ + uint32_t i; + int32_t ret; + X509 *x509cert = NULL; + int32_t subjectNameLen = 0; + int32_t certAliasLen = 0; + struct CmBlob *blob = (struct CmBlob *)certificateList->data; + for (i = 0; i < certificateList->size; i++) { + ret = CertManagerGetCertificatesStatus(context, &blob[i], store, &status[i]); + if (ret != 0) { + CM_LOG_E("Failed to get certificates status"); + return CMR_ERROR; + } + x509cert = InitCertContext(blob[i].data, blob[i].size); + subjectNameLen = GetX509SubjectNameLongFormat(x509cert, (char *)certBlob->subjectName[i].data, + MAX_LEN_SUBJECT_NAME); + if (subjectNameLen == 0) { + CM_LOG_E("Failed to get certificatessubjectName"); + return CMR_ERROR; + } + certBlob->subjectName[i].size = (uint32_t)subjectNameLen; + + certAliasLen = GetX509SubjectName(x509cert, CM_ORGANIZATION_NAME, (char *)certBlob->certAlias[i].data, + MAX_LEN_CERT_ALIAS); + if (certAliasLen == 0) { + certAliasLen = GetX509SubjectName(x509cert, CM_COMMON_NAME, (char *)certBlob->certAlias[i].data, + MAX_LEN_CERT_ALIAS); + } + if (certAliasLen == 0) { + CM_LOG_E("Failed to get certificates CN name"); + return CMR_ERROR; + } + if (certAliasLen < 0) { + return certAliasLen; + } + FreeCertContext(x509cert); + certBlob->certAlias[i].size = (uint32_t)certAliasLen; + } + return CMR_OK; +} + +int32_t CertManagerListTrustedCertificates(const struct CmContext *context, struct CmBlob *certificateList, + uint32_t store, struct CertBlob *certBlob, uint32_t *status) +{ + int32_t ret = CMR_OK; + struct CmMutableBlob fileNames; + char path[CERT_MAX_PATH_LEN] = {0}; + + struct CmMutableBlob pathBlob = { sizeof(path), (uint8_t *)path }; + ret = CmGetFilePath(context, store, &pathBlob); + if (ret != CMR_OK) { + CM_LOG_E("Failed obtain path fot store %x", store); + return CMR_ERROR; + } + ret = CertManagerGetFilenames(&fileNames, path, certBlob->uri); + if (ret < 0) { + CM_LOG_E("Failed to read certificates from directory: %s", path); + ret = CMR_ERROR_STORAGE; + goto cleanup; + } + ret = CmCreateCertificateList(certificateList, &fileNames, path); + if (ret < 0) { + CM_LOG_E("Failed to create certificates list: %s", path); + ret = CMR_ERROR_STORAGE; + goto cleanup; + } + + ret = CertMangerGetCertificateList(context, certificateList, store, certBlob, status); + if (ret != CMR_OK) { + CM_LOG_E("Failed to get certificates info"); + ret = CMR_ERROR_STORAGE; + goto cleanup; + } + +cleanup: + CmFreeCaFileNames(&fileNames); + return ret; +} + +static int32_t CertManagerFreeTrustedCertificatesList(struct CmBlob *certificateList) +{ + uint32_t i; + int32_t ret = CMR_OK; + struct CmMutableBlob *certificateDataList = NULL; + + if (certificateList == NULL) { + CM_LOG_E("Failed to CMFree certificateList"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + certificateDataList = (struct CmMutableBlob *)certificateList->data; + if (certificateDataList == NULL) { + CM_LOG_E("CertificateList data is null"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + for (i = 0; i < certificateDataList->size; i++) { + if (certificateDataList[i].data == NULL) { + CM_LOG_E("Corrupted data in certificate list"); + ret = CMR_ERROR_NOT_FOUND; + } else { + CMFree(certificateDataList[i].data); + certificateDataList[i].data = NULL; + certificateDataList[i].size = 0; + } + } + + CMFree(certificateList->data); + certificateList->data = NULL; + + return ret; +} + +static int32_t InitParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramcount) +{ + int32_t ret = HksInitParamSet(paramSet); + if (ret != CMR_OK) { + CM_LOG_E("HksInitParamSet failed"); + return ret; + } + + ret = HksAddParams(*paramSet, params, paramcount); + if (ret != CMR_OK) { + CM_LOG_E("HksAddParams failed"); + return ret; + } + + ret = HksBuildParamSet(paramSet); + if (ret != CMR_OK) { + CM_LOG_E("HksBuildParamSet failed"); + return ret; + } + + return ret; +} + +static int32_t NameHash(struct HksBlob *subjectName, struct CmMutableBlob *nameDigest) +{ + if ((nameDigest == NULL) || (nameDigest->data == NULL) || (nameDigest->size < NAME_DIGEST_SIZE)) { + CM_LOG_E("Invalid parameter"); + return CMR_ERROR_INVALID_ARGUMENT; + } + int32_t ret = CMR_OK; + + struct HksParam hashParam = { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_MD5 + }; + struct HksParamSet *hashParamSet; + ret = InitParamSet(&hashParamSet, &hashParam, sizeof(hashParam) / sizeof(struct HksParam)); + if (ret != CMR_OK) { + ret = CMR_ERROR; + goto cleanup; + } + + uint8_t hashBuff[CERT_MANAGER_MD5_SIZE]; + struct HksBlob hash = { sizeof(hashBuff), hashBuff}; + struct HksBlob tmp = HKS_BLOB(subjectName); + ret = HksHash(hashParamSet, &tmp, &hash); + if (ret != CMR_OK) { + ret = CMR_ERROR; + goto cleanup; + } + nameDigest->size = NAME_DIGEST_SIZE; + if (sprintf_s((char*)nameDigest->data, MAX_NAME_PREFIX, "%02x%02x%02x%02x", + hashBuff[3], hashBuff[2], hashBuff[1], hashBuff[0]) < 0) { /* 2 3 is array index */ + ret = CMR_ERROR; + goto cleanup; + } + +cleanup: + if (hashParamSet != NULL) { + HksFreeParamSet(&hashParamSet); + } + return ret; +} + +static int32_t NameHashFromAsn1(const struct CmAsn1Obj *subject, struct CmMutableBlob *nameDigest) +{ + if (subject == NULL) { + CM_LOG_E("NULL pointer error"); + return CMR_ERROR_NULL_POINTER; + } + + uint8_t nameBuf[subject->header.size + subject->value.size]; + struct HksBlob subjectName = {sizeof(nameBuf), nameBuf}; + int32_t ret = memcpy_s(nameBuf, sizeof(nameBuf), subject->header.data, subject->header.size); + if (ret != EOK) { + CM_LOG_E("Memory copy failed"); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + ret = memcpy_s(nameBuf + subject->header.size, sizeof(nameBuf) - subject->header.size, + subject->value.data, subject->value.size); + if (ret != EOK) { + CM_LOG_E("Memory copy failed"); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + return NameHash(&subjectName, nameDigest); +} + +static int32_t CmGetFilenames(const struct CmContext *context, struct CmMutableBlob *pathBlob, + uint32_t store, struct CmMutableBlob *fileNames, const char *path) +{ + int32_t ret = CmGetFilePath(context, store, pathBlob); + if (ret != CMR_OK) { + CM_LOG_E("Failed obtain path for store %x", store); + return CMR_ERROR; + } + + struct CmBlob uri[MAX_COUNT_CERTIFICATE]; + uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob); + (void)memset_s(uri, len, 0, len); + if (CertManagerGetFilenames(fileNames, path, uri) < 0) { + CM_LOG_E("Failed to read certificates from directory: %s\n", path); + ret = CMR_ERROR_STORAGE; + } + + CmFreeFileNameUri(uri, MAX_COUNT_CERTIFICATE); + + return ret; +} + +static int32_t CmDifferentiateStore(const struct CmContext *context, const struct CmBlob *certificate, + uint32_t store, uint32_t *status) +{ + if (store != CM_CREDENTIAL_STORE) { + int32_t ret = CertManagerGetCertificatesStatus(context, certificate, store, status); + if (ret != CMR_OK) { + CM_LOG_E("Failed to CertManagerGetCertificatesStatus"); + return CMR_ERROR_READ_FILE_ERROR; + } + } + return CMR_OK; +} + +static int32_t CmGetMatchedFileNameIndex(const struct CmContext *context, const struct CmBlob *nameDigest, + const struct CmMutableBlob *fileNames, struct CmMathedIndexPara indexPara) +{ + uint32_t i; + uint32_t fileSize; + int32_t ret; + uint8_t certBuff[CERT_MANAGER_MAX_CERT_SIZE]; + struct CmBlob certificate; + uint32_t store = indexPara.store; + char *path = indexPara.path; + uint32_t *status = indexPara.status; + uint8_t *indexes = indexPara.indexes; + uint32_t *count = indexPara.count; + struct CmMutableBlob *fname = (struct CmMutableBlob *)fileNames->data; + + for (i = 0; i < fileNames->size; i++) { + if (memcmp(fname[i].data, nameDigest->data, nameDigest->size) == 0) { + fileSize = CmFileRead(path, (char *)fname[i].data, 0, certBuff, sizeof(certBuff)); + if (fileSize == 0) { + CM_LOG_E("Failed to read file: %s/%s", path, fname[i].data); + return CMR_ERROR_READ_FILE_ERROR; + } + + certificate.data = certBuff; + certificate.size = fileSize; + ret = CmDifferentiateStore(context, &certificate, store, status); + if (ret != CMR_OK) { + CM_LOG_E("Failed to CmDifferentiateStore"); + return CMR_ERROR_READ_FILE_ERROR; + } + indexes[*count] = i; + (*count)++; + } + } + return CMR_OK; +} + +static int32_t CmGetMatchedFileNames(struct CmMutableBlob *matchName, const struct CmMutableBlob *fname, + uint32_t count, uint8_t *indexes) +{ + uint32_t i; + uint32_t index; + if (matchName == NULL || fname == NULL || indexes == NULL) { + CM_LOG_E("Paramset is NULL"); + return CMR_ERROR_NULL_POINTER; + } + + for (i = 0; i < count; i++) { + index = indexes[i]; + matchName[i].size = fname[index].size + 1; + matchName[i].data = malloc(matchName[i].size); + if (matchName[i].data == NULL) { + CM_LOG_E("Failed to allocate memory for filename: %s", fname[index].data); + return CMR_ERROR_MALLOC_FAIL; + } + + if (strcpy_s((char *)matchName[i].data, (size_t)matchName[i].size, (char*)fname[index].data) != EOK) { + CM_LOG_E("strcpy_s failed for: %s", fname[index].data); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + } + return CMR_OK; +} + +static int32_t CmInitFileNameIndexArray(uint8_t **indexes, struct CmMutableBlob fileNames) +{ + uint8_t *fileNameIndex = (uint8_t *)malloc(fileNames.size); + if (fileNameIndex == NULL) { + CM_LOG_E("Failed to allocate memory for indexes"); + return CMR_ERROR_MALLOC_FAIL; + } + + if (memset_s(fileNameIndex, fileNames.size, 0, fileNames.size) != EOK) { + CM_LOG_E("Failed to memset memory"); + return CMR_ERROR; + } + + *indexes = fileNameIndex; + + return CMR_OK; +} + +static void CmFreeCertificatesInfo(struct CmMutableBlob *fileNames, struct CmMutableBlob *matchingFiles, + uint8_t *indexes, struct CmBlob *certificateList, int32_t retVal) +{ + CmFreeCaFileNames(fileNames); + CmFreeCaFileNames(matchingFiles); + CMFree(indexes); + if (retVal != CMR_OK) { + CertManagerFreeTrustedCertificatesList(certificateList); + } +} + +int32_t CmGetCertificatesByUri(const struct CmContext *context, struct CmBlob *certificateList, + uint32_t store, const struct CmBlob *nameDigest, uint32_t *status) +{ + int32_t retVal = 0; + uint32_t count = 0; + uint8_t *indexes = NULL; + char path[CERT_MAX_PATH_LEN]; + struct CmMutableBlob pathBlob = {sizeof(path), (uint8_t *)path}; + struct CmMutableBlob fileNames = {0, NULL}, matchingFiles = {0, NULL}; + + retVal = CmGetFilenames(context, &pathBlob, store, &fileNames, path); + if (retVal != CMR_OK) { + CM_LOG_E("Failed to get file names"); + return retVal; + } + if (CmInitFileNameIndexArray(&indexes, fileNames) != CMR_OK) { + CM_LOG_E("Failed to init file name indexes arrary"); + retVal = CMR_ERROR_MALLOC_FAIL; + goto cleanup; + } + + struct CmMathedIndexPara indexPara = {path, store, status, &count, indexes}; + if (CmGetMatchedFileNameIndex(context, nameDigest, &fileNames, indexPara) != EOK) { + CM_LOG_E("GetCertificatesByUri Failed to get matched file name indexes"); + retVal = CMR_ERROR; + goto cleanup; + } + + matchingFiles.size = count; + matchingFiles.data = malloc(sizeof(struct CmMutableBlob) * count); + if (matchingFiles.data == NULL) { + CM_LOG_E("GetCertificatesByUri Failed to allocate memory for files"); + retVal = CMR_ERROR_MALLOC_FAIL; + goto cleanup; + } + + struct CmMutableBlob *fname = (struct CmMutableBlob *)fileNames.data; + struct CmMutableBlob *matchName = (struct CmMutableBlob *)matchingFiles.data; + if (CmGetMatchedFileNames(matchName, fname, count, indexes) != EOK) { + CM_LOG_E("GetCertificatesByUri Failed to get matched file Name indexes"); + retVal = CMR_ERROR; + goto cleanup; + } + + if (CmCreateCertificateList(certificateList, &matchingFiles, path) < 0) { + CM_LOG_E("GetCertificatesByUri Failed to create certificates: %s", path); + retVal = CMR_ERROR_STORAGE; + goto cleanup; + } + +cleanup: + CmFreeCertificatesInfo(&fileNames, &matchingFiles, indexes, certificateList, retVal); + return retVal; +} + +static int32_t CmGetMatchedFileSubjectNameIndex(const struct CmMutableBlob *nameDigest, + const struct CmMutableBlob *fileNames, const struct CmAsn1Obj *subjectName, struct CmMathedIndexPara indexPara) +{ + uint32_t i; + struct CmAsn1Obj subjectFromList; + uint8_t certBuff[CERT_MANAGER_MAX_CERT_SIZE]; + struct CmBlob certificate = {sizeof(certBuff), certBuff}; + char *path = indexPara.path; + uint8_t *indexes = indexPara.indexes; + uint32_t *count = indexPara.count; + struct CmMutableBlob *fname = (struct CmMutableBlob *)fileNames->data; + + (void)memset_s(&subjectFromList, sizeof(struct CmAsn1Obj), 0, sizeof(struct CmAsn1Obj)); + for (i = 0; i < fileNames->size; i++) { + if (memcmp(fname[i].data, nameDigest->data, nameDigest->size) == 0) { + if (CmFileRead(path, (char *)fname[i].data, 0, certBuff, sizeof(certBuff)) == 0) { + CM_LOG_E("Failed to read file: %s/%s", path, fname[i].data); + return CMR_ERROR_READ_FILE_ERROR; + } + + if (CmGetSubjectNameAsn1(&certificate, &subjectFromList) != CMR_OK) { + CM_LOG_E("Failed to obtain subjectName"); + return CMR_ERROR_NOT_FOUND; + } + if ((subjectName->value.size == subjectFromList.value.size) || + (memcmp(subjectName->value.data, subjectFromList.value.data, subjectName->value.size))) { + indexes[*count] = i; + count++; + } + } + } + return CMR_OK; +} + +static int32_t CmListCertificatesBySubjectNameAsn1(const struct CmContext *context, + struct CmBlob *certificateList, uint32_t store, const struct CmAsn1Obj *subjectName) +{ + int32_t retVal = 0; + uint32_t count = 0; + uint8_t *indexes = NULL; + uint32_t *status = NULL; + struct CmMutableBlob fileNames = {0, NULL}, matchingFiles = {0, NULL}; + char path[CERT_MAX_PATH_LEN]; + uint8_t buff[MAX_NAME_DIGEST_LEN]; + struct CmMutableBlob nameDigest = {sizeof(buff), buff}, pathBlob = {sizeof(path), (uint8_t *)path}; + + retVal = NameHashFromAsn1(subjectName, &nameDigest); + if (retVal != CMR_OK) { + return retVal; + } + + if (CmGetFilenames(context, &pathBlob, store, &fileNames, path) != CMR_OK) { + return CMR_ERROR_STORAGE; + } + + if (CmInitFileNameIndexArray(&indexes, fileNames) != CMR_OK) { + retVal = CMR_ERROR_MALLOC_FAIL; + goto cleanup; + } + + struct CmMathedIndexPara indexPara = {path, store, status, &count, indexes}; + if (CmGetMatchedFileSubjectNameIndex(&nameDigest, &fileNames, subjectName, indexPara) != CMR_OK) { + CM_LOG_E("Failed to get matched file name indexes"); + retVal = CMR_ERROR; + goto cleanup; + } + + matchingFiles.size = count; + matchingFiles.data = malloc(sizeof(struct CmMutableBlob) * count); + if (matchingFiles.data == NULL) { + CM_LOG_E("Failed to allocate memory for files"); + retVal = CMR_ERROR_MALLOC_FAIL; + goto cleanup; + } + + struct CmMutableBlob *fname = (struct CmMutableBlob *)fileNames.data; + struct CmMutableBlob *matchName = (struct CmMutableBlob *)matchingFiles.data; + + if (CmGetMatchedFileNames(matchName, fname, count, indexes) != CMR_OK) { + CM_LOG_E("Failed to get matched file Name indexes"); + retVal = CMR_ERROR; + goto cleanup; + } + + if (CmCreateCertificateList(certificateList, &matchingFiles, path) < 0) { + CM_LOG_E("Failed to create certificates: %s", path); + retVal = CMR_ERROR_STORAGE; + goto cleanup; + } + +cleanup: + CmFreeCertificatesInfo(&fileNames, &matchingFiles, indexes, certificateList, retVal); + return retVal; +} + +int32_t CertManagerListCertificatesBySubjectName(const struct CmContext *context, + struct CmBlob *certificateList, uint32_t store, const struct CmBlob *subjectName) +{ + struct CmAsn1Obj subjectAsn1; + struct CmBlob skip = {0, NULL}; + errno_t ret; + + (void)memset_s(&subjectAsn1, sizeof(struct CmAsn1Obj), 0, sizeof(struct CmAsn1Obj)); + ret = CmAsn1ExtractTag(&skip, &subjectAsn1, &CM_BLOB(subjectName), ASN_1_TAG_TYPE_SEQ); + if (ret != CMR_OK) { + CM_LOG_E("Subject name in bad format"); + return CMR_ERROR_NOT_FOUND; + } + return CmListCertificatesBySubjectNameAsn1(context, certificateList, store, &subjectAsn1); +} + +/* This function constructes md5 hash part of filename for storing certificate. + * All cetificates are stored in files namePrefix.count. where namePrefix = md5(subjectName) + * and count is = 0, 1.... needed fpr potential hash collisions. + */ +static int32_t CertManagerGetFileNamePrefix(const struct CmBlob *certificate, struct CmMutableBlob *namePrefix) +{ + struct CmAsn1Obj subjectAsn1; + + (void)memset_s(&subjectAsn1, sizeof(struct CmAsn1Obj), 0, sizeof(struct CmAsn1Obj)); + int32_t retVal = CmGetSubjectNameAsn1(certificate, &subjectAsn1); + if (retVal != CMR_OK) { + CM_LOG_E("Failed to obtain subjectName"); + return CMR_ERROR_NOT_FOUND; + } + /* Compute name prefix for the certificate */ + return NameHashFromAsn1(&subjectAsn1, namePrefix); +} + +int32_t CertManagerFindCertFileNameByUri(const struct CmContext *context, const struct CmBlob *certUri, + uint32_t store, struct CmMutableBlob *path) +{ + ASSERT_ARGS(context && certUri && certUri->data); + int32_t ret = CMR_ERROR_NOT_FOUND; + struct CmMutableBlob *fNames = NULL; + struct CmMutableBlob fileNames = {0, NULL}; + struct CmBlob uri[MAX_COUNT_CERTIFICATE]; + + if (CmGetFilePath(context, store, path) != CMR_OK) { + CM_LOG_E("Failed obtain path for store %x\n", store); + return CMR_ERROR; + } + + uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob); + (void)memset_s(uri, len, 0, len); + if (CertManagerGetFilenames(&fileNames, (char*)path->data, uri) < 0) { + CM_LOG_E("Failed obtain filenames from path: %s", (char *)path->data); + ret = CMR_ERROR_STORAGE; + goto cleanup; + } + + fNames = (struct CmMutableBlob *)fileNames.data; + + for (uint32_t i = 0; i < fileNames.size; i++) { + if (fNames[i].data == NULL) { + CM_LOG_E("Corrupted file name at index: %u", i); + ret = CMR_ERROR_STORAGE; + goto cleanup; + } + /* Check if url is matching with the cert filename */ + if ((certUri->size <= fNames[i].size) && (memcmp(certUri->data, fNames[i].data, certUri->size) == 0)) { + ret = CMR_OK; + break; + } + } + +cleanup: + CmFreeFileNameUri(uri, MAX_COUNT_CERTIFICATE); + if (fileNames.data != NULL) { + (void)CmFreeCaFileNames(&fileNames); + } + + return ret; +} + +static int32_t GetMathedCertificateFileName(const struct CmBlob *certificate, const struct CmMutableBlob *fNames, + const struct CmMutableBlob *path, struct CmMutableBlob *fileName, uint32_t index) +{ + uint32_t fsize; + int32_t ret = CMR_ERROR; + uint8_t certBuff[CERT_MANAGER_MAX_CERT_SIZE] = {0}; + + fsize = CertManagerFileRead((char *)path->data, (char *)fNames[index].data, 0, certBuff, sizeof(certBuff)); + if (fsize == 0) { + CM_LOG_E("Failed to read file: %s/%s", (char *)path->data, fNames[index].data); + return CMR_ERROR_READ_FILE_ERROR; + } + + /* Verify that this file contains certificate to be removed. i.e. we don't just have hash collision */ + if ((certificate->size == fsize) && (memcmp(certificate->data, certBuff, fsize) == 0)) { + CM_LOG_I("Matching certificate found: %s\n", (char*)fNames[index].data); + /* this is the certificate, return the filename */ + if (fileName->size < fNames[index].size + 1) { + /* shouldn't happen */ + CM_LOG_E("File name buffer too small"); + ret = CMR_ERROR_READ_FILE_ERROR; + } + + if (memcpy_s(fileName->data, fileName->size, fNames[index].data, fNames[index].size) != EOK) { + CM_LOG_E("Failed to copy file name.\n"); + ret = CMR_ERROR; + } else { + fileName->data[fNames[index].size] = '\0'; + fileName->size = fNames[index].size; + ret = CMR_OK; + } + } + return ret; +} + +static int32_t FindCertFileName(const struct CmMutableBlob *fileNames, const struct CmBlob *certificate, + struct CmMutableBlob nameDigest, const struct CmMutableBlob *path, struct CmMutableBlob *fileName) +{ + uint32_t i; + int32_t retVal = CMR_ERROR_NOT_FOUND; + struct CmMutableBlob *fNames = (struct CmMutableBlob *)fileNames->data; + + for (i = 0; i < fileNames->size; i++) { + if (fNames[i].data == NULL) { + CM_LOG_E("Corrupted file name at index: %u", i); + retVal = CMR_ERROR_STORAGE; + } + /* Check if file content is matching with the certificate */ + if ((nameDigest.size < fNames[i].size) && (memcmp(nameDigest.data, fNames[i].data, nameDigest.size) == 0)) { + retVal = GetMathedCertificateFileName(certificate, fNames, path, fileName, i); + if (retVal != CMR_OK) { + CM_LOG_E("Failed to get matched file"); + } else { + break; + } + } + } + return retVal; +} + +int32_t CertManagerFindCertFileName(const struct CmContext *context, const struct CmBlob *certificate, + uint32_t store, struct CmMutableBlob *path, struct CmMutableBlob *fileName) +{ + ASSERT_ARGS(context && certificate && fileName); + struct CmMutableBlob fileNames = {0, NULL}; + struct CmBlob uri[MAX_COUNT_CERTIFICATE]; + uint8_t namePrefix[MAX_NAME_PREFIX] = {0}; + struct CmMutableBlob nameDigest = {sizeof(namePrefix), namePrefix}; + /* Compute name prefix for the certificate */ + int32_t ret = CertManagerGetFileNamePrefix(certificate, &nameDigest); + if (ret != CMR_OK) { + CM_LOG_E("Failed to compute for removed certificate"); + return ret; + } + + do { + if (CmGetFilePath(context, store, path) != CMR_OK) { + CM_LOG_E("Failed obtain path for store %u", store); + ret = CMR_ERROR; + break; + } + uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob); + (void)memset_s(uri, len, 0, len); + if (CertManagerGetFilenames(&fileNames, (char *)path->data, uri) < 0) { + CM_LOG_E("Failed obtain filenames from path: %s", (char *)path->data); + ret = CMR_ERROR_STORAGE; + break; + } + + ret = FindCertFileName(&fileNames, certificate, nameDigest, path, fileName); + if (ret != CMR_OK) { + CM_LOG_E("Failed find files"); + break; + } + } while (0); + + CmFreeFileNameUri(uri, MAX_COUNT_CERTIFICATE); + if (fileNames.data != NULL) { + (void) CmFreeCaFileNames(&fileNames); + } + return ret; +} + +int32_t CmRemoveAppCert(const struct CmContext *context, const struct CmBlob *keyUri, + const uint32_t store) +{ + ASSERT_ARGS(context && keyUri && keyUri->data && keyUri->size); + int32_t ret; + char pathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob path = { sizeof(pathBuf), (uint8_t*) pathBuf }; + + ret = CmGetFilePath(context, store, &path); + if (ret != CMR_OK) { + CM_LOG_E("Failed obtain path for store %u", store); + return ret; + } + + ret = CertManagerFileRemove(pathBuf, (char *)keyUri->data); + if (ret != CMR_OK) { + CM_LOG_E("CertManagerFileRemove failed ret: %d", ret); + return ret; + } + /* ignore the return of HksDeleteKey */ + ret = HksDeleteKey(&HKS_BLOB(keyUri), NULL); + if (ret != HKS_SUCCESS && ret != HKS_ERROR_NOT_EXIST) { + CM_LOG_I("CertManagerKeyRemove failed, ret: %d", ret); + } + + return CMR_OK; +} + +static int32_t CmAppCertGetFilePath(const struct CmContext *context, const uint32_t store, struct CmBlob *path) +{ + int32_t ret = CM_FAILURE; + + switch (store) { + case CM_CREDENTIAL_STORE : + ret = sprintf_s((char*)path->data, MAX_PATH_LEN, "%s%u", CREDNTIAL_STORE, context->userId); + break; + case CM_PRI_CREDENTIAL_STORE : + ret = sprintf_s((char*)path->data, MAX_PATH_LEN, "%s%u", APP_CA_STORE, context->userId); + break; + default: + break; + } + if (ret < 0) { + return CM_FAILURE; + } + return CM_SUCCESS; +} + +void CmFreeFileNames(struct CmBlob *fileNames, const uint32_t fileSize) +{ + if (fileNames == NULL) { + CM_LOG_E("CmFreeFileNames fileNames is null"); + } + + for (uint32_t i = 0; i < fileSize; i++) { + if (fileNames[i].data != NULL) { + CMFree(fileNames[i].data); + fileNames[i].size = 0; + } + } +} + +int32_t CmGetUri(const char *filePath, struct CmBlob *uriBlob) +{ + uint32_t i; + if ((filePath == NULL) || (uriBlob == NULL) || (uriBlob->data == NULL)) { + CM_LOG_E("CmGetUri param is null"); + return CM_FAILURE; + } + + uint32_t filePathLen = strlen(filePath); + if (filePathLen == 0) { + return CM_FAILURE; + } + + for (i = filePathLen - 1; i >= 0; i--) { + if (filePath[i] == '/') { + break; + } + } + + uint32_t uriLen = filePathLen - i - 1; + if ((uriLen == 0) || (memcpy_s(uriBlob->data, MAX_LEN_URI, &filePath[i + 1], uriLen) != EOK)) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + uriBlob->size = uriLen; + + return CM_SUCCESS; +} + +static int32_t CmRemoveSpecifiedAppCert(const struct CmContext *context, const uint32_t store) +{ + uint32_t fileCount = 0; + int32_t retCode, ret = CM_SUCCESS; + char pathBuf[CERT_MAX_PATH_LEN] = {0}; + char uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob fileNames[MAX_COUNT_CERTIFICATE]; + struct CmBlob path = { sizeof(pathBuf), (uint8_t*)pathBuf }; + struct CmBlob uriBlob = { sizeof(uriBuf), (uint8_t*)uriBuf }; + uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob); + (void)memset_s(fileNames, len, 0, len); + + do { + if (CmAppCertGetFilePath(context, store, &path) != CM_SUCCESS) { + ret = CM_FAILURE; + CM_LOG_E("Get file path for store:%u faild", store); + break; + } + + if (CmUserIdLayerGetFileCountAndNames(pathBuf, fileNames, MAX_COUNT_CERTIFICATE, &fileCount) != CM_SUCCESS) { + ret = CM_FAILURE; + CM_LOG_E("Get file count and names from path faild: %s", pathBuf); + break; + } + + CM_LOG_I("CmRemoveSpecifiedAppCert fileCount:%u", fileCount); + + for (uint32_t i = 0; i < fileCount; i++) { + if (CertManagerFileRemove(NULL, (char *)fileNames[i].data) != CM_SUCCESS) { + CM_LOG_E("App cert %u remove faild, ret: %d", i, ret); + continue; + } + + (void)memset_s(uriBuf, MAX_LEN_URI, 0, MAX_LEN_URI); + if (CmGetUri((char *)fileNames[i].data, &uriBlob) != CM_SUCCESS) { + CM_LOG_E("Get uri failed"); + continue; + } + + CM_LOG_I("CmRemoveSpecifiedAppCert i:%d, uri:%s", i, (char *)uriBlob.data); + + /* ignore the return of HksDeleteKey */ + retCode = HksDeleteKey(&HKS_BLOB(&uriBlob), NULL); + if (retCode != HKS_SUCCESS && retCode != HKS_ERROR_NOT_EXIST) { + CM_LOG_I("App key %u remove failed ret: %d", i, ret); + } + } + } while (0); + + CmFreeFileNames(fileNames, MAX_COUNT_CERTIFICATE); + return ret; +} + +int32_t CmRemoveAllAppCert(const struct CmContext *context) +{ + /* Only public and private credential removed can be returned */ + /* remove pubic credential app cert */ + int32_t ret = CmRemoveSpecifiedAppCert(context, CM_CREDENTIAL_STORE); + if (ret != CM_SUCCESS) { + CM_LOG_E("remove pubic credential app cert faild"); + } + + /* remove private credential app cert */ + ret = CmRemoveSpecifiedAppCert(context, CM_PRI_CREDENTIAL_STORE); + if (ret != CM_SUCCESS) { + CM_LOG_E("remove private credential app cert faild"); + } + + return ret; +} + +void CmFreeFileNameUri(struct CmBlob *uri, uint32_t size) +{ + for (uint32_t i = 0; i < size; i++) { + CM_FREE_BLOB(uri[i]); + } +} + +int32_t CmServiceGetAppCertList(const struct CmContext *context, uint32_t store, struct CmBlob *fileNames, + const uint32_t fileSize, uint32_t *fileCount) +{ + char pathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmBlob path = { sizeof(pathBuf), (uint8_t*)pathBuf }; + + if (store != CM_CREDENTIAL_STORE && store != CM_PRI_CREDENTIAL_STORE) { + CM_LOG_E("Parm is invalid store:%u", store); + return CM_FAILURE; + } + + int32_t ret = CmAppCertGetFilePath(context, store, &path); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get file path for store:%u faild", store); + return CM_FAILURE; + } + + ret = CmUserIdLayerGetFileCountAndNames(pathBuf, fileNames, fileSize, fileCount); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get file count and names from path faild ret:%d:path:%s", ret, pathBuf); + return ret; + } + + return CM_SUCCESS; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_auth.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_auth.c new file mode 100644 index 0000000..1add328 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_auth.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "securec.h" +#include "cert_manager.h" +#include "cm_log.h" +#include "cert_manager_status.h" +#include "cert_manager_util.h" +#include "cert_manager_uri.h" +#include "hks_api.h" +#include "hks_param.h" +#include "hks_type.h" + +#define MAX_UID_LEN 10 +#define MAX_MAC_LEN 32 + +#define KEY_INFO_LIST_MAX_SIZE 4096 // maximum number of keys (including mac-keys) + +#ifdef __cplusplus +extern "C" { +#endif + +static int32_t UriSetIdStr(char **str, uint32_t value) +{ + char *s = NULL; + ASSERT_MALLOC(s, MAX_UID_LEN); + if (snprintf_s(s, MAX_UID_LEN, MAX_UID_LEN - 1, "%u", value) < 0) { + return CMR_ERROR_INVALID_OPERATION; + } + s[MAX_UID_LEN - 1] = 0; + *str = s; + return CMR_OK; +} + +static int32_t UriAddQuery(struct CMUri *uri, const struct CMApp *clientApp, const char *mac) +{ + if (clientApp != NULL) { + ASSERT_FUNC(UriSetIdStr(&uri->clientUser, clientApp->userId)); + ASSERT_FUNC(UriSetIdStr(&uri->clientApp, clientApp->uid)); + } + if (mac != NULL) { + uri->mac = strdup(mac); + } + return CMR_OK; +} + +static int32_t EncodeUri(char **s, const struct CMUri *uri) +{ + int rc = CMR_OK; + char *encoded = NULL; + uint32_t len = 0; + + ASSERT_FUNC(CertManagerUriEncode(NULL, &len, uri)); + ASSERT_MALLOC(encoded, len); + (void)memset_s(encoded, len, 0, len); + + TRY_FUNC(CertManagerUriEncode(encoded, &len, uri), rc); + + CM_LOG_D("Has uri: %s\n", encoded); + +finally: + if (rc == CMR_OK) { + *s = encoded; + } else if (encoded != NULL) { + FREE(encoded); + } + return rc; +} + +struct CmClient { + const struct CMApp *clientApp; + const char *mac; +}; + +static int32_t BuildUri( + char **objUri, const char *name, uint32_t type, + const struct CMApp *app, const struct CmClient *clientInfo) +{ + int32_t rc = CMR_OK; + const struct CMApp *clientApp = clientInfo->clientApp; + const char *mac = clientInfo->mac; + struct CMUri uri = {0}; + uri.object = strdup(name); + uri.type = type; + + TRY_FUNC(UriSetIdStr(&uri.user, app->userId), rc); + TRY_FUNC(UriSetIdStr(&uri.app, app->uid), rc); + TRY_FUNC(UriAddQuery(&uri, clientApp, mac), rc); + TRY_FUNC(EncodeUri(objUri, &uri), rc); + +finally: + CertManagerFreeUri(&uri); + return rc; +} + +int32_t BuildObjUri(char **objUri, const char *name, uint32_t type, const struct CMApp *app) +{ + const struct CmClient clientInfo = { NULL, NULL }; + return BuildUri(objUri, name, type, app, &clientInfo); +} + +static inline int32_t CheckKeyObjectType(uint32_t type) +{ + if (! CertManagerIsKeyObjectType(type)) { + CM_LOG_W("Not a valid key object type: %u\n", type); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CMR_OK; +} + +int32_t CertManagerImportKeyPair( + const struct CMApp *caller, + const struct CmBlob *keyPair, + const struct CMKeyProperties *properties, + const char *name) +{ + ASSERT_ARGS(caller && keyPair && properties && name); + ASSERT_ARGS(strlen(name) > 0); + ASSERT_ARGS(strlen(name) <= CM_NAME_MAX_LEN); + + uint32_t type = properties->type; + ASSERT_FUNC(CheckKeyObjectType(type)); + + int rc = CMR_OK; + char *objUri = NULL; + struct HksParamSet *params = NULL; + + TRY_FUNC(CertManagerBuildKeySpec(¶ms, properties), rc); + TRY_FUNC(BuildObjUri(&objUri, name, type, caller), rc); + + struct HksBlob alias = { .size = strlen(objUri), .data = (uint8_t *) objUri }; + TRY_CM_CALL(HksImportKey(&alias, params, &HKS_BLOB(keyPair)), rc); + +finally: + if (params != NULL) { + HksFreeParamSet(¶ms); + } + if (objUri != NULL) { + FREE(objUri); + } + return rc; +} + +#ifdef __cplusplus +} +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file.c new file mode 100644 index 0000000..e5539a7 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "securec.h" +#include "cert_manager.h" +#include "cert_manager_file.h" +#include "cert_manager_mem.h" +#include "cert_manager_type.h" +#include "cm_log.h" +#include "cm_type.h" +#include "cert_manager_file_operator.h" + +#define MAX_LEN_URI 64 + +inline uint32_t CertManagerFileSize(const char *path, const char *fileName) +{ + return CmFileSize(path, fileName); +} + +inline uint32_t CertManagerFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len) +{ + return CmFileRead(path, fileName, offset, buf, len); +} + +inline int32_t CertManagerFileWrite(const char *path, const char *fileName, + uint32_t offset, const uint8_t *buf, uint32_t len) +{ + return CM_ERROR(CmFileWrite(path, fileName, offset, buf, len)); +} + +inline int32_t CertManagerFileRemove(const char *path, const char *fileName) +{ + return CM_ERROR(CmFileRemove(path, fileName)); +} + +static uint32_t GetNumberOfFiles(const char *path) +{ + void *dir = CmOpenDir(path); + if (dir == NULL) { + CM_LOG_W("can't open directory"); + return -1; + } + + uint32_t count = 0; + struct CmFileDirentInfo dire = {{0}}; + while (CmGetDirFile(dir, &dire) == CMR_OK) { + count++; + } + (void)CmCloseDir(dir); + return count; +} + +static int32_t MallocFileNames(struct CmMutableBlob *fileNames, const char *path, struct CmMutableBlob **fNames, + uint32_t *fileCount) +{ + struct CmMutableBlob *tmp = NULL; + uint32_t fileNums = GetNumberOfFiles(path); + if (fileNums < 0) { + CM_LOG_E("Failed to obtain number of files from: path = %s", path); + return -1; + } + + *fileCount = (uint32_t)fileNums; + + tmp = (struct CmMutableBlob *)CMMalloc(sizeof(struct CmMutableBlob) * fileNums); + if (tmp == NULL) { + CM_LOG_E("Failed to allocate memory for file names"); + return -1; + } + + for (uint32_t i = 0; i < fileNums; i++) { + tmp[i].data = NULL; + tmp[i].size = 0; + } + fileNames->data = (uint8_t *)tmp; + fileNames->size = (uint32_t)fileNums; + *fNames = tmp; + + return 0; +} + +static void FreeFileNames(struct CmMutableBlob *fNames, uint32_t endIndex) +{ + uint32_t i; + for (i = 0; i < endIndex; i++) { + if (fNames[i].data != NULL) { + if (memset_s(fNames[i].data, fNames[i].size, 0, fNames[i].size) != EOK) { + return; + } + CMFree(fNames[i].data); + fNames[i].data = NULL; + fNames[i].size = 0; + } + } + CMFree(fNames); + fNames = NULL; +} + +int32_t CertManagerGetFilenames(struct CmMutableBlob *fileNames, const char *path, struct CmBlob *uri) +{ + uint32_t i = 0, fileCount = 0; + struct CmMutableBlob *fNames = NULL; + + if ((fileNames == NULL) || (path == NULL)) { + CM_LOG_E("Bad parameters: path = %s", path); + return -1; + } + + if (MallocFileNames(fileNames, path, &fNames, &fileCount) != 0) { + CM_LOG_E("Failed to malloc memory for files name"); + return -1; + } + + void *d = CmOpenDir(path); + if (d == NULL) { + CM_LOG_E("Failed to open directory: %s", path); + goto err; + } + + struct CmFileDirentInfo dire = {0}; + while (CmGetDirFile(d, &dire) == CMR_OK) { + fNames[i].size = strlen(dire.fileName); + fNames[i].data = (uint8_t *) strdup(dire.fileName); + + uri[i].size = MAX_LEN_URI; + uri[i].data = (uint8_t *)CMMalloc(MAX_LEN_URI); + if (uri[i].data == NULL) { + goto err; + } + if (memset_s(uri[i].data, MAX_LEN_URI, 0, MAX_LEN_URI) != EOK) { + goto err; + } + + uri[i].size = fNames[i].size; + if (memcpy_s(uri[i].data, MAX_LEN_URI, fNames[i].data, fNames[i].size) != EOK) { + goto err; + } + i++; + } + + if (i != fileCount) { + goto err; + } + + (void) CmCloseDir(d); + + return fileCount; +err: + (void) CmCloseDir(d); + FreeFileNames(fNames, i); + CmFreeFileNameUri(uri, MAX_COUNT_CERTIFICATE); + + return -1; +} \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file_operator.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file_operator.c new file mode 100644 index 0000000..73d8f93 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_file_operator.c @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef CM_CONFIG_FILE +#include CM_CONFIG_FILE +#else +#include "cm_config.h" +#endif + +#include "cert_manager_file_operator.h" +#include +#include +#include +#include +#include +#include "securec.h" +#include "cm_log.h" +#include "cert_manager_mem.h" + +static int32_t GetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen) +{ + if (path != NULL) { + if (strncpy_s(fullFileName, fullFileNameLen, path, strlen(path)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + + if (path[strlen(path) - 1] != '/') { + if (strncat_s(fullFileName, fullFileNameLen, "/", strlen("/")) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + } + + if (strncat_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + } else { + if (strncpy_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + } + return CMR_OK; +} + +static int32_t GetFullFileName(const char *path, const char *fileName, char **fullFileName) +{ + uint32_t nameLen = CM_MAX_FILE_NAME_LEN; + char *tmpFileName = (char *)CMMalloc(nameLen); + if (tmpFileName == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + if (memset_s(tmpFileName, nameLen, 0, nameLen) != EOK) { + return CMR_ERROR; + } + + int32_t ret = GetFileName(path, fileName, tmpFileName, nameLen); + if (ret != CMR_OK) { + CM_LOG_E("get full fileName failed"); + CM_FREE_PTR(tmpFileName); + return ret; + } + *fullFileName = tmpFileName; + + return CMR_OK; +} + +static int32_t IsFileExist(const char *fileName) +{ + if (access(fileName, F_OK) != 0) { + return CMR_ERROR_NOT_EXIST; + } + + return CMR_OK; +} + +int32_t CmIsDirExist(const char *path) +{ + if (path == NULL) { + return CMR_ERROR_NULL_POINTER; + } + return IsFileExist(path); +} + +static uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len) +{ + (void)offset; + if (IsFileExist(fileName) != CMR_OK) { + return 0; + } + + char filePath[PATH_MAX + 1] = {0}; + (void)realpath(fileName, filePath); + if (strstr(filePath, "../") != NULL) { + CM_LOG_E("invalid filePath, path %s", filePath); + return 0; + } + + FILE *fp = fopen(filePath, "rb"); + if (fp == NULL) { + CM_LOG_E("failed to open file"); + return 0; + } + + uint32_t size = fread(buf, 1, len, fp); + if (fclose(fp) < 0) { + CM_LOG_E("failed to close file"); + return 0; + } + + return size; +} + +static uint32_t FileSize(const char *fileName) +{ + if (IsFileExist(fileName) != CMR_OK) { + CM_LOG_E("file IsFileExist fail."); + return 0; + } + + struct stat fileStat; + (void)memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat)); + + if (stat(fileName, &fileStat) != 0) { + CM_LOG_E("file stat fail."); + return 0; + } + + return (uint32_t)fileStat.st_size; +} + +static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len) +{ + (void)offset; + char filePath[PATH_MAX + 1] = {0}; + if (memcpy_s(filePath, sizeof(filePath) - 1, fileName, strlen(fileName)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + (void)realpath(fileName, filePath); + if (strstr(filePath, "../") != NULL) { + CM_LOG_E("invalid filePath, path %s", filePath); + return CMR_ERROR_NOT_EXIST; + } + + /* caller function ensures that the folder exists */ + FILE *fp = fopen(filePath, "wb+"); + if (fp == NULL) { + CM_LOG_E("open file fail. filePath:%s", filePath); + return CMR_ERROR_OPEN_FILE_FAIL; + } + + if (chmod(filePath, S_IRUSR | S_IWUSR) < 0) { + CM_LOG_E("chmod file fail."); + fclose(fp); + return CMR_ERROR_OPEN_FILE_FAIL; + } + + uint32_t size = fwrite(buf, 1, len, fp); + if (size != len) { + CM_LOG_E("write file size fail."); + fclose(fp); + return CMR_ERROR_WRITE_FILE_FAIL; + } + + if (fclose(fp) < 0) { + CM_LOG_E("failed to close file"); + return CMR_ERROR_CLOSE_FILE_FAIL; + } + + return CMR_OK; +} + +static int32_t FileRemove(const char *fileName) +{ + int32_t ret = IsFileExist(fileName); + if (ret != CMR_OK) { + return CMR_OK; /* if file not exist, return ok */ + } + + struct stat tmp; + if (stat(fileName, &tmp) != 0) { + return CMR_ERROR_INVALID_OPERATION; + } + + if (S_ISDIR(tmp.st_mode)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + if ((unlink(fileName) != 0) && (errno != ENOENT)) { + CM_LOG_E("failed to remove file: filename = %s, errno = 0x%x", fileName, errno); + return CMR_ERROR_REMOVE_FILE_FAIL; + } + + return CMR_OK; +} + +int32_t CmFileRemove(const char *path, const char *fileName) +{ + if (fileName == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + char *fullFileName = NULL; + int32_t ret = GetFullFileName(path, fileName, &fullFileName); + if (ret != CMR_OK) { + return ret; + } + + ret = FileRemove(fullFileName); + CM_FREE_PTR(fullFileName); + return ret; +} + +int32_t CmMakeDir(const char *path) +{ + if ((access(path, F_OK)) != -1) { + CM_LOG_I(" %s exist", path); + return CMR_OK; + } + + if (mkdir(path, S_IRWXU) == 0) { + return CMR_OK; + } else { + if (errno == EEXIST || errno == EAGAIN) { + return CMR_ERROR_ALREADY_EXISTS; + } else { + return CMR_ERROR_MAKE_DIR_FAIL; + } + } +} + +void *CmOpenDir(const char *path) +{ + return (void *)opendir(path); +} + +int32_t CmCloseDir(void *dirp) +{ + return closedir((DIR *)dirp); +} + +int32_t CmGetDirFile(void *dirp, struct CmFileDirentInfo *direntInfo) +{ + DIR *dir = (DIR *)dirp; + struct dirent *dire = readdir(dir); + + while (dire != NULL) { + if (dire->d_type != DT_REG) { /* only care about files. */ + dire = readdir(dir); + continue; + } + + uint32_t len = strlen(dire->d_name); + if (memcpy_s(direntInfo->fileName, sizeof(direntInfo->fileName) - 1, dire->d_name, len) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + direntInfo->fileName[len] = '\0'; + return CMR_OK; + } + + return CMR_ERROR_NOT_EXIST; +} + +uint32_t CmFileRead(const char *path, const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len) +{ + if ((fileName == NULL) || (buf == NULL) || (len == 0)) { + return 0; + } + + char *fullFileName = NULL; + int32_t ret = GetFullFileName(path, fileName, &fullFileName); + if (ret != CMR_OK) { + return 0; + } + + uint32_t size = FileRead(fullFileName, offset, buf, len); + CM_FREE_PTR(fullFileName); + return size; +} + +int32_t CmFileWrite(const char *path, const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len) +{ + if ((fileName == NULL) || (buf == NULL) || (len == 0)) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + char *fullFileName = NULL; + int32_t ret = GetFullFileName(path, fileName, &fullFileName); + if (ret != CMR_OK) { + return ret; + } + + ret = FileWrite(fullFileName, offset, buf, len); + CM_FREE_PTR(fullFileName); + return ret; +} + +uint32_t CmFileSize(const char *path, const char *fileName) +{ + if (fileName == NULL) { + CM_LOG_E("fileName is NULL"); + return 0; + } + + char *fullFileName = NULL; + int32_t ret = GetFullFileName(path, fileName, &fullFileName); + if (ret != CMR_OK) { + CM_LOG_E("GetFullFileName failed"); + return 0; + } + + uint32_t size = FileSize(fullFileName); + CM_FREE_PTR(fullFileName); + return size; +} + +static int32_t CmUidLayerGetFileNames(const char *filePath, struct CmBlob *fileNames, + const uint32_t arraySize, uint32_t count) +{ + if (count >= arraySize) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + uint32_t filePathLen = strlen(filePath); + fileNames[count].data = (uint8_t *)CMMalloc(filePathLen + 1); + if (fileNames[count].data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + (void)memset_s(fileNames[count].data, filePathLen + 1, 0, filePathLen + 1); + if (memcpy_s(fileNames[count].data, CM_MAX_FILE_NAME_LEN, + filePath, filePathLen) != EOK) { + /* fileNames memory free in top layer function */ + return CMR_ERROR_BUFFER_TOO_SMALL; + } + fileNames[count].size = filePathLen; + return CM_SUCCESS; +} + +static int32_t CmUidLayerGetFileCountAndNames(const char *path, struct CmBlob *fileNames, + const uint32_t arraySize, uint32_t *fileCount) +{ + uint32_t count = *fileCount; + char uidPath[CM_MAX_FILE_NAME_LEN] = {0}; + /* do nothing when dir is not exist */ + if (CmIsDirExist(path) != CMR_OK) { + CM_LOG_I("Uid layer dir is not exist:%s", path); + return CM_SUCCESS; + } + DIR *dir = opendir(path); + if (dir == NULL) { + CM_LOG_E("open uid layer dir failed"); + return CMR_ERROR_OPEN_FILE_FAIL; + } + + struct dirent *dire = readdir(dir); + while (dire != NULL) { + (void)memset_s(uidPath, CM_MAX_FILE_NAME_LEN, 0, CM_MAX_FILE_NAME_LEN); + if (strncpy_s(uidPath, sizeof(uidPath), path, strlen(path)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if (uidPath[strlen(uidPath) - 1] != '/') { + if (strncat_s(uidPath, sizeof(uidPath), "/", strlen("/")) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + } + + if (strncat_s(uidPath, sizeof(uidPath), dire->d_name, strlen(dire->d_name)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if ((strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0)) { + if (CmUidLayerGetFileNames(uidPath, fileNames, arraySize, count) != CM_SUCCESS) { + closedir(dir); + return CM_FAILURE; + } + count++; + } + dire = readdir(dir); + } + *fileCount = count; + closedir(dir); + return CM_SUCCESS; +} + +int32_t CmUserIdLayerGetFileCountAndNames(const char *path, struct CmBlob *fileNames, + const uint32_t arraySize, uint32_t *fileCount) +{ + char userIdPath[CM_MAX_FILE_NAME_LEN] = { 0 }; + /* do nothing when dir is not exist */ + if (CmIsDirExist(path) != CMR_OK) { + CM_LOG_I("UserId layer dir is not exist:%s", path); + return CM_SUCCESS; + } + DIR *dir = opendir(path); + if (dir == NULL) { + CM_LOG_E("open userId layer dir failed"); + return CMR_ERROR_OPEN_FILE_FAIL; + } + struct dirent *dire = readdir(dir); + while (dire != NULL) { + (void)memset_s(userIdPath, CM_MAX_FILE_NAME_LEN, 0, CM_MAX_FILE_NAME_LEN); + if (strncpy_s(userIdPath, sizeof(userIdPath), path, strlen(path)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if (userIdPath[strlen(userIdPath) - 1] != '/') { + if (strncat_s(userIdPath, sizeof(userIdPath), "/", strlen("/")) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + } + + if (strncat_s(userIdPath, sizeof(userIdPath), dire->d_name, strlen(dire->d_name)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + CM_LOG_E("CmIpcServiceGetAppCert07:%d", *fileCount); + if ((dire->d_type == DT_DIR) && (strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0)) { + if (CmUidLayerGetFileCountAndNames(userIdPath, fileNames, arraySize, fileCount) != CM_SUCCESS) { + CM_LOG_E("CmUidLayerGetFileCountAndNames faild"); + closedir(dir); + return CM_FAILURE; + } + } else if (dire->d_type != DT_DIR) { + (void)remove(userIdPath); + } + dire = readdir(dir); + CM_LOG_E("CmIpcServiceGetAppCert20:%d", *fileCount); + } + closedir(dir); + return CM_SUCCESS; +} + diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_mem.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_mem.c new file mode 100644 index 0000000..06654ff --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_mem.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cert_manager_mem.h" + +#include + +void *CMMalloc(size_t size) +{ + return malloc(size); +} + +void CMFree(void *ptr) +{ + free(ptr); +} diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_status.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_status.c new file mode 100644 index 0000000..7f8d848 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_status.c @@ -0,0 +1,745 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "securec.h" +#include "cert_manager.h" +#include "cm_log.h" +#include "cert_manager_mem.h" +#include "cert_manager_status.h" +#include "cert_manager_type.h" +#include "cert_manager_file.h" +#include "cert_manager_file_operator.h" +#include "cert_manager_util.h" +#include "cm_type.h" +#include "hks_type.h" +#include "hks_api.h" +#include "rbtree.h" + +#define HEADER_LEN (4 + CM_INTEGRITY_TAG_LEN + CM_INTEGRITY_SALT_LEN) +#define APPLICATION_TRUSTED_STORE 2 +#define ENCODED_INT_COUNT 3 + +#ifdef __cplusplus +extern "C" { +#endif + +/* red-black tree to store disabled certificate file names. */ +static struct RbTree g_trees[] = { {0}, {0}, {0} }; +static const uint32_t g_treeCount = 3; + +static const char *g_statusFiles[] = { + CERT_STATUS_SYSTEM_STORE, + CERT_STATUS_USER_STORE, + CERT_STATUS_APPLICATION_STORE, +}; + +static pthread_rwlock_t g_treeLocks[] = { + PTHREAD_RWLOCK_INITIALIZER, + PTHREAD_RWLOCK_INITIALIZER, + PTHREAD_RWLOCK_INITIALIZER, +}; + +static pthread_rwlock_t g_fileLocks[] = { + PTHREAD_RWLOCK_INITIALIZER, + PTHREAD_RWLOCK_INITIALIZER, + PTHREAD_RWLOCK_INITIALIZER, +}; + +static pthread_rwlock_t g_statusLock = PTHREAD_RWLOCK_INITIALIZER; + +struct CertEnableStatus { + bool getter; + uint32_t *oldStatus; + uint32_t status; +}; + +struct treeNode { + uint32_t store; + bool *found; + RbTreeKey key; +}; + +static int32_t Ikhmac(uint8_t *data, uint32_t len, uint8_t *mac) +{ + struct CmBlob dataBlob = { .size = len, .data = data}; + struct CmMutableBlob macBlob = { .size = CM_INTEGRITY_TAG_LEN, .data = mac}; + return CertManagerHmac(CM_INTEGRITY_KEY_URI, &dataBlob, &macBlob); +} + +static void FreeStatus(struct CertStatus *cs) +{ + if (cs != NULL) { + if (cs->fileName != NULL) { + CMFree(cs->fileName); + } + CMFree(cs); + } +} + +static void FreeTreeNodeValue(RbTreeKey key, RbTreeValue v, const void *context) +{ + (void) context; + (void) key; + if (v != NULL) { + FreeStatus((struct CertStatus *) v); + } +} + +static int GetStoreIndex(uint32_t store) +{ + switch (store) { + case CM_SYSTEM_TRUSTED_STORE: + return 0; + case CM_USER_TRUSTED_STORE: + return 1; + case CM_PRI_CREDENTIAL_STORE: + return APPLICATION_TRUSTED_STORE; + default: + CM_LOG_W("No index for store %u\n", store); + return -1; + } +} + +static int EncodeStatus(RbTreeValue value, uint8_t *buf, uint32_t *size) +{ + /* each cert status struct is encoded as (userId | uid | status | fileName) + Note that fileName is null terminated */ + + struct CertStatus *cs = (struct CertStatus *) value; + if (cs == NULL) { + CM_LOG_E("Unexpectef NULL value.\n"); + return CMR_ERROR; + } + + /* encode 3 integers and a string */ + uint32_t sz = 3 * sizeof(uint32_t) + strlen(cs->fileName) + 1; + + if (buf == NULL) { + /* only return the required size */ + *size = sz; + return CMR_OK; + } + + if (*size < sz) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + uint8_t *s = buf; + uint32_t r = *size; + + if (memcpy_s(s, r, &cs->userId, sizeof(uint32_t)) != EOK) { + CM_LOG_W("Failed to cs->userId "); + return CMR_ERROR; + } + s += sizeof(uint32_t); + r -= sizeof(uint32_t); + + if (memcpy_s(s, r, &cs->uid, sizeof(uint32_t)) != EOK) { + CM_LOG_W("Failed to cs->uid "); + return CMR_ERROR; + } + s += sizeof(uint32_t); + r -= sizeof(uint32_t); + + if (memcpy_s(s, r, &cs->status, sizeof(uint32_t)) != EOK) { + CM_LOG_W("Failed to cs->status "); + return CMR_ERROR; + } + s += sizeof(uint32_t); + r -= sizeof(uint32_t); + + if (memcpy_s(s, r, cs->fileName, strlen(cs->fileName) + 1) != EOK) { + CM_LOG_W("Failed to cs->fileName "); + return CMR_ERROR; + } + + *size = sz; + return CMR_OK; +} + +static int DecodeStatus(RbTreeValue *value, const uint8_t *buf, uint32_t size) +{ + /* each cert status struct is encoded as (userId | uid | status | fileName) + Note that fileName is null terminated + Require 3 integers and at least 1 character */ + if (buf == NULL || size < ENCODED_INT_COUNT * sizeof(uint32_t) + 1) { + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + if (buf[size - 1] != '\0') { + CM_LOG_W("Unexpected cert status value.\n"); + return CMR_ERROR; + } + + struct CertStatus *cs = CMMalloc(sizeof(struct CertStatus)); + if (cs == NULL) { + CM_LOG_E("Failed to allocate memory.\n"); + return CMR_ERROR_MALLOC_FAIL; + } + + const uint8_t *s = buf; + + if (memcpy_s(&cs->userId, sizeof(uint32_t), s, sizeof(uint32_t)) != EOK) { + return CMR_ERROR; + } + s += sizeof(uint32_t); + + if (memcpy_s(&cs->uid, sizeof(uint32_t), s, sizeof(uint32_t)) != EOK) { + return CMR_ERROR; + } + s += sizeof(uint32_t); + + if (memcpy_s(&cs->status, sizeof(uint32_t), s, sizeof(uint32_t)) != EOK) { + return CMR_ERROR; + } + s += sizeof(uint32_t); + + cs->fileName = strdup((char *) s); + *value = cs; + return CMR_OK; +} + +static int32_t ReadFile(const char *file, uint8_t **bufptr, uint32_t *size) +{ + uint32_t sz = 0; + int32_t rc = CMR_OK; + uint8_t *buf = NULL; + uint32_t nb = 0; + + sz = CertManagerFileSize(CERT_STATUS_DIR, file); + if (sz == 0) { + CM_LOG_I("Status file not found. Skip loading from %s/%s\n", CERT_STATUS_DIR, file); + goto finally; + } + + if (sz < HEADER_LEN) { + CM_LOG_W("Status file size too small. Must be at least %u bytes.\n", HEADER_LEN); + rc = CMR_ERROR_STORAGE; + goto finally; + } + + buf = CMMalloc(sz); + if (buf == NULL) { + CM_LOG_W("Failed to allocate memory.\n"); + rc = CMR_ERROR_MALLOC_FAIL; + goto finally; + } + nb = CertManagerFileRead(CERT_STATUS_DIR, file, 0, buf, sz); + if (nb != sz) { + CM_LOG_W("Failed to read status file: %u bytes expected but only has %u\n", sz, nb); + rc = CMR_ERROR_STORAGE; + goto finally; + } + +finally: + if (rc != CMR_OK) { + FREE_PTR(buf); + } else { + *bufptr = buf; + *size = sz; + } + return rc; +} + +static int32_t LoadTreeStatus(struct RbTree *tree, pthread_rwlock_t *treeLock, uint8_t *buf, uint32_t sz) +{ + int32_t rc = CMR_OK; + CM_LOG_W("LoadTreeStatus6"); + if (buf == NULL || sz == 0) { + /* file does not exist or is empty */ + CM_LOG_D("Status file does not exist or is empty."); + return CMR_OK; + } + + uint32_t ver = DECODE_UINT32(buf); + /* currently version 1 (with value 0) is supported */ + if (ver != VERSION_1) { + CM_LOG_W("Unsupported version: %u\n", ver); + return CMR_ERROR; + } + + uint8_t *tag = buf + sizeof(uint32_t); + uint8_t *data = tag + CM_INTEGRITY_TAG_LEN; + uint32_t dataLen = sz - sizeof(uint32_t) - CM_INTEGRITY_TAG_LEN; + uint8_t mac[CM_INTEGRITY_TAG_LEN] = {0}; + + ASSERT_FUNC(Ikhmac(data, dataLen, mac)); + if (memcmp(mac, tag, CM_INTEGRITY_TAG_LEN)) { + CM_LOG_W("Status file MAC mismatch.\n"); + return CMR_ERROR; + } + + data += CM_INTEGRITY_SALT_LEN; + dataLen -= CM_INTEGRITY_SALT_LEN; + if (dataLen > 0) { + pthread_rwlock_wrlock(treeLock); + rc = RbTreeDecode(tree, DecodeStatus, data, dataLen); + pthread_rwlock_unlock(treeLock); + + if (rc != CMR_OK) { + CM_LOG_E("Failed to decode status tree: %d", rc); + return rc; + } + } + CM_LOG_I("Status loaded for store"); + return rc; +} + +static int32_t LoadStatus(uint32_t store) +{ + uint32_t sz = 0; + int32_t rc = CMR_OK; + uint8_t *buf = NULL; + + int storeIndex = GetStoreIndex(store); + if (storeIndex < 0) { + return CMR_ERROR; + } + struct RbTree *tree = &g_trees[storeIndex]; + const char *file = g_statusFiles[storeIndex]; + pthread_rwlock_t *fileLock = &g_fileLocks[storeIndex]; + pthread_rwlock_t *treeLock = &g_treeLocks[storeIndex]; + + pthread_rwlock_rdlock(fileLock); + rc = ReadFile(file, &buf, &sz); + pthread_rwlock_unlock(fileLock); + + if (rc != CMR_OK) { + CM_LOG_E("Failed to read status file: %d", rc); + return rc; + } + + rc = LoadTreeStatus(tree, treeLock, buf, sz); + + if (buf != NULL) { + CMFree(buf); + } + return rc; +} + +static int32_t EncodeTree(struct RbTree *tree, uint8_t **bufptr, uint32_t *size) +{ + int32_t rc = CMR_OK; + uint8_t *buf = NULL; + uint32_t sz = 0; + + TRY_FUNC(RbTreeEncode(tree, EncodeStatus, NULL, &sz), rc); + CM_LOG_D("%u bytes required to encode the status tree.\n", sz); + + sz += HEADER_LEN; + + buf = CMMalloc(sz); + if (buf == NULL) { + CM_LOG_W("Failed to allocate memory.\n"); + return CMR_ERROR_MALLOC_FAIL; + } + ASSERT_FUNC(memset_s(buf, sz, 0, sz)); + + ENCODE_UINT32(buf, VERSION_1); + + uint8_t *salt = buf + sizeof(uint32_t) + CM_INTEGRITY_TAG_LEN; + + /* generate random salt */ + struct HksBlob r = { .size = CM_INTEGRITY_SALT_LEN, .data = salt }; + (void) HksGenerateRandom(NULL, &r); + + uint8_t *data = buf + HEADER_LEN; + uint32_t dataLen = sz - HEADER_LEN; + TRY_FUNC(RbTreeEncode(tree, EncodeStatus, data, &dataLen), rc); + +finally: + if (rc != CMR_OK) { + FREE_PTR(buf); + } else { + *bufptr = buf; + *size = sz; + } + return rc; +} + +static int32_t WriteStatus(uint32_t store) +{ + int storeIndex = GetStoreIndex(store); + if (storeIndex < 0) { + return CMR_ERROR; + } + struct RbTree *tree = &g_trees[storeIndex]; + const char *file = g_statusFiles[storeIndex]; + pthread_rwlock_t *fileLock = &g_fileLocks[storeIndex]; + pthread_rwlock_t *treeLock = &g_treeLocks[storeIndex]; + + int32_t rc = CMR_OK; + uint8_t *buf = NULL; + uint32_t sz = 0; + + pthread_rwlock_rdlock(treeLock); + rc = EncodeTree(tree, &buf, &sz); + pthread_rwlock_unlock(treeLock); + + if (rc != CMR_OK) { + CM_LOG_E("Failed to encode status tree: %d", rc); + goto finally; + } + + uint8_t *tag = buf + sizeof(uint32_t); + uint8_t *data = tag + CM_INTEGRITY_TAG_LEN; + uint32_t dataLen = sz - sizeof(uint32_t) - CM_INTEGRITY_TAG_LEN; + + TRY_FUNC(Ikhmac(data, dataLen, tag), rc); + + pthread_rwlock_wrlock(fileLock); + rc = CertManagerFileWrite(CERT_STATUS_DIR, file, 0, buf, sz); + pthread_rwlock_unlock(fileLock); + if (rc != CMR_OK) { + CM_LOG_E("Failed to write status file: %d", rc); + } + +finally: + if (buf != NULL) { + CMFree(buf); + } + return rc; +} + +int32_t CertManagerStatusInit(void) +{ + int rc = CMR_OK; + if (CmMakeDir(CERT_STATUS_DIR) == CMR_ERROR_MAKE_DIR_FAIL) { + CM_LOG_E("Failed to create folder %s\n", CERT_STATUS_DIR); + return CMR_ERROR_WRITE_FILE_FAIL; + } + + pthread_rwlock_wrlock(&g_statusLock); + for (uint32_t i = 0; i < g_treeCount; i++) { + TRY_FUNC(RbTreeNew(&g_trees[i]), rc); + } + + TRY_FUNC(CertManagerGenerateHmacKey(CM_INTEGRITY_KEY_URI), rc); + TRY_FUNC(LoadStatus(CM_SYSTEM_TRUSTED_STORE), rc); + TRY_FUNC(LoadStatus(CM_USER_TRUSTED_STORE), rc); + TRY_FUNC(LoadStatus(CM_PRI_CREDENTIAL_STORE), rc); + +finally: + pthread_rwlock_unlock(&g_statusLock); + return rc; +} + +int32_t CertManagerStatusDestroy(void) +{ + pthread_rwlock_wrlock(&g_statusLock); + for (uint32_t i = 0; i < g_treeCount; i++) { + (void) RbTreeDestroyEx(&g_trees[i], FreeTreeNodeValue, NULL); + } + pthread_rwlock_unlock(&g_statusLock); + return CMR_OK; +} + +inline static RbTreeKey GetRbTreeKeyFromName(char *name) +{ + /* use the first 4 bytes of file name (exluding the first bit) as the key */ + return DECODE_UINT32(name) & 0x7fffffff; +} + +static uint32_t GetCertStatusNode(const struct RbTreeNode *node) +{ + if (node == NULL) { + /* not in the cache. by .default certificate is enabled. */ + return CERT_STATUS_ENABLED; + } + + struct CertStatus *cs = node->value; + if (cs == NULL) { + return CERT_STATUS_ENABLED; + } + return cs->status; +} + +static int32_t SetCertStatusNode(const struct CmContext *ctx, struct RbTree *tree, + struct RbTreeNode *node, char *name, uint32_t status) +{ + if (node != NULL) { + /* found a matching node */ + struct CertStatus *cs = node->value; + if (cs == NULL) { + CM_LOG_E("No status attached to tree node !!\n"); + return CMR_ERROR; + } + + if (status == CERT_STATUS_ENABLED) { + /* the default status is ENABLED. hence, we just delete it from the tree */ + FreeStatus(cs); + node->value = NULL; + return RbTreeDelete(tree, node); + } + + /* for other status values, just overwrite */ + cs->status = status; + return CMR_OK; + } else { + /* no match was found, insert a new node */ + struct CertStatus *cs = CMMalloc(sizeof(struct CertStatus)); + if (cs == NULL) { + CM_LOG_E("Unable to allocate memory!!\n"); + return CMR_ERROR_MALLOC_FAIL; + } + cs->userId = ctx->userId; + cs->uid = ctx->uid; + cs->fileName = strdup(name); + cs->status = status; + int rc = RbTreeInsert(tree, GetRbTreeKeyFromName(name), cs); + if (rc != CMR_OK) { + CM_LOG_E("Failed to insert new node: %d\n", rc); + CMFree(cs->fileName); + CMFree(cs); + } + return rc; + } +} + +/* return true if the status matches the filename and the caller */ +static bool StatusMatch(const struct CmContext *context, const struct CertStatus *cs, + uint32_t store, const char *fileName) +{ + if (context == NULL || cs == NULL || fileName == NULL) { + CM_LOG_E("Paramset is NULL"); + return false; + } + + if (strcmp(cs->fileName, fileName)) { + /* file name must always match */ + return false; + } + + if (store == CM_USER_TRUSTED_STORE) { + /* for user store, the user ID must match the caller */ + if (cs->userId != context->userId) { + return false; + } + } else if (store == CM_PRI_CREDENTIAL_STORE) { + /* for application store, the user ID and app UID must match the caller */ + if (cs->userId != context->userId || + cs->uid != context->uid) { + return false; + } + } + return true; +} + +static int32_t CertManagerFindMatchedFile(const struct CmContext *context, struct RbTreeNode **treeNode, + struct RbTree *tree, struct treeNode tempPara, char *fn) +{ + uint32_t store = tempPara.store; + bool *found = tempPara.found; + RbTreeKey key = tempPara.key; + struct RbTreeNode *node = *treeNode; + + while (node != NULL && node != tree->nil) { + struct CertStatus *cs = node->value; + if (cs == NULL) { + /* shouldn't happen */ + CM_LOG_E("No value set to status node.\n"); + return CMR_ERROR; + } + + if (StatusMatch(context, cs, store, fn)) { + /* match found */ + *found = true; + break; + } + + if (node->right != tree->nil && RbTreeNodeKey(node->right) == key) { + node = node->right; + } else if (node->left != tree->nil && RbTreeNodeKey(node->left) == key) { + node = node->left; + } else { + /* no match possible */ + break; + } + } + *treeNode = node; + return CMR_OK; +} + +static int32_t CertManagerStatus(const struct CmContext *context, struct RbTree *tree, + struct CertEnableStatus certStatus, uint32_t store, char *fn) +{ + int rc = CMR_OK; + bool found = false; + struct RbTreeNode *node = NULL; + bool getter = certStatus.getter; + uint32_t status = certStatus.status; + uint32_t *oldStatus = certStatus.oldStatus; + RbTreeKey key = GetRbTreeKeyFromName(fn); + + rc = RbTreeFindNode(&node, key, tree); + if (rc != CMR_OK && rc != CMR_ERROR_NOT_FOUND) { + /* someting is wrong */ + CM_LOG_W("Failed to search in the status cache"); + return rc; + } + + /* furthrt check if the actual file name matched. */ + struct treeNode tempPara = {store, &found, key}; + rc = CertManagerFindMatchedFile(context, &node, tree, tempPara, fn); + if (rc != CMR_OK) { + CM_LOG_W("Failed to search file name"); + return rc; + } + + if (!found) { + node = NULL; + } + + *oldStatus = GetCertStatusNode(node); + if (!getter && *oldStatus != status) { + CM_LOG_I("start setting status"); + ASSERT_FUNC(SetCertStatusNode(context, tree, node, fn, status)); + } + + return rc; +} + +static int32_t CertManagerIsCallerPrivileged(const struct CmContext *context) +{ + (void) context; + return CMR_OK; +} + +static int32_t CertManagerCheckStorePermission(const struct CmContext *context, uint32_t store, bool statusOnly) +{ + /* System Store is read-only therefore we don't even try to use it. */ + if (store == CM_SYSTEM_TRUSTED_STORE) { + if (!statusOnly) { + CM_LOG_E("Storege type %u should be read on;y\n", store); + return CMR_ERROR_NOT_PERMITTED; + } else if (CMR_OK != CertManagerIsCallerPrivileged(context)) { + CM_LOG_W("Only privileged caller can change status in system stores.\n"); + return CMR_ERROR_NOT_PERMITTED; + } + } else if (store == CM_CREDENTIAL_STORE) { + CM_LOG_E("Credential certificates should be set via CertManagerIsCallerPrivileged\n"); + return CMR_ERROR_NOT_SUPPORTED; + } else if (store == CM_USER_TRUSTED_STORE) { + /* only priviled callers can update the user store */ + if (CMR_OK != CertManagerIsCallerPrivileged(context)) { + CM_LOG_W("Only privileged caller can modify user stores.\n"); + return CMR_ERROR_NOT_PERMITTED; + } + } else if (store == CM_PRI_CREDENTIAL_STORE) { + /* no additional checks here. context->caller can remove its own */ + } else { + CM_LOG_W("Invalid store type. Only a asingle store should be indicated: %u\n", store); + return CMR_ERROR_INVALID_ARGUMENT; + } + + return CMR_OK; +} + +static int32_t CertManagerStatusFile(const struct CmContext *context, struct CertFile certFile, + uint32_t store, const uint32_t status, uint32_t *stp) +{ + ASSERT_ARGS(context && certFile.path && certFile.fileName); + ASSERT_ARGS(certFile.path->size && certFile.path->data && certFile.fileName->size && certFile.fileName->data); + ASSERT_ARGS((status <= CERT_STATUS_MAX || stp != NULL)); + ASSERT_FUNC(CertManagerCheckStorePermission(context, store, true)); + + int rc = CMR_OK; + uint32_t oldStatus = 0; + bool getter = (stp != NULL); + int storeIndex = GetStoreIndex(store); + if (storeIndex < 0) { + return CMR_ERROR; + } + pthread_rwlock_t *lock = &g_treeLocks[storeIndex]; + struct RbTree *tree = &g_trees[storeIndex]; + + char fn[MAX_LEN_URI] = {0}; + if (memcpy_s(fn, MAX_LEN_URI, certFile.fileName->data, certFile.fileName->size) != EOK) { + CM_LOG_E("copy filename error"); + return CMR_ERROR; + } + + if (getter) { + pthread_rwlock_rdlock(lock); + } else { + pthread_rwlock_wrlock(lock); + } + struct CertEnableStatus certStatus = {getter, &oldStatus, status}; + rc = CertManagerStatus(context, tree, certStatus, store, fn); + + pthread_rwlock_unlock(lock); + if (rc != CMR_OK && rc != CMR_ERROR_NOT_FOUND) { + /* error occured */ + return rc; + } + if (getter) { + *stp = oldStatus; + } else if (oldStatus != status) { + /* setter */ + ASSERT_FUNC(WriteStatus(store)); + } + return CMR_OK; +} + +static int32_t CertStatus(const struct CmContext *context, const struct CmBlob *certificate, + uint32_t store, uint32_t status, uint32_t *stp) +{ + char fnBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob fileName = { sizeof(fnBuf), (uint8_t *) fnBuf }; + char pathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob path = { sizeof(pathBuf), (uint8_t *) pathBuf }; + ASSERT_FUNC(CertManagerFindCertFileName(context, certificate, store, &path, &fileName)); + struct CertFile certFile = {0, 0}; + + certFile.path = &(CM_BLOB(&path)); + certFile.fileName = &(CM_BLOB(&fileName)); + + return CertManagerStatusFile(context, certFile, store, status, stp); +} + +int32_t SetcertStatus(const struct CmContext *context, const struct CmBlob *certUri, + uint32_t store, uint32_t status, uint32_t *stp) +{ + char pathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob path = { sizeof(pathBuf), (uint8_t *) pathBuf }; + struct CertFile certFile = {0, 0}; + int32_t ret = CertManagerFindCertFileNameByUri(context, certUri, store, &path); + if (ret != CMR_OK) { + CM_LOG_E("CertManagerFindCertFileNameByUri error = %d", ret); + return ret; + } + certFile.path = &(CM_BLOB(&path)); + certFile.fileName = &(CM_BLOB(certUri)); + + return CertManagerStatusFile(context, certFile, store, status, stp); +} + +int32_t CertManagerSetCertificatesStatus(const struct CmContext *context, const struct CmBlob *certUri, + uint32_t store, uint32_t status) +{ + return SetcertStatus(context, certUri, store, status, NULL); +} + +int32_t CertManagerGetCertificatesStatus(const struct CmContext *context, const struct CmBlob *certificate, + uint32_t store, uint32_t *status) +{ + return CertStatus(context, certificate, store, CERT_STATUS_INVALID, status); +} + +#ifdef __cplusplus +} +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_uri.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_uri.c new file mode 100644 index 0000000..5f0370a --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_uri.c @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "securec.h" + +#include "cm_log.h" +#include "cert_manager_status.h" +#include "cert_manager_uri.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IS_TYPE_VALID(t) ((t) <= CM_URI_TYPE_MAX) + +#define SCHEME "oh:" +#define P_OBJECT "o=" +#define P_TYPE "t=" +#define P_USER "u=" +#define P_APP "a=" +#define Q_MAC "m=" +#define Q_CLIENT_USER "cu=" +#define Q_CLIENT_APP "ca=" + +// characters do not need to be encoded in path, other than digits and algabets +#define P_RES_AVAIL "-._~:[]@!$'()*+,=&" +// characters do not need to be encoded in query, other than digits and algabets +#define Q_RES_AVAIL "-._~:[]@!$'()*+,=/?|" + +int32_t CertManagerFreeUri(struct CMUri *uri) +{ + if (uri == NULL) { + return CMR_OK; + } + FREE_PTR(uri->object); + FREE_PTR(uri->user); + FREE_PTR(uri->app); + FREE_PTR(uri->mac); + FREE_PTR(uri->clientUser); + FREE_PTR(uri->clientApp); + return CMR_OK; +} + +inline bool CertManagerIsKeyObjectType(uint32_t type) +{ + return (type == CM_URI_TYPE_APP_KEY || type == CM_URI_TYPE_WLAN_KEY); +} + +static int IsUnreserved(const char *resAvail, size_t resAvailLen, char c) +{ + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) { + return 1; + } + if (resAvail != NULL) { + for (size_t i = 0; i < resAvailLen; i++) { + if (c == resAvail[i]) { + return 1; + } + } + } + return 0; +} + +static uint32_t GetComponentEncodedLen( + const char *key, const char *value, + const char *resAvail, uint32_t *sep) +{ + if (value == NULL) { + return 0; + } + size_t resAvailLen = strlen(resAvail); + size_t keyLen = strlen(key); + size_t valueLen = strlen(value); + size_t reserved = 0; + for (size_t i = 0; i < valueLen; i++) { + if (!IsUnreserved(resAvail, resAvailLen, value[i])) { + reserved++; + } + } + // each reserved character requires 2 extra bytes to percent-encode + uint32_t len = (uint32_t) (keyLen + valueLen + reserved * 2 + *sep); + *sep = 1; + return len; +} + +static uint32_t GetEncodedLen(const struct CMUri *uri) +{ + if (uri == NULL) { + return 0; + } + + uint32_t sep = 0; + uint32_t len = strlen(SCHEME); + + len += GetComponentEncodedLen(P_TYPE, g_types[uri->type], P_RES_AVAIL, &sep); + len += GetComponentEncodedLen(P_OBJECT, uri->object, P_RES_AVAIL, &sep); + len += GetComponentEncodedLen(P_USER, uri->user, P_RES_AVAIL, &sep); + len += GetComponentEncodedLen(P_APP, uri->app, P_RES_AVAIL, &sep); + + uint32_t qlen = 0; + sep = 0; + qlen += GetComponentEncodedLen(Q_CLIENT_USER, uri->clientUser, Q_RES_AVAIL, &sep); + qlen += GetComponentEncodedLen(Q_CLIENT_APP, uri->clientApp, Q_RES_AVAIL, &sep); + qlen += GetComponentEncodedLen(Q_MAC, uri->mac, Q_RES_AVAIL, &sep); + + return len + sep + qlen; +} + +// encode the last 4 bits of an integer to a hex char +static inline uint32_t HexEncode(uint32_t v) +{ + v &= 0xf; + if (v < DEC_LEN) { + return ('0' + v); + } else { + return ('A' + v - DEC_LEN); + } +} + +static int32_t EncodeComp( + char *buf, uint32_t *offset, uint32_t *available, + const char *key, const char *value, + const char *resAvail, + uint32_t *sep, char sepChar) +{ + if (value == NULL) { + return CMR_OK; + } + + size_t resAvailLen = strlen(resAvail); + size_t keyLen = strlen(key); + size_t valueLen = strlen(value); + uint32_t off = *offset; + uint32_t avail = *available; + + if (avail < *sep + keyLen + valueLen) { + return CMR_ERROR; + } + + if (*sep) { + buf[off] = sepChar; + off++; + } + + if (EOK != memcpy_s(buf + off, avail, key, keyLen)) { + return CMR_ERROR; + } + off += keyLen; + avail -= keyLen; + + for (size_t i = 0; i < valueLen; i++) { + if (IsUnreserved(resAvail, resAvailLen, value[i])) { + if (avail < 1) { + return CMR_ERROR; + } + buf[off] = value[i]; + off++; + avail--; + } else { + // each percent-encoded character requires 3 bytes + if (avail < 3) { + return CMR_ERROR; + } + buf[off] = '%'; + off++; + buf[off] = (char) HexEncode(value[i] >> 4); // higher 4 bits of the char byte + off++; + buf[off] = (char) HexEncode(value[i]); // lower 4 bits of the char byte + off++; + // each percent-encoded character requires 3 bytes + avail -= 3; + } + } + + *sep = 1; + *offset = off; + *available = avail; + return CMR_OK; +} + +int32_t CertManagerUriEncode(char *encoded, uint32_t *encodedLen, const struct CMUri *uri) +{ + ASSERT_ARGS(encodedLen); + ASSERT_ARGS(uri && IS_TYPE_VALID(uri->type)); + + uint32_t encLen = GetEncodedLen(uri) + 1; + if (encoded == NULL) { + *encodedLen = encLen; + return CMR_OK; + } + + if (*encodedLen < encLen) { + CM_LOG_W("Buffer to small for encoded URI (%u < %u).\n", *encodedLen, encLen); + return CMR_ERROR_BUFFER_TOO_SMALL; + } + + uint32_t sep = 0; + uint32_t off = 0; + uint32_t avail = *encodedLen; + + if (EOK != memcpy_s(encoded, avail, SCHEME, strlen(SCHEME))) { + return CMR_ERROR; + } + off += strlen(SCHEME); + avail -= strlen(SCHEME); + + ASSERT_FUNC(EncodeComp(encoded, &off, &avail, P_TYPE, g_types[uri->type], P_RES_AVAIL, &sep, ';')); + ASSERT_FUNC(EncodeComp(encoded, &off, &avail, P_OBJECT, uri->object, P_RES_AVAIL, &sep, ';')); + ASSERT_FUNC(EncodeComp(encoded, &off, &avail, P_USER, uri->user, P_RES_AVAIL, &sep, ';')); + ASSERT_FUNC(EncodeComp(encoded, &off, &avail, P_APP, uri->app, P_RES_AVAIL, &sep, ';')); + + if (uri->clientUser == NULL && uri->clientApp == NULL && uri->mac == NULL) { + // no query. we are done. + *encodedLen = off; + return CMR_OK; + } + + encoded[off] = '?'; + off++; + avail--; + sep = 0; + ASSERT_FUNC(EncodeComp(encoded, &off, &avail, Q_CLIENT_USER, uri->clientUser, Q_RES_AVAIL, &sep, '&')); + ASSERT_FUNC(EncodeComp(encoded, &off, &avail, Q_CLIENT_APP, uri->clientApp, Q_RES_AVAIL, &sep, '&')); + ASSERT_FUNC(EncodeComp(encoded, &off, &avail, Q_MAC, uri->mac, Q_RES_AVAIL, &sep, '&')); + + *encodedLen = off; + return CMR_OK; +} + +static uint32_t HexDecode(uint32_t h) +{ + h &= 0xff; + if (h >= '0' && h <= '9') { + return h - '0'; + } + if (h >= 'a' && h <= 'f') { + return h - 'a' + DEC_LEN; + } + if (h >= 'A' && h <= 'F') { + return h - 'A' + DEC_LEN; + } + return 0; +} + +static inline uint32_t HexDecode2(uint32_t h1, uint32_t h2) +{ + return ((HexDecode(h1) << 4) | HexDecode(h2)) & 0xff; /* 4 is number of shifts */ +} + +static inline uint32_t IndexOf(char sep, const char *data, uint32_t start, uint32_t end) +{ + for (uint32_t i = start; i < end; i++) { + if (data[i] == sep) { + return i; + } + } + return end; +} + +static char *DecodeValue(const char *s, uint32_t off, uint32_t len) +{ + if (s == NULL || len <= 0) { + return NULL; + } + char *buf = MALLOC(len + 1); + (void)memset_s(buf, len + 1, 0, len + 1); + + uint32_t bufOff = 0; + for (uint32_t i = off; i < off + len; i++, bufOff++) { + if (s[i] != '%') { + buf[bufOff] = s[i]; + } else { + buf[bufOff] = HexDecode2(s[i+1], s[i+2]); /* 2 is array index */ + i += 2; /* 2 is array index */ + } + } + char *ret = strndup(buf, bufOff); + free(buf); + return ret; +} + +static uint32_t DecodeEnum(const char *s, uint32_t off, uint32_t len, const char *values[], uint32_t valueCount) +{ + for (uint32_t i = 0; i < valueCount; i++) { + size_t valLen = strlen(values[i]); + if (valLen == len && memcmp(s + off, values[i], len) == 0) { + return i; + } + } + // no match found, default value is an invalid enum value + return valueCount + 1; +} + +static int32_t DecodePath(struct CMUri *uri, const char *path, uint32_t start, uint32_t end) +{ + while (start < end) { + uint32_t i = IndexOf(';', path, start, end); + if (i <= start) { + // something is wrong + CM_LOG_W("Invalid uri path: %s\n", path); + return CMR_ERROR_INVALID_ARGUMENT; + } + + uint32_t valueOff = 0; + uint32_t valueLen = 0; + + // for string field + char **field = NULL; + + // for enum field + uint32_t *e = NULL; + const char **values = NULL; + uint32_t valueCount = 0; + + if (!strncmp(P_OBJECT, path + start, strlen(P_OBJECT))) { + valueOff = start + strlen(P_OBJECT); + valueLen = i - start - strlen(P_OBJECT); + field = &uri->object; + } else if (!strncmp(P_TYPE, path + start, strlen(P_TYPE))) { + valueOff = start + strlen(P_TYPE); + valueLen = i - start - strlen(P_TYPE); + e = &uri->type; + values = g_types; + valueCount = TYPE_COUNT; + } else if (!strncmp(P_USER, path + start, strlen(P_USER))) { + valueOff = start + strlen(P_USER); + valueLen = i - start - strlen(P_USER); + field = &uri->user; + } else if (!strncmp(P_APP, path + start, strlen(P_APP))) { + valueOff = start + strlen(P_APP); + valueLen = i - start - strlen(P_APP); + field = &uri->app; + } + + if (field != NULL) { + if (valueLen == 0) { + *field = NULL; + } else { + *field = DecodeValue(path, valueOff, valueLen); + } + } else if (e != NULL) { + *e = DecodeEnum(path, valueOff, valueLen, values, valueCount); + } else { + CM_LOG_W("Invalid field in path: %s\n", path); + return CMR_ERROR_INVALID_ARGUMENT; + } + + start = i + 1; + } + + return CMR_OK; +} + +static int32_t DecodeQuery(struct CMUri *uri, const char *query, uint32_t start, uint32_t end) +{ + while (start < end) { + uint32_t i = IndexOf('&', query, start, end); + if (i <= start) { + // something is wrong + CM_LOG_W("Invalid uri query: %s\n", query); + return CMR_ERROR_INVALID_ARGUMENT; + } + + uint32_t valueOff = 0; + uint32_t valueLen = 0; + char **field = NULL; + if (!strncmp(Q_CLIENT_USER, query + start, strlen(Q_CLIENT_USER))) { + valueOff = start + strlen(Q_CLIENT_USER); + valueLen = i - start - strlen(Q_CLIENT_USER); + field = &uri->clientUser; + } else if (!strncmp(Q_CLIENT_APP, query + start, strlen(Q_CLIENT_APP))) { + valueOff = start + strlen(Q_CLIENT_APP); + valueLen = i - start - strlen(Q_CLIENT_APP); + field = &uri->clientApp; + } else if (!strncmp(Q_MAC, query + start, strlen(Q_MAC))) { + valueOff = start + strlen(Q_MAC); + valueLen = i - start - strlen(Q_MAC); + field = &uri->mac; + } + + if (field != NULL) { + if (valueLen == 0) { + *field = NULL; + } else { + *field = DecodeValue(query, valueOff, valueLen); + } + } else { + CM_LOG_W("Invalid field in query: %s\n", query); + return CMR_ERROR_INVALID_ARGUMENT; + } + + start = i + 1; + } + return CMR_OK; +} + +int32_t CertManagerUriDecode(struct CMUri *uri, const char *encoded) +{ + ASSERT_ARGS(uri); + ASSERT_ARGS(encoded); + + uri->type = CM_URI_TYPE_INVALID; + + uint32_t len = strlen(encoded); + uint32_t off = 0; + CM_LOG_I("CertManagerUriDecode keyUri:%s, %s, len:%d, schem:%d", encoded, SCHEME, len, strlen(SCHEME)); + if (len < strlen(SCHEME) || memcmp(encoded, SCHEME, strlen(SCHEME))) { + CM_LOG_W("Scheme mismatch. Not a cert manager URI: %s\n", encoded); + return CMR_ERROR_INVALID_ARGUMENT; + } + off += strlen(SCHEME); + + uint32_t pathStart = off; + uint32_t pathEnd = IndexOf('?', encoded, off, len); + uint32_t queryStart = pathEnd == len ? len : pathEnd + 1; + uint32_t queryEnd = len; + + ASSERT_FUNC(DecodePath(uri, encoded, pathStart, pathEnd)); + ASSERT_FUNC(DecodeQuery(uri, encoded, queryStart, queryEnd)); + + return CMR_OK; +} + +#ifdef __cplusplus +} +#endif diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_util.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_util.c new file mode 100644 index 0000000..e3d5a3c --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cert_manager_util.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdio.h" +#include "stdbool.h" +#include "stdint.h" +#include "cert_manager_type.h" +#include "cert_manager_file.h" +#include "cert_manager_status.h" +#include "cert_manager_mem.h" +#include "cert_manager_util.h" +#include "cm_log.h" +#include "cm_type.h" +#include "hks_api.h" +#include "hks_type.h" +#include "hks_param.h" + +#define CMALG(x) (x) +#define CMPURPOSE(x) (x) +#define CMDIGEST(x) (x) +#define CMPADDING(x) (x) +#define CMAUTHTYPE(x) (x) + +int32_t CertManagerBuildKeySpec(struct HksParamSet **params, const struct CMKeyProperties *properties) +{ + int32_t rc = CMR_OK; + ASSERT_CM_CALL(HksInitParamSet(params)); + + struct HksParam p[] = { + { .tag = HKS_TAG_IMPORT_KEY_TYPE, .uint32Param = HKS_KEY_TYPE_KEY_PAIR }, + { .tag = HKS_TAG_ALGORITHM, .uint32Param = CMALG(properties->alg) }, + { .tag = HKS_TAG_KEY_SIZE, .uint32Param = properties->size }, + { .tag = HKS_TAG_PURPOSE, .uint32Param = CMPURPOSE(properties->purpose) }, + { .tag = HKS_TAG_DIGEST, .uint32Param = CMDIGEST(properties->digest) }, + { .tag = HKS_TAG_PADDING, .uint32Param = CMPADDING(properties->padding) }, + }; + TRY_CM_CALL(HksAddParams(*params, p, sizeof(p) / sizeof(struct HksParam)), rc); + + if (properties->authType != CM_AUTH_TYPE_NONE) { + struct HksParam authParams[] = { + { .tag = HKS_TAG_NO_AUTH_REQUIRED, .boolParam = false }, + { .tag = HKS_TAG_USER_AUTH_TYPE, .uint32Param = CMAUTHTYPE(properties->authType) }, + { .tag = HKS_TAG_AUTH_TIMEOUT, .uint32Param = properties->authTimeout }, + }; + TRY_CM_CALL(HksAddParams(*params, authParams, sizeof(authParams) / sizeof(struct HksParam)), rc); + } + + TRY_CM_CALL(HksBuildParamSet(params), rc); + +finally: + if (rc != HKS_SUCCESS && *params != NULL) { + HksFreeParamSet(params); + *params = NULL; + } + return CM_ERROR(rc); +} + +static int32_t CertManagerBuildMacKeySpec(struct HksParamSet **params) +{ + struct CMKeyProperties props = { + .alg = HKS_ALG_HMAC, + .size = CM_HMAC_KEY_SIZE_256, + .padding = 0, + .purpose = HKS_KEY_PURPOSE_MAC, + .digest = HKS_DIGEST_SHA256 + }; + return CertManagerBuildKeySpec(params, &props); +} + +int32_t CertManagerHmac(const char *uri, const struct CmBlob *data, struct CmMutableBlob *mac) +{ + ASSERT_ARGS(uri && data && mac); + + int rc = CMR_OK; + + struct HksBlob in = HKS_BLOB(data); + struct HksBlob out = HKS_BLOB(mac); + struct HksBlob alias = { .size = strlen(uri), .data = (uint8_t *) uri }; + + struct HksParamSet *params = NULL; + TRY_FUNC(CertManagerBuildMacKeySpec(¶ms), rc); + TRY_CM_CALL(HksMac(&alias, params, &in, &out), rc); + + CM_LOG_D("Mac computed. Len=%u\n", out.size); + mac->size = out.size; + +finally: + if (params != NULL) { + HksFreeParamSet(¶ms); + } + return rc; +} + +int32_t CertManagerGenerateHmacKey(const char *uri) +{ + ASSERT_ARGS(uri); + int32_t rc = CMR_OK; + struct HksParamSet *params = NULL; + + TRY_FUNC(CertManagerBuildMacKeySpec(¶ms), rc); + + struct HksBlob alias = {.size = strlen(uri), .data = (uint8_t *) uri}; + + int32_t hksRc = HksKeyExist(&alias, NULL); + if (hksRc == HKS_ERROR_NOT_EXIST) { + TRY_CM_CALL(HksGenerateKey(&alias, params, NULL), rc); + } else { + rc = CM_ERROR(hksRc); + } + +finally: + if (params != NULL) { + HksFreeParamSet(¶ms); + } + return rc; +} \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_asn1.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_asn1.c new file mode 100644 index 0000000..c8ff9cf --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_asn1.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_asn1.h" +#include "cm_log.h" +#include "securec.h" + +#define BIT_NUM_OF_UINT8 8 +#define ASN_1_EXPLICIT_TAG_LEN 3 +#define ASN_1_EXPLICIT_TAG_TYPE_BOOL 0xA0 +#define ASN_1_TAG_TYPE_EXTRA_IDENTIFIER 0x1F +#define TLV_HEADER_TYPE_2_LEN 4 +#define BASE128_ENCODE_BIT_LEN 7 + +static int32_t Asn1GetObj(struct CmBlob *next, struct CmAsn1Obj *obj, const struct CmBlob *data) +{ + uint8_t *buf = data->data; + uint32_t length = 0; + obj->header.data = buf; + CM_ASN1_DECODE_BYTE(buf, obj->header.type); + if (buf[0] < ASN_1_MIN_VAL_1_EXTRA_LEN_BYTE) { + CM_ASN1_DECODE_BYTE(buf, length); + } else { + uint32_t b; + CM_ASN1_DECODE_BYTE(buf, b); + + switch (b) { + case ASN_1_TAG_TYPE_1_BYTE_LEN: + CM_ASN1_DECODE_BYTE(buf, length); + break; + case ASN_1_TAG_TYPE_2_BYTE_LEN: + if (data->size < ASN_1_MIN_HEADER_LEN + 1) { + CM_LOG_E("invalid data to decode two bytes.\n"); + return CMR_ERROR_INSUFFICIENT_DATA; + } + CM_ASN1_DECODE_TWO_BYTE(buf, length); + break; + default: + CM_LOG_E("Object length does not make sense.\n"); + return CMR_ERROR_INVALID_ARGUMENT; + } + } + obj->header.size = buf - data->data; + if (length > data->size - obj->header.size) { + CM_LOG_E("data buffer is not big enough to hold %u bytes.\n", length); + return CMR_ERROR_INSUFFICIENT_DATA; + } + + obj->value.type = obj->header.type; + obj->value.size = length; + obj->value.data = buf; + next->data = data->data + obj->header.size + obj->value.size; + next->size = data->size - obj->header.size - obj->value.size; + + return CM_SUCCESS; +} + +int32_t CmAsn1ExtractTag(struct CmBlob *next, struct CmAsn1Obj *obj, const struct CmBlob *data, + uint32_t expectedTag) +{ + if ((next == NULL) || (obj == NULL) || (data == NULL) || (data->size < ASN_1_MIN_HEADER_LEN)) { + CM_LOG_E("invalid params"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + int32_t ret = Asn1GetObj(next, obj, data); + if (ret != CM_SUCCESS) { + CM_LOG_E("get asn1 obj fail.\n"); + return ret; + } + if (obj->header.type != expectedTag) { + CM_LOG_E("tag %u does not match expected: %u\n", obj->header.type, expectedTag); + return CM_FAILURE; + } + return CM_SUCCESS; +} \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_event_process.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_event_process.c new file mode 100644 index 0000000..79098bc --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_event_process.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_type.h" +#include "cm_log.h" +#include "cert_manager_status.h" +#include +#include "hks_type.h" +#include "hks_api.h" +#include "hks_param.h" +#include "cert_manager_file_operator.h" +#include "securec.h" +#include "cert_manager.h" +#include "cm_event_process.h" + +int32_t CmTraversalDirActionCredential(const char *filePath, const char *fileName) +{ + CM_LOG_I("CmTraversalDirActionCredential: fileName is:%s", fileName); + int32_t ret = remove(filePath); + if (ret != CM_SUCCESS) { + CM_LOG_E("App cert delete faild, ret: %d", ret); + return ret; + } + + struct CmBlob keyUri = { strlen(fileName) + 1, (uint8_t *)fileName }; + + /* ignore the return of HksDeleteKey */ + ret = HksDeleteKey(&HKS_BLOB(&keyUri), NULL); + if (ret != HKS_SUCCESS && ret != HKS_ERROR_NOT_EXIST) { + CM_LOG_I("App key delete failed ret: %d", ret); + } + + return CM_SUCCESS; +} + +int32_t CmTraversalDirActionUserCa(struct CmContext *context, const char *filePath, const char *fileName, + const uint32_t store) +{ + uint32_t status = CERT_STATUS_ENABLED; + struct CmBlob certUri = { strlen(fileName), (uint8_t *)fileName }; + int32_t ret = remove(filePath); + if (ret != CM_SUCCESS) { + CM_LOG_E("User cert delete faild, ret: %d", ret); + return ret; + } + + CM_LOG_I("CmTraversalDirActionUserCa: fileName is:%s", fileName); + CM_LOG_I("CmTraversalDirActionUserCa: uid is %u userId is %u", context->uid, context->userId); + + ret = SetcertStatus(context, &certUri, store, status, NULL); + if (ret != CM_SUCCESS) { + CM_LOG_E("User set status faild, ret: %d", ret); + return ret; + } + + return CM_SUCCESS; +} + +int32_t CmTraversalDirAction(struct CmContext *context, const char *filePath, + const char *fileName, const uint32_t store) +{ + int32_t ret = CM_SUCCESS; + + switch (store) { + case CM_CREDENTIAL_STORE : + case CM_PRI_CREDENTIAL_STORE : + ret = CmTraversalDirActionCredential(filePath, fileName); + break; + case CM_USER_TRUSTED_STORE : + ret = CmTraversalDirActionUserCa(context, filePath, fileName, store); + break; + default: + break; + } + if (ret != CM_SUCCESS) { + CM_LOG_E("CmTraversalDirAction failed store:%u", store); + } + + return CM_SUCCESS; +} + +int32_t CmTraversalUidLayerDir(struct CmContext *context, const char *path, const uint32_t store) +{ + int32_t ret = CM_SUCCESS; + char uidPath[CM_MAX_FILE_NAME_LEN] = {0}; + /* do nothing when dir is not exist */ + if (CmIsDirExist(path) != CMR_OK) { + CM_LOG_I("Dir is not exist:%s", path); + return CM_SUCCESS; + } + DIR *dir = opendir(path); + if (dir == NULL) { + CM_LOG_E("open dir failed"); + return CMR_ERROR_OPEN_FILE_FAIL; + } + struct dirent *dire = readdir(dir); + while (dire != NULL) { + if (strncpy_s(uidPath, sizeof(uidPath), path, strlen(path)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if (uidPath[strlen(uidPath) - 1] != '/') { + if (strncat_s(uidPath, sizeof(uidPath), "/", strlen("/")) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + } + + if (strncat_s(uidPath, sizeof(uidPath), dire->d_name, strlen(dire->d_name)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if ((strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0)) { + ret = CmTraversalDirAction(context, uidPath, dire->d_name, store); + if (ret != CM_SUCCESS) { + return ret; + } + } + dire = readdir(dir); + } + closedir(dir); + ret = remove(path); + return ret; +} + +int32_t CmTraversalUserIdLayerDir(struct CmContext *context, const char *path, const uint32_t store) +{ + uint32_t uid; + bool isUserDeleteEvent = (context->uid == INVALID_VALUE); + int32_t ret = CM_SUCCESS; + char userIdPath[CM_MAX_FILE_NAME_LEN] = {0}; + /* do nothing when dir is not exist */ + if (CmIsDirExist(path) != CMR_OK) { + CM_LOG_I("UserId dir is not exist:%s", path); + return CM_SUCCESS; + } + DIR *dir = opendir(path); + if (dir == NULL) { + CM_LOG_E("Open userId dir failed"); + return CMR_ERROR_OPEN_FILE_FAIL; + } + struct dirent *dire = readdir(dir); + while (dire != NULL) { + if (strncpy_s(userIdPath, sizeof(userIdPath), path, strlen(path)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if (userIdPath[strlen(userIdPath) - 1] != '/') { + if (strncat_s(userIdPath, sizeof(userIdPath), "/", strlen("/")) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + } + + if (strncat_s(userIdPath, sizeof(userIdPath), dire->d_name, strlen(dire->d_name)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if (dire->d_type == DT_DIR && (strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0)) { + uid = (uint32_t)atoi(dire->d_name); + CM_LOG_I("CmTraversalUserIdLayerDir userId:%u, uid:%u", context->userId, uid); + /* user delete event */ + if (isUserDeleteEvent) { + context->uid = uid; + ret = CmTraversalUidLayerDir(context, userIdPath, store); + /* package delete event */ + } else if (uid == context->uid) { + ret = CmTraversalUidLayerDir(context, userIdPath, store); + } + } else if (dire->d_type != DT_DIR) { + (void)remove(userIdPath); + } + dire = readdir(dir); + } + closedir(dir); + /* delete userId directory only in user remove event */ + if (isUserDeleteEvent) { + ret = remove(path); + } + + return ret; +} + +int32_t CmTraversalDir(struct CmContext *context, const char *path, const uint32_t store) +{ + int32_t ret = CM_SUCCESS; + char deletePath[CM_MAX_FILE_NAME_LEN] = { 0 }; + /* do nothing when dir is not exist */ + if (CmIsDirExist(path) != CMR_OK) { + CM_LOG_I("Root dir is not exist:%s", path); + return CM_SUCCESS; + } + DIR *dir = opendir(path); + if (dir == NULL) { + CM_LOG_E("open dir failed"); + return CMR_ERROR_OPEN_FILE_FAIL; + } + struct dirent *dire = readdir(dir); + while (dire != NULL) { + if (strncpy_s(deletePath, sizeof(deletePath), path, strlen(path)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if (deletePath[strlen(deletePath) - 1] != '/') { + if (strncat_s(deletePath, sizeof(deletePath), "/", strlen("/")) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + } + + if (strncat_s(deletePath, sizeof(deletePath), dire->d_name, strlen(dire->d_name)) != EOK) { + closedir(dir); + return CMR_ERROR_INVALID_OPERATION; + } + + if (dire->d_type == DT_DIR && (strcmp("..", dire->d_name) != 0) && (strcmp(".", dire->d_name) != 0) && + ((uint32_t)atoi(dire->d_name) == context->userId)) { + ret = CmTraversalUserIdLayerDir(context, deletePath, store); + } else if (dire->d_type != DT_DIR) { + (void)remove(deletePath); + } + dire = readdir(dir); + } + closedir(dir); + + return ret; +} + +int32_t CmDeleteProcessInfo(struct CmContext *context) +{ + int32_t ret = CM_SUCCESS; + /* Delete user ca */ + ret = CmTraversalDir(context, USER_CA_STORE, CM_USER_TRUSTED_STORE); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmDeleteUserCa faild"); + } + + /* Delete private credentail */ + ret = CmTraversalDir(context, APP_CA_STORE, CM_PRI_CREDENTIAL_STORE); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmDeletePrivateCredential faild"); + } + + /* Delete public credentail */ + ret = CmTraversalDir(context, CREDNTIAL_STORE, CM_CREDENTIAL_STORE); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmDeletePublicCredential faild"); + } + return ret; +} diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_curve25519.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_curve25519.c new file mode 100644 index 0000000..b2c2a9d --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_curve25519.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_openssl_engine.h" +#include "cm_openssl_curve25519.h" + +#define CM_OPENSSL_SUCCESS 1 /* openssl return 1: success */ + +int32_t SaveCurve25519KeyMaterial(uint32_t algType, const EVP_PKEY *pKey, struct CmBlob *keyOut) +{ + uint32_t totalSize = sizeof(struct KeyMaterial25519) + (CURVE25519_KEY_LEN << 1); + uint8_t *buffer = (uint8_t *)CmMalloc(totalSize); + if (buffer == NULL) { + CM_LOG_E("malloc size %u failed", totalSize); + return CMR_ERROR_MALLOC_FAIL; + } + + size_t tmpPubKeyLen = CURVE25519_KEY_LEN; + size_t tmpPriKeyLen = CURVE25519_KEY_LEN; + uint32_t offset = sizeof(struct KeyMaterial25519); + + if (EVP_PKEY_get_raw_public_key(pKey, buffer + offset, &tmpPubKeyLen) != CM_OPENSSL_SUCCESS) { + CM_LOG_E("EVP_PKEY_get_raw_public_key failed"); + CmFree(buffer); + return CMR_ERROR_INVALID_OPERATION; + } + uint32_t pubKeyLen = (uint32_t)tmpPubKeyLen; + + offset += pubKeyLen; + if (EVP_PKEY_get_raw_private_key(pKey, buffer + offset, &tmpPriKeyLen) != CM_OPENSSL_SUCCESS) { + CM_LOG_E("EVP_PKEY_get_raw_private_key"); + CmFree(buffer); + return CMR_ERROR_INVALID_OPERATION; + } + uint32_t priKeyLen = (uint32_t)tmpPriKeyLen; + + struct KeyMaterial25519 *keyMaterial = (struct KeyMaterial25519 *)buffer; + keyMaterial->keyAlg = algType; + keyMaterial->keySize = CURVE25519_KEY_BITS; + keyMaterial->pubKeySize = pubKeyLen; + keyMaterial->priKeySize = priKeyLen; + + keyOut->data = buffer; + keyOut->size = totalSize; + return CM_SUCCESS; +} \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_ecc.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_ecc.c new file mode 100644 index 0000000..6aed30d --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_ecc.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "cm_type.h" +#include "cm_config.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_openssl_engine.h" +#include "cm_openssl_ecc.h" +#include "securec.h" + +static int32_t TransEccKeyToKeyBlob( + const EC_KEY *eccKey, const struct KeyMaterialEcc *keyMaterial, BIGNUM *pubX, BIGNUM *pubY, uint8_t *rawMaterial) +{ + const EC_GROUP *ecGroup = EC_KEY_get0_group(eccKey); + int retCode = EC_POINT_get_affine_coordinates_GFp(ecGroup, EC_KEY_get0_public_key(eccKey), pubX, pubY, NULL); + if (retCode <= 0) { + CM_LOG_E("EC_POINT_get_affine_coordinates_GFp failed"); + return CM_FAILURE; + } + + const BIGNUM *priv = EC_KEY_get0_private_key(eccKey); + uint32_t offset = sizeof(struct KeyMaterialEcc); + + retCode = BN_bn2binpad(pubX, rawMaterial + offset, keyMaterial->xSize); + if (retCode <= 0) { + CM_LOG_E("BN_bn2binpad pubX failed"); + return CM_FAILURE; + } + offset += keyMaterial->xSize; + + retCode = BN_bn2binpad(pubY, rawMaterial + offset, keyMaterial->ySize); + if (retCode <= 0) { + CM_LOG_E("BN_bn2binpad pubY failed"); + return CM_FAILURE; + } + offset += keyMaterial->ySize; + + retCode = BN_bn2binpad(priv, rawMaterial + offset, keyMaterial->zSize); + if (retCode <= 0) { + CM_LOG_E("BN_bn2binpad priv failed"); + return CM_FAILURE; + } + + return CM_SUCCESS; +} + +int32_t EccSaveKeyMaterial(const EC_KEY *eccKey, const struct CmKeySpec *spec, + uint8_t **output, uint32_t *outputSize) +{ + uint32_t keySize = spec->keyLen; + /* public exponent x and y, and private exponent, so need size is: keySize / 8 * 3 */ + uint32_t rawMaterialLen = sizeof(struct KeyMaterialEcc) + CM_KEY_BYTES(keySize) * ECC_KEYPAIR_CNT; + uint8_t *rawMaterial = (uint8_t *)CmMalloc(rawMaterialLen); + if (rawMaterial == NULL) { + CM_LOG_E("malloc buffer failed!"); + return CMR_ERROR_MALLOC_FAIL; + } + + (void)memset_s(rawMaterial, rawMaterialLen, 0, rawMaterialLen); + + /* + * ECC key data internal struct: + * struct KeyMaterialEcc + pubX_data + pubY_data + pri_data + */ + struct KeyMaterialEcc *keyMaterial = (struct KeyMaterialEcc *)rawMaterial; + keyMaterial->keyAlg = (enum CmKeyAlg)spec->algType; + keyMaterial->keySize = keySize; + keyMaterial->xSize = CM_KEY_BYTES(keySize); + keyMaterial->ySize = CM_KEY_BYTES(keySize); + keyMaterial->zSize = CM_KEY_BYTES(keySize); + + BIGNUM *pubX = BN_new(); + BIGNUM *pubY = BN_new(); + + int32_t ret; + do { + if ((pubX == NULL) || (pubY == NULL)) { + CM_LOG_E("BN_new x or y failed"); + ret = CMR_ERROR_NULL_POINTER; + CmFree(rawMaterial); + break; + } + ret = TransEccKeyToKeyBlob(eccKey, keyMaterial, pubX, pubY, rawMaterial); + if (ret != CM_SUCCESS) { + CM_LOG_E("transfer ecc key to key blob failed"); + CmFree(rawMaterial); + break; + } + *output = rawMaterial; + *outputSize = rawMaterialLen; + } while (0); + + if (pubX != NULL) { + BN_free(pubX); + pubX = NULL; + } + if (pubY != NULL) { + BN_free(pubY); + pubY = NULL; + } + return ret; +} diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_rsa.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_rsa.c new file mode 100644 index 0000000..fcb2938 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/cm_openssl_rsa.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_openssl_rsa.h" +#include +#include +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_openssl_engine.h" +#include "cm_openssl_rsa.h" +#include "securec.h" + +int32_t RsaSaveKeyMaterial(const RSA *rsa, const uint32_t keySize, struct CmBlob *key) +{ + const uint32_t keyByteLen = keySize / CM_BITS_PER_BYTE; + const uint32_t rawMaterialLen = sizeof(struct KeyMaterialRsa) + keyByteLen * CM_RSA_KEYPAIR_CNT; + uint8_t *rawMaterial = (uint8_t *)CmMalloc(rawMaterialLen); + if (rawMaterial == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + + (void)memset_s(rawMaterial, rawMaterialLen, 0, rawMaterialLen); + + struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)rawMaterial; + keyMaterial->keyAlg = CM_ALG_RSA; + keyMaterial->keySize = keySize; + + uint8_t tmpBuff[keyByteLen]; + if (memset_s(tmpBuff, keyByteLen, 0, keyByteLen) != EOK) { + CmFree(rawMaterial); + return CMR_ERROR_INVALID_OPERATION; + } + + uint32_t offset = sizeof(*keyMaterial); + keyMaterial->nSize = (uint32_t)BN_bn2bin(RSA_get0_n(rsa), tmpBuff); + if (memcpy_s(rawMaterial + offset, keyByteLen, tmpBuff, keyMaterial->nSize) != EOK) { + CmFree(rawMaterial); + return CMR_ERROR_INVALID_OPERATION; + } + + offset += keyMaterial->nSize; + keyMaterial->eSize = (uint32_t)BN_bn2bin(RSA_get0_e(rsa), tmpBuff); + if (memcpy_s(rawMaterial + offset, keyByteLen, tmpBuff, keyMaterial->eSize) != EOK) { + CmFree(rawMaterial); + return CMR_ERROR_INVALID_OPERATION; + } + + offset += keyMaterial->eSize; + keyMaterial->dSize = (uint32_t)BN_bn2bin(RSA_get0_d(rsa), tmpBuff); + if (memcpy_s(rawMaterial + offset, keyByteLen, tmpBuff, keyMaterial->dSize) != EOK) { + CmFree(rawMaterial); + return CMR_ERROR_INVALID_OPERATION; + } + + key->data = rawMaterial; + key->size = sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize + keyMaterial->dSize; + + return CM_SUCCESS; +} diff --git a/services/cert_manager_standard/cert_manager_engine/main/core/src/rbtree.c b/services/cert_manager_standard/cert_manager_engine/main/core/src/rbtree.c new file mode 100644 index 0000000..10154fe --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/core/src/rbtree.c @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "securec.h" +#include "cert_manager_util.h" +#include "cert_manager_mem.h" +#include "cert_manager_status.h" +#include "cm_log.h" +#include "rbtree.h" + +#define RC_OK CMR_OK +#define RC_ERROR CMR_ERROR +#define RC_MEM_ERROR CMR_ERROR_MALLOC_FAIL +#define RC_NOT_FOUND CMR_ERROR_NOT_FOUND +#define RC_BUFFER_TOO_SMALL CMR_ERROR_BUFFER_TOO_SMALL +#define RC_INSUFFICIENT_DATA CMR_ERROR_BUFFER_TOO_SMALL + +/* void orintRbTree(struct RbTree *t) + Implementation of a red-black tree, with serialization + Reference: Introduction to Algortihms, 3ed edition + thr following assume each key is a 31-bit integer (uint32_t), adjust if nedded */ +#define COLOR_MASK 0x80000000 +#define KEY_MASK 0x7fffffff +#define BLACK 0x80000000 +#define RED 0 + +#define COLOR(n) ((n)->key & COLOR_MASK) +#define IS_RED(n) (COLOR((n)) == RED) +#define IS_BLACK(n) (COLOR((n)) == BLACK) + +#define SET_COLOR(n, color) ((n)->key = ((n)->key & KEY_MASK) | (color)) +#define SET_RED(n) SET_COLOR((n), RED) +#define SET_BLACK(n) SET_COLOR((n), BLACK) + +#define KEY(n) ((n)->key & KEY_MASK) + +#ifdef __cplusplus +extern "C" { +#endif + +struct EncoderContext { + uint8_t *buf; + uint32_t off; + uint32_t len; + int status; + RbTreeValueEncoder enc; +}; + +RbTreeKey RbTreeNodeKey(const struct RbTreeNode *n) +{ + return n == NULL ? 0 : KEY(n); +} + +static int NewNode(struct RbTreeNode **nptr, RbTreeKey key, RbTreeValue value) +{ + struct RbTreeNode *n = CMMalloc(sizeof(struct RbTreeNode)); + if (n == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + *nptr = n; + n->key = key; + n->value = value; + n->p = NULL; + n->left = NULL; + n->right = NULL; + return CMR_OK; +} + +int RbTreeNew(struct RbTree *t) +{ + ASSERT_ARGS(t); + + ASSERT_FUNC(NewNode(&(t->nil), 0, NULL)); + SET_BLACK(t->nil); + t->root = t->nil; + + return CMR_OK; +} + +static void LeftRotate(struct RbTree *t, struct RbTreeNode *x) +{ + struct RbTreeNode *y = x->right; + x->right = y->left; + if (y->left != t->nil) { + y->left->p = x; + } + y->p = x->p; + if (x->p == t->nil) { + t->root = y; + } else if (x == x->p->left) { + x->p->left = y; + } else { + x->p->right = y; + } + y->left = x; + x->p = y; +} + +static void RightRotate(struct RbTree *t, struct RbTreeNode *x) +{ + struct RbTreeNode *y = x->left; + x->left = y->right; + if (y->right != t->nil) { + y->right->p = x; + } + y->p = x->p; + if (x->p == t->nil) { + t->root = y; + } else if (x == x->p->right) { + x->p->right = y; + } else { + x->p->left = y; + } + y->right = x; + x->p = y; +} + +static void InsertFixUpRed(struct RbTree *t, struct RbTreeNode **zTreeNode) +{ + struct RbTreeNode *y = NULL; + struct RbTreeNode *z = *zTreeNode; + y = z->p->p->right; + if (IS_RED(y)) { + SET_BLACK(z->p); + SET_BLACK(y); + SET_RED(z->p->p); + z = z->p->p; + } else { + if (z == z->p->right) { + z = z->p; + LeftRotate(t, z); + } + // case 3 + SET_BLACK(z->p); + SET_RED(z->p->p); + RightRotate(t, z->p->p); + } + *zTreeNode = z; +} + +static void InsertFixUpBlack(struct RbTree *t, struct RbTreeNode **zTreeNode) +{ + struct RbTreeNode *y = NULL; + struct RbTreeNode *z = *zTreeNode; + + y = z->p->p->left; + if (IS_RED(y)) { + SET_BLACK(z->p); + SET_BLACK(y); + SET_RED(z->p->p); + z = z->p->p; + } else { + if (z == z->p->left) { + z = z->p; + RightRotate(t, z); + } + SET_BLACK(z->p); + SET_RED(z->p->p); + LeftRotate(t, z->p->p); + } + *zTreeNode = z; +} + +static void InsertFixUp(struct RbTree *t, struct RbTreeNode *z) +{ + while (IS_RED(z->p)) { + if (z->p == z->p->p->left) { + InsertFixUpRed(t, &z); + } else { + InsertFixUpBlack(t, &z); + } + } + + SET_BLACK(t->root); +} + +int RbTreeInsert(struct RbTree *t, RbTreeKey key, const RbTreeValue value) +{ + ASSERT_ARGS(t); + + struct RbTreeNode *z = NULL; + ASSERT_FUNC(NewNode(&z, key, value)); + + struct RbTreeNode *y = t->nil; + struct RbTreeNode *x = t->root; + + while (x != t->nil) { + y = x; + if (KEY(z) < KEY(x)) { + x = x->left; + } else { + x = x->right; + } + } + + z->p = y; + if (y == t->nil) { + t->root = z; + } else if (KEY(z) < KEY(y)) { + y->left = z; + } else { + y->right = z; + } + + z->left = t->nil; + z->right = t->nil; + SET_RED(z); + + InsertFixUp(t, z); + + return CMR_OK; +} + +static void Transplant(struct RbTree *t, struct RbTreeNode *u, struct RbTreeNode *v) +{ + if (u->p == t->nil) { + t->root = v; + } else if (u == u->p->left) { + u->p->left = v; + } else { + u->p->right = v; + } + v->p = u->p; +} + +static struct RbTreeNode *Minimum(const struct RbTree *t, struct RbTreeNode *x) +{ + while (x->left != t->nil) { + x = x->left; + } + return x; +} + +static void DeleteFixUpBlack(struct RbTree *t, struct RbTreeNode **treeNode) +{ + struct RbTreeNode *w = NULL; + struct RbTreeNode *x = *treeNode; + w = x->p->right; + if (IS_RED(w)) { + SET_BLACK(w); + SET_RED(x->p); + LeftRotate(t, x->p); + w = x->p->right; + } + if (IS_BLACK(w->left) && IS_BLACK(w->right)) { + SET_RED(w); + x = x->p; + } else { + if (IS_BLACK(w->right)) { + SET_BLACK(w->left); + SET_RED(w); + RightRotate(t, w); + w = x->p->right; + } + + SET_COLOR(w, COLOR(x->p)); + SET_BLACK(x->p); + SET_BLACK(w->right); + LeftRotate(t, x->p); + x = t->root; + } + *treeNode = x; +} + +static void DeleteFixUpRed(struct RbTree *t, struct RbTreeNode **treeNode) +{ + struct RbTreeNode *w = NULL; + struct RbTreeNode *x = *treeNode; + + w = x->p->left; + if (IS_RED(w)) { + SET_BLACK(w); + SET_RED(x->p); + RightRotate(t, x->p); + w = x->p->left; + } + if (IS_BLACK(w->right) && IS_BLACK(w->left)) { + SET_RED(w); + x = x->p; + } else { + if (IS_BLACK(w->left)) { + SET_BLACK(w->right); + SET_RED(w); + LeftRotate(t, w); + w = x->p->left; + } + + SET_COLOR(w, COLOR(x->p)); + SET_BLACK(x->p); + SET_BLACK(w->left); + RightRotate(t, x->p); + x = t->root; + } + *treeNode = x; +} + +static void DeleteFixUp(struct RbTree *t, struct RbTreeNode *x) +{ + while (x != t->root && IS_BLACK(x)) { + if (x == x->p->left) { + DeleteFixUpBlack(t, &x); + } else { + DeleteFixUpRed(t, &x); + } + } + SET_BLACK(x); +} + +int RbTreeDelete(struct RbTree *t, struct RbTreeNode *z) +{ + ASSERT_ARGS(t); + struct RbTreeNode *x = NULL; + struct RbTreeNode *y = z; + RbTreeKey yColor = COLOR(y); + + if (z->left == t->nil) { + x = z->right; + Transplant(t, z, z->right); + } else if (z->right == t->nil) { + x = z->left; + Transplant(t, z, z->left); + } else { + y = Minimum(t, z->right); + yColor = COLOR(y); + x = y->right; + if (y->p == z) { + x->p = y; + } else { + Transplant(t, y, y->right); + y->right = z->right; + y->right->p = y; + } + Transplant(t, z, y); + y->left = z->left; + y->left->p = y; + SET_COLOR(y, COLOR(z)); + } + if (yColor == BLACK) { + DeleteFixUp(t, x); + } + CMFree(z); + return CMR_OK; +} + +int RbTreeFindNode(struct RbTreeNode **np, RbTreeKey key, const struct RbTree *t) +{ + ASSERT_ARGS(t && np); + + *np = NULL; + + struct RbTreeNode *n = t->root; + while (n != t->nil) { + if (KEY(n) == key) { + *np = n; + return CMR_OK; + } else if (key < KEY(n)) { + n = n->left; + } else { + n = n->right; + } + } + return CMR_ERROR_NOT_FOUND; +} + +static void TraverseInOrder(const struct RbTree *t, const struct RbTreeNode *x, + RbTreeNodeHandler handler, const void *context) +{ + if (x == t->nil) { + return; + } + TraverseInOrder(t, x->left, handler, context); + handler(KEY(x), x->value, context); + TraverseInOrder(t, x->right, handler, context); +} + +static void TraversePreOrder(const struct RbTree *t, const struct RbTreeNode *x, + RbTreeNodeHandler handler, const void *context) +{ + if (x == t->nil) { + return; + } + handler(KEY(x), x->value, context); + TraversePreOrder(t, x->left, handler, context); + TraversePreOrder(t, x->right, handler, context); +} + +static void TraversePostOrder(const struct RbTree *t, const struct RbTreeNode *x, + RbTreeNodeHandler handler, const void *context) +{ + if (x == t->nil) { + return; + } + TraversePostOrder(t, x->left, handler, context); + TraversePostOrder(t, x->right, handler, context); + handler(KEY(x), x->value, context); +} + +static void Destroy(struct RbTree *t, struct RbTreeNode *x) +{ + if (x != t->nil) { + Destroy(t, x->left); + x->left = t->nil; + Destroy(t, x->right); + x->right = t->nil; + CMFree(x); + } +} + +static int RbTreeDestroy(struct RbTree *t) +{ + ASSERT_ARGS(t); + Destroy(t, t->root); + CMFree(t->nil); + + t->nil = NULL; + t->root = NULL; + return RC_OK; +} + +int RbTreeDestroyEx(struct RbTree *t, RbTreeNodeHandler handler, const void *context) +{ + ASSERT_ARGS(t && handler); + TraverseInOrder(t, t->root, handler, context); + return RbTreeDestroy(t); +} + +static void Encoder(RbTreeKey key, RbTreeValue value, const void *context) +{ + struct EncoderContext *ctx = (struct EncoderContext *) context; + if (ctx->status != CMR_OK) { + /* already failed. do not continue */ + CM_LOG_W("already failed: %d\n", ctx->status); + return; + } + uint32_t keySize = sizeof(RbTreeKey); + uint32_t valueSize = 0; + + /* get value size */ + int rc = ctx->enc(value, NULL, &valueSize); + if (rc != CMR_OK) { + CM_LOG_W("value encoder get length failed: %d\n", rc); + ctx->status = rc; + return; + } + + /* each code is encoded ad (key | encoded_value_len | encoded_value) + encoded_value_len is uint32_t. */ + uint32_t sz = keySize + sizeof(uint32_t) + valueSize; + + /* if buffer is provided, do the actual encoding */ + if (ctx->buf != NULL) { + if (ctx->off + sz > ctx->len) { + ctx->status = CMR_ERROR_BUFFER_TOO_SMALL; + return; + } + uint8_t *buf = ctx->buf + ctx->off; + if (memcpy_s(buf, ctx->len, &key, keySize) != EOK) { + return; + } + buf += keySize; + if (memcpy_s(buf, ctx->len, &valueSize, sizeof(uint32_t)) != EOK) { + return; + } + buf += sizeof(uint32_t); + rc = ctx->enc(value, buf, &valueSize); + if (rc != CMR_OK) { + CM_LOG_W("value encoder encoding failed: %d\n", rc); + ctx->status = rc; + return; + } + } + /* in any case, updata offset in context. */ + ctx->off += sz; +} + + +int RbTreeEncode(const struct RbTree *t, RbTreeValueEncoder enc, uint8_t *buf, uint32_t *size) +{ + ASSERT_ARGS(t && t->root && enc && size); + + struct EncoderContext ctx = { + .buf = buf, + .off = 0, + .len = *size, + .status = CMR_OK, + .enc = enc, + }; + + TraverseInOrder(t, t->root, Encoder, &ctx); + if (ctx.status != CMR_OK) { + return ctx.status; + } + *size = ctx.off; + return CMR_OK; +} + +int RbTreeDecode(struct RbTree *t, RbTreeValueDecoder dec, uint8_t *buf, uint32_t size) +{ + ASSERT_ARGS(t && t->root && dec && size); + + uint32_t off = 0; + while (off < size) { + uint32_t remaining = size - off; + uint32_t headerSize = sizeof(RbTreeKey) + sizeof(uint32_t); + + if (remaining < headerSize) { + /* something is wrong */ + return RC_INSUFFICIENT_DATA; + } + + uint8_t *s = buf + off; + + RbTreeKey key; + if (memcpy_s(&key, sizeof(RbTreeKey), s, sizeof(RbTreeKey)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + s += sizeof(RbTreeKey); + + uint32_t valueSize; + if (memcpy_s(&valueSize, sizeof(RbTreeKey), s, sizeof(uint32_t)) != EOK) { + return CMR_ERROR_INVALID_OPERATION; + } + s += sizeof(uint32_t); + + uint32_t sz = headerSize + valueSize; + if (remaining < sz) { + return RC_INSUFFICIENT_DATA; + } + + RbTreeValue value = NULL; + int rc = dec(&value, s, valueSize); + if (rc != CMR_OK) { + return rc; + } + + rc = RbTreeInsert(t, key, value); + if (rc != CMR_OK) { + return rc; + } + off += sz; + } + return CMR_OK; +} + +#ifdef __cplusplus +} + +#endif \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_service.cfg b/services/cert_manager_standard/cert_manager_service.cfg new file mode 100644 index 0000000..de43712 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service.cfg @@ -0,0 +1,24 @@ +{ + "jobs" : [{ + "name" : "post-fs-data", + "cmds" : [ + "mkdir /data/service/el1/public/cert_manager_service 0711 cert_manager_server cert_manager_server", + "mkdir /data/service/el1/public/cert_manager_service/status 0711 cert_manager_server cert_manager_server", + "mkdir /data/service/el1/public/cert_manager_service/certificates 0711 cert_manager_server cert_manager_server", + "mkdir /data/service/el1/public/cert_manager_service/certificates/credential 0711 cert_manager_server cert_manager_server", + "mkdir /data/service/el1/public/cert_manager_service/certificates/user 0711 cert_manager_server cert_manager_server", + "mkdir /data/service/el1/public/cert_manager_service/certificates/priv_credential 0711 cert_manager_server cert_manager_server" + ] + } + ], + "services" : [{ + "name" : "cert_manager_service", + "path" : ["/system/bin/sa_main", "/system/profile/cert_manager_service.xml"], + "ondemand" : true, + "uid" : "cert_manager_server", + "gid" : ["cert_manager_server", "shell"], + "start-mode" : "condition", + "secon" : "u:r:cert_manager_service:s0" + } + ] +} diff --git a/services/cert_manager_standard/cert_manager_service.rc b/services/cert_manager_standard/cert_manager_service.rc new file mode 100644 index 0000000..e8b7f37 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service.rc @@ -0,0 +1,21 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +on post-fs-data + start cert_manager_service + +service cert_manager_service /system/bin/sa_main /system/profile/cert_manager_service.xml + class z_core + user system + group system shell + seclabel u:r:deviceauth_service:s0 diff --git a/services/cert_manager_standard/cert_manager_service/main/BUILD.gn b/services/cert_manager_standard/cert_manager_service/main/BUILD.gn new file mode 100644 index 0000000..e44be8e --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_static_library("libcert_manager_service_standard_static") { + subsystem_name = "security" + part_name = "certificate_manager" + defines = [ + "L2_STANDARD", + "_CM_LOG_ENABLE_", + ] + public_deps = [ + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_service/main/os_dependency:libcert_manager_service_os_dependency_standard_static", + ] + + complete_static_lib = true +} diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn b/services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn new file mode 100644 index 0000000..6637c30 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn @@ -0,0 +1,70 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("cert_manager_config") { + include_dirs = [ "service" ] +} + +ohos_static_library("libcert_manager_service_os_dependency_standard_static") { + subsystem_name = "security" + part_name = "certificate_manager" + public_configs = [ ":cert_manager_config" ] + include_dirs = [ + "//third_party/json/include", + "//commonlibrary/c_utils/base/include", + "//utils/system/safwk/native/include", + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_engine/main/core/include", + ] + + defines = [ + "L2_STANDARD", + "_CM_LOG_ENABLE_", + ] + sources = [ + "sa/cm_sa.cpp" + ] + deps = [ + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/common:libcert_manager_common_standard_static", + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/os_dependency:libcert_manager_os_dependency_standard_static", + ] + public_deps = [ "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl:libcm_service_idl_standard_static" ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + if (support_jsapi) { + sources += [ "sa/cm_event_observer.cpp" ] + defines += [ "SUPPORT_COMMON_EVENT" ] + external_deps += [ + "ability_base:want", + "bundle_framework:appexecfwk_base", + "common_event_service:cesfwk_innerkits", + "os_account:os_account_innerkits", + "c_utils:utils" + ] + + } + + cflags_cc = [ + "-Wall", + "-Werror", + ] + cflags = cflags_cc + complete_static_lib = true +} diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/BUILD.gn b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/BUILD.gn new file mode 100644 index 0000000..2a1f4ca --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/BUILD.gn @@ -0,0 +1,71 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("cert_manager_config") { + include_dirs = [ + "cm_ipc", + ] +} + +ohos_static_library("libcm_service_idl_standard_static") { + subsystem_name = "security" + part_name = "certificate_manager" + public_configs = [ ":cert_manager_config" ] + include_dirs = [ + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_passthrough", + "//third_party/json/include", + "//commonlibrary/c_utils/base/include", + "//base/security/huks/interfaces/innerkits/huks_standard/main/include", + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/os_dependency/cm_ipc/include", + "//third_party/openssl/include" + ] + defines = [ + "L2_STANDARD", + "_CM_LOG_ENABLE_", + ] + sources = [ + "cm_ipc/cm_ipc_serialization.c", + "cm_ipc/cm_ipc_service.c", + "cm_ipc/cm_response.cpp", + ] + deps = [ + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/os_dependency:libcert_manager_os_dependency_standard_static", + "//base/security/certificate_manager/frameworks/cert_manager_standard/main/common:libcert_manager_common_standard_static", + "//base/security/certificate_manager/services/cert_manager_standard/cert_manager_engine/main/core:cert_manager_engine_core_standard", + "//third_party/openssl:libcrypto_shared" + ] + external_deps = [ + "ipc:ipc_core", + "os_account:os_account_innerkits", + "c_utils:utils" + ] + + if (support_jsapi) { + external_deps += [ + "access_token:libaccesstoken_sdk", + "os_account:os_account_innerkits" + ] + defines += [ + ] + } + + cflags_cc = [ + "-DHILOG_ENABLE", + "-Wall", + "-Werror", + ] + cflags = cflags_cc + complete_static_lib = true +} diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.c b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.c new file mode 100644 index 0000000..e637758 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_ipc_serialization.h" + +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_param.h" + +#include "cm_ipc_check.h" + +static int32_t GetContextFromBuffer(struct CmContext *cmContext, const struct CmBlob *srcData, uint32_t *offset) +{ + struct CmBlob blob = {0}; + int32_t ret = GetUint32FromBuffer(&(cmContext->userId), srcData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("get cmContext->userId failed"); + return ret; + } + + ret = GetUint32FromBuffer(&(cmContext->uid), srcData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("get cmContext->uri failed"); + return ret; + } + ret = CmGetBlobFromBuffer(&blob, srcData, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("malloc packageName data failed"); + return ret; + } + if (memcpy_s(cmContext->packageName, MAX_LEN_PACKGE_NAME, blob.data, blob.size) != EOK) { + CM_LOG_E("copy packageName failed"); + return CMR_ERROR_INVALID_OPERATION; + } + return ret; +} + +int32_t CmTrustCertificateListUnpack(const struct CmBlob *srcData, struct CmContext *cmContext, uint32_t *store) +{ + uint32_t offset = 0; + + int32_t ret = GetContextFromBuffer(cmContext, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("get cmContext failed"); + return ret; + } + + ret = GetUint32FromBuffer(store, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("get store failed"); + return ret; + } + + return ret; +} + +int32_t CmTrustCertificateInfoUnpack(const struct CmBlob *srcData, struct CmContext *cmContext, + struct CmBlob *uriBlob, uint32_t *store) +{ + uint32_t offset = 0; + + int32_t ret = GetContextFromBuffer(cmContext, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("get cmContext failed"); + return ret; + } + + ret = CmGetBlobFromBuffer(uriBlob, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("malloc packageName data failed"); + return ret; + } + + ret = GetUint32FromBuffer(store, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("get store failed"); + return ret; + } + + return ret; +} + +int32_t CmCertificateStatusUnpack(const struct CmBlob *srcData, struct CmContext *cmContext, + struct CmBlob *uriBlob, uint32_t *store, uint32_t *status) +{ + uint32_t offset = 0; + + int32_t ret = GetContextFromBuffer(cmContext, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("StatusUnpack get cmContext failed"); + return ret; + } + + ret = CmGetBlobFromBuffer(uriBlob, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("StatusUnpack malloc packageName data failed"); + return ret; + } + + ret = GetUint32FromBuffer(store, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("StatusUnpack get store failed"); + return ret; + } + + ret = GetUint32FromBuffer(status, srcData, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("StatusUnpack get status failed"); + return ret; + } + + return ret; +} + +static int32_t GetNormalParam(const struct CmParam *param, struct CmParamOut *outParams) +{ + switch (GetTagType(outParams->tag)) { + case CM_TAG_TYPE_INT: + *(outParams->int32Param) = param->int32Param; + break; + case CM_TAG_TYPE_UINT: + *(outParams->uint32Param) = param->uint32Param; + break; + case CM_TAG_TYPE_ULONG: + *(outParams->uint64Param) = param->uint64Param; + break; + case CM_TAG_TYPE_BOOL: + *(outParams->boolParam) = param->boolParam; + break; + case CM_TAG_TYPE_BYTES: + *(outParams->blob) = param->blob; + break; + default: + CM_LOG_I("invalid tag type:%x", GetTagType(outParams->tag)); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +static int32_t GetNullBlobParam(const struct CmParamSet *paramSet, struct CmParamOut *outParams) +{ + if (GetTagType(outParams->tag) != CM_TAG_TYPE_BYTES) { + CM_LOG_E("get param tag[0x%x] from ipc buffer failed", outParams->tag); + return CMR_ERROR_PARAM_NOT_EXIST; + } + + struct CmParam *param = NULL; + int32_t ret = CmGetParam(paramSet, outParams->tag + CM_PARAM_BUFFER_NULL_INTERVAL, ¶m); + if (ret != CM_SUCCESS) { + CM_LOG_E("get param tag[0x%x] from ipc buffer failed", outParams->tag + CM_PARAM_BUFFER_NULL_INTERVAL); + return ret; + } + + outParams->blob->data = NULL; + outParams->blob->size = 0; + return CM_SUCCESS; +} + +int32_t CmParamSetToParams(const struct CmParamSet *paramSet, struct CmParamOut *outParams, uint32_t cnt) +{ + int32_t ret; + struct CmParam *param = NULL; + for (uint32_t i = 0; i < cnt; i++) { + ret = CmGetParam(paramSet, outParams[i].tag, ¶m); + if (ret == CM_SUCCESS) { + ret = GetNormalParam(param, &outParams[i]); + } else { + ret = GetNullBlobParam(paramSet, &outParams[i]); + } + if (ret != CM_SUCCESS) { + CM_LOG_E("get param failed, ret = %d", ret); + return ret; + } + } + return CM_SUCCESS; +} diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.h b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.h new file mode 100644 index 0000000..24efa79 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_serialization.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_IPC_SERIALIZATION_H +#define CM_IPC_SERIALIZATION_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CmTrustCertificateListUnpack(const struct CmBlob *srcData, struct CmContext *cmContext, uint32_t *store); + +int32_t CmTrustCertificateInfoUnpack(const struct CmBlob *srcData, struct CmContext *cmContext, + struct CmBlob *uriBlob, uint32_t *store); + +int32_t CmCertificateStatusUnpack(const struct CmBlob *srcData, struct CmContext *cmContext, + struct CmBlob *uriBlob, uint32_t *store, uint32_t* status); + +int32_t CmParamSetToParams(const struct CmParamSet *paramSet, struct CmParamOut *outParams, uint32_t cnt); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.c b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.c new file mode 100644 index 0000000..7efe325 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.c @@ -0,0 +1,1171 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_ipc_service.h" + +#include +#include +#include +#include +#include +#include +#include "cm_ipc_serialization.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "cm_response.h" +#include "cert_manager_status.h" +#include "cert_manager.h" +#include "cm_pfx.h" +#include "cert_manager_file_operator.h" +#include "cert_manager_uri.h" +#include "cm_ipc_check.h" +#include "cm_param.h" +#include +#include +#include "cert_manager_type.h" +#include "hks_type.h" +#include "cm_openssl_ecc.h" +#include "cm_openssl_rsa.h" +#include "cm_openssl_curve25519.h" + +#define MAX_PACKAGENAME_LEN 32 +#define MAX_LEN_CERTIFICATE 8196 +#define MAX_LEN_PRIVATE_KEY 1024 +#define INSTALL_PARAMSET_SZIE 4 + +static int32_t CmTrustCertificateListPack(struct CmBlob *tempCertificateList, const struct CmBlob *certificateList, + const struct CertBlob *certBlob, const uint32_t *status) +{ + int32_t ret; + uint32_t offset = 0; + uint32_t buffSize; + + /* buff struct: cert count + (cert subjectname + cert status + cert uri + cert alias) * MAX_CERT_COUNT */ + buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) + sizeof(uint32_t) + + MAX_LEN_URI + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE; + + tempCertificateList->data = (uint8_t *)CmMalloc(buffSize); + if (tempCertificateList->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + return ret; + } + tempCertificateList->size = buffSize; + ret = CopyUint32ToBuffer(certificateList->size, tempCertificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate count failed"); + return ret; + } + + for (uint32_t i = 0; i < certificateList->size; i++) { + ret = CopyBlobToBuffer(&(certBlob->subjectName[i]), tempCertificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate subject failed"); + return ret; + } + ret = CopyUint32ToBuffer(status[i], tempCertificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate status failed"); + return ret; + } + ret = CopyBlobToBuffer(&(certBlob->uri[i]), tempCertificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate uri failed"); + return ret; + } + ret = CopyBlobToBuffer(&(certBlob->certAlias[i]), tempCertificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate certAlias failed"); + return ret; + } + } + return ret; +} + +static int32_t CmMallocCertInfo(struct CertBlob *certBlob) +{ + uint32_t i; + + if (certBlob == NULL) { + return CMR_ERROR_INVALID_ARGUMENT; + } + + for (i = 0; i < MAX_COUNT_CERTIFICATE; i++) { + certBlob->subjectName[i].size = MAX_LEN_CERTIFICATE; + certBlob->subjectName[i].data = (uint8_t *)CmMalloc(MAX_LEN_SUBJECT_NAME); + if (certBlob->subjectName[i].data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + ASSERT_FUNC(memset_s(certBlob->subjectName[i].data, MAX_LEN_SUBJECT_NAME, 0, MAX_LEN_SUBJECT_NAME)); + + certBlob->certAlias[i].size = MAX_LEN_CERTIFICATE; + certBlob->certAlias[i].data = (uint8_t *)CmMalloc(MAX_LEN_CERT_ALIAS); + if (certBlob->certAlias[i].data == NULL) { + return CMR_ERROR_MALLOC_FAIL; + } + ASSERT_FUNC(memset_s(certBlob->certAlias[i].data, MAX_LEN_CERT_ALIAS, 0, MAX_LEN_CERT_ALIAS)); + } + return CM_SUCCESS; +} + +static void CmFreeCertInfo(struct CertBlob *certBlob) +{ + uint32_t i; + + if (certBlob == NULL) { + CM_LOG_E("CmFreeCertInfo certBlob null"); + return; + } + + for (i = 0; i < MAX_COUNT_CERTIFICATE; i++) { + CMMUTABLE_FREE_BLOB(certBlob->subjectName[i]); + CMMUTABLE_FREE_BLOB(certBlob->certAlias[i]); + CMMUTABLE_FREE_BLOB(certBlob->uri[i]); + } +} + +void CmIpcServiceGetCertificateList(const struct CmBlob *srcData, const struct CmContext *context) +{ + int32_t ret; + uint32_t store; + struct CmContext cmContext = {0}; + struct CmBlob certificateList = { 0, NULL }; + struct CmBlob tempCertificateList = { 0, NULL }; + uint32_t status[MAX_COUNT_CERTIFICATE] = {0}; + struct CertBlob certBlob; + + (void)memset_s(&certBlob, sizeof(struct CertBlob), 0, sizeof(struct CertBlob)); + do { + ret = CmMallocCertInfo(&certBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmMallocCertInfo fail"); + break; + } + + ret = CmTrustCertificateListUnpack(srcData, &cmContext, &store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmTrustCertificateListUnpack Ipc fail"); + break; + } + + ret = CertManagerListTrustedCertificates(&cmContext, &certificateList, store, &certBlob, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertManagerListTrustedCertificates fail, ret = %d", ret); + break; + } + ret = CmTrustCertificateListPack(&tempCertificateList, &certificateList, &certBlob, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmIpcServiceGetCertificateList pack fail, ret = %d", ret); + break; + } + + CmSendResponse(context, ret, &tempCertificateList); + } while (0); + + if (ret != CM_SUCCESS) { + CmSendResponse(context, ret, NULL); + } + CmCertificateListFree((struct CmMutableBlob *)certificateList.data, certificateList.size); + CM_FREE_BLOB(tempCertificateList); + CmFreeCertInfo(&certBlob); +} + +static int32_t CmTrustCertificateInfoPack(struct CmBlob *certificateInfo, + const struct CmBlob *certificateList, uint32_t status) +{ + int32_t ret; + uint32_t buffSize; + uint32_t offset = 0; + + if (certificateList->data == NULL || certificateList->size == 0) { + CM_LOG_E("certificateList data is null"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + const struct CmBlob *blob = &(((const struct CmBlob *)certificateList->data)[0]); + + /* buff struct: cert len + cert data + cert staus */ + buffSize = sizeof(uint32_t) + MAX_LEN_CERTIFICATE + sizeof(uint32_t); + certificateInfo->data = (uint8_t *)CmMalloc(buffSize); + if (certificateInfo->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + return ret; + } + certificateInfo->size = buffSize; + + ret = CopyBlobToBuffer(blob, certificateInfo, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy certificateInfo failed"); + return ret; + } + + ret = CopyUint32ToBuffer(status, certificateInfo, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate count failed"); + return ret; + } + + return ret; +} + +void CmIpcServiceGetCertificateInfo(const struct CmBlob *srcData, const struct CmContext *context) +{ + struct CmContext cmContext = {0}; + uint32_t store; + struct CmBlob certificateList = { 0, NULL }; + struct CmBlob certificateInfo = { 0, NULL }; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob uriBlob = { 0, uriBuf }; + int32_t ret; + uint32_t status = 0; + + do { + ret = CmTrustCertificateInfoUnpack(srcData, &cmContext, &uriBlob, &store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmTrustCertificateInfoUnpack Ipc fail"); + break; + } + + ret = CmGetCertificatesByUri(context, &certificateList, store, &uriBlob, &status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetCertificatesByUri fail, ret = %d", ret); + break; + } + + ret = CmTrustCertificateInfoPack(&certificateInfo, &certificateList, status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmIpcServiceGetCertificateInfo pack fail, ret = %d", ret); + break; + } + CmSendResponse(context, ret, &certificateInfo); + } while (0); + + if (ret != CM_SUCCESS) { + CmSendResponse(context, ret, NULL); + } + CmCertificateListFree((struct CmMutableBlob *)certificateList.data, certificateList.size); + CM_FREE_BLOB(certificateInfo); +} + +void CmIpcServiceSetCertStatus(const struct CmBlob *srcData, const struct CmContext *context) +{ + struct CmContext cmContext = {0}; + uint32_t store; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob uriBlob = { 0, uriBuf }; + uint32_t status = 0; + int32_t ret; + + do { + ret = CmCertificateStatusUnpack(srcData, &cmContext, &uriBlob, &store, &status); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmIpcServiceSetCertStatus Ipc fail"); + break; + } + + ret = CertManagerSetCertificatesStatus(&cmContext, &uriBlob, store, status); + + CmSendResponse(context, ret, NULL); + + CM_LOG_I("CmIpcServiceSetCertStatus end:%d", ret); + } while (0); + + if (ret != CM_SUCCESS) { + CmSendResponse(context, ret, NULL); + } +} + +static int32_t CmWriteAppCert(const struct CmContext *context, const struct CmBlob *certDer, + const uint32_t store, const struct CmBlob *certAlias, const struct CMApp *caller) +{ + int32_t ret = CMR_OK; + char *objUri = NULL; + uint8_t pathBuf[CERT_MAX_PATH_LEN] = {0}; + struct CmMutableBlob pathBlob = { sizeof(pathBuf), pathBuf }; + + ret = CmGetFilePath(context, store, &pathBlob); + if (ret != CMR_OK) { + CM_LOG_E("Failed obtain path for store:%u path:%s", store, pathBuf); + return CMR_ERROR; + } + + CM_LOG_I("CmWriteAppCert path:%s", pathBuf); + + do { + ret = BuildObjUri(&objUri, (char *)certAlias->data, CM_URI_TYPE_APP_KEY, caller); + if (ret != CMR_OK || objUri == NULL) { + CM_LOG_E("BuildObjUri failed"); + break; + } + + if (CmFileWrite((char *)pathBuf, objUri, 0, certDer->data, certDer->size) != CMR_OK) { + CM_LOG_E("Failed to write certificate path:%s", pathBuf); + ret = CMR_ERROR_WRITE_FILE_FAIL; + break; + } + } while (0); + + if (objUri != NULL) { + CmFree(objUri); + } + return ret; +} + +static int32_t CertManagerImportRsaKey(const struct CMApp *caller, EVP_PKEY *priKey, + const struct CmBlob *certAlias) +{ + RSA *rsa = NULL; + int32_t ret = CMR_OK; + struct CmBlob keyPair = { 0, NULL }; + + rsa = EVP_PKEY_get0_RSA(priKey); + if (rsa == NULL) { + CM_LOG_E("EVP_PKEY_get1_RSA error %s", ERR_reason_error_string(ERR_get_error())); + goto err; + } + uint32_t keySize = ((uint32_t)RSA_size(rsa)) * CM_BITS_PER_BYTE; + + const struct CmKeySpec spec = { + .algType = CM_ALG_RSA, + .keyLen = keySize, + .algParam = NULL + }; + + ret = RsaSaveKeyMaterial(rsa, spec.keyLen, &keyPair); + if (ret != CMR_OK) { + CM_LOG_E("save rsa key material failed ret=0x%x", ret); + goto err; + } + + struct CMKeyProperties props = { + .type = CM_URI_TYPE_APP_KEY, + .alg = CM_ALG_RSA, + .size = keySize, + .purpose = CM_KEY_PURPOSE_SIGN | CM_KEY_PURPOSE_VERIFY, + .digest = CM_DIGEST_SHA256, + .padding = HKS_PADDING_PSS + }; + + ret = CertManagerImportKeyPair(caller, &keyPair, &props, (char *)certAlias->data); + if (ret != CMR_OK) { + CM_LOG_E("rsa keypair import faild"); + } + +err: + CM_FREE_BLOB(keyPair); + + return ret; +} + +static int32_t CertManagerImportEccKey(const struct CMApp *caller, EVP_PKEY *priKey, + const struct CmBlob *certAlias) +{ + EC_KEY *eccKey = NULL; + int32_t ret = CMR_OK; + struct CmBlob keyPair = { 0, NULL }; + + eccKey = EVP_PKEY_get0_EC_KEY(priKey); + if (eccKey == NULL) { + CM_LOG_E("EVP_PKEY_get0_EC_KEY faild"); + goto err; + } + + uint32_t keyLen = (uint32_t)EC_GROUP_order_bits(EC_KEY_get0_group(eccKey)); + + struct CmKeySpec spec = { + .algType = CM_ALG_ECC, + .keyLen = keyLen, + .algParam = NULL + }; + + ret = EccSaveKeyMaterial(eccKey, &spec, &keyPair.data, &keyPair.size); + if (ret != CMR_OK) { + CM_LOG_E("save ec key material failed ret=0x%x", ret); + goto err; + } + + const struct CMKeyProperties props = { + .type = CM_URI_TYPE_APP_KEY, + .alg = CM_ALG_ECC, + .size = keyLen, + .purpose = CM_KEY_PURPOSE_SIGN | CM_KEY_PURPOSE_VERIFY, + .digest = CM_DIGEST_SHA256 + }; + + ret = CertManagerImportKeyPair(caller, &keyPair, &props, (char *)certAlias->data); + if (ret != CMR_OK) { + CM_LOG_E("ecc Key type import faild"); + } + +err: + CM_FREE_BLOB(keyPair); + + return ret; +} + +static int32_t CertManagerImportEd25519Key(const struct CMApp *caller, const EVP_PKEY *priKey, + const struct CmBlob *certAlias) +{ + int32_t ret = CMR_OK; + struct CmBlob keyPair = { 0, NULL }; + + struct CMKeyProperties props = { + .type = CM_URI_TYPE_APP_KEY, + .alg = HKS_ALG_ED25519, + .size = HKS_CURVE25519_KEY_SIZE_256, + .purpose = CM_KEY_PURPOSE_SIGN | CM_KEY_PURPOSE_VERIFY, + .digest = CM_DIGEST_SHA256 + }; + + const struct CmKeySpec spec = { + .algType = HKS_ALG_ED25519, + .keyLen = HKS_CURVE25519_KEY_SIZE_256, + .algParam = NULL + }; + + ret = SaveCurve25519KeyMaterial(spec.algType, priKey, &keyPair); + if (ret != CMR_OK) { + CM_LOG_E("save curve25519 key material failed"); + goto err; + } + + ret = CertManagerImportKeyPair(caller, &keyPair, &props, (char *)certAlias->data); + if (ret != CMR_OK) { + CM_LOG_E("Ed25519 key type import faild"); + } +err: + CM_FREE_BLOB(keyPair); + + return ret; +} + +static int32_t CmImportKeyPairInfo(EVP_PKEY *priKey, struct CMApp *caller, + const struct CmBlob *certAlias) +{ + int32_t ret = CM_SUCCESS; + + int32_t keyType = EVP_PKEY_base_id(priKey); + + switch (keyType) { + case EVP_PKEY_RSA: + ret = CertManagerImportRsaKey(caller, priKey, certAlias); + break; + + case EVP_PKEY_EC: + ret = CertManagerImportEccKey(caller, priKey, certAlias); + break; + + case EVP_PKEY_ED25519: + ret = CertManagerImportEd25519Key(caller, priKey, certAlias); + break; + + default: + CM_LOG_E("Import key:%d type not suported", keyType); + } + return ret; +} + +static int32_t CmInstallAppCert(const struct CmContext *context, const struct CmBlob *keystore, + const struct CmBlob *keystorePwd, const struct CmBlob *certAlias, const uint32_t store) +{ + int32_t ret = CM_SUCCESS; + EVP_PKEY *priKey = NULL; + struct AppCert appCert; + struct CmBlob certBlob = { 0, NULL }; + (void)memset_s(&appCert, sizeof(struct AppCert), 0, sizeof(struct AppCert)); + struct CMApp caller = { + .userId = context->userId, + .uid = context->uid, + .packageName = context->packageName, + }; + + do { + ret = CmParsePkcs12Cert(keystore, (char *)keystorePwd->data, &priKey, &appCert); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmParsePkcs12Cert fail"); + ret = CM_FAILURE; + break; + } + + ret = CmImportKeyPairInfo(priKey, &caller, certAlias); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmImportKeyPairInfo fail"); + break; + } + + appCert.keyCount = 1; + certBlob.size = sizeof(struct AppCert) - MAX_LEN_CERTIFICATE_CHAIN + appCert.certSize; + certBlob.data = (uint8_t *)(&appCert); + + ret = CmWriteAppCert(context, &certBlob, store, certAlias, &caller); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmWriteAppCert fail"); + ret = CM_FAILURE; + break; + } + } while (0); + + EVP_PKEY_free(priKey); + return ret; +} + +static bool AppCertCheckBlobValid(const struct CmBlob *data) +{ + bool validChar = true; + + for (uint32_t i = 0; i < data->size; i++) { + if ((!isalnum(data->data[i])) && (data->data[i] != '_') && (data->data[i] != '\0')) { + validChar = false; + CM_LOG_E("data include invalid character"); + break; + } + } + + return validChar; +} + +static int32_t CmInstallAppCertCheck(const struct CmBlob *appCert, const struct CmBlob *appCertPwd, + const struct CmBlob *certAlias, uint32_t store) +{ + if (appCert->data == NULL || appCertPwd->data == NULL || certAlias->data == NULL) { + CM_LOG_E("CmInstallAppCertCheck paramSet check fail"); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (appCert->size == 0 || appCert->size == 0 ||appCert->size == 0 || + appCert->size > MAX_LEN_APP_CERT || appCertPwd->size > MAX_LEN_APP_CERT_PASSWD || + certAlias->size > MAX_LEN_CERT_ALIAS) { + CM_LOG_E("CmInstallAppCertCheck paramSet check fail, appCert:%u, appCertPwd:%u, certAlias:%u", + appCert->size, appCertPwd->size, certAlias->size); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (store != CM_CREDENTIAL_STORE && store != CM_PRI_CREDENTIAL_STORE) { + CM_LOG_E("CmInstallAppCertCheck store check fail, store:%u", store); + return CMR_ERROR_INVALID_ARGUMENT; + } + + if (!AppCertCheckBlobValid(appCertPwd) || !AppCertCheckBlobValid(certAlias)) { + CM_LOG_E("CmInstallAppCertCheck blob data check fail"); + return CMR_ERROR_INVALID_ARGUMENT; + } + return CM_SUCCESS; +} + +static int32_t CmServiceInstallAppCertPack(const struct CmContext *context, + const struct CmBlob *certAlias, struct CmBlob *keyUri) +{ + int32_t ret; + uint32_t offset = 0; + char *objUri = NULL; + struct CMApp caller = { + .userId = context->userId, + .uid = context->uid, + .packageName = context->packageName, + }; + + /* buff struct: keyUriSize + keyUriData */ + uint32_t buffSize = sizeof(uint32_t) + MAX_LEN_URI; + keyUri->data = (uint8_t *)CmMalloc(buffSize); + if (keyUri->data == NULL) { + keyUri->size = 0; + return CMR_ERROR_MALLOC_FAIL; + } + keyUri->size = buffSize; + do { + ret = BuildObjUri(&objUri, (char *)certAlias->data, CM_URI_TYPE_APP_KEY, &caller); + if (ret != CMR_OK || objUri == NULL) { + CM_LOG_E("BuildObjUri failed"); + break; + } + struct CmBlob blob = { strlen(objUri) + 1, (uint8_t *)objUri }; + ret = CopyBlobToBuffer(&blob, keyUri, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy keyUri failed"); + break; + } + } while (0); + + if (objUri != NULL) { + CmFree(objUri); + } + + return ret; +} + +static int32_t CmInstallAppCertGetParam(const struct CmBlob *paramSetBlob, struct CmParamSet **paramSet, + struct CmParamOut *params, uint32_t paramsSize, struct CertParam *certParam) +{ + uint8_t *aliasBuff = certParam->aliasBuff; + uint8_t *passWdBuff = certParam->passWdBuff; + int32_t ret = CmGetParamSet((struct CmParamSet *)paramSetBlob->data, paramSetBlob->size, paramSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("InstallAppCert CmGetParamSet fail, ret = %d", ret); + return CM_FAILURE; + } + + ret = CmParamSetToParams(*paramSet, params, paramsSize); + if (ret != CM_SUCCESS) { + CM_LOG_E("InstallAppCert CmParamSetToParams fail, ret = %d", ret); + return CM_FAILURE; + } + + if (paramsSize > INSTALL_PARAMSET_SZIE) { + CM_LOG_E("paramsSize check faild, paramsSize:%u", paramsSize); + return CM_FAILURE; + } + + struct CmBlob *appCert = params[0].blob, *appCertPwd = params[1].blob, *certAlias = params[2].blob; + uint32_t store = *(params[3].uint32Param); + ret = CmInstallAppCertCheck(appCert, appCertPwd, certAlias, store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmInstallAppCertCheck fail, ret = %d", ret); + return CM_FAILURE; + } + + if (appCertPwd->data[appCertPwd->size - 1] != '\0') { + if (memcpy_s(passWdBuff, MAX_LEN_APP_CERT_PASSWD, appCertPwd->data, appCertPwd->size) != EOK) { + CM_LOG_E("Copy passWdBuff failed"); + return CMR_ERROR_INVALID_OPERATION; + } + passWdBuff[appCertPwd->size] = '\0'; + appCertPwd->data = passWdBuff; + appCertPwd->size++; + } + + if (certAlias->data[certAlias->size - 1] != '\0') { + if (memcpy_s(aliasBuff, MAX_LEN_CERT_ALIAS, certAlias->data, certAlias->size) != EOK) { + CM_LOG_E("Copy aliasBuff failed"); + return CMR_ERROR_INVALID_OPERATION; + } + aliasBuff[certAlias->size] = '\0'; + certAlias->data = aliasBuff; + certAlias->size++; + } + + return CM_SUCCESS; +} + +void CmIpcServiceInstallAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + int32_t ret; + uint32_t store; + (void)outData; + uint8_t aliasBuff[MAX_LEN_CERT_ALIAS] = {0}, passWdBuff[MAX_LEN_APP_CERT_PASSWD] = {0}; + struct CertParam certParam = { aliasBuff, passWdBuff }; + struct CmContext cmContext = {0}; + struct CmBlob appCert = { 0, NULL }, appCertPwd = { 0, NULL }; + struct CmBlob certAlias = { 0, NULL }, keyUri = { 0, NULL }; + struct CmParamSet *paramSet = NULL; + struct CmParamOut params[] = { + { + .tag = CM_TAG_PARAM0_BUFFER, .blob = &appCert + }, { + .tag = CM_TAG_PARAM1_BUFFER, .blob = &appCertPwd + }, { + .tag = CM_TAG_PARAM2_BUFFER, .blob = &certAlias + }, { + .tag = CM_TAG_PARAM0_UINT32, .uint32Param = &store + }, + }; + + do { + ret = CmInstallAppCertGetParam(paramSetBlob, ¶mSet, params, CM_ARRAY_SIZE(params), &certParam); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmInstallAppCertGetParam fail, ret = %d", ret); + break; + } + + ret = CmGetProcessInfoForIPC(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetProcessInfoForIPC fail, ret = %d", ret); + break; + } + + ret = CmInstallAppCert(&cmContext, &appCert, &appCertPwd, &certAlias, store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmInstallAppCert fail, ret = %d", ret); + break; + } + + ret = CmServiceInstallAppCertPack(&cmContext, &certAlias, &keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmServiceInstallAppCertPack fail, ret = %d", ret); + } + } while (0); + + CmSendResponse(context, ret, &keyUri); + CmFreeParamSet(¶mSet); + CM_FREE_BLOB(keyUri); + CM_LOG_I("CmIpcServiceInstallAppCert end:%d", ret); +} + +void CmIpcServiceUninstallAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + int32_t ret; + (void)outData; + uint32_t store; + struct CmParamSet *paramSet = NULL; + struct CmBlob keyUri = { 0, NULL }; + struct CmContext cmContext = {0}; + + struct CmParamOut params[] = { + { + .tag = CM_TAG_PARAM0_BUFFER, + .blob = &keyUri + }, { + .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = &store + }, + }; + + do { + ret = CmGetParamSet((struct CmParamSet *)paramSetBlob->data, paramSetBlob->size, ¶mSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("UninstallAppCert CmGetParamSet fail, ret = %d", ret); + break; + } + + ret = CmParamSetToParams(paramSet, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("UninstallAppCert CmParamSetToParams fail, ret = %d", ret); + break; + } + + ret = CmGetProcessInfoForIPC(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("UninstallAppCert CmGetProcessInfoForIPC fail, ret = %d", ret); + break; + } + + ret = CmRemoveAppCert(&cmContext, &keyUri, store); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmRemoveAppCert fail"); + } + } while (0); + + CmSendResponse(context, ret, NULL); + CmFreeParamSet(¶mSet); + CM_LOG_I("CmIpcServiceUninstallAppCert end:%d", ret); +} + +void CmIpcServiceUninstallAllAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + (void)outData; + (void)paramSetBlob; + int32_t ret = CM_SUCCESS; + struct CmContext cmContext = {0}; + + ret = CmGetProcessInfoForIPC(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetProcessInfoForIPC fail, ret = %d", ret); + } + + ret = CmRemoveAllAppCert(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmRemoveAllAppCert fail"); + } + + CmSendResponse(context, ret, NULL); + CM_LOG_I("CmIpcServiceUninstallAllAppCert end:%d", ret); +} + +static int32_t GetAppCertInfo(const struct CmBlob *keyUri, struct CmBlob *certType, + struct CmBlob *certUri, struct CmBlob *cerAlies) +{ + int32_t ret; + char uriBuf[MAX_LEN_URI] = {0}; + struct CMUri uri; + + do { + if ((keyUri->size >= MAX_LEN_URI) || memcpy_s(uriBuf, MAX_LEN_URI, keyUri->data, keyUri->size) != EOK) { + CM_LOG_E("Failed to copy keyUri"); + ret = CMR_ERROR; + break; + } + + (void)memset_s(&uri, sizeof(struct CMUri), 0, sizeof(struct CMUri)); + ret = CertManagerUriDecode(&uri, (char *)keyUri->data); + if (ret != CM_SUCCESS) { + CM_LOG_E("CertManagerUriDecode failed"); + break; + } + + if (memcpy_s(certType->data, MAX_LEN_SUBJECT_NAME, g_types[uri.type], + strlen(g_types[uri.type])) != EOK) { + CM_LOG_E("Failed to copy certType->data"); + ret = CMR_ERROR; + break; + } + certType->size = strlen(g_types[uri.type]) + 1; + + if (memcpy_s(certUri->data, MAX_LEN_URI, uriBuf, strlen(uriBuf)) != EOK) { + CM_LOG_E("Failed to copy certUri->data"); + ret = CMR_ERROR; + break; + } + certUri->size = strlen(uriBuf) + 1; + + if (memcpy_s(cerAlies->data, MAX_LEN_CERT_ALIAS, uri.object, strlen(uri.object)) != EOK) { + CM_LOG_E("Failed to copy cerAlies->data"); + ret = CMR_ERROR; + break; + } + cerAlies->size = strlen(uri.object) + 1; + } while (0); + + CertManagerFreeUri(&uri); + return ret; +} + +static int32_t CmCertListGetAppCertInfo(const struct CmBlob *fileName, struct CmBlob *certType, + struct CmBlob *certUri, struct CmBlob *certAlies) +{ + char uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { sizeof(uriBuf), (uint8_t *)uriBuf }; + + int32_t ret = CmGetUri((char *)fileName->data, &keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get uri failed"); + return ret; + } + + ret = GetAppCertInfo(&keyUri, certType, certUri, certAlies); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertInfo failed"); + return ret; + } + + return ret; +} + +static int32_t CmServiceGetAppCertListPack(struct CmBlob *certificateList, const struct CmBlob *fileNames, + const uint32_t fileCount) +{ + int32_t ret; + uint32_t offset = 0, buffSize = 0; + uint8_t typeBuf[MAX_LEN_SUBJECT_NAME] = {0}, certUriBuf[MAX_LEN_URI] = {0}, aliesBuf[MAX_LEN_CERT_ALIAS] = {0}; + struct CmBlob certType = { 0, typeBuf }, certUri = { 0, certUriBuf }, certAlies = { 0, aliesBuf }; + + /* buff struct: cert count + (cert type + cert uri + cert alias) * MAX_CERT_COUNT */ + buffSize = sizeof(uint32_t) + (sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) + + MAX_LEN_URI + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS) * MAX_COUNT_CERTIFICATE; + + certificateList->data = (uint8_t *)CmMalloc(buffSize); + if (certificateList->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + return ret; + } + + certificateList->size = buffSize; + ret = CopyUint32ToBuffer(fileCount, certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certificate count failed"); + return ret; + } + + for (uint32_t i = 0; i < fileCount; i++) { + (void)memset_s(typeBuf, MAX_LEN_SUBJECT_NAME, 0, MAX_LEN_SUBJECT_NAME); + (void)memset_s(certUriBuf, MAX_LEN_URI, 0, MAX_LEN_URI); + (void)memset_s(aliesBuf, MAX_LEN_CERT_ALIAS, 0, MAX_LEN_CERT_ALIAS); + + ret = CmCertListGetAppCertInfo(&fileNames[i], &certType, &certUri, &certAlies); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmCertListGetAppCertInfo failed"); + return ret; + } + + CM_LOG_I("CmServiceGetAppCertListPack i:%u, Type:%s, certUri:%s, Alies:%s", i, typeBuf, certUriBuf, aliesBuf); + + ret = CopyBlobToBuffer(&certType, certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certType failed"); + return ret; + } + + ret = CopyBlobToBuffer(&certUri, certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certUri failed"); + return ret; + } + + ret = CopyBlobToBuffer(&certAlies, certificateList, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy certAlies failed"); + return ret; + } + } + + return ret; +} + +void CmIpcServiceGetAppCertList(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + int32_t ret; + (void)outData; + uint32_t store, fileCount = 0; + struct CmContext cmContext = {0}; + struct CmBlob certificateList = { 0, NULL }; + struct CmBlob fileNames[MAX_COUNT_CERTIFICATE]; + struct CmParamSet *paramSet = NULL; + struct CmParamOut params[] = { + { + .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = &store + }, + }; + uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob); + (void)memset_s(fileNames, len, 0, len); + do { + ret = CmGetParamSet((struct CmParamSet *)paramSetBlob->data, paramSetBlob->size, ¶mSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertList CmGetParamSet fail, ret = %d", ret); + break; + } + + ret = CmParamSetToParams(paramSet, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertList CmParamSetToParams fail, ret = %d", ret); + break; + } + + ret = CmGetProcessInfoForIPC(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetProcessInfoForIPC fail, ret = %d", ret); + break; + } + + ret = CmServiceGetAppCertList(&cmContext, store, fileNames, MAX_COUNT_CERTIFICATE, &fileCount); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get App cert list fail, ret = %d", ret); + break; + } + + ret = CmServiceGetAppCertListPack(&certificateList, fileNames, fileCount); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmServiceGetAppCertListPack pack fail, ret = %d", ret); + } + } while (0); + + CmSendResponse(context, ret, &certificateList); + CmFreeParamSet(¶mSet); + CmFreeFileNames(fileNames, fileCount); + CM_FREE_BLOB(certificateList); + CM_LOG_I("CmIpcServiceGetAppCertList end:%d", ret); +} + +static int32_t CopyCertificateInfoToBuffer(const struct CmBlob *certBlob, + const struct CmBlob *certificateInfo, uint32_t *offset) +{ + struct AppCert *appCert = (struct AppCert *)certBlob->data; + + int32_t ret = CopyUint32ToBuffer(appCert->certCount, certificateInfo, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy appcert->certCount failed"); + return ret; + } + + ret = CopyUint32ToBuffer(appCert->keyCount, certificateInfo, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("get appcert->keyCount failed"); + return ret; + } + + struct CmBlob appCertBlob = { appCert->certSize, appCert->appCertdata }; + ret = CopyBlobToBuffer(&appCertBlob, certificateInfo, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy appCertBlob failed"); + } + + return ret; +} + +static int32_t CopyCertSize(const struct CmBlob *certBlob, const struct CmBlob *certificateInfo, + uint32_t *offset) +{ + uint32_t certCount = (((certBlob->size > 0) && (certBlob->data != NULL)) ? 1 : 0); + + int32_t ret = CopyUint32ToBuffer(certCount, certificateInfo, offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("copy certificateList->size failed"); + return ret; + } + if (certCount == 0) { + CM_LOG_E("app cert not exist"); + return CMR_ERROR_NOT_EXIST; + } + return ret; +} + +static int32_t CmAppCertificateInfoPack(struct CmBlob *certificateInfo, + const struct CmBlob *certBlob, const struct CmBlob *keyUri) +{ + int32_t ret; + uint32_t buffSize = 0, offset = 0; + uint8_t typeBuf[MAX_LEN_SUBJECT_NAME] = {0}; + uint8_t certUriBuf[MAX_LEN_URI] = {0}; + uint8_t aliesBuf[MAX_LEN_CERT_ALIAS] = {0}; + struct CmBlob certType = { 0, typeBuf }; + struct CmBlob certUri = { 0, certUriBuf }; + struct CmBlob cerAlies = { 0, aliesBuf }; + + buffSize = sizeof(uint32_t) + sizeof(uint32_t) + MAX_LEN_SUBJECT_NAME + sizeof(uint32_t) + MAX_LEN_CERT_ALIAS + + sizeof(uint32_t) + MAX_LEN_URI + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + + MAX_LEN_CERTIFICATE_CHAIN; + certificateInfo->data = (uint8_t *)CmMalloc(buffSize); + if (certificateInfo->data == NULL) { + ret = CMR_ERROR_MALLOC_FAIL; + return ret; + } + certificateInfo->size = buffSize; + + if (CopyCertSize(certBlob, certificateInfo, &offset) != CM_SUCCESS) { + return CMR_ERROR_NOT_EXIST; + } + + ret = GetAppCertInfo(keyUri, &certType, &certUri, &cerAlies); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCertInfo failed"); + return ret; + } + + if (CopyBlobToBuffer(&certType, certificateInfo, &offset) != CM_SUCCESS) { + CM_LOG_E("Copy certType failed"); + return CMR_ERROR; + } + + if (CopyBlobToBuffer(&certUri, certificateInfo, &offset) != CM_SUCCESS) { + CM_LOG_E("Copy certUri failed"); + return CMR_ERROR; + } + + if (CopyBlobToBuffer(&cerAlies, certificateInfo, &offset) != CM_SUCCESS) { + CM_LOG_E("Copy cerAlies failed"); + return CMR_ERROR; + } + + ret = CopyCertificateInfoToBuffer(certBlob, certificateInfo, &offset); + if (ret != CM_SUCCESS) { + CM_LOG_E("Copy CertificateInfo failed"); + return ret; + } + + return ret; +} + +static int32_t CmServiceGetAppCert(const struct CmContext *context, uint32_t store, + struct CmBlob *keyUri, struct CmBlob *certBlob) +{ + uint32_t certSize, fileCount = 0; + struct CmBlob fileNames[MAX_COUNT_CERTIFICATE]; + + char uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob uriBlob = { sizeof(uriBuf), (uint8_t*)uriBuf }; + uint32_t len = MAX_COUNT_CERTIFICATE * sizeof(struct CmBlob); + (void)memset_s(fileNames, len, 0, len); + if (CmServiceGetAppCertList(context, store, fileNames, MAX_COUNT_CERTIFICATE, &fileCount) != CM_SUCCESS) { + CM_LOG_E("Get App cert list fail"); + CmFreeFileNames(fileNames, MAX_COUNT_CERTIFICATE); + return CM_FAILURE; + } + + for (uint32_t i = 0; i < fileCount; i++) { + if (CmGetUri((char *)fileNames[i].data, &uriBlob) != CM_SUCCESS) { + CM_LOG_E("Get uri failed"); + continue; + } + + if (memcmp(uriBlob.data, keyUri->data, keyUri->size) == 0) { + certSize = CmFileSize(NULL, (char *)fileNames[i].data); + certBlob->data = (uint8_t *)CmMalloc(certSize); + if (certBlob->data == NULL) { + CM_LOG_E("Malloc memory faild file:%s", (char *)fileNames[i].data); + continue; + } + certBlob->size = certSize; + + if (CmFileRead(NULL, (char *)fileNames[i].data, 0, certBlob->data, certSize) != certSize) { + CM_LOG_E("Read file faild"); + CM_FREE_BLOB(*certBlob); + continue; + } + CmFreeFileNames(fileNames, MAX_COUNT_CERTIFICATE); + return CM_SUCCESS; + } + } + CmFreeFileNames(fileNames, MAX_COUNT_CERTIFICATE); + CM_FREE_BLOB(*certBlob); + return CM_FAILURE; +} + +void CmIpcServiceGetAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context) +{ + int32_t ret; + (void)outData; + uint32_t store; + struct CmBlob keyUri = { 0, NULL }, certificateInfo = { 0, NULL }, certBlob = { 0, NULL }; + struct CmContext cmContext = {0}; + struct CmParamSet *paramSet = NULL; + struct CmParamOut params[] = { + { + .tag = CM_TAG_PARAM0_BUFFER, + .blob = &keyUri + }, + { + .tag = CM_TAG_PARAM0_UINT32, + .uint32Param = &store + }, + }; + do { + ret = CmGetParamSet((struct CmParamSet *)paramSetBlob->data, paramSetBlob->size, ¶mSet); + if (ret != CM_SUCCESS) { + CM_LOG_E("GetAppCert CmGetParamSet fail, ret = %d", ret); + break; + } + + ret = CmParamSetToParams(paramSet, params, CM_ARRAY_SIZE(params)); + if (ret != CM_SUCCESS) { + break; + } + + ret = CmGetProcessInfoForIPC(&cmContext); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmGetProcessInfoForIPC fail, ret = %d", ret); + break; + } + + ret = CmServiceGetAppCert(&cmContext, store, &keyUri, &certBlob); + if (ret != CM_SUCCESS) { + CM_LOG_E("Get App cert list fail, ret = %d", ret); + break; + } + + ret = CmAppCertificateInfoPack(&certificateInfo, &certBlob, &keyUri); + if (ret != CM_SUCCESS) { + CM_LOG_E("CmAppCertificateInfoPack fail, ret = %d", ret); + } + } while (0); + + CmSendResponse(context, ret, &certificateInfo); + CmFreeParamSet(¶mSet); + CM_FREE_BLOB(certBlob); + CM_FREE_BLOB(certificateInfo); + CM_LOG_I("CmIpcServiceGetAppCert end:%d", ret); +} \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.h b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.h new file mode 100644 index 0000000..e9c7588 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_ipc_service.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_IPC_SERVICE_H +#define CM_IPC_SERVICE_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct CertParam { + uint8_t *aliasBuff; + uint8_t *passWdBuff; +}; + +void CmIpcServiceGetCertificateList(const struct CmBlob *srcData, const struct CmContext *context); + +void CmIpcServiceGetCertificateInfo(const struct CmBlob *srcData, const struct CmContext *context); + +void CmIpcServiceSetCertStatus(const struct CmBlob *srcData, const struct CmContext *context); + +void CmIpcServiceInstallAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceUninstallAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceUninstallAllAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceGetAppCertList(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +void CmIpcServiceGetAppCert(const struct CmBlob *paramSetBlob, struct CmBlob *outData, + const struct CmContext *context); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.cpp b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.cpp new file mode 100644 index 0000000..e4df11e --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_response.h" + +#include +#include +#include +#include + +#include "ipc_skeleton.h" + +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type_inner.h" +#include "os_account_manager.h" + +using namespace OHOS; + +void CmSendResponse(const struct CmContext *context, int32_t result, const struct CmBlob *response) +{ + if (context == nullptr) { + CM_LOG_E("SendResponse NULL Pointer"); + return; + } + MessageParcel *reply = (MessageParcel *)context; + reply->WriteInt32(result); + if (response == nullptr) { + reply->WriteUint32(0); + } else { + reply->WriteUint32(response->size); + reply->WriteBuffer(response->data, (size_t)response->size); + CM_LOG_I("CmSendResponse before result = %d, size = %u", result, response->size); + } +} + +int32_t CmGetProcessNameForIPC(const struct CmContext *context, struct CmBlob *processName) +{ + if ((context == nullptr) || (processName == nullptr)) { + CM_LOG_D("CmGetProcessNameForIPC don't need get process name in hosp."); + return CM_SUCCESS; + } + + auto callingUid = IPCSkeleton::GetCallingUid(); + uint8_t *name = (uint8_t *)CmMalloc(sizeof(callingUid)); + if (name == nullptr) { + CM_LOG_E("CmGetProcessNameForIPC malloc failed."); + return CMR_ERROR_MALLOC_FAIL; + } + + if (memcpy_s(name, sizeof(callingUid), &callingUid, sizeof(callingUid)) != EOK) { + return CM_FAILURE; + } + processName->size = sizeof(callingUid); + processName->data = name; + return CM_SUCCESS; +} + +int32_t CmGetProcessInfoForIPC(struct CmContext *cmContext) +{ + if (cmContext == nullptr) { + CM_LOG_D("CmGetProcessInfoForIPC Paramset is Invalid"); + return CM_FAILURE; + } + + int userId = 0; + auto callingUid = IPCSkeleton::GetCallingUid(); + + OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + CM_LOG_I("CmGetProcessInfoForIPC callingUid = %d, userId = %d", callingUid, userId); + + cmContext->uid = (uint32_t)callingUid; + cmContext->userId = (uint32_t)userId; + + return CM_SUCCESS; +} diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.h b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.h new file mode 100644 index 0000000..1686178 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/idl/cm_ipc/cm_response.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_RESPONSE_H +#define CM_RESPONSE_H + +#include "cm_type_inner.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void CmSendResponse(const struct CmContext *context, int32_t result, const struct CmBlob *response); + +int32_t CmGetProcessNameForIPC(const struct CmContext *context, struct CmBlob *processName); + +int32_t CmGetProcessInfoForIPC(struct CmContext *cmContext); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.cpp b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.cpp new file mode 100644 index 0000000..4993349 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_event_observer.h" + +#include "bundle_constants.h" +#include "common_event_support.h" +#include "os_account_manager.h" +#include "cm_event_process.h" +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_type.h" +#include "securec.h" + +namespace OHOS { +namespace Security { +namespace Cm { +std::shared_ptr SystemEventObserver::systemEventSubscriber_ = nullptr; + +SystemEventSubscriber::SystemEventSubscriber(const OHOS::EventFwk::CommonEventSubscribeInfo &subscriberInfo) + : OHOS::EventFwk::CommonEventSubscriber(subscriberInfo) +{ +} + +void SystemEventSubscriber::OnReceiveEvent(const OHOS::EventFwk::CommonEventData &data) +{ + int uid; + struct CmContext context; + context.userId = INVALID_VALUE; + auto want = data.GetWant(); + std::string action = want.GetAction(); + if (action == OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED || + action == OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) { + context.uid = (uint32_t)want.GetIntParam(AppExecFwk::Constants::UID, -1); + OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(context.uid, uid); + context.userId = (uint32_t)uid; + CM_LOG_I("CmService package removed: uid is %u userId is %u", context.uid, context.userId); + CmDeleteProcessInfo(&context); + } else if (action == OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED) { + int userId = data.GetCode(); + CM_LOG_I("CmService user removed: userId is %d", userId); + CmDeleteProcessInfo(&context); + } +} + +SystemEventObserver::~SystemEventObserver() +{ + if (systemEventSubscriber_ != nullptr) { + UnSubscribeSystemEvent(); + } +} + +bool SystemEventObserver::SubscribeSystemEvent() +{ + OHOS::EventFwk::MatchingSkills matchingSkills; + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED); + OHOS::EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills); + systemEventSubscriber_ = std::make_shared(subscriberInfo); + + if (systemEventSubscriber_ == nullptr) { + CM_LOG_E("Cm system subscriber nullptr"); + return false; + } + + return OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(systemEventSubscriber_); +} + +bool SystemEventObserver::UnSubscribeSystemEvent() +{ + if (systemEventSubscriber_ == nullptr) { + CM_LOG_E("Cm system subscriber nullptr"); + return false; + } + return OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(systemEventSubscriber_); +} + +} // namespace Cm +} // namespace Security +} // namespace OHOS diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.h b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.h new file mode 100644 index 0000000..092cfa7 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_event_observer.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_EVENT_OBSERVER_H +#define CM_EVENT_OBSERVER_H + +#include +#include "common_event_manager.h" +#include "common_event_subscriber.h" + +namespace OHOS { +namespace Security { +namespace Cm { +class SystemEventSubscriber : public OHOS::EventFwk::CommonEventSubscriber { +public: + explicit SystemEventSubscriber(const OHOS::EventFwk::CommonEventSubscribeInfo &subscriberInfo); + ~SystemEventSubscriber() = default; + virtual void OnReceiveEvent(const OHOS::EventFwk::CommonEventData &data); +}; + +class SystemEventObserver { +public: + SystemEventObserver() = default; + ~SystemEventObserver(); + static bool SubscribeSystemEvent(); + static bool UnSubscribeSystemEvent(); + +private: + static std::shared_ptr systemEventSubscriber_; +}; +} // namespace Cm +} // namespace Security +} // namespace OHOS + +#endif // CM_EVENT_OBSERVER_H diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp new file mode 100644 index 0000000..71a5e3a --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_sa.h" + +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +#include "cm_log.h" +#include "cm_mem.h" +#include "cm_ipc_service.h" + +#include "cert_manager.h" +#include "cert_manager_type.h" + +static bool g_certManagerStatusInit = false; + +namespace OHOS { +namespace Security { +namespace CertManager { +REGISTER_SYSTEM_ABILITY_BY_ID(CertManagerService, SA_ID_KEYSTORE_SERVICE, true); + +std::mutex CertManagerService::instanceLock; +sptr CertManagerService::instance; +const uint32_t MAX_MALLOC_LEN = 1 * 1024 * 1024; /* max malloc size 1 MB */ + +using CmIpcHandlerFuncProc = void (*)(const struct CmBlob *msg, const CmContext *context); + +using CmIpcAppHandlerFuncProc = void (*)(const struct CmBlob *msg, struct CmBlob *outData, + const CmContext *context); + +enum CmMessage { + CM_MSG_BASE = 0x3a400, + + CM_MSG_GEN_KEY = CM_MSG_BASE, + CM_MSG_GET_CERTIFICATE_LIST, + CM_MSG_GET_CERTIFICATE_INFO, + CM_MSG_SET_CERTIFICATE_STATUS, + CM_MSG_INSTALL_APP_CERTIFICATE, + CM_MSG_UNINSTALL_APP_CERTIFICATE, + CM_MSG_UNINSTALL_ALL_APP_CERTIFICATE, + CM_MSG_GET_APP_CERTIFICATE_LIST, + CM_MSG_GET_APP_CERTIFICATE, + /* new cmd type must be added before HKS_MSG_MAX */ + CM_MSG_MAX, +}; + +struct CmIpcPoint { + enum CmMessage msgId; + CmIpcAppHandlerFuncProc handler; +}; + +struct CmIpcEntryPoint { + enum CmMessage msgId; + CmIpcHandlerFuncProc handler; +}; + +static struct CmIpcPoint g_cmIpcHandler[] = { + { CM_MSG_INSTALL_APP_CERTIFICATE, CmIpcServiceInstallAppCert }, + { CM_MSG_UNINSTALL_APP_CERTIFICATE, CmIpcServiceUninstallAppCert }, + { CM_MSG_UNINSTALL_ALL_APP_CERTIFICATE, CmIpcServiceUninstallAllAppCert }, + { CM_MSG_GET_APP_CERTIFICATE_LIST, CmIpcServiceGetAppCertList }, + { CM_MSG_GET_APP_CERTIFICATE, CmIpcServiceGetAppCert }, +}; + +static struct CmIpcEntryPoint g_cmIpcMessageHandler[] = { + { CM_MSG_GET_CERTIFICATE_LIST, CmIpcServiceGetCertificateList }, + { CM_MSG_GET_CERTIFICATE_INFO, CmIpcServiceGetCertificateInfo }, + { CM_MSG_SET_CERTIFICATE_STATUS, CmIpcServiceSetCertStatus }, +}; + +static inline bool IsInvalidLength(uint32_t length) +{ + return (length == 0) || (length > MAX_MALLOC_LEN); +} + +static int32_t ProcessMessage(uint32_t code, uint32_t outSize, const struct CmBlob &srcData, MessageParcel &reply) +{ + uint32_t size = sizeof(g_cmIpcMessageHandler) / sizeof(g_cmIpcMessageHandler[0]); + for (uint32_t i = 0; i < size; ++i) { + CM_LOG_E("ProcessMessage msgId:%x gmsg:%x", code, g_cmIpcMessageHandler[i].msgId); + if (code == g_cmIpcMessageHandler[i].msgId) { + g_cmIpcMessageHandler[i].handler((const struct CmBlob *)&srcData, (const CmContext *)&reply); + return NO_ERROR; + } + } + + size = sizeof(g_cmIpcHandler) / sizeof(g_cmIpcHandler[0]); + for (uint32_t i = 0; i < size; ++i) { + if (code != g_cmIpcHandler[i].msgId) { + continue; + } + struct CmBlob outData = { 0, nullptr }; + if (outSize != 0) { + outData.size = outSize; + if (outData.size > MAX_MALLOC_LEN) { + CM_LOG_E("outData size is invalid, size:%u", outData.size); + return HW_SYSTEM_ERROR; + } + outData.data = (uint8_t *)CmMalloc(outData.size); + if (outData.data == nullptr) { + CM_LOG_E("Malloc outData failed."); + return HW_SYSTEM_ERROR; + } + } + g_cmIpcHandler[i].handler((const struct CmBlob *)&srcData, &outData, (const CmContext *)&reply); + CM_FREE_BLOB(outData); + break; + } + + return NO_ERROR; +} + +CertManagerService::CertManagerService(int saId, bool runOnCreate = true) + : SystemAbility(saId, runOnCreate), registerToService_(false), runningState_(STATE_NOT_START) +{ + CM_LOG_D("CertManagerService"); +} + +CertManagerService::~CertManagerService() +{ + CM_LOG_D("~CertManagerService"); +} + +sptr CertManagerService::GetInstance() +{ + std::lock_guard autoLock(instanceLock); + if (instance == nullptr) { + instance = new (std::nothrow) CertManagerService(SA_ID_KEYSTORE_SERVICE, true); + } + + return instance; +} + +bool CertManagerService::Init() +{ + CM_LOG_I("CertManagerService::Init Ready to init"); + + if (!registerToService_) { + sptr ptrInstance = CertManagerService::GetInstance(); + if (ptrInstance == nullptr) { + CM_LOG_E("CertManagerService::Init GetInstance Failed"); + return false; + } + if (!Publish(ptrInstance)) { + CM_LOG_E("CertManagerService::Init Publish Failed"); + return false; + } + CM_LOG_I("CertManagerService::Init Publish service success"); + registerToService_ = true; + } + + CM_LOG_I("CertManagerService::Init success."); + return true; +} + +int CertManagerService::OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + // this is the temporary version which comments the descriptor check + std::u16string descriptor = CertManagerService::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + + uint32_t outSize = (uint32_t)data.ReadUint32(); + struct CmBlob srcData = { 0, nullptr }; + srcData.size = (uint32_t)data.ReadUint32(); + if (IsInvalidLength(srcData.size)) { + CM_LOG_E("srcData size is invalid, size:%u", srcData.size); + return HW_SYSTEM_ERROR; + } + + srcData.data = (uint8_t *)CmMalloc(srcData.size); + if (srcData.data == nullptr) { + CM_LOG_E("Malloc srcData failed."); + return HW_SYSTEM_ERROR; + } + const uint8_t *pdata = data.ReadBuffer((size_t)srcData.size); + if (pdata == nullptr) { + CM_FREE_BLOB(srcData); + CM_LOG_I("CMR_ERROR_NULL_POINTER"); + return CMR_ERROR_NULL_POINTER; + } + if (memcpy_s(srcData.data, srcData.size, pdata, srcData.size) != EOK) { + CM_LOG_E("copy remote data failed!"); + CM_FREE_BLOB(srcData); + return CMR_ERROR_INVALID_OPERATION; + } + if (ProcessMessage(code, outSize, srcData, reply) != NO_ERROR) { + CM_LOG_E("process message!"); + CM_FREE_BLOB(srcData); + CM_LOG_E("copy remote data failed!"); + return CMR_ERROR_INVALID_OPERATION; + } + CM_LOG_I("OnRemoteRequest: %d", NO_ERROR); + CM_FREE_BLOB(srcData); + return NO_ERROR; +} + +void CertManagerService::OnStart() +{ + CM_LOG_I("CertManagerService OnStart"); + + if (runningState_ == STATE_RUNNING) { + CM_LOG_I("CertManagerService has already Started"); + return; + } + + if (!Init()) { + CM_LOG_E("Failed to init CertManagerService"); + return; + } + + if (!g_certManagerStatusInit) { + if (CertManagerInitialize() != CMR_OK) { + CM_LOG_E("Failed to init CertManagerService"); + return; + } + } + + runningState_ = STATE_RUNNING; + CM_LOG_I("CertManagerService start success."); +} + +void CertManagerService::OnStop() +{ + CM_LOG_I("CertManagerService Service OnStop"); + runningState_ = STATE_NOT_START; + registerToService_ = false; +} +} // namespace CertManager +} // namespace Security +} // namespace OHOS diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.h b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.h new file mode 100644 index 0000000..1aefab2 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_SA_H +#define CM_SA_H + +#include "iremote_broker.h" +#include "iremote_stub.h" +#include "nocopyable.h" +#include "system_ability.h" + +namespace OHOS { +namespace Security { +namespace CertManager { +enum ServiceRunningState { + STATE_NOT_START, + STATE_RUNNING +}; +enum ResponseCode { + HW_NO_ERROR = 0, + HW_SYSTEM_ERROR = -1, + HW_PERMISSION_DENIED = -2, +}; + +constexpr int SA_ID_KEYSTORE_SERVICE = 3512; + +class ICertManagerService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.security.CertManager.service"); +}; + +class CertManagerService : public SystemAbility, public IRemoteStub { + DECLEAR_SYSTEM_ABILITY(CertManagerService) + +public: + DISALLOW_COPY_AND_MOVE(CertManagerService); + CertManagerService(int saId, bool runOnCreate); + virtual ~CertManagerService(); + + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + + static sptr GetInstance(); + +protected: + void OnStart() override; + void OnStop() override; + +private: + CertManagerService(); + bool Init(); + + bool registerToService_; + ServiceRunningState runningState_; + static std::mutex instanceLock; + static sptr instance; +}; +} // namespace CertManager +} // namespace Security +} // namespace OHOS + +#endif // CM_SA_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/BUILD.gn b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/BUILD.gn new file mode 100644 index 0000000..958763f --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("cert_manager_sa_profile") { + part_name = "certificate_manager" + + sources = [ "cert_manager_service.xml" ] +} diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.xml b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.xml new file mode 100644 index 0000000..ad9a514 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.xml @@ -0,0 +1,24 @@ + + + + cert_manager_service + + 3512 + libcert_manager_service.z.so + true + false + 1 + + diff --git a/test/BUILD.gn b/test/BUILD.gn new file mode 100644 index 0000000..c432411 --- /dev/null +++ b/test/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") + +module_output_path = "cert_manager_standard/cert_manager_standard_test" + +ohos_unittest("cm_sdk_test") { + module_out_path = module_output_path + sources = [ + "unittest/src/cm_app_cert_test.cpp", + "unittest/src/cm_get_certinfo_test.cpp", + "unittest/src/cm_get_certlist_test.cpp", + "unittest/src/cm_set_status_test.cpp", + "unittest/src/cm_test_common.cpp", + ] + + include_dirs = [ + "//commonlibrary/c_utils/base/include", + "//third_party/bounds_checking_function/include", + "unittest/include", + ] + cflags_cc = [ + "-Wall", + "-Werror", + ] + cflags = cflags_cc + deps = [ + "//base/security/certificate_manager/frameworks/cert_manager_standard/main:cert_manager_standard_frameworks", + "//base/security/certificate_manager/interfaces/innerkits/cert_manager_standard/main:cert_manager_sdk", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/googletest:gtest_main", + "//third_party/openssl:libcrypto_static", + ] + external_deps = [ "c_utils:utils" ] + resource_config_file = "//base/security/certificate_manager/test/resource/certificate_manager/ohos_test.xml" +} + +group("unittest") { + testonly = true + deps = [ ":cm_sdk_test" ] +} diff --git a/test/resource/certificate_manager/ohos_test.xml b/test/resource/certificate_manager/ohos_test.xml new file mode 100644 index 0000000..ed66f76 --- /dev/null +++ b/test/resource/certificate_manager/ohos_test.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + diff --git a/test/unittest/include/cm_test_common.h b/test/unittest/include/cm_test_common.h new file mode 100644 index 0000000..0b1e55b --- /dev/null +++ b/test/unittest/include/cm_test_common.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_TEST_COMMON_H +#define CM_TEST_COMMON_H + +#include "cm_type.h" +#include "securec.h" +#include + +#define DELIMITER "$$$" +#define ENDOF "\n" + +namespace CertmanagerTest { +void FreeCMBlobData(struct CmBlob *blob); +uint32_t InitCertList(struct CertList **certlist); +void FreeCertList(struct CertList *certList); + +uint32_t InitUserContext(struct CmContext* userCtx, const uint32_t userid, const uint32_t uid, const char *pktname); + +bool CompareCert(const struct CertAbstract *firstCert, const struct CertAbstract *secondCert); + +bool CompareCertInfo(const struct CertInfo *firstCert, const struct CertInfo *secondCert); + +bool CompareCredential(const struct Credential *firstCredential, const struct Credential *secondCredential); + +bool CompareCredentialList(const struct CredentialAbstract *firstCert, const struct CredentialAbstract *secondCert); + +std::string DumpCertAbstractInfo(const struct CertAbstract *certAbstract); +std::string DumpCertInfo(const struct CertInfo* certInfo); +std::string DumpCertList(struct CertList *certList); +} +#endif /* CM_TEST_COMMON_H */ diff --git a/test/unittest/include/cm_test_log.h b/test/unittest/include/cm_test_log.h new file mode 100644 index 0000000..fc64904 --- /dev/null +++ b/test/unittest/include/cm_test_log.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_TEST_LOG_H +#define CM_TEST_LOG_H + +#define CM_TEST_ASSERT(test) \ + if (!(test)) { \ + printf("[ASSERT][%s](%d):fail\n", __func__, __LINE__); \ + } + +#define CM_TEST_LOG_E(fmt...) \ +do { \ + printf("[ERROR]\t[%s](%d): ", __func__, __LINE__); \ + printf(fmt); \ + printf("\r\n"); \ +} while (0) + +#define CM_TEST_LOG_I(fmt...) \ +do { \ + printf("[INFO]\t[%s](%d): ", __func__, __LINE__); \ + printf(fmt); \ + printf("\r\n"); \ +} while (0) + +#define CM_TEST_LOG_W(fmt...) \ +do { \ + printf("[WARN]\t[%s](%d): ", __func__, __LINE__); \ + printf(fmt); \ + printf("\r\n"); \ +} while (0) + +#define CM_TEST_LOG_D(fmt...) \ +do { \ + printf("[DEBUG]\t[%s](%d): ", __func__, __LINE__); \ + printf(fmt); \ + printf("\r\n"); \ +} while (0) + +#endif /* CM_TEST_LOG_H */ \ No newline at end of file diff --git a/test/unittest/src/cm_app_cert_test.cpp b/test/unittest/src/cm_app_cert_test.cpp new file mode 100644 index 0000000..b9fc8cd --- /dev/null +++ b/test/unittest/src/cm_app_cert_test.cpp @@ -0,0 +1,931 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cm_test_log.h" +#include "cm_test_common.h" +#include "cert_manager_api.h" +#include "cm_log.h" +#include "cm_mem.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { +struct CredentialResult { + struct Credential certificate; + bool bExpectResult; +}; + +struct CredentialResult g_credentialexpectResult[] = { + { + {1, "ak", "keyA", "oh:t=ak;o=keyA;u=0;a=0", 1, 1, { 0, NULL }}, true + } +}; + +struct CredentialAbstractResult { + struct CredentialAbstract credentialAbstract; + bool bExpectResult; +}; + +struct CredentialAbstractResult g_expectList[] = { + { + {"ak", "keyA", "oh:t=ak;o=keyA;u=100;a=500"}, false + }, + { + {"ak", "keyA", "oh:t=ak;o=keyA;u=0;a=0"}, true + }, + { + {"ak", "keyA", "oh:t=ak;o=keyA;u=200;a=0"}, false + } +}; + +static const uint8_t g_p12Certinfo[] = { + 0x30, 0x82, 0x0b, 0xc1, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0b, 0x87, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x0b, 0x78, 0x04, 0x82, 0x0b, 0x74, 0x30, 0x82, + 0x0b, 0x70, 0x30, 0x82, 0x06, 0x27, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + 0x06, 0xa0, 0x82, 0x06, 0x18, 0x30, 0x82, 0x06, 0x14, 0x02, 0x01, 0x00, 0x30, 0x82, 0x06, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x1a, 0x8f, 0xc1, + 0xd1, 0xda, 0x6c, 0xd1, 0xa9, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x05, 0xe0, 0xd0, 0x2f, 0x2d, + 0x52, 0x09, 0x86, 0x55, 0x53, 0xf0, 0x49, 0x8f, 0x00, 0xa1, 0x4d, 0x21, 0xc8, 0xb4, 0xad, 0x27, + 0x12, 0x44, 0xab, 0x4d, 0x10, 0x14, 0xe3, 0x3c, 0x9a, 0x05, 0x77, 0x51, 0x90, 0x4a, 0x3a, 0x8a, + 0x09, 0xa9, 0x4b, 0x36, 0x50, 0x60, 0x22, 0x4b, 0x77, 0x12, 0x5c, 0x2f, 0x60, 0xd3, 0xd9, 0x30, + 0x94, 0x4d, 0x9e, 0x81, 0xc3, 0xe9, 0x9d, 0xd9, 0x47, 0xb3, 0x54, 0xa2, 0x9a, 0x8f, 0xe7, 0x58, + 0x95, 0xd7, 0x48, 0x87, 0xc4, 0x40, 0xad, 0x9a, 0x42, 0x1d, 0x36, 0xb7, 0x48, 0xbc, 0x70, 0x8c, + 0x84, 0xcb, 0x3c, 0x02, 0x25, 0x9f, 0xfe, 0x2c, 0x4a, 0x76, 0xb1, 0x27, 0x94, 0x8f, 0xb0, 0x07, + 0xf0, 0xc0, 0x00, 0x3a, 0x69, 0x16, 0xe1, 0x63, 0x0c, 0xe5, 0x92, 0xc2, 0x7d, 0x99, 0xd9, 0x11, + 0x40, 0xd8, 0x64, 0xab, 0x13, 0xda, 0x73, 0x7b, 0x12, 0x53, 0xb1, 0x0b, 0x0c, 0x67, 0x81, 0xe1, + 0xf5, 0x59, 0x3a, 0xc7, 0xe0, 0xe9, 0xda, 0x12, 0xc7, 0x2b, 0xab, 0x3d, 0xbc, 0x10, 0x3d, 0x1a, + 0x88, 0xc7, 0x1d, 0x31, 0x5f, 0x39, 0x63, 0x51, 0x8b, 0x11, 0x99, 0x05, 0xf9, 0x40, 0x42, 0x27, + 0xad, 0x75, 0x6f, 0xe2, 0x2d, 0x66, 0x28, 0x97, 0x7c, 0x6f, 0xf4, 0xfc, 0x95, 0xaa, 0x67, 0x81, + 0xd8, 0x15, 0x3c, 0xf4, 0x7b, 0x97, 0x08, 0x7b, 0x1b, 0x8c, 0xd3, 0x45, 0x8b, 0x96, 0x54, 0x2c, + 0xb1, 0x00, 0x87, 0x59, 0x5c, 0x94, 0x78, 0x29, 0xaa, 0x7b, 0x9c, 0x5c, 0x61, 0xff, 0xcc, 0x32, + 0x14, 0x4e, 0xc3, 0x1b, 0x96, 0xad, 0x4c, 0xde, 0x49, 0xe4, 0x8e, 0x63, 0x52, 0x5d, 0x24, 0x9c, + 0xd3, 0x45, 0xed, 0x98, 0xe1, 0x6e, 0x15, 0xcd, 0x76, 0xa1, 0x0b, 0x67, 0x84, 0x79, 0xbc, 0xb0, + 0x9c, 0x3e, 0xff, 0x48, 0xf9, 0xc1, 0xab, 0x76, 0xc4, 0xe4, 0x61, 0x84, 0x7a, 0xb0, 0x88, 0xa2, + 0x14, 0x0a, 0xdc, 0x01, 0x47, 0xff, 0xf6, 0x27, 0x46, 0x1e, 0x37, 0xe5, 0x5e, 0x9a, 0x55, 0x49, + 0x67, 0x7b, 0x04, 0xba, 0xef, 0x89, 0x32, 0x8a, 0x2b, 0x72, 0x8c, 0xb9, 0xba, 0x19, 0xfa, 0x09, + 0x7f, 0x24, 0xea, 0xbd, 0xcc, 0xa5, 0x3c, 0xa8, 0xc6, 0x30, 0x0f, 0xcf, 0xd2, 0xf3, 0x10, 0xed, + 0x5c, 0x7d, 0xbb, 0x0a, 0x6a, 0x27, 0x60, 0x32, 0x9a, 0xa2, 0xfb, 0x2c, 0x38, 0xd2, 0x62, 0x92, + 0x5d, 0x77, 0xe8, 0xb8, 0x3a, 0x64, 0xfe, 0xb8, 0x2f, 0x69, 0xc4, 0xdd, 0x78, 0xdd, 0x92, 0xeb, + 0xc3, 0x08, 0xc2, 0x05, 0xef, 0xa6, 0x9c, 0x12, 0xd5, 0x48, 0x27, 0xfb, 0x19, 0x66, 0x66, 0x24, + 0x52, 0x47, 0xf1, 0x7c, 0xad, 0xc9, 0xb8, 0x1a, 0xd0, 0x2d, 0x40, 0xe9, 0x36, 0xce, 0x9e, 0x07, + 0x06, 0xd0, 0xe3, 0x5d, 0x98, 0xfb, 0x67, 0x1a, 0xd1, 0x62, 0x35, 0x03, 0xe8, 0x34, 0xf0, 0xfd, + 0x24, 0xe4, 0x06, 0x52, 0x03, 0xda, 0x8e, 0x68, 0x6d, 0x74, 0xfd, 0xda, 0x9b, 0xca, 0x8e, 0x52, + 0x71, 0x9c, 0x14, 0x05, 0x10, 0x61, 0x63, 0xa4, 0x53, 0x72, 0x4a, 0xda, 0x15, 0xf8, 0x0a, 0x56, + 0x89, 0x00, 0xdd, 0x87, 0xf5, 0xdd, 0x69, 0xd6, 0x6c, 0x89, 0x15, 0x1a, 0x1f, 0x48, 0xd6, 0x2c, + 0x1e, 0x4f, 0x23, 0x06, 0x6e, 0x34, 0x0d, 0x4e, 0xe3, 0x17, 0x40, 0x22, 0x7a, 0x68, 0x37, 0xad, + 0x05, 0xdb, 0x99, 0xde, 0x1a, 0x47, 0x2f, 0xb1, 0x9e, 0x7e, 0xdb, 0xad, 0x69, 0x06, 0x25, 0xd5, + 0xd9, 0x8e, 0xaf, 0xe2, 0xaa, 0x5a, 0x9a, 0x79, 0xd6, 0xeb, 0x02, 0x10, 0xf8, 0x72, 0x78, 0x4e, + 0x51, 0x2a, 0x53, 0x55, 0xb9, 0xd3, 0x7c, 0x31, 0x42, 0xff, 0x59, 0x39, 0x92, 0xd6, 0xec, 0x46, + 0x2d, 0x4f, 0xea, 0xf1, 0x0e, 0x83, 0x57, 0x55, 0x7b, 0xf1, 0x43, 0x47, 0x82, 0x10, 0x0d, 0x72, + 0xa2, 0x40, 0x2e, 0xf7, 0x2d, 0xcb, 0x80, 0x5b, 0x8a, 0x02, 0x5b, 0x71, 0xd9, 0xa5, 0x55, 0xea, + 0x41, 0x3f, 0x15, 0x9b, 0xee, 0x92, 0x4a, 0x3e, 0x87, 0x2e, 0xc3, 0xba, 0x71, 0x81, 0x57, 0xb9, + 0x7e, 0xb3, 0xd7, 0x52, 0x05, 0x91, 0x57, 0x87, 0x16, 0x48, 0x36, 0xdb, 0x4b, 0x45, 0x32, 0xaf, + 0x22, 0xc0, 0x3b, 0xc8, 0x90, 0xce, 0x53, 0xf3, 0x85, 0x64, 0xa3, 0x04, 0xe7, 0xfc, 0xa8, 0xc1, + 0x12, 0x77, 0x4a, 0x22, 0xd6, 0xfb, 0x01, 0x8f, 0x78, 0xd3, 0x2d, 0x33, 0x4c, 0xc8, 0x9d, 0x89, + 0xd7, 0x1f, 0xf2, 0x50, 0xf7, 0x94, 0x13, 0xe7, 0x3b, 0x4e, 0x36, 0x56, 0x93, 0x1a, 0xc7, 0x7e, + 0x4f, 0x92, 0xa2, 0xae, 0x4d, 0x9d, 0xbc, 0x03, 0xd4, 0x07, 0x76, 0x38, 0xc1, 0x59, 0x59, 0x3d, + 0xc9, 0xcf, 0xdd, 0x43, 0xcc, 0x82, 0xdb, 0xc1, 0x85, 0xbe, 0x3e, 0xab, 0x18, 0xd7, 0x7d, 0x17, + 0xc9, 0x9c, 0x9c, 0x81, 0x5b, 0xa8, 0x03, 0x04, 0x62, 0xc4, 0xd8, 0x78, 0x95, 0xd0, 0xfa, 0x8e, + 0x71, 0x43, 0x30, 0x3b, 0xdd, 0x64, 0x54, 0xb5, 0xd2, 0xa6, 0x0d, 0x8a, 0x73, 0x97, 0x46, 0x81, + 0xd6, 0x61, 0x61, 0x41, 0x07, 0xed, 0x23, 0x32, 0xd2, 0x20, 0x18, 0x27, 0x2b, 0x89, 0x8e, 0x3b, + 0xd7, 0x6e, 0xed, 0x50, 0x3f, 0xcb, 0x27, 0xab, 0xb5, 0x26, 0x9b, 0x9e, 0xe4, 0xe3, 0x2a, 0x88, + 0xf5, 0x4f, 0xf7, 0xb8, 0xc4, 0x11, 0xb0, 0x0c, 0xd7, 0x85, 0x3a, 0xc9, 0x65, 0x06, 0x43, 0xbf, + 0x66, 0x19, 0xf2, 0x2a, 0xed, 0x36, 0xf0, 0xf6, 0x39, 0x78, 0xd2, 0x4b, 0xe6, 0x20, 0x64, 0x66, + 0xe2, 0x87, 0x73, 0x5d, 0x09, 0x98, 0xe5, 0x06, 0xc1, 0xc7, 0xdf, 0x47, 0x12, 0x3a, 0xe0, 0xd6, + 0x7f, 0xb4, 0x29, 0x46, 0x3e, 0x49, 0x8f, 0x3d, 0xea, 0xd6, 0x0b, 0x36, 0xa3, 0xd2, 0xa3, 0x6b, + 0x9c, 0x0c, 0xe0, 0x47, 0x58, 0xbf, 0xfd, 0x42, 0xa2, 0x94, 0xe9, 0xd1, 0xfd, 0xc4, 0xcc, 0x68, + 0x32, 0x3a, 0x1e, 0xd2, 0x6f, 0x6b, 0x48, 0xe1, 0x48, 0xe0, 0x20, 0x23, 0xfc, 0x7c, 0xf9, 0x30, + 0xb1, 0xb0, 0x0e, 0x3c, 0x14, 0xf6, 0x73, 0x17, 0x1c, 0x71, 0x4c, 0xd9, 0x1d, 0x16, 0xcf, 0x31, + 0x6d, 0x79, 0xd6, 0x99, 0x66, 0xd5, 0x7f, 0xe7, 0xc2, 0x0d, 0xb8, 0xcb, 0xdb, 0x5e, 0x26, 0x95, + 0x35, 0xf1, 0x57, 0x5c, 0xec, 0xcd, 0xf0, 0xdb, 0xb4, 0x18, 0x7f, 0x04, 0x22, 0x50, 0xbe, 0xb3, + 0x04, 0x5c, 0xcd, 0x3a, 0x62, 0xe2, 0x3b, 0x5f, 0xa1, 0xa0, 0xd8, 0xd1, 0xf0, 0x45, 0x43, 0xf4, + 0xee, 0x27, 0x4f, 0x45, 0xb7, 0x06, 0x46, 0x53, 0x65, 0x49, 0xca, 0x4c, 0x12, 0xc9, 0x5b, 0x05, + 0xb6, 0xf6, 0x26, 0x5d, 0x90, 0x4a, 0x9b, 0x50, 0xaf, 0x65, 0x92, 0x13, 0xfc, 0xc2, 0x47, 0xff, + 0xe8, 0xb6, 0x4e, 0xd2, 0xa7, 0x48, 0x8c, 0xbe, 0x3a, 0x13, 0x2e, 0xe6, 0xb9, 0xb7, 0x29, 0x2d, + 0x30, 0xaa, 0x80, 0xcf, 0x74, 0x77, 0x14, 0xb2, 0x78, 0x52, 0x25, 0xf6, 0x97, 0x99, 0x40, 0x9a, + 0xea, 0xce, 0x92, 0x68, 0xb9, 0x5c, 0x9e, 0xf4, 0xbf, 0xd9, 0xd4, 0x43, 0x7d, 0xf6, 0x10, 0x05, + 0x9d, 0xa4, 0xe2, 0x8f, 0x8e, 0x2e, 0xce, 0x07, 0x57, 0x7b, 0xa2, 0xb2, 0x90, 0xd7, 0xd5, 0x66, + 0x12, 0xaa, 0x27, 0xce, 0xcb, 0x0a, 0xe9, 0x59, 0x47, 0xbd, 0x3e, 0x65, 0xd9, 0x83, 0xa2, 0x65, + 0x27, 0x06, 0x7f, 0x04, 0xc3, 0x35, 0xba, 0x55, 0x3d, 0x68, 0xc7, 0x0c, 0xa2, 0x50, 0xc3, 0xb1, + 0x66, 0x65, 0x7f, 0x74, 0xda, 0x05, 0x11, 0x89, 0xaf, 0xf2, 0x04, 0x8b, 0x60, 0x1d, 0xbf, 0x06, + 0x84, 0x7c, 0x1d, 0xcd, 0xcb, 0x5e, 0xf3, 0xfa, 0xfd, 0x1a, 0xb0, 0x1f, 0xc1, 0x6e, 0x91, 0x67, + 0xaa, 0x05, 0x9e, 0x2d, 0x6f, 0x4c, 0xdb, 0xab, 0x99, 0x83, 0x81, 0x80, 0x21, 0xbd, 0x17, 0x50, + 0x59, 0x3b, 0x16, 0x3a, 0x66, 0x2b, 0xd9, 0xab, 0x3f, 0x4a, 0xb1, 0xa3, 0x56, 0x9e, 0xbd, 0xd3, + 0x4a, 0x85, 0x63, 0x58, 0xa5, 0xbb, 0xdf, 0x64, 0x79, 0x43, 0x8d, 0x78, 0xa3, 0x88, 0x8e, 0x0d, + 0xbe, 0x1a, 0x14, 0xc2, 0xcf, 0x48, 0x0c, 0x55, 0xa8, 0xd6, 0xea, 0xdb, 0x5d, 0x50, 0x90, 0x84, + 0xfd, 0xe9, 0xd1, 0x90, 0xfe, 0xeb, 0xd8, 0xd1, 0x9c, 0xbe, 0xd5, 0x92, 0xd8, 0x71, 0x58, 0x58, + 0xc1, 0xbf, 0x4c, 0xe2, 0xa9, 0xd5, 0xc1, 0xce, 0x4a, 0xec, 0xde, 0xb3, 0x0a, 0xa2, 0xc0, 0x00, + 0xa2, 0xfa, 0x6a, 0x83, 0x9b, 0xae, 0x6e, 0x1f, 0x35, 0x8b, 0xcf, 0xcc, 0x3f, 0xdc, 0xac, 0x68, + 0x2a, 0x50, 0x65, 0x56, 0xb8, 0x2c, 0x92, 0xff, 0xc2, 0x1a, 0xd4, 0x4e, 0x12, 0x3d, 0x40, 0x67, + 0x62, 0x75, 0xcd, 0x4f, 0x1b, 0x45, 0xff, 0xbf, 0x46, 0xf8, 0xa2, 0xd1, 0xd2, 0xc9, 0xe6, 0xb6, + 0x26, 0x55, 0xd9, 0x55, 0xc9, 0x7b, 0xe4, 0xa9, 0x69, 0x43, 0x13, 0xdb, 0x7d, 0x8f, 0xaa, 0x02, + 0x15, 0x24, 0x6d, 0x80, 0x1f, 0x42, 0x7b, 0x32, 0x76, 0xbd, 0x0c, 0xcd, 0x3c, 0x5e, 0x55, 0x4f, + 0x49, 0xf1, 0x28, 0x6d, 0xc1, 0x36, 0x39, 0x93, 0x57, 0xf5, 0x83, 0xc2, 0x9e, 0xbb, 0x7b, 0x05, + 0xbe, 0x89, 0xab, 0x80, 0x93, 0xf0, 0x9c, 0xc3, 0x97, 0xcf, 0x03, 0x25, 0xb5, 0x2e, 0x6b, 0x18, + 0xe8, 0x72, 0x46, 0x0c, 0x8f, 0xc0, 0x27, 0x52, 0x31, 0x2c, 0x20, 0x96, 0x30, 0x29, 0x66, 0xa5, + 0x70, 0x9f, 0xbf, 0xfa, 0xb3, 0x4c, 0xfd, 0xd1, 0x73, 0xf4, 0x3c, 0x29, 0x74, 0xac, 0xa9, 0xc0, + 0xb4, 0x16, 0x72, 0x4a, 0x7f, 0x07, 0xe3, 0xfe, 0xd5, 0xa0, 0x3f, 0x47, 0x86, 0x59, 0x10, 0xbc, + 0xff, 0x0d, 0x0e, 0xdc, 0xc9, 0x6d, 0x8f, 0xb0, 0xc7, 0x78, 0xd7, 0xa2, 0x79, 0xdd, 0x6b, 0x10, + 0x8b, 0x9f, 0x3c, 0xba, 0x14, 0xe5, 0x3a, 0xf1, 0x1f, 0xb5, 0x84, 0xc1, 0x6a, 0xd5, 0xad, 0x59, + 0xe8, 0x15, 0x22, 0x33, 0xb6, 0x79, 0x6d, 0xe1, 0x59, 0xb9, 0xa7, 0x0f, 0x4c, 0xcc, 0x5f, 0x2a, + 0xbd, 0xab, 0x0e, 0x45, 0x47, 0x0c, 0x8d, 0x8a, 0xe3, 0xfb, 0x61, 0x64, 0x51, 0x36, 0x87, 0x04, + 0xc7, 0xd8, 0x16, 0x46, 0x9f, 0xa4, 0x35, 0xd0, 0xa6, 0x1a, 0x85, 0xf0, 0x91, 0x34, 0xfe, 0xe7, + 0x0b, 0xd2, 0xd7, 0x91, 0x46, 0xd0, 0xfe, 0xa9, 0xfb, 0xd7, 0xf7, 0x4d, 0x81, 0x95, 0x1b, 0x96, + 0x51, 0x21, 0xa5, 0xdc, 0xee, 0x25, 0xbe, 0xb2, 0x7d, 0x3f, 0x7b, 0x35, 0x05, 0x92, 0x30, 0x5d, + 0x2d, 0x57, 0x53, 0x45, 0xa7, 0x51, 0xab, 0x09, 0x71, 0xe0, 0x01, 0x96, 0x1c, 0x9b, 0xa5, 0x2d, + 0xcf, 0xff, 0x0e, 0x80, 0xf5, 0xa4, 0x3c, 0x52, 0xa6, 0xf3, 0x16, 0x96, 0xa6, 0x64, 0xac, 0x7e, + 0xaf, 0xb7, 0xc6, 0x34, 0xfd, 0xf7, 0x0a, 0x10, 0xe6, 0x2b, 0xda, 0x10, 0xdd, 0xb2, 0x44, 0x8d, + 0x95, 0x71, 0xbf, 0xb1, 0xf3, 0x91, 0xac, 0xc6, 0x93, 0xe1, 0x91, 0x62, 0x05, 0x90, 0x38, 0x33, + 0xcf, 0x36, 0xff, 0xa5, 0x82, 0x4e, 0x14, 0x78, 0x33, 0x40, 0x18, 0x22, 0xd6, 0x60, 0x6b, 0x0b, + 0x97, 0x4f, 0x2d, 0xd0, 0x36, 0x82, 0xb3, 0x1a, 0xe8, 0xd7, 0x93, 0xff, 0x19, 0xd1, 0x74, 0xd2, + 0x29, 0xe1, 0x97, 0x60, 0x09, 0x48, 0xef, 0xc9, 0x61, 0xae, 0x3b, 0x4f, 0xd4, 0x30, 0x82, 0x05, + 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x32, + 0x04, 0x82, 0x05, 0x2e, 0x30, 0x82, 0x05, 0x2a, 0x30, 0x82, 0x05, 0x26, 0x06, 0x0b, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, + 0xea, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, + 0x0e, 0x04, 0x08, 0x2b, 0xef, 0x2d, 0x9b, 0x33, 0xf6, 0x82, 0x62, 0x02, 0x02, 0x08, 0x00, 0x04, + 0x82, 0x04, 0xc8, 0x59, 0x60, 0xea, 0x6e, 0x23, 0x9e, 0x82, 0x1c, 0x0a, 0x8e, 0xbd, 0x09, 0x94, + 0x98, 0x5e, 0x1a, 0x1b, 0x4a, 0xfe, 0x86, 0x2d, 0xf4, 0x54, 0xaa, 0x17, 0xba, 0xf1, 0xf1, 0x58, + 0x12, 0xa2, 0x81, 0x1c, 0x29, 0xe7, 0x94, 0x78, 0xbc, 0x68, 0x07, 0x8f, 0xdb, 0x3f, 0xab, 0xa7, + 0xa7, 0x73, 0x6d, 0xea, 0x25, 0x6f, 0x97, 0xc8, 0xba, 0x73, 0xcc, 0x1e, 0xa0, 0x73, 0x18, 0x14, + 0xe8, 0xae, 0xe0, 0x5d, 0x3c, 0x9b, 0x9e, 0xad, 0xf4, 0x46, 0xeb, 0xa4, 0x73, 0xe2, 0xb5, 0x16, + 0x8f, 0x70, 0x35, 0xe7, 0x84, 0x2d, 0x02, 0xc7, 0xc3, 0x9d, 0x1e, 0x91, 0xba, 0x47, 0xfe, 0xf2, + 0x43, 0xc2, 0x9e, 0xeb, 0x68, 0x87, 0xeb, 0x3b, 0x9a, 0x59, 0x87, 0xf6, 0x2a, 0x1e, 0xf0, 0x07, + 0x13, 0xd0, 0xc0, 0x0f, 0xe7, 0x41, 0xb7, 0x5e, 0xb2, 0x2d, 0x12, 0xd2, 0x99, 0x6f, 0x90, 0x29, + 0xf2, 0x96, 0x9e, 0xfc, 0x00, 0x75, 0xab, 0x2f, 0x87, 0x49, 0x0e, 0xe6, 0xaf, 0x46, 0xe2, 0x69, + 0x88, 0x8f, 0xd3, 0x45, 0xda, 0xcc, 0x4c, 0xf6, 0xfd, 0xaa, 0xda, 0x83, 0x77, 0xee, 0xf9, 0x4a, + 0xa9, 0x31, 0x50, 0x8d, 0x8d, 0x86, 0x89, 0xb2, 0xf3, 0xcf, 0x9b, 0xba, 0xef, 0xa2, 0x09, 0x7c, + 0x72, 0x49, 0xf2, 0xf3, 0x86, 0xa2, 0x78, 0x3e, 0xbf, 0x61, 0x2a, 0x18, 0x96, 0xa2, 0x17, 0xe2, + 0x63, 0x75, 0xfd, 0xf0, 0x82, 0xd6, 0x36, 0x5b, 0x44, 0xf3, 0x9a, 0x96, 0x29, 0x1c, 0x50, 0x91, + 0x20, 0xbb, 0x7b, 0x2d, 0x96, 0xe1, 0x0e, 0xc6, 0xce, 0x01, 0x40, 0xe8, 0x22, 0xc5, 0xac, 0x3f, + 0xfa, 0xd0, 0xac, 0xc9, 0x4e, 0x1e, 0x20, 0x8a, 0xc6, 0x40, 0xed, 0x6b, 0xb6, 0xc4, 0xc1, 0x43, + 0xec, 0x3c, 0xfe, 0xb7, 0x50, 0x19, 0x09, 0x1b, 0x21, 0x83, 0x63, 0x93, 0x18, 0xbd, 0x73, 0x42, + 0x73, 0x25, 0x4f, 0xda, 0xdb, 0x4f, 0xf9, 0xba, 0x11, 0xf3, 0x91, 0xc0, 0x5b, 0x9d, 0x93, 0xfd, + 0x94, 0x89, 0xb6, 0xea, 0x90, 0x15, 0xe5, 0xf0, 0xe8, 0xd8, 0x31, 0x2c, 0xe0, 0x92, 0x6a, 0xb7, + 0xe3, 0x43, 0x51, 0xfc, 0xa0, 0x20, 0x2b, 0x5c, 0xbb, 0xf0, 0x22, 0x2b, 0xa5, 0x00, 0x40, 0xe9, + 0x0d, 0x64, 0xf0, 0xe7, 0xca, 0x29, 0x85, 0xfc, 0x89, 0x38, 0x03, 0xaa, 0x0c, 0xad, 0x71, 0xe6, + 0xc9, 0xde, 0x42, 0x5e, 0x97, 0x74, 0x35, 0x6a, 0x88, 0x94, 0x99, 0xd5, 0xbd, 0x91, 0xa5, 0x92, + 0x35, 0x1d, 0xf4, 0x11, 0xf7, 0x7e, 0x47, 0x96, 0xe4, 0x2f, 0x85, 0x75, 0x3a, 0x16, 0x2a, 0x45, + 0x96, 0xd7, 0xb1, 0x8f, 0xd5, 0x64, 0x87, 0x5d, 0xd0, 0x44, 0x1e, 0xd6, 0x67, 0x0c, 0xc6, 0xdb, + 0xb4, 0x0a, 0xe4, 0x18, 0x0c, 0x12, 0x73, 0xb5, 0x4f, 0x44, 0xc8, 0xd6, 0x97, 0x8b, 0x99, 0x19, + 0x66, 0x55, 0x08, 0xcb, 0xa0, 0xca, 0x9e, 0x09, 0x0f, 0xe1, 0x8b, 0xd7, 0xa1, 0x12, 0x54, 0x46, + 0x2d, 0x09, 0x44, 0x27, 0x30, 0xcd, 0x02, 0xcc, 0x88, 0x8f, 0x69, 0x22, 0xed, 0x31, 0x25, 0x14, + 0x5f, 0x37, 0x5f, 0xce, 0x91, 0x95, 0x30, 0x07, 0x32, 0xaa, 0x2e, 0x55, 0x9a, 0xc4, 0x33, 0xab, + 0xd0, 0x55, 0x3d, 0x04, 0xe3, 0x84, 0x0c, 0xf1, 0xe4, 0xe6, 0x52, 0x39, 0x0e, 0x22, 0x8b, 0x4f, + 0xf3, 0x5c, 0xc2, 0xc7, 0xc3, 0xd4, 0xc1, 0x5c, 0x45, 0x83, 0xee, 0x37, 0x3e, 0xa7, 0xd9, 0xa2, + 0x9c, 0x5b, 0x4b, 0x6b, 0xdf, 0xc5, 0x5c, 0x50, 0x12, 0x1d, 0x6c, 0x73, 0xea, 0xf4, 0xdc, 0x70, + 0x3f, 0x11, 0x70, 0x0e, 0x3d, 0x4d, 0x8c, 0x69, 0xaf, 0x8b, 0x6a, 0x20, 0x75, 0x55, 0xeb, 0x6e, + 0x27, 0x21, 0x5d, 0x9c, 0xdb, 0xbb, 0xf7, 0xf9, 0x3e, 0x81, 0x2f, 0x4f, 0x96, 0xcb, 0x2e, 0xb1, + 0xc3, 0x01, 0x1f, 0xa7, 0x87, 0x43, 0xc8, 0x89, 0xec, 0x5b, 0x41, 0x42, 0x2e, 0x19, 0x0b, 0xdf, + 0x3a, 0x90, 0xaa, 0x98, 0x2f, 0xe9, 0xad, 0x02, 0xf9, 0x96, 0x40, 0x51, 0xdd, 0x4b, 0x8b, 0xe5, + 0xca, 0x84, 0xe2, 0x93, 0xdd, 0xad, 0x43, 0x37, 0x62, 0x14, 0xa1, 0x07, 0x17, 0x5d, 0x71, 0x73, + 0xc0, 0xd8, 0x02, 0x0f, 0x44, 0xcf, 0x5e, 0x6f, 0x55, 0x44, 0x70, 0xa6, 0x22, 0xe7, 0x2d, 0xc3, + 0x2c, 0x44, 0xc3, 0x0e, 0xf1, 0xda, 0x02, 0x57, 0x40, 0x24, 0x36, 0xc8, 0xf9, 0x4f, 0x17, 0x0b, + 0x9b, 0x2a, 0xa8, 0x0d, 0x84, 0xf1, 0x49, 0x3b, 0x6d, 0x23, 0xb9, 0x97, 0x47, 0x2a, 0x0b, 0xc3, + 0x80, 0xe5, 0xdf, 0x4e, 0x1f, 0x94, 0xd1, 0x0e, 0x69, 0xb5, 0xb0, 0xf8, 0xa5, 0x7d, 0x9c, 0x9f, + 0x68, 0x7d, 0x04, 0x18, 0x42, 0x32, 0x72, 0xdc, 0xab, 0xdc, 0xe6, 0xba, 0x09, 0xe8, 0xd4, 0x27, + 0x53, 0x95, 0x9c, 0x39, 0xd5, 0x70, 0x0d, 0x1e, 0xb5, 0xb7, 0x2b, 0x0a, 0x79, 0xc7, 0xd6, 0x0b, + 0xee, 0xea, 0xf8, 0x6f, 0x6a, 0xb1, 0xfc, 0x90, 0x35, 0xce, 0x46, 0x99, 0xfa, 0x88, 0x01, 0x48, + 0xd5, 0x70, 0x26, 0x4c, 0x08, 0x2a, 0x13, 0x60, 0xb0, 0x96, 0x91, 0xa7, 0xc5, 0x05, 0xd3, 0xcd, + 0x5e, 0xcb, 0x9f, 0xa4, 0x5c, 0x29, 0x98, 0xbc, 0xd6, 0x2e, 0x6a, 0xeb, 0xc8, 0xfa, 0x58, 0x45, + 0x79, 0x15, 0x30, 0x98, 0x59, 0x65, 0x30, 0x7f, 0x14, 0x14, 0xbd, 0x27, 0xd1, 0x0c, 0xbc, 0x52, + 0xda, 0x42, 0x09, 0xc5, 0xc4, 0x58, 0xdb, 0x04, 0x22, 0xbd, 0x7a, 0xac, 0x55, 0x94, 0x52, 0x46, + 0x51, 0x32, 0x84, 0x9a, 0xeb, 0xe1, 0xd3, 0x9e, 0x9d, 0x48, 0x3d, 0xd2, 0x21, 0xfa, 0x7d, 0x10, + 0x04, 0x50, 0x06, 0xf0, 0x84, 0xcb, 0x9f, 0x39, 0xbe, 0xec, 0x03, 0x7d, 0x86, 0x85, 0xf5, 0x06, + 0x8c, 0x51, 0x74, 0x13, 0xf1, 0xfa, 0x50, 0xe1, 0x69, 0x23, 0xf6, 0x3e, 0x13, 0xd2, 0xc7, 0x52, + 0x80, 0xe6, 0x41, 0x86, 0x1d, 0x8a, 0xda, 0x3c, 0x3f, 0x90, 0x5c, 0x82, 0x85, 0x8d, 0x8c, 0x64, + 0x2a, 0xeb, 0xb9, 0x23, 0x6c, 0x0a, 0xd3, 0x2b, 0x35, 0xbe, 0xb0, 0x66, 0xd8, 0x1b, 0x45, 0xa1, + 0xb6, 0x67, 0x2d, 0xa6, 0xd6, 0xcd, 0x69, 0x88, 0x57, 0x70, 0xe6, 0xaa, 0x02, 0x3b, 0x84, 0x6a, + 0xb6, 0xa5, 0x91, 0x4a, 0x69, 0x20, 0x01, 0xd7, 0x5d, 0xf2, 0x7b, 0x3e, 0xf2, 0xbb, 0xe4, 0x9e, + 0x3a, 0xc0, 0xaa, 0x72, 0x2d, 0xa6, 0x47, 0x09, 0x2e, 0x0f, 0xf6, 0x9b, 0x8e, 0x7c, 0x41, 0xa6, + 0xc6, 0x10, 0x29, 0xcc, 0x4e, 0xcf, 0x01, 0xd5, 0x93, 0x75, 0x51, 0xb8, 0xd4, 0xec, 0xee, 0x6a, + 0x2f, 0x8b, 0x45, 0x65, 0xe8, 0xf5, 0x3e, 0xbc, 0xf4, 0x59, 0xec, 0x3e, 0x20, 0x18, 0x85, 0x31, + 0x8e, 0x25, 0x59, 0x16, 0x0f, 0xf0, 0x6e, 0xb1, 0x1e, 0x58, 0x83, 0x33, 0x10, 0x0d, 0x52, 0xc3, + 0x8f, 0x7e, 0x09, 0x27, 0xba, 0xd7, 0xf5, 0x8d, 0x79, 0xcf, 0x60, 0x52, 0xa2, 0x03, 0x46, 0xf5, + 0xf8, 0x9d, 0x6d, 0x5f, 0x23, 0x68, 0x7a, 0xb0, 0x2a, 0x55, 0x44, 0xd9, 0x58, 0xfd, 0xd1, 0x2d, + 0xcc, 0x75, 0xa2, 0x90, 0x8e, 0x7f, 0x91, 0x56, 0xa5, 0x3f, 0x62, 0x1a, 0x67, 0xd5, 0xb2, 0xc8, + 0x06, 0x66, 0xa7, 0xf7, 0xeb, 0x0c, 0xe0, 0xb0, 0xb5, 0x28, 0x8d, 0xda, 0x75, 0xd5, 0x03, 0x3e, + 0xc4, 0x4e, 0xd7, 0x6c, 0x7b, 0x28, 0x92, 0x7c, 0xeb, 0xb8, 0x67, 0x1a, 0x0c, 0xc4, 0xed, 0x5f, + 0x50, 0x5a, 0xb6, 0x52, 0xba, 0x9b, 0xe5, 0xcc, 0xb6, 0x78, 0x76, 0x9a, 0xcd, 0x2d, 0x43, 0x56, + 0xa4, 0xe7, 0x97, 0x6c, 0xdc, 0xb2, 0x2c, 0xb4, 0x2c, 0x30, 0x23, 0x1c, 0x51, 0x96, 0xca, 0x0d, + 0xbd, 0xf9, 0x2d, 0x97, 0x3c, 0x84, 0x45, 0x16, 0xcb, 0x25, 0xe2, 0x73, 0x9c, 0x4b, 0xbe, 0x36, + 0x12, 0xb3, 0xd0, 0x76, 0x9e, 0x5c, 0x40, 0xb9, 0x6f, 0x4e, 0x55, 0x1c, 0x87, 0xc4, 0x8d, 0x5a, + 0xda, 0x1b, 0xec, 0xd5, 0x03, 0x7f, 0x58, 0x78, 0xcc, 0xfa, 0xae, 0x0a, 0xb4, 0x3c, 0x50, 0xcd, + 0xa8, 0x7e, 0xfc, 0x17, 0x31, 0xd8, 0xe9, 0x86, 0x60, 0xa9, 0x0b, 0x11, 0x6b, 0xda, 0xfb, 0x6e, + 0x44, 0x62, 0xd8, 0x96, 0x4f, 0x61, 0xdb, 0x62, 0x0d, 0x03, 0xa6, 0x2f, 0x11, 0x91, 0x95, 0x38, + 0xf3, 0x49, 0x94, 0xf0, 0x93, 0x0e, 0xaf, 0xff, 0x28, 0xe6, 0x24, 0xbc, 0xc4, 0x1d, 0x0d, 0xfb, + 0x00, 0xc4, 0x5b, 0xef, 0xda, 0x55, 0x76, 0xbf, 0x52, 0xf9, 0x00, 0xab, 0xd5, 0xef, 0xa5, 0x31, + 0x37, 0x60, 0xcf, 0xad, 0x79, 0x45, 0xef, 0x0f, 0x97, 0xc8, 0x0e, 0x88, 0x61, 0x56, 0x58, 0x3b, + 0xd5, 0x1c, 0xe8, 0xb0, 0x93, 0x02, 0xdf, 0xa5, 0x6c, 0xaf, 0x4b, 0x5e, 0x66, 0x7d, 0xfe, 0xaa, + 0xaf, 0xa0, 0xd4, 0x35, 0xcd, 0x81, 0xa0, 0x71, 0xe4, 0x45, 0x12, 0x24, 0x1e, 0x0d, 0x06, 0x96, + 0x1e, 0x23, 0xa3, 0x39, 0xd8, 0xcc, 0x72, 0xd7, 0xac, 0x72, 0x5c, 0x8c, 0xdf, 0x6c, 0xb4, 0xc4, + 0x2b, 0xbc, 0x1c, 0xeb, 0xbe, 0x1b, 0xbb, 0xf3, 0xbc, 0x45, 0x34, 0xe9, 0x5a, 0x7f, 0x11, 0x61, + 0xd7, 0x61, 0x15, 0x18, 0x0e, 0xf8, 0x8b, 0x23, 0x97, 0xa7, 0x46, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x8b, 0x4e, + 0x13, 0x2a, 0xf1, 0x4d, 0xa3, 0xe9, 0x31, 0x5c, 0x6d, 0xce, 0x5a, 0x09, 0x93, 0x0a, 0xf4, 0x12, + 0x19, 0x7b, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14, 0x00, 0x3b, 0x70, 0x95, 0x68, 0xd3, 0xd8, 0x4f, 0x71, 0xd0, 0x7d, 0x41, 0x49, + 0x48, 0xef, 0x88, 0x6d, 0xe0, 0x9d, 0x53, 0x04, 0x08, 0x0e, 0x46, 0xa3, 0xb5, 0x73, 0x88, 0x7c, + 0x22, 0x02, 0x02, 0x08, 0x00 +}; + +static const uint8_t g_p12AbnormalCertinfo[] = { + 0x30, 0x82, 0x0b, 0xc1, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0b, 0x87, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x0b, 0x78, 0x04, 0x82, 0x0b, 0x74, 0x30, 0x82, + 0x0b, 0x70, 0x30, 0x82, 0x06, 0x27, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + 0x06, 0xa0, 0x82, 0x06, 0x18, 0x30, 0x82, 0x06, 0x14, 0x02, 0x01, 0x00, 0x30, 0x82, 0x06, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x1a, 0x8f, 0xc1, + 0xd1, 0xda, 0x6c, 0xd1, 0xa9, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x05, 0xe0, 0xd0, 0x2f, 0x2d, + 0x52, 0x09, 0x86, 0x55, 0x53, 0xf0, 0x49, 0x8f, 0x00, 0xa1, 0x4d, 0x21, 0xc8, 0xb4, 0xad, 0x27, + 0x12, 0x44, 0xab, 0x4d, 0x10, 0x14, 0xe3, 0x3c, 0x9a, 0x05, 0x77, 0x51, 0x90, 0x4a, 0x3a, 0x8a, + 0x09, 0xa9, 0x4b, 0x36, 0x50, 0x60, 0x22, 0x4b, 0x77, 0x12, 0x5c, 0x2f, 0x60, 0xd3, 0xd9, 0x30, + 0x94, 0x4d, 0x9e, 0x81, 0xc3, 0xe9, 0x9d, 0xd9, 0x47, 0xb3, 0x54, 0xa2, 0x9a, 0x8f, 0xe7, 0x58, + 0x95, 0xd7, 0x48, 0x87, 0xc4, 0x40, 0xad, 0x9a, 0x42, 0x1d, 0x36, 0xb7, 0x48, 0xbc, 0x70, 0x8c, + 0x84, 0xcb, 0x3c, 0x02, 0x25, 0x9f, 0xfe, 0x2c, 0x4a, 0x76, 0xb1, 0x27, 0x94, 0x8f, 0xb0, 0x07, + 0xf0, 0xc0, 0x00, 0x3a, 0x69, 0x16, 0xe1, 0x63, 0x0c, 0xe5, 0x92, 0xc2, 0x7d, 0x99, 0xd9, 0x11, + 0x40, 0xd8, 0x64, 0xab, 0x13, 0xda, 0x73, 0x7b, 0x12, 0x53, 0xb1, 0x0b, 0x0c, 0x67, 0x81, 0xe1, + 0xf5, 0x59, 0x3a, 0xc7, 0xe0, 0xe9, 0xda, 0x12, 0xc7, 0x2b, 0xab, 0x3d, 0xbc, 0x10, 0x3d, 0x1a, + 0x88, 0xc7, 0x1d, 0x31, 0x5f, 0x39, 0x63, 0x51, 0x8b, 0x11, 0x99, 0x05, 0xf9, 0x40, 0x42, 0x27, + 0xad, 0x75, 0x6f, 0xe2, 0x2d, 0x66, 0x28, 0x97, 0x7c, 0x6f, 0xf4, 0xfc, 0x95, 0xaa, 0x67, 0x81, + 0xd8, 0x15, 0x3c, 0xf4, 0x7b, 0x97, 0x08, 0x7b, 0x1b, 0x8c, 0xd3, 0x45, 0x8b, 0x96, 0x54, 0x2c, + 0xb1, 0x00, 0x87, 0x59, 0x5c, 0x94, 0x78, 0x29, 0xaa, 0x7b, 0x9c, 0x5c, 0x61, 0xff, 0xcc, 0x32, + 0x14, 0x4e, 0xc3, 0x1b, 0x96 +}; + +static const uint8_t g_p12EccNormalCertinfo[] = { + 0x30, 0x82, 0x04, 0x6a, 0x02, 0x01, 0x03, 0x30, 0x82, 0x04, 0x30, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x04, 0x21, 0x04, 0x82, 0x04, 0x1d, 0x30, 0x82, + 0x04, 0x19, 0x30, 0x82, 0x03, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + 0x06, 0xa0, 0x82, 0x03, 0x00, 0x30, 0x82, 0x02, 0xfc, 0x02, 0x01, 0x00, 0x30, 0x82, 0x02, 0xf5, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x1a, 0x75, 0xee, + 0xca, 0xf7, 0x3d, 0x49, 0x03, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x02, 0xc8, 0x26, 0x53, 0x8f, + 0xb3, 0xb4, 0x94, 0x16, 0x73, 0x7a, 0xd1, 0xe7, 0x07, 0x16, 0x11, 0xdd, 0xd0, 0x9c, 0x04, 0x0f, + 0x4b, 0x3c, 0x3c, 0xbd, 0xa9, 0x35, 0xf7, 0xdf, 0x33, 0xc2, 0xfe, 0x49, 0xe9, 0x66, 0xe0, 0x51, + 0x31, 0xe2, 0xd1, 0xfa, 0x06, 0x98, 0x63, 0x65, 0x1c, 0xdf, 0x38, 0xa7, 0x82, 0x27, 0xe2, 0x19, + 0x8f, 0x55, 0xe0, 0x24, 0x34, 0x82, 0x5b, 0xd8, 0x36, 0xd8, 0x56, 0x09, 0x93, 0xb3, 0x1c, 0x6e, + 0xd9, 0x5e, 0x60, 0x28, 0xf3, 0x42, 0xe7, 0x52, 0x41, 0xd0, 0x95, 0x93, 0x62, 0xc2, 0xf9, 0xe6, + 0x26, 0xba, 0x07, 0x04, 0x24, 0xdf, 0xa9, 0x84, 0x98, 0xa3, 0x20, 0x10, 0xe8, 0x4c, 0x15, 0xfb, + 0xaa, 0x09, 0x81, 0xf5, 0xb7, 0x31, 0x1b, 0x22, 0xff, 0xca, 0xc3, 0xa6, 0x61, 0x98, 0x03, 0xb1, + 0x5d, 0xcc, 0x4d, 0x2e, 0xd5, 0xc6, 0x9e, 0x15, 0xb1, 0xb7, 0x67, 0xdf, 0xba, 0xb3, 0x80, 0x8e, + 0x0f, 0xc8, 0xb5, 0x04, 0xa1, 0x93, 0xfc, 0x83, 0x30, 0x15, 0x84, 0x52, 0xc7, 0xaa, 0x1f, 0x16, + 0x3d, 0xf3, 0xd8, 0x49, 0xe0, 0xfd, 0x7f, 0xe6, 0x4d, 0xfb, 0x95, 0x48, 0xe5, 0x3f, 0x88, 0xcf, + 0x8b, 0x9e, 0xa7, 0x84, 0x00, 0x5b, 0x06, 0x54, 0xcd, 0x0e, 0xeb, 0x5e, 0x3d, 0xc2, 0x50, 0x09, + 0x9a, 0x01, 0xb6, 0xb1, 0xd7, 0x5b, 0xef, 0x5a, 0x38, 0x51, 0x85, 0x37, 0x47, 0x3b, 0xc5, 0xfc, + 0x97, 0x65, 0xbc, 0xe7, 0x52, 0x9a, 0xfd, 0x86, 0x9b, 0x6e, 0x69, 0x72, 0x7f, 0x0e, 0x35, 0x4a, + 0xac, 0x2c, 0xba, 0xb6, 0xd0, 0x94, 0x96, 0x8a, 0x71, 0x2e, 0xc1, 0xe5, 0xac, 0x9e, 0xef, 0x89, + 0x91, 0xbf, 0x0f, 0x78, 0x2c, 0x61, 0x1d, 0x96, 0x95, 0x66, 0x92, 0x0a, 0xd0, 0x8d, 0x30, 0xe4, + 0x5b, 0x54, 0x7a, 0x1c, 0x3a, 0xaf, 0x2e, 0x20, 0xd8, 0x3f, 0xba, 0x57, 0xec, 0xa3, 0x5f, 0x40, + 0xd3, 0xa8, 0x2f, 0x15, 0x7d, 0xfa, 0x8f, 0x47, 0x3a, 0x1f, 0x9b, 0xd9, 0xe8, 0x59, 0xd3, 0x6f, + 0x12, 0x97, 0x63, 0xa4, 0xbf, 0x52, 0xcb, 0x11, 0x0e, 0xe8, 0xa0, 0x60, 0xe2, 0x6e, 0x83, 0xb0, + 0x55, 0x8e, 0xce, 0x90, 0xa9, 0x9a, 0xe8, 0xb3, 0x2d, 0xcb, 0xf1, 0xb4, 0x03, 0x9b, 0x17, 0xcb, + 0xf1, 0x8e, 0x1b, 0xa0, 0xc0, 0xc9, 0xfc, 0xab, 0xb6, 0x32, 0xb1, 0x5e, 0xd0, 0x7a, 0x14, 0x2f, + 0xe4, 0xfd, 0x80, 0xf1, 0xd6, 0x1f, 0xb4, 0x7c, 0xe6, 0x33, 0x91, 0xb5, 0x05, 0x7d, 0x95, 0x3b, + 0x07, 0x2f, 0x7b, 0x3d, 0x55, 0xc4, 0x55, 0x5c, 0x26, 0x87, 0x8f, 0xad, 0x51, 0xa9, 0x62, 0xf7, + 0x14, 0x18, 0x25, 0xd1, 0xdf, 0x53, 0x68, 0xd6, 0xed, 0x16, 0x92, 0x53, 0x6a, 0xd2, 0xa3, 0xfb, + 0xfc, 0xb4, 0x38, 0x98, 0xec, 0xed, 0x7f, 0x34, 0xbf, 0xa5, 0x47, 0x09, 0x58, 0x91, 0x8a, 0x99, + 0x4b, 0x2e, 0xf1, 0x60, 0xe9, 0xe8, 0xbf, 0x4c, 0xfe, 0xed, 0xda, 0x3e, 0xf4, 0x07, 0x2e, 0x96, + 0x38, 0x03, 0xb7, 0xfd, 0xdc, 0xa8, 0xdc, 0x78, 0xda, 0x74, 0xbd, 0x8a, 0x5b, 0x2e, 0x8b, 0xe9, + 0x6e, 0x51, 0x55, 0xc5, 0x2e, 0xde, 0xca, 0x6d, 0xba, 0xfe, 0x1f, 0x0b, 0x55, 0x55, 0xdf, 0x6b, + 0x6d, 0x9f, 0xa7, 0x4f, 0x6e, 0xbe, 0x46, 0x59, 0xbf, 0x75, 0x53, 0xbc, 0x3b, 0x68, 0xa1, 0x7f, + 0x1f, 0x1b, 0x26, 0xcf, 0x52, 0x0f, 0x0b, 0x9b, 0x1b, 0x89, 0x5d, 0xbb, 0x03, 0xcf, 0x7c, 0x41, + 0x35, 0x42, 0xe0, 0xf6, 0xce, 0x88, 0xd4, 0x8c, 0x60, 0xba, 0x82, 0x5a, 0x1b, 0x3b, 0xec, 0xd2, + 0x72, 0x72, 0xde, 0xf8, 0x49, 0x87, 0x59, 0xa8, 0xb6, 0x6c, 0xf5, 0xb9, 0x58, 0xbd, 0x18, 0xa1, + 0x3d, 0xd8, 0x05, 0x48, 0x02, 0x51, 0x9f, 0x4c, 0xce, 0x6d, 0x77, 0x4e, 0x8d, 0xe8, 0x41, 0x3b, + 0xb7, 0xd6, 0xf5, 0xf4, 0xbb, 0x6d, 0xc5, 0x1a, 0xa1, 0x38, 0x30, 0xff, 0x61, 0xc9, 0xa8, 0xd1, + 0x56, 0x9c, 0x69, 0x62, 0x7b, 0x71, 0x9e, 0x44, 0x64, 0x04, 0x40, 0x67, 0x00, 0x20, 0xba, 0x90, + 0x1a, 0x6c, 0xaf, 0xe9, 0x61, 0xf1, 0x45, 0x14, 0xdb, 0x0c, 0xd7, 0x2b, 0xc5, 0x61, 0x07, 0xfb, + 0x28, 0xb8, 0xbe, 0x6d, 0x01, 0x6b, 0xdc, 0x97, 0x72, 0x86, 0x42, 0xb6, 0x1c, 0x34, 0x3e, 0xec, + 0x3b, 0xca, 0x3c, 0x68, 0xfb, 0xac, 0xe6, 0xed, 0x8f, 0xce, 0x7f, 0xbf, 0xa4, 0x4a, 0xce, 0x6b, + 0x25, 0x52, 0xeb, 0x30, 0xdf, 0x73, 0xb4, 0xc2, 0x81, 0xf9, 0x0b, 0xfe, 0x12, 0xf6, 0x65, 0xc0, + 0x99, 0xa9, 0x75, 0x8b, 0xe8, 0x6b, 0x1e, 0x0b, 0xd2, 0x3f, 0x75, 0x73, 0x63, 0x7e, 0x35, 0xdc, + 0xc9, 0xa1, 0x2a, 0x3a, 0xc8, 0xe5, 0x58, 0x9f, 0x5f, 0xfc, 0x4f, 0x98, 0x4b, 0x9d, 0xff, 0xb2, + 0xc9, 0xe5, 0x45, 0xa4, 0xf3, 0x03, 0x67, 0x7d, 0xfa, 0xf8, 0x7b, 0xd5, 0x0e, 0x8f, 0xa2, 0x53, + 0x8e, 0x07, 0x26, 0x4c, 0x25, 0xb8, 0x91, 0xf0, 0xca, 0x40, 0xfa, 0x57, 0x9b, 0x46, 0x1f, 0x7c, + 0x85, 0x39, 0xb5, 0x99, 0xca, 0xa4, 0x0c, 0x24, 0x39, 0x0d, 0x63, 0x46, 0xf5, 0xe2, 0x5c, 0x10, + 0xd3, 0xbc, 0xa1, 0x03, 0xbe, 0xac, 0x43, 0x5b, 0xee, 0x40, 0xbf, 0x45, 0xca, 0x5b, 0xbe, 0x20, + 0x77, 0xb9, 0x7f, 0x3f, 0x8a, 0x30, 0x82, 0x01, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x81, 0xf4, 0x04, 0x81, 0xf1, 0x30, 0x81, 0xee, 0x30, 0x81, 0xeb, + 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x81, 0xb4, + 0x30, 0x81, 0xb1, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, + 0x03, 0x30, 0x0e, 0x04, 0x08, 0x2a, 0xb6, 0x2c, 0x63, 0x26, 0xad, 0xdb, 0x85, 0x02, 0x02, 0x08, + 0x00, 0x04, 0x81, 0x90, 0xb8, 0x7f, 0x9b, 0xaa, 0x07, 0xff, 0x57, 0xe6, 0xea, 0x25, 0xd9, 0x2e, + 0x28, 0x54, 0xdd, 0xc1, 0x23, 0x32, 0x4b, 0xda, 0x85, 0xfb, 0x2a, 0xd9, 0xe4, 0xc0, 0x98, 0x02, + 0x5a, 0x04, 0x7c, 0x47, 0xde, 0xf8, 0x8a, 0xde, 0x03, 0xac, 0x77, 0x42, 0x95, 0xdf, 0xfc, 0xcf, + 0x3a, 0xc4, 0xf3, 0xbc, 0x63, 0x7e, 0x1b, 0xb7, 0xee, 0x45, 0xda, 0x58, 0x29, 0x67, 0x3c, 0xcf, + 0xde, 0x66, 0x41, 0xce, 0x37, 0x58, 0x64, 0xdc, 0x01, 0x6c, 0xee, 0xca, 0x96, 0x13, 0x80, 0x61, + 0xa6, 0xe5, 0x1b, 0xdc, 0x16, 0xcc, 0x65, 0x4e, 0x1b, 0x2d, 0x4e, 0xd0, 0x5a, 0x9d, 0x87, 0xa4, + 0x1f, 0x9d, 0x20, 0x34, 0xe6, 0xfd, 0xf1, 0xe2, 0x13, 0xb8, 0x27, 0x56, 0x25, 0x40, 0xb9, 0x4f, + 0x9d, 0x65, 0xe5, 0xca, 0xeb, 0x67, 0xba, 0x59, 0xa5, 0x88, 0x73, 0x83, 0x70, 0xd8, 0xfa, 0xf1, + 0x9d, 0x46, 0x30, 0x6a, 0x57, 0x6b, 0x9c, 0xef, 0x9f, 0xcd, 0x72, 0x4f, 0x74, 0xa9, 0x76, 0x43, + 0xee, 0x07, 0x40, 0x38, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x1f, 0x76, 0x37, 0x30, 0x3a, 0xfc, 0xac, 0xf2, 0x00, + 0xc5, 0x48, 0x8c, 0xab, 0xaa, 0x55, 0x28, 0x1d, 0xf1, 0x40, 0x12, 0x30, 0x31, 0x30, 0x21, 0x30, + 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x44, 0x6e, 0xbe, 0x14, + 0x6e, 0x93, 0x4d, 0xf6, 0x28, 0x4f, 0xb2, 0xc0, 0x5a, 0x51, 0x2b, 0x02, 0x53, 0xfb, 0x5c, 0xc3, + 0x04, 0x08, 0xcd, 0x17, 0xf0, 0x58, 0x6d, 0x8b, 0x4c, 0x49, 0x02, 0x02, 0x08, 0x00 +}; + +static bool FindCredentialAbstract(const struct CredentialAbstract *abstract, const struct CredentialList *listCert) +{ + bool bFind = false; + + if (abstract == nullptr || listCert == nullptr || listCert->credentialCount == 0) { + return false; + } + for (uint32_t i = 0; i < listCert->credentialCount; ++i) { + if (CompareCredentialList(abstract, &(listCert->credentialAbstract[i]))) { + bFind = true; + break; + } + } + return bFind; +} + +class CmAppCertTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); + +public: + struct CredentialList *certificateList; + struct Credential *certificate; +}; + +void CmAppCertTest::SetUpTestCase(void) +{ +} + +void CmAppCertTest::TearDownTestCase(void) +{ +} + +void CmAppCertTest::SetUp() +{ +} + +void CmAppCertTest::TearDown() +{ +} + +/** + * @tc.name: AppCertInstallBaseTest001 + * @tc.desc: Test CertManager Install app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertInstallBaseTest001, TestSize.Level0) +{ + int32_t ret; + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + char uriBuf[MAX_LEN_URI] = "oh:t=ak;o=keyA;u=0;a=0"; + char retUriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, (uint8_t *)retUriBuf }; + + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstallBaseTest001 credentail test failed, retcode:" << ret; + + store = CM_PRI_CREDENTIAL_STORE; + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstallBaseTest001 pri_credentail test failed, retcode:" << ret; + + EXPECT_EQ(strcmp(uriBuf, (char *)keyUri.data), 0) << "strcmp failed"; +} + +/** + * @tc.name: AppCertInstallBaseTest002 + * @tc.desc: Test CertManager Install app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertInstallBaseTest002, TestSize.Level0) +{ + int32_t ret; + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t appCertPwdBuf[] = "12345678"; + uint8_t certAliasBuf[] = "keyA"; + uint8_t keyUriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, keyUriBuf }; + + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_FAILURE) << "AppCertInstallBaseTest002 credentail test failed, retcode:" << ret; + + store = CM_PRI_CREDENTIAL_STORE; + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_FAILURE) << "AppCertInstallBaseTest002 pri_credentail test failed, retcode:" << ret; +} + +/** + * @tc.name: AppCertInstallBaseTest003 + * @tc.desc: Test CertManager Install app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertInstallTest003, TestSize.Level0) +{ + int32_t ret; + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + uint8_t keyUriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, keyUriBuf }; + + struct CmBlob appCert = { sizeof(g_p12AbnormalCertinfo), (uint8_t*)g_p12AbnormalCertinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_FAILURE) << "AppCertInstallTest003 credentail test failed, retcode:" << ret; + + store = CM_PRI_CREDENTIAL_STORE; + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_FAILURE) << "AppCertInstallTest003 pri_credentail test failed, retcode:" << ret; +} + +/** + * @tc.name: AppCertInstallAbnormalTest004 + * @tc.desc: Test CertManager install app cert interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertInstallAbnormalTest004, TestSize.Level0) +{ + int32_t ret; + uint32_t store = 10; + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + uint8_t keyUriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, keyUriBuf }; + + struct CmBlob appCert = { sizeof(g_p12AbnormalCertinfo), (uint8_t*)g_p12AbnormalCertinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "AppCertInstallAbnormalTest004 test failed, retcode:" << ret; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "AppCertInstallAbnormalTest004 privite test failed, retcode:" << ret; +} + +/** + * @tc.name: AppCertInstallBaseEccTest005 + * @tc.desc: Test CertManager Install app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertInstallBaseEccTest005, TestSize.Level0) +{ + int32_t ret; + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyB"; + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t keyUriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, keyUriBuf }; + + struct CmBlob appCert = { sizeof(g_p12EccNormalCertinfo), (uint8_t*)g_p12EccNormalCertinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstallBaseEccTest005 test failed, retcode:" << ret; + + store = CM_PRI_CREDENTIAL_STORE; + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstallBaseEccTest005 privite test failed, retcode:" << ret; + + ret = CmUninstallAllAppCert(); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertUnInstallAllTest test failed, retcode:" << ret; +} + +/** + * @tc.name: CmGetAppCertBaseTest001 + * @tc.desc: Test CertManager get app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppCertBaseTest001, TestSize.Level0) +{ + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t keyUriBuf[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { strlen((char*)keyUriBuf), keyUriBuf }; + struct Credential certificate; + + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob retUri = { MAX_LEN_URI, uriBuf }; + + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + int32_t ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &retUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstallTest01 test failed, retcode:" << ret; + + + (void)memset_s(&certificate, sizeof(Credential), 0, sizeof(Credential)); + certificate.credData.data = (uint8_t *)CmMalloc(MAX_LEN_CERTIFICATE_CHAIN); + ASSERT_TRUE(certificate.credData.data != NULL); + certificate.credData.size = MAX_LEN_CERTIFICATE_CHAIN; + + ret = CmGetAppCert(&keyUri, store, &certificate); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAppCertBaseTest001 test failed, retcode:" << ret; + + FreeCMBlobData(&certificate.credData); +} + +/** + * @tc.name: CmGetAppCertPerformanceTest002 + * @tc.desc: Test CertManager get app cert interface performance + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppCertPerformanceTest002, TestSize.Level0) +{ + int32_t ret; + uint32_t times = 1; + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t keyUriBuf[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { strlen((char*)keyUriBuf), keyUriBuf }; + struct Credential certificate; + + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob retUri = { MAX_LEN_URI, uriBuf }; + + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &retUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstallTest01 test failed, retcode:" << ret; + + for (uint32_t i = 0; i < times; i++) { + + (void)memset_s(&certificate, sizeof(Credential), 0, sizeof(Credential)); + certificate.credData.data = (uint8_t *)CmMalloc(MAX_LEN_CERTIFICATE_CHAIN); + ASSERT_TRUE(certificate.credData.data != NULL); + certificate.credData.size = MAX_LEN_CERTIFICATE_CHAIN; + + ret = CmGetAppCert(&keyUri, store, &certificate); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAppCert failed,retcode:" << ret; + EXPECT_EQ(CompareCredential(&certificate, &(g_credentialexpectResult[0].certificate)), true); + FreeCMBlobData(&(certificate.credData)); + } +} + +/** + * @tc.name: CmGetAppBaseCertTest003 + * @tc.desc: Test CertManager get app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppBaseCertTest003, TestSize.Level0) +{ + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t keyUriBuf[] = "oh:t=ak;o=keyC;u=0;a=0"; + struct CmBlob keyUri = { strlen((char*)keyUriBuf), keyUriBuf }; + struct Credential firstcertificate, secondcertificate; + (void)memset_s(&firstcertificate, sizeof(Credential), 0, sizeof(Credential)); + (void)memset_s(&secondcertificate, sizeof(Credential), 0, sizeof(Credential)); + + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyC"; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob retUri = { MAX_LEN_URI, uriBuf }; + + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + + int32_t ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &retUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstallTest01 test failed, retcode:" << ret; + + + (void)memset_s(&firstcertificate, sizeof(Credential), 0, sizeof(Credential)); + firstcertificate.credData.data = (uint8_t *)CmMalloc(MAX_LEN_CERTIFICATE_CHAIN); + ASSERT_TRUE(firstcertificate.credData.data != NULL); + firstcertificate.credData.size = MAX_LEN_CERTIFICATE_CHAIN; + + ret = CmGetAppCert(&keyUri, store, &firstcertificate); + EXPECT_EQ(ret, CM_SUCCESS) << "first CmGetAppCert failed, retcode:" << ret; + + (void)memset_s(&secondcertificate, sizeof(Credential), 0, sizeof(Credential)); + secondcertificate.credData.data = (uint8_t *)CmMalloc(MAX_LEN_CERTIFICATE_CHAIN); + ASSERT_TRUE(secondcertificate.credData.data != NULL); + secondcertificate.credData.size = MAX_LEN_CERTIFICATE_CHAIN; + + ret = CmGetAppCert(&keyUri, store, &secondcertificate); + EXPECT_EQ(ret, CM_SUCCESS) << "second CmGetAppCert failed, retcode:" << ret; + + EXPECT_EQ(CompareCredential(&firstcertificate, &secondcertificate), true); + FreeCMBlobData(&(firstcertificate.credData)); + FreeCMBlobData(&(secondcertificate.credData)); +} + +/** + * @tc.name: CmGetAppCertAbnormalTest004 + * @tc.desc: Test CertManager get app cert interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppCertAbnormalTest004, TestSize.Level0) +{ + int32_t ret; + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t keyUriBuf[] = "oh:t=ak;o=keyA;u=0;a=0"; + struct CmBlob keyUri = { strlen((char*)keyUriBuf), keyUriBuf }; + struct Credential certificate; + (void)memset_s(&certificate, sizeof(Credential), 0, sizeof(Credential)); + + ret = CmGetAppCert(NULL, store, &certificate); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "CmGetAppCert Test failed, retcode:" << ret; + FreeCMBlobData(&(certificate.credData)); + + ret = CmGetAppCert(&keyUri, store, NULL); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "CmGetAppCert Test failed, retcode:" << ret; + FreeCMBlobData(&(certificate.credData)); + + ret = CmGetAppCert(&keyUri, 10, &certificate); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "CmGetAppCert Test failed, retcode:" << ret; + FreeCMBlobData(&(certificate.credData)); + + ret = CmUninstallAllAppCert(); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertUnInstallAllTest test failed, retcode:" << ret; +} + +/** + * @tc.name: CmGetAppCertListPerformanceTest001 + * @tc.desc: Test CertManager get app cert list interface performance + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppCertListPerformanceTest001, TestSize.Level0) +{ + int32_t ret; + uint32_t times = 1; + uint32_t store = CM_CREDENTIAL_STORE; + struct CredentialList certificateList = { 0, NULL }; + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, uriBuf }; + + uint32_t buffSize = (MAX_COUNT_CERTIFICATE * sizeof(struct CredentialAbstract)); + certificateList.credentialAbstract = (struct CredentialAbstract *)CmMalloc(buffSize); + ASSERT_TRUE(certificateList.credentialAbstract != NULL); + certificateList.credentialCount = MAX_COUNT_CERTIFICATE; + + ret = memset_s(certificateList.credentialAbstract, buffSize, 0, buffSize); + EXPECT_EQ(ret, EOK); + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAppCertListPerformanceTest001 test failed, retcode:" << ret; + + store = CM_PRI_CREDENTIAL_STORE; + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAppCertListPerformanceTest001 private test failed, retcode:" << ret; + + for (uint32_t i = 0; i < times; i++) { + (void)memset_s(&certificateList, sizeof(CredentialList), 0, sizeof(CredentialList)); + ret = CmGetAppCertList(store, &certificateList); + + if (certificateList.credentialCount != 0) { + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAppCertListTest test failed, retcode:" << ret; + CM_LOG_E("CmGetAppCertListTest size:%u", credentialCount); + } + if (certificateList.credentialAbstract != NULL) { + CmFree(certificateList.credentialAbstract); + } + } +} + +/** + * @tc.name: CmGetAppCertListBaseTest002 + * @tc.desc: Test CertManager get app cert list interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppCertListBaseTest002, TestSize.Level0) +{ + int32_t ret; + uint32_t store = CM_CREDENTIAL_STORE; + struct CredentialList certificateList = { 0, NULL }; + bool bFind = false; + uint32_t length = sizeof(g_expectList) / sizeof(g_expectList[0]); + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, uriBuf }; + + uint32_t buffSize = (MAX_COUNT_CERTIFICATE * sizeof(struct CredentialAbstract)); + certificateList.credentialAbstract = (struct CredentialAbstract *)CmMalloc(buffSize); + ASSERT_TRUE(certificateList.credentialAbstract != NULL); + certificateList.credentialCount = MAX_COUNT_CERTIFICATE; + + ret = memset_s(certificateList.credentialAbstract, buffSize, 0, buffSize); + EXPECT_EQ(ret, EOK); + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "Normal AppCertInstallTest test failed, retcode:" << ret; + + (void)memset_s(&certificateList, sizeof(CredentialList), 0, sizeof(CredentialList)); + ret = CmGetAppCertList(store, &certificateList); + + if (certificateList.credentialCount != 0) { + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetAppCertListTest02 test failed, retcode:" << ret; + for (uint32_t j = 0; j < length; ++j) { + bFind = FindCredentialAbstract(&(g_expectList[j].credentialAbstract), &certificateList); + EXPECT_EQ(bFind, g_expectList[j].bExpectResult); + } + } + if (certificateList.credentialAbstract != NULL) { + CmFree(certificateList.credentialAbstract); + } +} + +/** + * @tc.name: CmGetAppCertListBaseTest003 + * @tc.desc: Test CertManager get app cert list interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppCertListBaseTest003, TestSize.Level0) +{ + uint32_t store = CM_CREDENTIAL_STORE; + int32_t ret = CmGetAppCertList(store, NULL); + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "Abnormal AppCertInstallTest03 test failed, retcode:" << ret; +} + +/** + * @tc.name: CmGetAppCertListAbnormalTest004 + * @tc.desc: Test CertManager get app cert list interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, CmGetAppCertListAbnormalTest004, TestSize.Level0) +{ + int32_t ret; + uint32_t store = 10; + struct CredentialList certificateList = { 0, NULL }; + + uint32_t buffSize = (MAX_COUNT_CERTIFICATE * sizeof(struct CredentialAbstract)); + certificateList.credentialAbstract = (struct CredentialAbstract *)CmMalloc(buffSize); + ASSERT_TRUE(certificateList.credentialAbstract != NULL); + certificateList.credentialCount = MAX_COUNT_CERTIFICATE; + + ret = memset_s(certificateList.credentialAbstract, buffSize, 0, buffSize); + EXPECT_EQ(ret, EOK); + + ret = CmGetAppCertList(store, &certificateList); + + if (certificateList.credentialCount != 0) { + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "Abnormal AppCertInstallTest04 test failed, retcode:" << ret; + } + + if (certificateList.credentialAbstract != NULL) { + CmFree(certificateList.credentialAbstract); + } +} + +/** + * @tc.name: AppCertUnInstallBaseTest001 + * @tc.desc: Test CertManager unInstall app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertUnInstallBaseTest001, TestSize.Level0) +{ + int32_t ret; + uint8_t keyUriBuf[] = "oh:t=ak;o=keyA;u=0;a=0"; + uint32_t store = CM_CREDENTIAL_STORE; + struct CmBlob keyUri = { strlen((char*)keyUriBuf), keyUriBuf }; + + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyA"; + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob retUri = { MAX_LEN_URI, uriBuf }; + + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &retUri); + EXPECT_EQ(ret, CM_SUCCESS) << "CmInstallAppCert test failed, retcode:" << ret; + + ret = CmUninstallAppCert(&keyUri, store); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertUnInstallBaseTest001 test failed, retcode:" << ret; +} + +/** + * @tc.name: AppCertUnInstallAbnormalTest002 + * @tc.desc: Test CertManager unInstall app cert interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertUnInstallAbnormalTest002, TestSize.Level0) +{ + int32_t ret; + uint32_t store = CM_CREDENTIAL_STORE; + ret = CmUninstallAppCert(NULL, store); + + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "SimpleAppCertUnInstallTest test failed, retcode:" << ret; +} + +/** + * @tc.name: AppCertUnInstallAbnormalTest003 + * @tc.desc: Test CertManager unInstall app cert interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertUnInstallAbnormalTest003, TestSize.Level0) +{ + int32_t ret; + uint8_t keyUriBuf[] = "oh:t=ak;o=keyA;u=0;a=0"; + uint32_t store = 10; + struct CmBlob keyUri = { strlen((char*)keyUriBuf), keyUriBuf }; + ret = CmUninstallAppCert(&keyUri, store); + + EXPECT_EQ(ret, CMR_ERROR_INVALID_ARGUMENT) << "AbNormalAppCertUnInstallTest test failed, retcode:" << ret; +} + +/** + * @tc.name: AppCertUnInstallAllAppCertBaseTest001 + * @tc.desc: Test CertManager unInstall all app cert interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertUnInstallAllAppCertBaseTest001, TestSize.Level0) +{ + uint32_t store = CM_CREDENTIAL_STORE; + uint8_t appCertPwdBuf[] = "123456"; + uint8_t certAliasBuf[] = "keyB"; + + struct CmBlob appCert = { sizeof(g_p12Certinfo), (uint8_t*)g_p12Certinfo }; + struct CmBlob appCertPwd = { sizeof(appCertPwdBuf), appCertPwdBuf }; + struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf }; + uint8_t uriBuf[MAX_LEN_URI] = {0}; + struct CmBlob keyUri = { MAX_LEN_URI, uriBuf }; + + int32_t ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstall failed, retcode:" << ret; + + store = CM_PRI_CREDENTIAL_STORE; + ret = CmInstallAppCert(&appCert, &appCertPwd, &certAlias, store, &keyUri); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertInstall failed, retcode:" << ret; + + ret = CmUninstallAllAppCert(); + EXPECT_EQ(ret, CM_SUCCESS) << "AppCertUnInstallAllAppCertBaseTest001 test failed, retcode:" << ret; +} + +/** + * @tc.name: AppCertUnInstallAllAppCertAbnormalTest002 + * @tc.desc: Test CertManager unInstall all app cert interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MI8 /SR000H09N9 + */ +HWTEST_F(CmAppCertTest, AppCertUnInstallAllAppCertAbnormalTest002, TestSize.Level0) +{ + int32_t ret = CmUninstallAllAppCert(); + + EXPECT_EQ(ret, CM_SUCCESS) << "AbNormalAppCertUnInstallAllTest test failed, retcode:" << ret; +} +} \ No newline at end of file diff --git a/test/unittest/src/cm_get_certinfo_test.cpp b/test/unittest/src/cm_get_certinfo_test.cpp new file mode 100644 index 0000000..71739e6 --- /dev/null +++ b/test/unittest/src/cm_get_certinfo_test.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cm_test_common.h" +#include "cm_test_log.h" +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { +static const uint32_t CM_CONTEXT_USERID = 1000; +static const uint32_t CM_CONTEXT_UID = 3000; +static const uint32_t CM_CONTEXT_USERID2 = 2000; +static const uint32_t CM_CONTEXT_UID2 = 3001; + +struct CertInfoResult { + struct CertInfo CertInfo; + bool bExpectResult; +}; + +struct CertInfoResult g_listCertInfoexpectResult[] = { + { + { + "2add47b6.0", + "GlobalSign", + true, + "CN=GlobalSign,OU=GlobalSign ECC Root CA - R5,O=GlobalSign", + "CN=GlobalSign,OU=GlobalSign ECC Root CA - R5,O=GlobalSign", + "605949E0262EBB55F90A778A71F94AD86C", + "2012-11-13", + "2038-1-19", + "17:9F:BC:14:8A:3D:D0:0F:D2:4E:A1:34:58:CC:43:BF:A7:F5:9C:81:82:D7:83:A5:13:F6:EB:EC:10:0C:89:24" + }, + true + }, + { + { + "85cde254.0", + "Starfield Technologies, Inc.", + true, + "CN=Starfield Root Certificate Authority - G2,OU=,O=Starfield Technologies, Inc.", + "CN=Starfield Root Certificate Authority - G2,OU=,O=Starfield Technologies, Inc.", + "0", + "2009-9-1", + "2037-12-31", + "2C:E1:CB:0B:F9:D2:F9:E1:02:99:3F:BE:21:51:52:C3:B2:DD:0C:AB:DE:1C:68:E5:31:9B:83:91:54:DB:B7:F5" + }, + true + }, + { + { + "3c860d51.0", + "SwissSign AG", + true, + "CN=SwissSign Gold CA - G2,OU=,O=SwissSign AG", + "CN=SwissSign Gold CA - G2,OU=,O=SwissSign AG", + "BB401C43F55E4FB0", + "2006-10-25", + "2036-10-25", + "62:DD:0B:E9:B9:F5:0A:16:3E:A0:F8:E7:5C:05:3B:1E:CA:57:EA:55:C8:68:8F:64:7C:68:81:F2:C8:35:7B:95" + }, + true + }, + { + { + "b0f3e76e.0", + "GlobalSign nv-sa", + true, + "CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa", + "CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa", + "040000000001154B5AC394", + "1998-9-1", + "2028-1-28", + "EB:D4:10:40:E4:BB:3E:C7:42:C9:E3:81:D3:1E:F2:A4:1A:48:B6:68:5C:96:E7:CE:F3:C1:DF:6C:D4:33:1C:99" + }, + true + }, + { + { + "869fbf79.0", + "eMudhra Inc", + true, + "CN=emSign ECC Root CA - C3,OU=emSign PKI,O=eMudhra Inc", + "CN=emSign ECC Root CA - C3,OU=emSign PKI,O=eMudhra Inc", + "7B71B68256B8127C9CA8", + "2018-2-18", + "2043-2-18", + "BC:4D:80:9B:15:18:9D:78:DB:3E:1D:8C:F4:F9:72:6A:79:5D:A1:64:3C:A5:F1:35:8E:1D:DB:0E:DC:0D:7E:B3" + }, + true + } +}; + +class CmGetCertInfoTest : public testing::Test { + public: + static void InfoSetUpTestCase(void); + + static void InfoTearDownTestCase(void); + + void SetUp(); + + void TearDown(); + + public: + + struct CmContext firstUserCtx; + struct CmContext secondUserCtx; + struct CertList *lstCert; +}; + +void CmGetCertInfoTest::InfoSetUpTestCase(void) +{ +} + +void CmGetCertInfoTest::InfoTearDownTestCase(void) +{ +} + +void CmGetCertInfoTest::SetUp() +{ + InitCertList(&lstCert); + InitUserContext(&firstUserCtx, CM_CONTEXT_USERID, CM_CONTEXT_UID, "com.hap.test"); + InitUserContext(&secondUserCtx, CM_CONTEXT_USERID2, CM_CONTEXT_UID2, "com.hap.test2"); +} + +void CmGetCertInfoTest::TearDown() +{ + FreeCertList(lstCert); +} + +/** + * @tc.name: SimpleCmGetCertInfo001 + * @tc.desc: Test CertManager get cert info interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmGetCertInfoTest, SimpleCmGetCertInfo001, TestSize.Level0) +{ + char *uri = g_listCertInfoexpectResult[0].CertInfo.uri; + struct CmBlob uriBlob = {strlen(uri), (uint8_t *)(uri)}; + struct CertInfo certInfo; + unsigned int len = sizeof(struct CertInfo); + (void)memset_s(&certInfo, len, 0, len); + int32_t ret = CmGetCertInfo(&firstUserCtx, &uriBlob, CM_SYSTEM_TRUSTED_STORE, &certInfo); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetCertInfo failed,retcode:" << ret; + + EXPECT_EQ(CompareCertInfo(&certInfo, &(g_listCertInfoexpectResult[0].CertInfo)), true) <certsCount; ++i) { + (void)memset_s(&certInfo, len, 0, len); + + struct CertAbstract *ptr = &(lstCert->certAbstract[i]); + ASSERT_TRUE(ptr != NULL); + + struct CmBlob uriBlob = {strlen(ptr->uri), (uint8_t *)(ptr->uri)}; + + ret = CmGetCertInfo(&secondUserCtx, &uriBlob, CM_SYSTEM_TRUSTED_STORE, &certInfo); + EXPECT_EQ(ret, CM_SUCCESS) << " CmGetCertInfo failed,retcode:" << ptr->uri; + FreeCMBlobData(&(certInfo.certInfo)); + } +} + +/** + * @tc.name: ExceptionGetCertInfoTest004 + * @tc.desc: Test CertManager get cert info interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmGetCertInfoTest, ExceptionGetCertInfoTest004, TestSize.Level0) +{ + char *uri = g_listCertInfoexpectResult[1].CertInfo.uri; + struct CmBlob uriBlob = {strlen(uri), (uint8_t *)(uri)}; + struct CertInfo certInfo; + unsigned int len = sizeof(struct CertInfo); + (void)memset_s(&certInfo, len, 0, len); + EXPECT_EQ(CmGetCertInfo(NULL, &uriBlob, CM_SYSTEM_TRUSTED_STORE, &certInfo), + CMR_ERROR_NULL_POINTER); + FreeCMBlobData(&(certInfo.certInfo)); + EXPECT_EQ(CmGetCertInfo(&secondUserCtx, NULL, CM_SYSTEM_TRUSTED_STORE, &certInfo), + CMR_ERROR_NULL_POINTER); + FreeCMBlobData(&(certInfo.certInfo)); + EXPECT_EQ(CmGetCertInfo(&firstUserCtx, &uriBlob, 10, &certInfo), CM_FAILURE); + FreeCMBlobData(&(certInfo.certInfo)); + EXPECT_EQ(CmGetCertInfo(&firstUserCtx, &uriBlob, CM_SYSTEM_TRUSTED_STORE, NULL), + CMR_ERROR_NULL_POINTER); + FreeCMBlobData(&(certInfo.certInfo)); + + const char *invalidUri = "INVALID"; + struct CmBlob invalidUriBlob = {strlen(invalidUri), (uint8_t *)invalidUri}; + EXPECT_EQ(CmGetCertInfo(&firstUserCtx, &invalidUriBlob, CM_SYSTEM_TRUSTED_STORE, &certInfo), + CMR_ERROR_INVALID_ARGUMENT); + FreeCMBlobData(&(certInfo.certInfo)); +} +} \ No newline at end of file diff --git a/test/unittest/src/cm_get_certlist_test.cpp b/test/unittest/src/cm_get_certlist_test.cpp new file mode 100644 index 0000000..69c26b5 --- /dev/null +++ b/test/unittest/src/cm_get_certlist_test.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cm_test_log.h" +#include "cm_test_common.h" +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { +static const uint32_t CM_CONTEXT_USERID = 1000; +static const uint32_t CM_CONTEXT_USERID2 = 2000; +static const uint32_t CM_CONTEXT_UID = 3000; +static const uint32_t CM_CONTEXT_UID2 = 3001; + +#define TIMES_PERFORMANCE 10 + +struct CertAbstractResult { + struct CertAbstract certAbstract; + bool bExpectResult; +}; + +struct CertAbstractResult g_listexpectResult[] = { + { + { + "2add47b6.0", + "GlobalSign", + true, "CN=GlobalSign,OU=GlobalSign ECC Root CA - R5,O=GlobalSign" + }, + true + }, + { + { + "85cde254.0", + "Starfield Technologies, Inc.", + true, + "CN=Starfield Root Certificate Authority - G2,OU=,O=Starfield Technologies, Inc." + }, + true + }, + { + { + "3c860d51.0", + "SwissSign AG", + true, + "CN=SwissSign Gold CA - G2,OU=,O=SwissSign AG" + }, + true + } +}; + +static bool FindCertAbstract(const struct CertAbstract *abstract, const struct CertList *listCert) +{ + bool bFind = false; + + if (abstract == NULL || listCert == NULL || listCert->certsCount == 0) { + return false; + } + for (uint32_t i = 0; i < listCert->certsCount; ++i) { + if (CompareCert(abstract, &(listCert->certAbstract[i]))) { + bFind = true; + break; + } + } + return bFind; +} + +class CmGetCertListTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); + +public: + struct CmContext firstUserCtx; + struct CmContext secondUserCtx; + struct CertList *lstCert; +}; + +void CmGetCertListTest::SetUpTestCase(void) +{ +} + +void CmGetCertListTest::TearDownTestCase(void) +{ +} + +void CmGetCertListTest::SetUp() +{ + InitCertList(&lstCert); + InitUserContext(&firstUserCtx, CM_CONTEXT_USERID, CM_CONTEXT_UID, "com.hap.test"); + InitUserContext(&secondUserCtx, CM_CONTEXT_USERID2, CM_CONTEXT_UID2, "com.hap.test2"); +} + +void CmGetCertListTest::TearDown() +{ + FreeCertList(lstCert); +} + +/** + * @tc.name: SimpleGetCertListTest001 + * @tc.desc: Test CertManager get cert list interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmGetCertListTest, SimpleGetCertListTest001, TestSize.Level0) +{ + int32_t ret = CmGetCertList(&firstUserCtx, CM_SYSTEM_TRUSTED_STORE, lstCert); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetCertList failed,retcode:" << ret; +} + +/** + * @tc.name: PerformanceGetCertListTest002 + * @tc.desc: Test CertManager get cert list interface performance + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmGetCertListTest, PerformanceGetCertListTest002, TestSize.Level0) +{ + for (int times = 0; times < TIMES_PERFORMANCE; ++times) { + struct CertList *listCert = NULL; + ASSERT_TRUE(InitCertList(&listCert) == CM_SUCCESS); + int32_t ret = CmGetCertList(&secondUserCtx, CM_SYSTEM_TRUSTED_STORE, listCert); + EXPECT_EQ(ret, CM_SUCCESS) << "CmGetCertList Performance failed,retcode:" << ret; + FreeCertList(listCert); + } +} + +/** + * @tc.name: GetCertListContent003 + * @tc.desc: Test CertManager get cert list content interface function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmGetCertListTest, GetCertListContent003, TestSize.Level0) +{ + int32_t ret = CmGetCertList(&firstUserCtx, CM_SYSTEM_TRUSTED_STORE, lstCert); + EXPECT_EQ(ret, CM_SUCCESS) << "firstUserCtx CmGetCertList failed,retcode:" << ret; + + uint32_t length = sizeof(g_listexpectResult) / sizeof(g_listexpectResult[0]); + bool bFind = false; + for (uint32_t j = 0; j < length; ++j) { + bFind = FindCertAbstract(&(g_listexpectResult[j].certAbstract), lstCert); + + EXPECT_EQ(bFind, g_listexpectResult[j].bExpectResult) << DumpCertList(lstCert); + } +} + +/** + * @tc.name: AppGetCertListCompare004 + * @tc.desc: Test CertManager get cert list compare interface function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmGetCertListTest, AppGetCertListCompare004, TestSize.Level0) +{ + int32_t ret = CmGetCertList(&firstUserCtx, CM_SYSTEM_TRUSTED_STORE, lstCert); + EXPECT_EQ(ret, CM_SUCCESS) << "first CmGetCertList failed,retcode:" << ret; + + struct CertList *secondListCert = NULL; + ASSERT_TRUE(InitCertList(&secondListCert) == CM_SUCCESS); + ret = CmGetCertList(&secondUserCtx, CM_SYSTEM_TRUSTED_STORE, secondListCert); + EXPECT_EQ(ret, CM_SUCCESS) << "secondUserCtx CmGetCertList failed,retcode:" << ret; + + EXPECT_EQ(lstCert->certsCount, secondListCert->certsCount) << "firstUserCtx count:" << lstCert->certsCount + << "secondUserCtx count:" << secondListCert->certsCount; + + FreeCertList(secondListCert); +} + +/** + * @tc.name: ExceptionGetCertList005 + * @tc.desc: Test CertManager get cert list interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmGetCertListTest, ExceptionGetCertList005, TestSize.Level0) +{ + EXPECT_EQ(CmGetCertList(NULL, CM_SYSTEM_TRUSTED_STORE, lstCert), CMR_ERROR_NULL_POINTER); + EXPECT_EQ(CmGetCertList(&firstUserCtx, CM_SYSTEM_TRUSTED_STORE, NULL), CMR_ERROR_NULL_POINTER); + EXPECT_EQ(CmGetCertList(&secondUserCtx, 10, lstCert), CM_FAILURE); +} +} \ No newline at end of file diff --git a/test/unittest/src/cm_set_status_test.cpp b/test/unittest/src/cm_set_status_test.cpp new file mode 100644 index 0000000..6f37df8 --- /dev/null +++ b/test/unittest/src/cm_set_status_test.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cm_test_log.h" +#include "cm_test_common.h" +#include "cert_manager_api.h" + +using namespace testing::ext; +using namespace CertmanagerTest; +namespace { +static const uint32_t CM_CONTEXT_UID = 3000; +static const uint32_t CM_CONTEXT_UID2 = 3001; +static const uint32_t CM_CONTEXT_USERID = 1000; +static const uint32_t CM_CONTEXT_USERID2 = 2000; + +struct CertStatusExpectResult { + char uri[MAX_LEN_URI]; + bool inparamStatus; + bool expectStatus; +}; + +struct CertStatusExpectResult g_expectList[] = { + { + {"2add47b6.0"}, false, false + }, + { + {"85cde254.0"}, false, false + }, + { + {"3c860d51.0"}, true, true + } +}; + +class CmSetCertStatusTest : public testing::Test { + public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); + + public: + struct CmContext firstUserCtx; + struct CmContext secondUserCtx; +}; + +void CmSetCertStatusTest::SetUpTestCase(void) +{ +} + +void CmSetCertStatusTest::TearDownTestCase(void) +{ +} + +void CmSetCertStatusTest::SetUp() +{ + InitUserContext(&firstUserCtx, CM_CONTEXT_USERID, CM_CONTEXT_UID, "com.hap.test"); + InitUserContext(&secondUserCtx, CM_CONTEXT_USERID2, CM_CONTEXT_UID2, "com.hap.test2"); +} + +void CmSetCertStatusTest::TearDown() +{ +} + +/** + * @tc.name: SimpleSetCertStatus001 + * @tc.desc: Test CertManager set cert status interface base function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmSetCertStatusTest, SimpleSetCertStatus001, TestSize.Level0) +{ + struct CmBlob uriBlob = {strlen(g_expectList[0].uri), (uint8_t *)(g_expectList[0].uri)}; + + int32_t ret = CmSetCertStatus(&firstUserCtx, + &uriBlob, CM_SYSTEM_TRUSTED_STORE, g_expectList[0].inparamStatus); + EXPECT_EQ(ret, CM_SUCCESS) << "SimpleSetCertStatus failed,retcode:" << ret; + + ret = CmSetCertStatus(&firstUserCtx, &uriBlob, CM_SYSTEM_TRUSTED_STORE, true); + EXPECT_EQ(ret, CM_SUCCESS) << "SimpleSetCertStatus true failed,retcode:" << ret; +} + +/** + * @tc.name: SetCertStatusAndQueryStatus002 + * @tc.desc: Test CertManager set cert status and query status interface function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmSetCertStatusTest, SetCertStatusAndQueryStatus002, TestSize.Level0) +{ + uint32_t size = sizeof(g_expectList) / sizeof(g_expectList[0]); + for (uint32_t i = 0; i < size; ++i) { + struct CmBlob uriBlob = {strlen(g_expectList[i].uri), (uint8_t *)(g_expectList[i].uri)}; + + int32_t ret = CmSetCertStatus(&firstUserCtx, + &uriBlob, CM_SYSTEM_TRUSTED_STORE, g_expectList[i].inparamStatus); + EXPECT_EQ(ret, CM_SUCCESS) << " SetCertStatusAndQueryStatus, CmSetCertStatus failed,retcode: " << ret; + + struct CertInfo certDetailInfo; + (void)memset_s(&certDetailInfo, sizeof(certDetailInfo), 0, sizeof(certDetailInfo)); + + ret = CmGetCertInfo(&firstUserCtx, &uriBlob, CM_SYSTEM_TRUSTED_STORE, &certDetailInfo); + EXPECT_EQ(ret, CM_SUCCESS) << "SetCertStatusAndQueryStatus,CmGetCertInfo failed,retcode: " << ret; + uint32_t uStatus = (g_expectList[i].expectStatus == certDetailInfo.status) ? 1 : 0; + + EXPECT_EQ(uStatus, 1) << "SetCertStatusAndQueryStatus fail, cert info: " << DumpCertInfo(&certDetailInfo); + FreeCMBlobData(&(certDetailInfo.certInfo)); + + ret = CmSetCertStatus(&firstUserCtx, &uriBlob, CM_SYSTEM_TRUSTED_STORE, true); + EXPECT_EQ(ret, CM_SUCCESS) << " SetCertStatusAndQueryStatus, CmSetCertStatus failed,retcode: " << ret; + } +} + +/** + * @tc.name: SetAllCertStatus003 + * @tc.desc: Test CertManager set all cert status interface function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmSetCertStatusTest, SetAllCertStatus003, TestSize.Level0) +{ + struct CertList *certlist = NULL; + + ASSERT_TRUE(InitCertList(&certlist) == CM_SUCCESS); + // CA trusted list + int32_t ret = CmGetCertList(&secondUserCtx, CM_SYSTEM_TRUSTED_STORE, certlist); + + EXPECT_EQ(ret, CM_SUCCESS) << "SetAllCertStatus,CmGetCertList failed,retcode:" << ret; + + for (uint32_t i = 0; i < certlist->certsCount; ++i) { + struct CertAbstract *ptr = &(certlist->certAbstract[i]); + ASSERT_TRUE(NULL != ptr); + struct CmBlob uriBlob = {strlen(ptr->uri), (uint8_t *)(ptr->uri)}; + ret = CmSetCertStatus(&secondUserCtx, &uriBlob, CM_SYSTEM_TRUSTED_STORE, false); + EXPECT_EQ(ret, CM_SUCCESS); + } + + for (uint32_t i = 0; i < certlist->certsCount; ++i) { + struct CertAbstract *ptr2 = &(certlist->certAbstract[i]); + ASSERT_TRUE(NULL != ptr2); + struct CmBlob uriBlob2 = {strlen(ptr2->uri), (uint8_t *)(ptr2->uri)}; + ret = CmSetCertStatus(&firstUserCtx, &uriBlob2, CM_SYSTEM_TRUSTED_STORE, true); + EXPECT_EQ(ret, CM_SUCCESS); + } + FreeCertList(certlist); +} + +/** + * @tc.name: ExceptionSetStatus004 + * @tc.desc: Test CertManager set cert status interface abnormal function + * @tc.type: FUNC + * @tc.require: AR000H0MJA /SR000H096P + */ +HWTEST_F(CmSetCertStatusTest, ExceptionSetStatus004, TestSize.Level0) +{ + struct CmBlob uriBlob = {strlen(g_expectList[1].uri), (uint8_t *)(g_expectList[1].uri)}; + EXPECT_EQ(CmSetCertStatus(NULL, &uriBlob, CM_SYSTEM_TRUSTED_STORE, true), + CMR_ERROR_NULL_POINTER); + EXPECT_EQ(CmSetCertStatus(&secondUserCtx, NULL, CM_SYSTEM_TRUSTED_STORE, true), + CMR_ERROR_NULL_POINTER); + + EXPECT_EQ(CmSetCertStatus(&firstUserCtx, &uriBlob, 10, true), CM_FAILURE); + + const char *invalidUri = "INVALIDXXXX"; + struct CmBlob invalidUriBlob = {strlen(invalidUri), (uint8_t *)invalidUri}; + EXPECT_EQ(CmSetCertStatus(&firstUserCtx, &invalidUriBlob, CM_SYSTEM_TRUSTED_STORE, true), + CMR_ERROR_NOT_FOUND); +} +} diff --git a/test/unittest/src/cm_test_common.cpp b/test/unittest/src/cm_test_common.cpp new file mode 100644 index 0000000..46ad594 --- /dev/null +++ b/test/unittest/src/cm_test_common.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include "cm_mem.h" +#include "cm_test_common.h" +#include "cm_test_log.h" + + +#define EOK (0) + +using namespace testing::ext; +namespace CertmanagerTest { +#ifndef errno_t +typedef int errno_t; +#endif + +uint32_t InitCertList(struct CertList **certlist) +{ + *certlist = (struct CertList *)CmMalloc(sizeof(struct CertList)); + if (*certlist == nullptr) { + return CMR_ERROR_MALLOC_FAIL; + } + (*certlist)->certAbstract = nullptr; + (*certlist)->certsCount = 0; + + return CM_SUCCESS; +} + +uint32_t InitUserContext(struct CmContext* userCtx, const uint32_t userid, const uint32_t uid, const char *pktname) +{ + if (pktname == nullptr || userCtx == nullptr) { + return CMR_ERROR_INVALID_ARGUMENT; + } + userCtx->userId = userid; + userCtx->uid = uid; + errno_t ret = strcpy_s(userCtx->packageName, MAX_LEN_PACKGE_NAME, pktname); + if (ret != EOK) { + return CM_FAILURE; + } + return CM_SUCCESS; +} + +void FreeCertList(struct CertList *certList) +{ + if (certList == nullptr || certList->certAbstract == nullptr) { + return; + } + + CmFree(certList->certAbstract); + certList->certAbstract = nullptr; + + CmFree(certList); + certList = nullptr; +} + + +void FreeCMBlobData(struct CmBlob *blob) +{ + if (blob == nullptr) { + return; + } + + if (blob->data != nullptr) { + CmFree(blob->data); + blob->data = nullptr; + } + blob->size = 0; +} + +bool CompareCert(const struct CertAbstract *firstCert, const struct CertAbstract *secondCert) +{ + if (firstCert == nullptr || secondCert == nullptr) { + CM_TEST_LOG_E("cert invalid parameter"); + } + return ((strcmp(firstCert->uri, secondCert->uri) == 0) && + (strcmp(firstCert->certAlias, secondCert->certAlias) == 0) && + (strcmp(firstCert->subjectName, secondCert->subjectName) == 0) && + (firstCert->status == secondCert->status)); +} + +bool CompareCredentialList(const struct CredentialAbstract *firstCert, const struct CredentialAbstract *secondCert) +{ + if (firstCert == nullptr || secondCert == nullptr) { + CM_TEST_LOG_E("cert invalid parameter"); + } + return ((strcmp(firstCert->type, secondCert->type) == 0) && + (strcmp(firstCert->alias, secondCert->alias) == 0) && + (strcmp(firstCert->keyUri, secondCert->keyUri) == 0)); +} + +std::string DumpCertAbstractInfo(const struct CertAbstract *certAbstract) +{ + if (certAbstract == nullptr) { + return " "; + } + std::string str = ""; + str += ENDOF; + str += certAbstract->uri; + str += DELIMITER; + str += certAbstract->certAlias; + str += DELIMITER; + str += certAbstract->subjectName; + str += DELIMITER; + str += (certAbstract->status)? "true":"false"; + str += ENDOF; + return str; +} + +std::string DumpCertList(struct CertList *certList) +{ + if (certList == nullptr) { + return " "; + } + + std::string str = ""; + if (certList->certsCount > 0 && certList->certAbstract != nullptr) { + for (uint32_t i = 0; i < certList->certsCount; i++) { + str += DumpCertAbstractInfo(&(certList->certAbstract[i])); + } + } + return str; +} + +bool CompareCertInfo(const struct CertInfo *firstCert, const struct CertInfo *secondCert) +{ + if (firstCert == nullptr || secondCert == nullptr) { + return false; + } + return ((strcmp(firstCert->uri, secondCert->uri) == 0) && + (strcmp(firstCert->certAlias, secondCert->certAlias) == 0) && + (firstCert->status == secondCert->status) && + (strcmp(firstCert->issuerName, secondCert->issuerName) == 0) && + (strcmp(firstCert->subjectName, secondCert->subjectName) == 0) && + (strcmp(firstCert->serial, secondCert->serial) == 0) && + (strcmp(firstCert->notBefore, secondCert->notBefore) == 0) && + (strcmp(firstCert->notAfter, secondCert->notAfter) == 0) && + (strcmp(firstCert->fingerprintSha256, secondCert->fingerprintSha256) == 0)); +} + +std::string DumpCertInfo(const struct CertInfo *certInfo) +{ + if (certInfo == nullptr) { + return " "; + } + std::string str = ""; + str += ENDOF; + str += certInfo->uri; + str += DELIMITER; + str += certInfo->certAlias; + str += DELIMITER; + str += certInfo->subjectName; + str += DELIMITER; + str += (certInfo->status)? "true":"false"; + str += ENDOF; + return str; +} + +bool CompareCredential(const struct Credential *firstCredential, const struct Credential *secondCredential) +{ + if (firstCredential == nullptr || secondCredential == nullptr) { + return false; + } + return ((strcmp(firstCredential->type, secondCredential->type) == 0) && + (strcmp(firstCredential->alias, secondCredential->alias) == 0) && + (strcmp(firstCredential->keyUri, secondCredential->keyUri) == 0) && + (firstCredential->certNum == secondCredential->certNum) && + (firstCredential->keyNum == secondCredential->keyNum)); +} + +int32_t IsFileExist(const char *fileName) +{ + if (access(fileName, F_OK) != 0) { + CM_TEST_LOG_E("file not exist, fileName %s", fileName); + return -1; + } + + return 0; +} + +uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len) +{ + (void)offset; + if (IsFileExist(fileName) != 0) { + return 0; + } + + char filePath[PATH_MAX + 1] = {0}; + (void)realpath(fileName, filePath); + if (strstr(filePath, "../") != nullptr) { + CM_TEST_LOG_E("invalid filePath, path %s", filePath); + return 0; + } + + FILE *fp = fopen(filePath, "rb"); + if (fp == nullptr) { + CM_TEST_LOG_E("failed to open file"); + return 0; + } + + uint32_t size = fread(buf, 1, len, fp); + if (fclose(fp) < 0) { + CM_TEST_LOG_E("failed to close file"); + return 0; + } + + return size; +} + +uint32_t FileSize(const char *fileName) +{ + if (IsFileExist(fileName) != 0) { + return 0; + } + + struct stat fileStat; + (void)memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat)); + if (stat(fileName, &fileStat) != 0) { + CM_TEST_LOG_E("file stat fail."); + return 0; + } + + return fileStat.st_size; +} +} \ No newline at end of file -- Gitee