diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..bf166669a5e4872a12c10d195268cc10752dc746 --- /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 0000000000000000000000000000000000000000..4947287f7b5ccb5d1e8b7b2d3aa5d89f322c160d --- /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 0000000000000000000000000000000000000000..3ae5bf2fbc643e6416e9e427371f195987608618 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 90deffd8906ef722e1eb69fa04cacba0438f64c2..95338ded79d969c2117ee1237c13c9c250392128 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 0000000000000000000000000000000000000000..e65619fc1324680ad1e7d55bdff4990ed5ca62dc --- /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 0000000000000000000000000000000000000000..2f4702d005bb913d1d1b4eee488692ef4081468c --- /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 0000000000000000000000000000000000000000..c7c04a21f99f2b5fe396e161a2b5a11d1f4f0587 --- /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 0000000000000000000000000000000000000000..4daa2f7cf96f9d2ba2c66645734c8873e939abce --- /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 Binary files /dev/null and b/config/systemCertificates/01419da9.0 differ diff --git a/config/systemCertificates/04f60c28.0 b/config/systemCertificates/04f60c28.0 new file mode 100644 index 0000000000000000000000000000000000000000..9c534960432c5290bc86f2a16a7eeb6037355494 Binary files /dev/null and b/config/systemCertificates/04f60c28.0 differ diff --git a/config/systemCertificates/0d69c7e1.0 b/config/systemCertificates/0d69c7e1.0 new file mode 100644 index 0000000000000000000000000000000000000000..160d545fc28b8cebba1b65d475f09a4544933af4 Binary files /dev/null and b/config/systemCertificates/0d69c7e1.0 differ diff --git a/config/systemCertificates/10531352.0 b/config/systemCertificates/10531352.0 new file mode 100644 index 0000000000000000000000000000000000000000..42f3c1b9ea851d77a1b156995ee2a5296e08767b Binary files /dev/null and b/config/systemCertificates/10531352.0 differ diff --git a/config/systemCertificates/111e6273.0 b/config/systemCertificates/111e6273.0 new file mode 100644 index 0000000000000000000000000000000000000000..4d937187ede7ff4298754f14e5399502f844f389 Binary files /dev/null and b/config/systemCertificates/111e6273.0 differ diff --git a/config/systemCertificates/12d55845.0 b/config/systemCertificates/12d55845.0 new file mode 100644 index 0000000000000000000000000000000000000000..95500f6bd1373c2dce681e3779ac7647a84ef251 Binary files /dev/null and b/config/systemCertificates/12d55845.0 differ diff --git a/config/systemCertificates/1ae85e5e.0 b/config/systemCertificates/1ae85e5e.0 new file mode 100644 index 0000000000000000000000000000000000000000..45a8215e1312759b1a2813c9f229b95e1845f55e Binary files /dev/null and b/config/systemCertificates/1ae85e5e.0 differ diff --git a/config/systemCertificates/1df5a75f.0 b/config/systemCertificates/1df5a75f.0 new file mode 100644 index 0000000000000000000000000000000000000000..1449f866336129f369b7dad1050d28facc41f037 Binary files /dev/null and b/config/systemCertificates/1df5a75f.0 differ diff --git a/config/systemCertificates/1e1eab7c.0 b/config/systemCertificates/1e1eab7c.0 new file mode 100644 index 0000000000000000000000000000000000000000..f81b63aa1e1b222d41e2b079e2088f3680dbd977 Binary files /dev/null and b/config/systemCertificates/1e1eab7c.0 differ diff --git a/config/systemCertificates/1e8e7201.0 b/config/systemCertificates/1e8e7201.0 new file mode 100644 index 0000000000000000000000000000000000000000..232c4b6121f7236eb429572c591127e8aa60166f Binary files /dev/null and b/config/systemCertificates/1e8e7201.0 differ diff --git a/config/systemCertificates/1eb37bdf.0 b/config/systemCertificates/1eb37bdf.0 new file mode 100644 index 0000000000000000000000000000000000000000..96b35e4f99bf06092b89952b539e427ec595ff2f Binary files /dev/null and b/config/systemCertificates/1eb37bdf.0 differ diff --git a/config/systemCertificates/1f58a078.0 b/config/systemCertificates/1f58a078.0 new file mode 100644 index 0000000000000000000000000000000000000000..3e49eba74782a8bcac1c87f76f3809872b98ddd0 Binary files /dev/null and b/config/systemCertificates/1f58a078.0 differ diff --git a/config/systemCertificates/219d9499.0 b/config/systemCertificates/219d9499.0 new file mode 100644 index 0000000000000000000000000000000000000000..3cd289bdff9d0a2185b4271ebd7d1e278714a542 Binary files /dev/null and b/config/systemCertificates/219d9499.0 differ diff --git a/config/systemCertificates/23f4c490.0 b/config/systemCertificates/23f4c490.0 new file mode 100644 index 0000000000000000000000000000000000000000..53a86ac2a010c22a604a8955755060c9c2b7cb1e Binary files /dev/null and b/config/systemCertificates/23f4c490.0 differ diff --git a/config/systemCertificates/27af790d.0 b/config/systemCertificates/27af790d.0 new file mode 100644 index 0000000000000000000000000000000000000000..75dfaf39fddbbd46f687e0324a3a5811372b0e3f Binary files /dev/null and b/config/systemCertificates/27af790d.0 differ diff --git a/config/systemCertificates/2add47b6.0 b/config/systemCertificates/2add47b6.0 new file mode 100644 index 0000000000000000000000000000000000000000..fed8dab45f4189d92f2ea62a549206841bd10c3b Binary files /dev/null and b/config/systemCertificates/2add47b6.0 differ diff --git a/config/systemCertificates/2d9dafe4.0 b/config/systemCertificates/2d9dafe4.0 new file mode 100644 index 0000000000000000000000000000000000000000..24e5adbb0d859d830f2c27e62342850b2b35399a Binary files /dev/null and b/config/systemCertificates/2d9dafe4.0 differ diff --git a/config/systemCertificates/2fa87019.0 b/config/systemCertificates/2fa87019.0 new file mode 100644 index 0000000000000000000000000000000000000000..13ce65e936bc95eed9275bde0a2ed38cce235f2d Binary files /dev/null and b/config/systemCertificates/2fa87019.0 differ diff --git a/config/systemCertificates/302904dd.0 b/config/systemCertificates/302904dd.0 new file mode 100644 index 0000000000000000000000000000000000000000..72e48c301e6035cbc5fe075b21fd5faf21eda1c4 Binary files /dev/null and b/config/systemCertificates/302904dd.0 differ diff --git a/config/systemCertificates/304d27c3.0 b/config/systemCertificates/304d27c3.0 new file mode 100644 index 0000000000000000000000000000000000000000..507b8428b59681a113d25ccc2e355636521b74a9 Binary files /dev/null and b/config/systemCertificates/304d27c3.0 differ diff --git a/config/systemCertificates/31188b5e.0 b/config/systemCertificates/31188b5e.0 new file mode 100644 index 0000000000000000000000000000000000000000..a4dfe1f0471d34a21b2e6c50c56dd9b4e9d6e2b2 Binary files /dev/null and b/config/systemCertificates/31188b5e.0 differ diff --git a/config/systemCertificates/33ee480d.0 b/config/systemCertificates/33ee480d.0 new file mode 100644 index 0000000000000000000000000000000000000000..1dd645cc4cdb3e5b9559e20346922dc459a2eac8 Binary files /dev/null and b/config/systemCertificates/33ee480d.0 differ diff --git a/config/systemCertificates/343eb6cb.0 b/config/systemCertificates/343eb6cb.0 new file mode 100644 index 0000000000000000000000000000000000000000..da61112c93babb53080276db8b0ebddc4b3a247c Binary files /dev/null and b/config/systemCertificates/343eb6cb.0 differ diff --git a/config/systemCertificates/35105088.0 b/config/systemCertificates/35105088.0 new file mode 100644 index 0000000000000000000000000000000000000000..2fa45b280e22a9fe641b25ffb3f7d866bebec657 Binary files /dev/null and b/config/systemCertificates/35105088.0 differ diff --git a/config/systemCertificates/399e7759.0 b/config/systemCertificates/399e7759.0 new file mode 100644 index 0000000000000000000000000000000000000000..2f1e5523af47d44e35ea27be89e25a663ea7f99f Binary files /dev/null and b/config/systemCertificates/399e7759.0 differ diff --git a/config/systemCertificates/3ad48a91.0 b/config/systemCertificates/3ad48a91.0 new file mode 100644 index 0000000000000000000000000000000000000000..da96dbb2c93d063581e5a96ebb4e258c37923087 Binary files /dev/null and b/config/systemCertificates/3ad48a91.0 differ diff --git a/config/systemCertificates/3c6676aa.0 b/config/systemCertificates/3c6676aa.0 new file mode 100644 index 0000000000000000000000000000000000000000..d189e90bf84570e394fafe9e8553d8401ee84f92 Binary files /dev/null and b/config/systemCertificates/3c6676aa.0 differ diff --git a/config/systemCertificates/3c860d51.0 b/config/systemCertificates/3c860d51.0 new file mode 100644 index 0000000000000000000000000000000000000000..4f228c2e26cc126a09cb156d66403d1594a98033 Binary files /dev/null and b/config/systemCertificates/3c860d51.0 differ diff --git a/config/systemCertificates/3c899c73.0 b/config/systemCertificates/3c899c73.0 new file mode 100644 index 0000000000000000000000000000000000000000..3a08309fc78bcf86f31db470fd7786f74f5b32e9 Binary files /dev/null and b/config/systemCertificates/3c899c73.0 differ diff --git a/config/systemCertificates/3c9a4d3b.0 b/config/systemCertificates/3c9a4d3b.0 new file mode 100644 index 0000000000000000000000000000000000000000..12f481ee4a2515594f587101f93cf7881798af89 Binary files /dev/null and b/config/systemCertificates/3c9a4d3b.0 differ diff --git a/config/systemCertificates/3e7271e8.0 b/config/systemCertificates/3e7271e8.0 new file mode 100644 index 0000000000000000000000000000000000000000..ce27297ade38c499c2db43ee85c55863b024de67 Binary files /dev/null and b/config/systemCertificates/3e7271e8.0 differ diff --git a/config/systemCertificates/40dc992e.0 b/config/systemCertificates/40dc992e.0 new file mode 100644 index 0000000000000000000000000000000000000000..433bb684bf3e53e453f73d9e7e84369bef1181cc Binary files /dev/null and b/config/systemCertificates/40dc992e.0 differ diff --git a/config/systemCertificates/455f1b52.0 b/config/systemCertificates/455f1b52.0 new file mode 100644 index 0000000000000000000000000000000000000000..011ca95b3f2d50a21c5023263fea135139625a60 Binary files /dev/null and b/config/systemCertificates/455f1b52.0 differ diff --git a/config/systemCertificates/48a195d8.0 b/config/systemCertificates/48a195d8.0 new file mode 100644 index 0000000000000000000000000000000000000000..71f9f88dd2a915982047b7b447940d2665519a9b Binary files /dev/null and b/config/systemCertificates/48a195d8.0 differ diff --git a/config/systemCertificates/4be590e0.0 b/config/systemCertificates/4be590e0.0 new file mode 100644 index 0000000000000000000000000000000000000000..7a8caf9169eaa54eb64a2e7e91c472ba65c282c1 Binary files /dev/null and b/config/systemCertificates/4be590e0.0 differ diff --git a/config/systemCertificates/5046c355.0 b/config/systemCertificates/5046c355.0 new file mode 100644 index 0000000000000000000000000000000000000000..9c4f697f4ad11091a546fcb3505b596f01a348e6 Binary files /dev/null and b/config/systemCertificates/5046c355.0 differ diff --git a/config/systemCertificates/524d9b43.0 b/config/systemCertificates/524d9b43.0 new file mode 100644 index 0000000000000000000000000000000000000000..1353d28fd986ba4777b6b6dc9e435bf611484f16 Binary files /dev/null and b/config/systemCertificates/524d9b43.0 differ diff --git a/config/systemCertificates/52b525c7.0 b/config/systemCertificates/52b525c7.0 new file mode 100644 index 0000000000000000000000000000000000000000..1a0c2e285ff94f867385bb83894e2d0b2cac502f Binary files /dev/null and b/config/systemCertificates/52b525c7.0 differ diff --git a/config/systemCertificates/583d0756.0 b/config/systemCertificates/583d0756.0 new file mode 100644 index 0000000000000000000000000000000000000000..75084805caf9a934724bfc907024692a58955f06 Binary files /dev/null and b/config/systemCertificates/583d0756.0 differ diff --git a/config/systemCertificates/5a250ea7.0 b/config/systemCertificates/5a250ea7.0 new file mode 100644 index 0000000000000000000000000000000000000000..c4cc8bb3c37a139bf2818ef224400b922a769997 Binary files /dev/null and b/config/systemCertificates/5a250ea7.0 differ diff --git a/config/systemCertificates/5a3f0ff8.0 b/config/systemCertificates/5a3f0ff8.0 new file mode 100644 index 0000000000000000000000000000000000000000..423a2be0636f4772c79e7c6031263e37cb88a072 Binary files /dev/null and b/config/systemCertificates/5a3f0ff8.0 differ diff --git a/config/systemCertificates/5acf816d.0 b/config/systemCertificates/5acf816d.0 new file mode 100644 index 0000000000000000000000000000000000000000..13d993b9e85009d8c276340f3e375fcab5568907 Binary files /dev/null and b/config/systemCertificates/5acf816d.0 differ diff --git a/config/systemCertificates/5cf9d536.0 b/config/systemCertificates/5cf9d536.0 new file mode 100644 index 0000000000000000000000000000000000000000..77e783a39ac84e67b76804a293f287933df5a9cf Binary files /dev/null and b/config/systemCertificates/5cf9d536.0 differ diff --git a/config/systemCertificates/5f47b495.0 b/config/systemCertificates/5f47b495.0 new file mode 100644 index 0000000000000000000000000000000000000000..194de84d8ce9e2bf50334b34b7c32dcb7562af4d Binary files /dev/null and b/config/systemCertificates/5f47b495.0 differ diff --git a/config/systemCertificates/60afe812.0 b/config/systemCertificates/60afe812.0 new file mode 100644 index 0000000000000000000000000000000000000000..b40648ca3f9907728a575d3d29dfc9cd11eee0fd Binary files /dev/null and b/config/systemCertificates/60afe812.0 differ diff --git a/config/systemCertificates/6187b673.0 b/config/systemCertificates/6187b673.0 new file mode 100644 index 0000000000000000000000000000000000000000..9d2132e7f1e352fabac7eafb231488b5da91ffb2 Binary files /dev/null and b/config/systemCertificates/6187b673.0 differ diff --git a/config/systemCertificates/63a2c897.0 b/config/systemCertificates/63a2c897.0 new file mode 100644 index 0000000000000000000000000000000000000000..e8b22b7783eec2b75027fe83d32db8f9095cc4ae Binary files /dev/null and b/config/systemCertificates/63a2c897.0 differ diff --git a/config/systemCertificates/69105f4f.0 b/config/systemCertificates/69105f4f.0 new file mode 100644 index 0000000000000000000000000000000000000000..391ffc14d3d58e371d34cb61b6f6d7e875022792 Binary files /dev/null and b/config/systemCertificates/69105f4f.0 differ diff --git a/config/systemCertificates/6b03dec0.0 b/config/systemCertificates/6b03dec0.0 new file mode 100644 index 0000000000000000000000000000000000000000..310219dfa956b8ac16752f89ea95c10e1b993d87 Binary files /dev/null and b/config/systemCertificates/6b03dec0.0 differ diff --git a/config/systemCertificates/75680d2e.0 b/config/systemCertificates/75680d2e.0 new file mode 100644 index 0000000000000000000000000000000000000000..5c715faed85eae3569262d7f3dd3fa93a62dff60 Binary files /dev/null and b/config/systemCertificates/75680d2e.0 differ diff --git a/config/systemCertificates/76579174.0 b/config/systemCertificates/76579174.0 new file mode 100644 index 0000000000000000000000000000000000000000..8c5b0c061f52df665b673dfb787b0780250ed9dd Binary files /dev/null and b/config/systemCertificates/76579174.0 differ diff --git a/config/systemCertificates/7892ad52.0 b/config/systemCertificates/7892ad52.0 new file mode 100644 index 0000000000000000000000000000000000000000..c55cb68833c0b472a02ef4356c8a08c6ed0ec319 Binary files /dev/null and b/config/systemCertificates/7892ad52.0 differ diff --git a/config/systemCertificates/7a7c655d.0 b/config/systemCertificates/7a7c655d.0 new file mode 100644 index 0000000000000000000000000000000000000000..7a991b766c37179da1de553d53c9b6d9b0c0190b Binary files /dev/null and b/config/systemCertificates/7a7c655d.0 differ diff --git a/config/systemCertificates/7a819ef2.0 b/config/systemCertificates/7a819ef2.0 new file mode 100644 index 0000000000000000000000000000000000000000..42127f823686338b34166e3ecf1b2e27d84535e0 Binary files /dev/null and b/config/systemCertificates/7a819ef2.0 differ diff --git a/config/systemCertificates/7c302982.0 b/config/systemCertificates/7c302982.0 new file mode 100644 index 0000000000000000000000000000000000000000..662b094951cf68cd45c1daa762f463f69dce016b Binary files /dev/null and b/config/systemCertificates/7c302982.0 differ diff --git a/config/systemCertificates/81b9768f.0 b/config/systemCertificates/81b9768f.0 new file mode 100644 index 0000000000000000000000000000000000000000..dae0196507d9166bbf9de6ed93ed5bd91d2a6f7c Binary files /dev/null and b/config/systemCertificates/81b9768f.0 differ diff --git a/config/systemCertificates/82223c44.0 b/config/systemCertificates/82223c44.0 new file mode 100644 index 0000000000000000000000000000000000000000..47d3400beb8045c2698e334efc202e160d3b205f Binary files /dev/null and b/config/systemCertificates/82223c44.0 differ diff --git a/config/systemCertificates/83e9984f.0 b/config/systemCertificates/83e9984f.0 new file mode 100644 index 0000000000000000000000000000000000000000..6eb01cc84d343fbdcef5934f70abecd93db5593b Binary files /dev/null and b/config/systemCertificates/83e9984f.0 differ diff --git a/config/systemCertificates/85cde254.0 b/config/systemCertificates/85cde254.0 new file mode 100644 index 0000000000000000000000000000000000000000..cf6588c801db52a03751774b92da032ff0c00fa8 Binary files /dev/null and b/config/systemCertificates/85cde254.0 differ diff --git a/config/systemCertificates/86212b19.0 b/config/systemCertificates/86212b19.0 new file mode 100644 index 0000000000000000000000000000000000000000..d64e89dec68ce83c11ddd3a04c24439db34a807c Binary files /dev/null and b/config/systemCertificates/86212b19.0 differ diff --git a/config/systemCertificates/869fbf79.0 b/config/systemCertificates/869fbf79.0 new file mode 100644 index 0000000000000000000000000000000000000000..1ff0c9cf054ea45c3944aeb5ac6035e0362135fb Binary files /dev/null and b/config/systemCertificates/869fbf79.0 differ diff --git a/config/systemCertificates/882de061.0 b/config/systemCertificates/882de061.0 new file mode 100644 index 0000000000000000000000000000000000000000..f49be65d6093ff1e64e3c8771c58d744684ceb2c Binary files /dev/null and b/config/systemCertificates/882de061.0 differ diff --git a/config/systemCertificates/88950faa.0 b/config/systemCertificates/88950faa.0 new file mode 100644 index 0000000000000000000000000000000000000000..2913bb06fb98e842ac0361867582aac63e9f7932 Binary files /dev/null and b/config/systemCertificates/88950faa.0 differ diff --git a/config/systemCertificates/89c02a45.0 b/config/systemCertificates/89c02a45.0 new file mode 100644 index 0000000000000000000000000000000000000000..9e42698728dd31fa171527c1f0ba5bbf0994c2d8 Binary files /dev/null and b/config/systemCertificates/89c02a45.0 differ diff --git a/config/systemCertificates/8d6437c3.0 b/config/systemCertificates/8d6437c3.0 new file mode 100644 index 0000000000000000000000000000000000000000..40db2f333a839819fc315dc43e7fb5c5fe6a9b80 Binary files /dev/null and b/config/systemCertificates/8d6437c3.0 differ diff --git a/config/systemCertificates/9282e51c.0 b/config/systemCertificates/9282e51c.0 new file mode 100644 index 0000000000000000000000000000000000000000..cbccb435dde7829075f291c4f29f36df4fa5fc84 Binary files /dev/null and b/config/systemCertificates/9282e51c.0 differ diff --git a/config/systemCertificates/9339512a.0 b/config/systemCertificates/9339512a.0 new file mode 100644 index 0000000000000000000000000000000000000000..6410587fe66e459b9df9dee42a0211149212b348 Binary files /dev/null and b/config/systemCertificates/9339512a.0 differ diff --git a/config/systemCertificates/9479c8c3.0 b/config/systemCertificates/9479c8c3.0 new file mode 100644 index 0000000000000000000000000000000000000000..9519275a5d737dc4eda1a28957c2455192a9c7ad Binary files /dev/null and b/config/systemCertificates/9479c8c3.0 differ diff --git a/config/systemCertificates/9576d26b.0 b/config/systemCertificates/9576d26b.0 new file mode 100644 index 0000000000000000000000000000000000000000..e5e2343aa815011b5044128b849639f2971c30be Binary files /dev/null and b/config/systemCertificates/9576d26b.0 differ diff --git a/config/systemCertificates/9591a472.0 b/config/systemCertificates/9591a472.0 new file mode 100644 index 0000000000000000000000000000000000000000..7031f880679bd310f3a39ef7c48a20f9a5cf4cfa Binary files /dev/null and b/config/systemCertificates/9591a472.0 differ diff --git a/config/systemCertificates/95aff9e3.0 b/config/systemCertificates/95aff9e3.0 new file mode 100644 index 0000000000000000000000000000000000000000..cf29ccc1b794186fe4c9689bfdfddb232c2b45bd Binary files /dev/null and b/config/systemCertificates/95aff9e3.0 differ diff --git a/config/systemCertificates/9685a493.0 b/config/systemCertificates/9685a493.0 new file mode 100644 index 0000000000000000000000000000000000000000..19f91c27e6151c05dc3d0db9460831d30a63f74b Binary files /dev/null and b/config/systemCertificates/9685a493.0 differ diff --git a/config/systemCertificates/985c1f52.0 b/config/systemCertificates/985c1f52.0 new file mode 100644 index 0000000000000000000000000000000000000000..3492b9555d8a927fc048accbdfd510d973a4bf8a Binary files /dev/null and b/config/systemCertificates/985c1f52.0 differ diff --git a/config/systemCertificates/9aef356c.0 b/config/systemCertificates/9aef356c.0 new file mode 100644 index 0000000000000000000000000000000000000000..684b051d9c6e4c99b33a0260b2491f20fdd56abd Binary files /dev/null and b/config/systemCertificates/9aef356c.0 differ diff --git a/config/systemCertificates/9d6523ce.0 b/config/systemCertificates/9d6523ce.0 new file mode 100644 index 0000000000000000000000000000000000000000..2ae55653898a9f1c3e47db696d90461de815f4b9 Binary files /dev/null and b/config/systemCertificates/9d6523ce.0 differ diff --git a/config/systemCertificates/9f533518.0 b/config/systemCertificates/9f533518.0 new file mode 100644 index 0000000000000000000000000000000000000000..74d17527c2ebb7dee136eef4496ec192d0e2e111 Binary files /dev/null and b/config/systemCertificates/9f533518.0 differ diff --git a/config/systemCertificates/a2c66da8.0 b/config/systemCertificates/a2c66da8.0 new file mode 100644 index 0000000000000000000000000000000000000000..99bcc84b7e68b5b28e4444f6fa21bc7c2baf497d Binary files /dev/null and b/config/systemCertificates/a2c66da8.0 differ diff --git a/config/systemCertificates/a3896b44.0 b/config/systemCertificates/a3896b44.0 new file mode 100644 index 0000000000000000000000000000000000000000..27d0266c51590d8c9b59f40957ce1e9ca390ac44 Binary files /dev/null and b/config/systemCertificates/a3896b44.0 differ diff --git a/config/systemCertificates/a7605362.0 b/config/systemCertificates/a7605362.0 new file mode 100644 index 0000000000000000000000000000000000000000..85c1c66bfee13097c9f6759700e86f10cdc0b4d7 Binary files /dev/null and b/config/systemCertificates/a7605362.0 differ diff --git a/config/systemCertificates/a81e292b.0 b/config/systemCertificates/a81e292b.0 new file mode 100644 index 0000000000000000000000000000000000000000..316a530a8126dfde6b2a51cf3bf0a21ff3308aee Binary files /dev/null and b/config/systemCertificates/a81e292b.0 differ diff --git a/config/systemCertificates/a9d40e02.0 b/config/systemCertificates/a9d40e02.0 new file mode 100644 index 0000000000000000000000000000000000000000..d5f8989dce1564daf6738935bcd542e65722375d Binary files /dev/null and b/config/systemCertificates/a9d40e02.0 differ diff --git a/config/systemCertificates/ab5346f4.0 b/config/systemCertificates/ab5346f4.0 new file mode 100644 index 0000000000000000000000000000000000000000..1f36f7c0c0c389c7566630eaf370a2a4a4f8f384 Binary files /dev/null and b/config/systemCertificates/ab5346f4.0 differ diff --git a/config/systemCertificates/ab59055e.0 b/config/systemCertificates/ab59055e.0 new file mode 100644 index 0000000000000000000000000000000000000000..e99af2e398cefbd29f07369b15f3b7fc451d8635 Binary files /dev/null and b/config/systemCertificates/ab59055e.0 differ diff --git a/config/systemCertificates/aeb67534.0 b/config/systemCertificates/aeb67534.0 new file mode 100644 index 0000000000000000000000000000000000000000..f1317bf3b2bdd38c9d3e97f65379e76cbcc0ef37 Binary files /dev/null and b/config/systemCertificates/aeb67534.0 differ diff --git a/config/systemCertificates/b0ed035a.0 b/config/systemCertificates/b0ed035a.0 new file mode 100644 index 0000000000000000000000000000000000000000..6927c52beb79d15a2169b05277faa8545efa2f4e Binary files /dev/null and b/config/systemCertificates/b0ed035a.0 differ diff --git a/config/systemCertificates/b0f3e76e.0 b/config/systemCertificates/b0f3e76e.0 new file mode 100644 index 0000000000000000000000000000000000000000..1e6967febb897f69cc81064c6ba584fc91bcfb13 Binary files /dev/null and b/config/systemCertificates/b0f3e76e.0 differ diff --git a/config/systemCertificates/b3fb433b.0 b/config/systemCertificates/b3fb433b.0 new file mode 100644 index 0000000000000000000000000000000000000000..ae9933cab4f4f764f56a9dcd4715a0ddace1f809 Binary files /dev/null and b/config/systemCertificates/b3fb433b.0 differ diff --git a/config/systemCertificates/b74d2bd5.0 b/config/systemCertificates/b74d2bd5.0 new file mode 100644 index 0000000000000000000000000000000000000000..235e1868581921cf51a8c6a0ef2eb6b70e80804b Binary files /dev/null and b/config/systemCertificates/b74d2bd5.0 differ diff --git a/config/systemCertificates/b7db1890.0 b/config/systemCertificates/b7db1890.0 new file mode 100644 index 0000000000000000000000000000000000000000..d0e8f0bd110db8e87ddcfb7a31663be8ec075664 Binary files /dev/null and b/config/systemCertificates/b7db1890.0 differ diff --git a/config/systemCertificates/b872f2b4.0 b/config/systemCertificates/b872f2b4.0 new file mode 100644 index 0000000000000000000000000000000000000000..556e55d2901f8c6d2d8d6ec0ff68a5df63e04854 Binary files /dev/null and b/config/systemCertificates/b872f2b4.0 differ diff --git a/config/systemCertificates/b936d1c6.0 b/config/systemCertificates/b936d1c6.0 new file mode 100644 index 0000000000000000000000000000000000000000..d6aa0f435805de638e5c6cac066ebb0081fac3c4 Binary files /dev/null and b/config/systemCertificates/b936d1c6.0 differ diff --git a/config/systemCertificates/bc3f2570.0 b/config/systemCertificates/bc3f2570.0 new file mode 100644 index 0000000000000000000000000000000000000000..3cdad66612f4e8cc4818c314745d0fd7e5429ef7 Binary files /dev/null and b/config/systemCertificates/bc3f2570.0 differ diff --git a/config/systemCertificates/bd43e1dd.0 b/config/systemCertificates/bd43e1dd.0 new file mode 100644 index 0000000000000000000000000000000000000000..91d8e47bc5096b56a9f08bf4c263551c2bc465c0 Binary files /dev/null and b/config/systemCertificates/bd43e1dd.0 differ diff --git a/config/systemCertificates/bdacca6f.0 b/config/systemCertificates/bdacca6f.0 new file mode 100644 index 0000000000000000000000000000000000000000..a601da5ded063e97190e5564bdc29d39f46cc235 Binary files /dev/null and b/config/systemCertificates/bdacca6f.0 differ diff --git a/config/systemCertificates/bf64f35b.0 b/config/systemCertificates/bf64f35b.0 new file mode 100644 index 0000000000000000000000000000000000000000..6590868cc391ba2bbd4c2757dc4e55617c91512e Binary files /dev/null and b/config/systemCertificates/bf64f35b.0 differ diff --git a/config/systemCertificates/c2c1704e.0 b/config/systemCertificates/c2c1704e.0 new file mode 100644 index 0000000000000000000000000000000000000000..bc42b2d8da356a2f403d4004d30e41925afe1588 Binary files /dev/null and b/config/systemCertificates/c2c1704e.0 differ diff --git a/config/systemCertificates/c491639e.0 b/config/systemCertificates/c491639e.0 new file mode 100644 index 0000000000000000000000000000000000000000..e18997f41000c0924f0a23a6897a1ed087852e7e Binary files /dev/null and b/config/systemCertificates/c491639e.0 differ diff --git a/config/systemCertificates/c51c224c.0 b/config/systemCertificates/c51c224c.0 new file mode 100644 index 0000000000000000000000000000000000000000..e79ccd2cbcb905153e1f396ce2f718e139a2860c Binary files /dev/null and b/config/systemCertificates/c51c224c.0 differ diff --git a/config/systemCertificates/c559d742.0 b/config/systemCertificates/c559d742.0 new file mode 100644 index 0000000000000000000000000000000000000000..79e2a480be60cbd7aa27a96251abfe7058d4b9b0 Binary files /dev/null and b/config/systemCertificates/c559d742.0 differ diff --git a/config/systemCertificates/c90bc37d.0 b/config/systemCertificates/c90bc37d.0 new file mode 100644 index 0000000000000000000000000000000000000000..1e927a7afe06c270670d6bc25c4d465db2e0a7e8 Binary files /dev/null and b/config/systemCertificates/c90bc37d.0 differ diff --git a/config/systemCertificates/cb156124.0 b/config/systemCertificates/cb156124.0 new file mode 100644 index 0000000000000000000000000000000000000000..ed68c11b82371f71b634b4f51834fc3cb10d6741 Binary files /dev/null and b/config/systemCertificates/cb156124.0 differ diff --git a/config/systemCertificates/cb1c3204.0 b/config/systemCertificates/cb1c3204.0 new file mode 100644 index 0000000000000000000000000000000000000000..d46aa38fd937d6cb86c99eba2dd0c38d1e6229cc Binary files /dev/null and b/config/systemCertificates/cb1c3204.0 differ diff --git a/config/systemCertificates/ccc52f49.0 b/config/systemCertificates/ccc52f49.0 new file mode 100644 index 0000000000000000000000000000000000000000..c5c8fe33c291164619f64e554bda4deae3115084 Binary files /dev/null and b/config/systemCertificates/ccc52f49.0 differ diff --git a/config/systemCertificates/cf701eeb.0 b/config/systemCertificates/cf701eeb.0 new file mode 100644 index 0000000000000000000000000000000000000000..d327a3af2d24e815a3d4b42eb8cf506486cecf9d Binary files /dev/null and b/config/systemCertificates/cf701eeb.0 differ diff --git a/config/systemCertificates/d06393bb.0 b/config/systemCertificates/d06393bb.0 new file mode 100644 index 0000000000000000000000000000000000000000..0911a562934374fbb203efb9d9d94edf0eb1d0b3 Binary files /dev/null and b/config/systemCertificates/d06393bb.0 differ diff --git a/config/systemCertificates/d0cddf45.0 b/config/systemCertificates/d0cddf45.0 new file mode 100644 index 0000000000000000000000000000000000000000..8f8493b5e37c9e96395026c35c15787e2987b474 Binary files /dev/null and b/config/systemCertificates/d0cddf45.0 differ diff --git a/config/systemCertificates/d16a5865.0 b/config/systemCertificates/d16a5865.0 new file mode 100644 index 0000000000000000000000000000000000000000..b188fea1e9a7766dcb9cca02c82d5e8c4fed639f Binary files /dev/null and b/config/systemCertificates/d16a5865.0 differ diff --git a/config/systemCertificates/d18e9066.0 b/config/systemCertificates/d18e9066.0 new file mode 100644 index 0000000000000000000000000000000000000000..ff212ef71504fa5f8b59f6d643783f7f0b4ad60b Binary files /dev/null and b/config/systemCertificates/d18e9066.0 differ diff --git a/config/systemCertificates/d39b0a2c.0 b/config/systemCertificates/d39b0a2c.0 new file mode 100644 index 0000000000000000000000000000000000000000..bcafb43bea2ff5306b4e037e85359aaf537b0e5f Binary files /dev/null and b/config/systemCertificates/d39b0a2c.0 differ diff --git a/config/systemCertificates/d41b5e2a.0 b/config/systemCertificates/d41b5e2a.0 new file mode 100644 index 0000000000000000000000000000000000000000..10ef4413d71f2d7bea1f20618459f1eb18311119 Binary files /dev/null and b/config/systemCertificates/d41b5e2a.0 differ diff --git a/config/systemCertificates/d4c339cb.0 b/config/systemCertificates/d4c339cb.0 new file mode 100644 index 0000000000000000000000000000000000000000..83fdeb776b5d848d48813c0e7346b1c9a2562b91 Binary files /dev/null and b/config/systemCertificates/d4c339cb.0 differ diff --git a/config/systemCertificates/d59297b8.0 b/config/systemCertificates/d59297b8.0 new file mode 100644 index 0000000000000000000000000000000000000000..a42b51999e61426079da0e4a7399e6d3888d586b Binary files /dev/null and b/config/systemCertificates/d59297b8.0 differ diff --git a/config/systemCertificates/d7746a63.0 b/config/systemCertificates/d7746a63.0 new file mode 100644 index 0000000000000000000000000000000000000000..c4347d3f5249399da3622cbe92e6efac8511c503 Binary files /dev/null and b/config/systemCertificates/d7746a63.0 differ diff --git a/config/systemCertificates/da7377f6.0 b/config/systemCertificates/da7377f6.0 new file mode 100644 index 0000000000000000000000000000000000000000..16a364ddbbf340861268c296c91a2277147e7739 Binary files /dev/null and b/config/systemCertificates/da7377f6.0 differ diff --git a/config/systemCertificates/dbc54cab.0 b/config/systemCertificates/dbc54cab.0 new file mode 100644 index 0000000000000000000000000000000000000000..832df1d8219ae219f28c393def73495c5cd6a617 Binary files /dev/null and b/config/systemCertificates/dbc54cab.0 differ diff --git a/config/systemCertificates/dbff3a01.0 b/config/systemCertificates/dbff3a01.0 new file mode 100644 index 0000000000000000000000000000000000000000..5a3dc5093cf825f6172ccf9b5862018079b598ec Binary files /dev/null and b/config/systemCertificates/dbff3a01.0 differ diff --git a/config/systemCertificates/dc99f41e.0 b/config/systemCertificates/dc99f41e.0 new file mode 100644 index 0000000000000000000000000000000000000000..96e02ca8d4c522b0f0b31433a56bc34a52fd3a38 Binary files /dev/null and b/config/systemCertificates/dc99f41e.0 differ diff --git a/config/systemCertificates/dfc0fe80.0 b/config/systemCertificates/dfc0fe80.0 new file mode 100644 index 0000000000000000000000000000000000000000..616047950db54c16921f77495aeae1e84a603d16 Binary files /dev/null and b/config/systemCertificates/dfc0fe80.0 differ diff --git a/config/systemCertificates/e442e424.0 b/config/systemCertificates/e442e424.0 new file mode 100644 index 0000000000000000000000000000000000000000..3f6981b6bc02fe7a08069effe16ea43ca8633607 Binary files /dev/null and b/config/systemCertificates/e442e424.0 differ diff --git a/config/systemCertificates/e48193cf.0 b/config/systemCertificates/e48193cf.0 new file mode 100644 index 0000000000000000000000000000000000000000..ac4443c70d12575d5be3907e6a217f33bbb478ba Binary files /dev/null and b/config/systemCertificates/e48193cf.0 differ diff --git a/config/systemCertificates/e8651083.0 b/config/systemCertificates/e8651083.0 new file mode 100644 index 0000000000000000000000000000000000000000..db0e85a5da32a3aef203bc6279821cd6441d21f0 Binary files /dev/null and b/config/systemCertificates/e8651083.0 differ diff --git a/config/systemCertificates/ed39abd0.0 b/config/systemCertificates/ed39abd0.0 new file mode 100644 index 0000000000000000000000000000000000000000..6dda6a38dc3d4d361acd02e4b52d4759d26ca563 Binary files /dev/null and b/config/systemCertificates/ed39abd0.0 differ diff --git a/config/systemCertificates/edcbddb5.0 b/config/systemCertificates/edcbddb5.0 new file mode 100644 index 0000000000000000000000000000000000000000..cef2834a83ce18346f5b40e9bf712ddb08a47f0f Binary files /dev/null and b/config/systemCertificates/edcbddb5.0 differ diff --git a/config/systemCertificates/f013ecaf.0 b/config/systemCertificates/f013ecaf.0 new file mode 100644 index 0000000000000000000000000000000000000000..c0310642c08c8930b7b3c7330bf12d77539e33ed Binary files /dev/null and b/config/systemCertificates/f013ecaf.0 differ diff --git a/config/systemCertificates/f0cd152c.0 b/config/systemCertificates/f0cd152c.0 new file mode 100644 index 0000000000000000000000000000000000000000..1c74b84d60b6cc899d337a1ea61debeeeacf351d Binary files /dev/null and b/config/systemCertificates/f0cd152c.0 differ diff --git a/config/systemCertificates/f459871d.0 b/config/systemCertificates/f459871d.0 new file mode 100644 index 0000000000000000000000000000000000000000..675cbeb1fe2031aad2cdfddc00627f9daa113bc3 Binary files /dev/null and b/config/systemCertificates/f459871d.0 differ diff --git a/config/systemCertificates/fb5fa911.0 b/config/systemCertificates/fb5fa911.0 new file mode 100644 index 0000000000000000000000000000000000000000..86d70df56ac1baf2944e3de7e6dd95e3d5c4812b Binary files /dev/null and b/config/systemCertificates/fb5fa911.0 differ diff --git a/config/systemCertificates/fd08c599.0 b/config/systemCertificates/fd08c599.0 new file mode 100644 index 0000000000000000000000000000000000000000..86b7dcd0b416fcbfd1636f5c019403ede4ddb413 Binary files /dev/null and b/config/systemCertificates/fd08c599.0 differ diff --git a/config/systemCertificates/fde84897.0 b/config/systemCertificates/fde84897.0 new file mode 100644 index 0000000000000000000000000000000000000000..8a3782c78c2702b7bb2354de74cec53919b3e402 Binary files /dev/null and b/config/systemCertificates/fde84897.0 differ diff --git a/frameworks/cert_manager_standard/main/BUILD.gn b/frameworks/cert_manager_standard/main/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..6223808dde8c0a5e752fde648d166471e6beb86c --- /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 0000000000000000000000000000000000000000..f7afc908201f0b495186ed50d6cd9e3fdb6f4189 --- /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 0000000000000000000000000000000000000000..5ae7392388024bf05d594a629ed466027881a39f --- /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 0000000000000000000000000000000000000000..b627d9c19a1014cde7096d09750be0e46dc7c1bd --- /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 0000000000000000000000000000000000000000..d4b27fbf4d8ceffcc81c2d0511c7b3c9534adceb --- /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 0000000000000000000000000000000000000000..e2265ca69d15e8b48428bb123ea87ab207e92d80 --- /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 0000000000000000000000000000000000000000..ce8689231fe6c827216d93ac4b5eea070472d3af --- /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 0000000000000000000000000000000000000000..df4928b036becb045b863ffb9053c4c6699d46f7 --- /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 0000000000000000000000000000000000000000..3bd47ff9b62f49eb4657fce1ee5d93ab6619886c --- /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 0000000000000000000000000000000000000000..c44561f323728c5968fde392145a839de0956d7b --- /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 0000000000000000000000000000000000000000..0ca733c935b69a770206b1edb03b76cfdca3a699 --- /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 0000000000000000000000000000000000000000..711576a2c490c717d5ddf4b166545621f54f1cdb --- /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 0000000000000000000000000000000000000000..ec96bba6a4abbb2e6de0be5674af157ae0627be8 --- /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 0000000000000000000000000000000000000000..5d9cd799d656893439a2a7e43109d98273b7e3a7 --- /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 0000000000000000000000000000000000000000..f2820122c4d6d311053d1dbfaedfe42c7653c9fc --- /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 0000000000000000000000000000000000000000..53fe066d0f043d87a04903101d16212f224d6a0d --- /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 0000000000000000000000000000000000000000..95213286003ca76cffa7d7fa53d55a652acf7ca3 --- /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 0000000000000000000000000000000000000000..0ff5b22f05383eb08c25f13307bbb05a4614219c --- /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 0000000000000000000000000000000000000000..cc55a82b925fa8a063385b01da6c0eb1fbba490e --- /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 0000000000000000000000000000000000000000..32a09a376b45fb120272102881818062977da2ba --- /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 0000000000000000000000000000000000000000..9396c4fa2938f8506a8bef2960ba32c795ca9bdc --- /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 0000000000000000000000000000000000000000..8b53bbabc1a55eb6c112a1e989132358d56b91c9 --- /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 0000000000000000000000000000000000000000..25a640bcb5af218cb9dc7f65777425f46535b175 --- /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 0000000000000000000000000000000000000000..f99882927ad8213eac3bde8621bc0065c2c8b85c --- /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 0000000000000000000000000000000000000000..e2aa996a94d56390cb417f6c68a81c9872aae01b --- /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 0000000000000000000000000000000000000000..13addacc8ca2bf801f7547c144735017ec8de8eb --- /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 0000000000000000000000000000000000000000..222e3563749d1b76e31633538e1b2054e206a3f2 --- /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 0000000000000000000000000000000000000000..396073f6fef70f4e9aef38670415c7aa1362ba2e --- /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 0000000000000000000000000000000000000000..da7d7f3006f32da8dbb47d0acb5e51afbb592db3 --- /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 0000000000000000000000000000000000000000..2871494819aa47f32738b44fee3e670f60e63621 --- /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 0000000000000000000000000000000000000000..c6c41e7f454393d286d5c7777a95639702fe4a57 --- /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 0000000000000000000000000000000000000000..7628a0ee41dcff9fae046981f4d240dbd006c935 --- /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 0000000000000000000000000000000000000000..867da4f44692657a156e9d5bcdeea104dc467f7c --- /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 0000000000000000000000000000000000000000..610eaec66b1595f62474d6c641b13baa0ef680f8 --- /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 0000000000000000000000000000000000000000..405172c9c0125aebf273be1c4b64e92a7c7e761b --- /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 0000000000000000000000000000000000000000..43bce8b394d74bc192c8808794fa16ab0ffb7ded --- /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 0000000000000000000000000000000000000000..6ab7782815de2f91dd6283b77cdac2d89d93eceb --- /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 0000000000000000000000000000000000000000..7c34ec3cb55aaffa5fa04e8915b8fb9d704c43b7 --- /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 0000000000000000000000000000000000000000..738f12a6c9f6af258409552321d2561f76f9133f --- /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 0000000000000000000000000000000000000000..3b5f8c9831bfd3e54cc36e279f738c2a09f88a70 --- /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 0000000000000000000000000000000000000000..9d9774c9ebfae558fc36c67da299f78ee428cec9 --- /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 0000000000000000000000000000000000000000..0cbbff8d41aaa9c7172449da89ebabd667de6264 --- /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 0000000000000000000000000000000000000000..526acdb65584cd315f00f804baf9adfa3606d50c --- /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 0000000000000000000000000000000000000000..ba8bb1b56070516d1d0e4cad2262014fad095598 --- /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 0000000000000000000000000000000000000000..9a40f4173676a8364f6a91e140be475ea04cabfc --- /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 0000000000000000000000000000000000000000..e5faead7ada40f69c3f8e51929b8ad5986eb3cf3 --- /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 0000000000000000000000000000000000000000..a3b098d577fd813133df4ebc4eaff4f4d50baeb3 --- /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 0000000000000000000000000000000000000000..8d7ae89b4f19458872ec8225f996f910465dd61a --- /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 0000000000000000000000000000000000000000..5cf152c833d22f96005c1f5f9f57a1f7f41b59d3 --- /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 0000000000000000000000000000000000000000..2ff0711fdde5f3d5b867b341db8435778dd7a10a --- /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 0000000000000000000000000000000000000000..132e7332f357aca1826a6371ca089a663ac7eda0 --- /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 0000000000000000000000000000000000000000..1d517437797d0e0c68cbdd08a6772cc52462858c --- /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 0000000000000000000000000000000000000000..f4ac423d5914bd9385cbe2a7c882768d1db832bd --- /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 0000000000000000000000000000000000000000..991b74af1e2cb0fe141f6b418371b82bbb640fcb --- /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 0000000000000000000000000000000000000000..9d7dceb11c46667aec9623c127dda57f10ead51e --- /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 0000000000000000000000000000000000000000..effc3a92a3466956a975cd17ebca468b590ad912 --- /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 0000000000000000000000000000000000000000..f3ca2a47d5df1e3fea177d5a83b93f7b3914f941 --- /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 0000000000000000000000000000000000000000..d090ece24b544e511c2f79e4a3d3ad3efa00a3da --- /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 0000000000000000000000000000000000000000..e65dc3d3bb7ffacf45ad86ab30f75329aa2f894f --- /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 0000000000000000000000000000000000000000..62eb359e8afa9808c45435e02bb7edf525752b72 --- /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 0000000000000000000000000000000000000000..fb417320d73be76cfac9f38700d77f96995d32d3 --- /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 0000000000000000000000000000000000000000..9f81cd44a6e4e015bdf84237047a680f6a4433b9 --- /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 0000000000000000000000000000000000000000..31b1ffb957d45cbd8fd3e0ea0eaadc8baff7bdb8 --- /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 0000000000000000000000000000000000000000..3264a8e1ab03d8c49037efc645208b88ae5e9595 --- /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 0000000000000000000000000000000000000000..d7e88b00af47afa791e743c3b6c8ee77dafda34a --- /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 0000000000000000000000000000000000000000..1369be0857dad77556a2caaa21c7eb92faca464a --- /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 0000000000000000000000000000000000000000..f7127bd5ec758eda3f545b9e83bde5ec6fca0bd1 --- /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 0000000000000000000000000000000000000000..d5fbf8e7a496ad394b142bd36dd581aba7de2258 --- /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 0000000000000000000000000000000000000000..9f4dc25f607f51a269bc6b5603ed162e12ac6533 --- /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 0000000000000000000000000000000000000000..e576d125dda7347f8921212191969171b3cbe8a8 --- /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 0000000000000000000000000000000000000000..b5b3b75f87c4c53a6aa2471aa5f5f2acf952e20f --- /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 0000000000000000000000000000000000000000..722c085f564a6d7e9862f7f07356c25bd699faaf --- /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 0000000000000000000000000000000000000000..d4206452517a819998b1b8544202d24033295452 --- /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 0000000000000000000000000000000000000000..ff7f86423bb54e898ed6d251adb4c1a939ddd2bd --- /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 0000000000000000000000000000000000000000..70b461307df1cbded888f13a622cec70d0789f1c --- /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 0000000000000000000000000000000000000000..a42e82b25dfa5a6659e7ebd61828cb61e615c707 --- /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 0000000000000000000000000000000000000000..50a3be7fd444b96727a3c17decc962b814671030 --- /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 0000000000000000000000000000000000000000..a63ef259dbf7e69d205b529ef6277359bc371f72 --- /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 0000000000000000000000000000000000000000..df51d06ad00327bdac39a556c6257b6ccf55f2af --- /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 0000000000000000000000000000000000000000..a3eceaaa98736c969a742a029e4a9b144da12ff5 --- /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 0000000000000000000000000000000000000000..71ca5ca2117382c9fcc8fd20562efc5fc765d960 --- /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 0000000000000000000000000000000000000000..012408f620d1397cb3ebe39a4fd9261a09cd99df --- /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 0000000000000000000000000000000000000000..acc0349b71e1cd0047c9bd3fe95fc6a5ef89eb5d --- /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 0000000000000000000000000000000000000000..28db760f9be192357e5201fc32a3dbfeadf4a806 --- /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 0000000000000000000000000000000000000000..19cab48d4022d86f59a1311d864e2c538ea6d232 --- /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 0000000000000000000000000000000000000000..f5ef13418fb5f0268c369982ac6c6e5c3368dc56 --- /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 0000000000000000000000000000000000000000..083c8492c46ed11992088d1d7af532508f0fa4b2 --- /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 0000000000000000000000000000000000000000..6156f20a4ba21ca3e95c8e7e5f6a11d8a94a73eb --- /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 0000000000000000000000000000000000000000..6a0376806f74510273fb671b8f034ffd5c2685da --- /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 0000000000000000000000000000000000000000..48a28e307d424ab8a169e536bcc141111c9d441a --- /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 0000000000000000000000000000000000000000..24c9ba03d6b66828687eace4910fbcdacce26c48 --- /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 0000000000000000000000000000000000000000..442d1316cffb9221cbe2ec04108d5115c23cda56 --- /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 0000000000000000000000000000000000000000..e6feb1e37d4d4b48f6de2e99c9680f1643cc4c6e --- /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 0000000000000000000000000000000000000000..dfad3068b94db61f2e2a2dc25f957cb003cf2570 --- /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 0000000000000000000000000000000000000000..6d3ceb6ef7c95a0191063d9a1027d8eb4a096d93 --- /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 0000000000000000000000000000000000000000..f89885a24722020844a25b470067b2adcff2fd4b --- /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 0000000000000000000000000000000000000000..6430097bc6a10619e4f563ad45ee2ea55bc315f4 --- /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 0000000000000000000000000000000000000000..5e04eeaabaf87f2af80f69c5ca9e3e8dcb86afa5 --- /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 0000000000000000000000000000000000000000..e6510032b4cdf28885ea2e3a40dd10ef45c51b70 --- /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 0000000000000000000000000000000000000000..997873918f08072d3a811c999708433f8fd416a1 --- /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 0000000000000000000000000000000000000000..f332bf855db93399be5cadcb62ce7fd36fcca67f --- /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 0000000000000000000000000000000000000000..59d991ef47be19f23a56fe1065e13095f0a2db3e --- /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 0000000000000000000000000000000000000000..8b89b23dd0a45c79f98f7978b1e2b263fbe0127f --- /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 0000000000000000000000000000000000000000..02edce2d4967cebd2fd5079a7438b340d66f2048 --- /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 0000000000000000000000000000000000000000..3ba5b1cb089d771d6bc915da1d587057f93e4828 --- /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 0000000000000000000000000000000000000000..1add328e24f2dfefd5cb194c3ec3b462ae9754a2 --- /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 0000000000000000000000000000000000000000..e5539a7ec362a0a64e79e047a7fa69c9a5978f82 --- /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 0000000000000000000000000000000000000000..73d8f936d7450c8de999bf2261bd1eed732a4e7b --- /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 0000000000000000000000000000000000000000..06654ff4d94d710d5539f77cef96cb72b0500242 --- /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 0000000000000000000000000000000000000000..7f8d848f517d6aac0898248051b9620bb98b0730 --- /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 0000000000000000000000000000000000000000..5f0370ad97ef9d8a83c9a3a7eaefe65b3f36f597 --- /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 0000000000000000000000000000000000000000..e3d5a3c503597c311900bebf69d06c524e2cba22 --- /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 0000000000000000000000000000000000000000..c8ff9cf7d1c1c9c9cf06963d20939cc19c706ecc --- /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 0000000000000000000000000000000000000000..79098bc52be1a0c859ad9a0e8451b71d1d110dac --- /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 0000000000000000000000000000000000000000..b2c2a9dca44ba4c54ae2fdbdf273f00b69683bac --- /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 0000000000000000000000000000000000000000..6aed30de2c52f59fe4b62062e740028689b6b719 --- /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 0000000000000000000000000000000000000000..fcb29380b9096c8a0de48af1d0f8589efdee4ed0 --- /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 0000000000000000000000000000000000000000..10154fe6dcaddec6c9e062a6403da752bfbbd34f --- /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 0000000000000000000000000000000000000000..de43712e46709ded91c776bd46bd50124024e356 --- /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 0000000000000000000000000000000000000000..e8b7f3794db330e23dc38a015094d008087dd0bd --- /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 0000000000000000000000000000000000000000..e44be8e0f33aa42e69985b8bd2ab8237357658f3 --- /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 0000000000000000000000000000000000000000..6637c30c56ff08d8225e2c8a8856b6af19662df5 --- /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 0000000000000000000000000000000000000000..2a1f4ca8d86d6155daeaafc502ae23330eb94f2e --- /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 0000000000000000000000000000000000000000..e63775886666068556aa04d28bf4a8a545d0927b --- /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 0000000000000000000000000000000000000000..24efa79d6a2690a816da3b95a92e43dd570b078c --- /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 0000000000000000000000000000000000000000..7efe325d8ea41807496cf53233a7908c6e33abe9 --- /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 0000000000000000000000000000000000000000..e9c758804ab06e1750d12e8efe6064c53cee4ea1 --- /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 0000000000000000000000000000000000000000..e4df11ec4c0fec02e4e513d4c4c270b27b6b71c8 --- /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 0000000000000000000000000000000000000000..168617806c21ddb551fb530f56aff34d374e611e --- /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 0000000000000000000000000000000000000000..499334954b0a2212f3f975e496aaff3eae655c53 --- /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 0000000000000000000000000000000000000000..092cfa75587e33afab11617065e7783ca2e61351 --- /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 0000000000000000000000000000000000000000..71a5e3a1d8861e060b3fa9096d472fd15e774251 --- /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 0000000000000000000000000000000000000000..1aefab2040d6cd18278fbc6de5b1832e61177b0a --- /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 0000000000000000000000000000000000000000..958763f3b4b0112db5f6faa1b57819cc4f0484fe --- /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 0000000000000000000000000000000000000000..ad9a5143ee2cdd78211d5e824afc697909e34479 --- /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 0000000000000000000000000000000000000000..c432411b1b408342185eda82648e519a8b8fc09a --- /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 0000000000000000000000000000000000000000..ed66f766ebb8a9b516ba73002050b1f6c6b8a601 --- /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 0000000000000000000000000000000000000000..0b1e55b01e861876157ff61c5333a1911c091760 --- /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 0000000000000000000000000000000000000000..fc6490412d4476904d626110fe11c9a9fc2385f0 --- /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 0000000000000000000000000000000000000000..b9fc8cd711d5ae9d77d2ec226c002ecadee33188 --- /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 0000000000000000000000000000000000000000..71739e629a39005e6c660b9ec2449acc26f2f378 --- /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 0000000000000000000000000000000000000000..69c26b5e7fcde900b25fd4935ff52fd430354a9b --- /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 0000000000000000000000000000000000000000..6f37df89293ca82ac9c1cf65490472805deaaf34 --- /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 0000000000000000000000000000000000000000..46ad594d7db273826616226987e3db37ef60ddea --- /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