1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "init/trusted_source_manager.h"
17
18 #include "common/hap_verify_log.h"
19
20 namespace OHOS {
21 namespace Security {
22 namespace Verify {
23 const std::string TrustedSourceManager::APP_TRUSTED_SOURCE_FILE_PATH =
24 "/system/etc/security/trusted_apps_sources.json";
25 const std::string TrustedSourceManager::APP_TRUSTED_SOURCE_TEST_FILE_PATH =
26 "/system/etc/security/trusted_apps_sources_test.json";
27 const std::string TrustedSourceManager::KEY_OF_APP_TRUSTED_SOURCE = "trust-app-source";
28 const std::string TrustedSourceManager::KEY_OF_APP_TRUSTED_SOURCE_VERSION = "version";
29 const std::string TrustedSourceManager::KEY_OF_APP_TRUSTED_SOURCE_RELEASETIME = "release-time";
30 const std::string TrustedSourceManager::KEY_OF_SOURCE_NAME = "name";
31 const std::string TrustedSourceManager::KEY_OF_APP_SIGNING_CERT = "app-signing-cert";
32 const std::string TrustedSourceManager::KEY_OF_PROFILE_SIGNING_CERTIFICATE = "profile-signing-certificate";
33 const std::string TrustedSourceManager::KEY_OF_PROFILE_DEBUG_SIGNING_CERTIFICATE = "profile-debug-signing-certificate";
34 const std::string TrustedSourceManager::KEY_OF_ISSUER = "issuer-ca";
35 const std::string TrustedSourceManager::KEY_OF_ROOT_CA = "root-ca";
36 const std::string TrustedSourceManager::KEY_OF_MAX_CERTS_PATH = "max-certs-path";
37 const std::string TrustedSourceManager::KEY_OF_CRITIALCAL_CERT_EXTENSION = "critialcal-cert-extension";
38 const std::string TrustedSourceManager::APP_GALLERY_SOURCE_NAME = "huawei app gallery";
39 const std::string TrustedSourceManager::APP_SYSTEM_SOURCE_NAME = "huawei system apps";
40 const std::string TrustedSourceManager::APP_THIRD_PARTY_PRELOAD_SOURCE_NAME = "third_party app preload";
41
GetInstance()42 TrustedSourceManager& TrustedSourceManager::GetInstance()
43 {
44 static TrustedSourceManager singleTrustedSourceManager;
45 return singleTrustedSourceManager;
46 }
47
TrustedSourceManager()48 TrustedSourceManager::TrustedSourceManager()
49 : appTrustedSources(), appTrustedSourcesForTest(), version(), versionForTest(), releaseTime(),
50 releaseTimeForTest(), isInit(false), isDebug(false)
51 {
52 }
53
~TrustedSourceManager()54 TrustedSourceManager::~TrustedSourceManager()
55 {
56 }
57
EnableDebug()58 bool TrustedSourceManager::EnableDebug()
59 {
60 if (isDebug) {
61 return true;
62 }
63
64 isDebug = GetAppTrustedSources(appTrustedSourcesForTest, versionForTest,
65 releaseTimeForTest, APP_TRUSTED_SOURCE_TEST_FILE_PATH);
66 if (isDebug) {
67 HAPVERIFY_LOG_INFO("trusted app source test version: %{public}s, releaseTime: %{public}s, Size:"
68 " %{public}zu", versionForTest.c_str(), releaseTimeForTest.c_str(), appTrustedSourcesForTest.size());
69 }
70 return isDebug;
71 }
72
DisableDebug()73 void TrustedSourceManager::DisableDebug()
74 {
75 isDebug = false;
76 appTrustedSourcesForTest.clear();
77 }
78
Init()79 bool TrustedSourceManager::Init()
80 {
81 if (isInit) {
82 return true;
83 }
84
85 isInit = GetAppTrustedSources(appTrustedSources, version, releaseTime, APP_TRUSTED_SOURCE_FILE_PATH);
86 if (isInit) {
87 HAPVERIFY_LOG_INFO("trusted app source version: %{public}s, releaseTime: %{public}s, Size:"
88 " %{public}zu", version.c_str(), releaseTime.c_str(), appTrustedSources.size());
89 }
90 return isInit;
91 }
92
Recovery()93 void TrustedSourceManager::Recovery()
94 {
95 appTrustedSources.clear();
96 isInit = false;
97 }
98
GetAppTrustedSources(SourceInfoVec & trustedAppSources,std::string & souucesVersion,std::string & souucesReleaseTime,const std::string & filePath)99 bool TrustedSourceManager::GetAppTrustedSources(SourceInfoVec& trustedAppSources, std::string& souucesVersion,
100 std::string& souucesReleaseTime, const std::string& filePath)
101 {
102 cJSON* trustedSourceJson = NULL;
103 std::string errorInfo;
104 if (!JsonParserUtils::ReadTrustedRootCAFromJson(&trustedSourceJson, filePath, errorInfo)) {
105 HAPVERIFY_LOG_ERROR("get jsonObj from %{public}s failed, because %{public}s",
106 filePath.c_str(), errorInfo.c_str());
107 return false;
108 }
109 if (!JsonParserUtils::GetJsonString(trustedSourceJson, KEY_OF_APP_TRUSTED_SOURCE_VERSION, souucesVersion)) {
110 HAPVERIFY_LOG_ERROR("get version failed");
111 cJSON_Delete(trustedSourceJson);
112 return false;
113 }
114 if (!JsonParserUtils::GetJsonString(trustedSourceJson,
115 KEY_OF_APP_TRUSTED_SOURCE_RELEASETIME, souucesReleaseTime)) {
116 HAPVERIFY_LOG_ERROR("get releaseTime failed");
117 cJSON_Delete(trustedSourceJson);
118 return false;
119 }
120 JsonObjVec trustedAppSourceJson;
121 if (!JsonParserUtils::ParseJsonToObjVec(trustedSourceJson, KEY_OF_APP_TRUSTED_SOURCE, trustedAppSourceJson)) {
122 HAPVERIFY_LOG_ERROR("get JsonObjVec failed");
123 cJSON_Delete(trustedSourceJson);
124 return false;
125 }
126 if (!ParseTrustedAppSourceJson(trustedAppSources, trustedAppSourceJson)) {
127 HAPVERIFY_LOG_ERROR("parse JsonObjVec failed");
128 cJSON_Delete(trustedSourceJson);
129 return false;
130 }
131 if (trustedAppSources.empty()) {
132 HAPVERIFY_LOG_ERROR("no app trusted source");
133 cJSON_Delete(trustedSourceJson);
134 return false;
135 }
136 cJSON_Delete(trustedSourceJson);
137 return true;
138 }
139
ParseTrustedAppSourceJson(SourceInfoVec & trustedAppSources,const JsonObjVec & trustedAppSourceJson)140 bool TrustedSourceManager::ParseTrustedAppSourceJson(SourceInfoVec& trustedAppSources,
141 const JsonObjVec& trustedAppSourceJson)
142 {
143 for (auto appSource : trustedAppSourceJson) {
144 HapAppSourceInfo hapAppSource;
145 if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_SOURCE_NAME, hapAppSource.sourceName)) {
146 HAPVERIFY_LOG_ERROR("Get sourceName Failed");
147 return false;
148 }
149 hapAppSource.source = GetTrustedSource(hapAppSource.sourceName);
150 if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_APP_SIGNING_CERT, hapAppSource.appSigningCert)) {
151 HAPVERIFY_LOG_ERROR("Get appSigningCert Failed");
152 return false;
153 }
154 if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_PROFILE_SIGNING_CERTIFICATE,
155 hapAppSource.profileSigningCertificate)) {
156 HAPVERIFY_LOG_ERROR("Get profileSigningCertificate Failed");
157 return false;
158 }
159 if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_PROFILE_DEBUG_SIGNING_CERTIFICATE,
160 hapAppSource.profileDebugSigningCertificate)) {
161 HAPVERIFY_LOG_ERROR("Get profileDebugSigningCertificate Failed");
162 return false;
163 }
164 if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_ISSUER, hapAppSource.issuer)) {
165 HAPVERIFY_LOG_ERROR("Get issuer Failed");
166 return false;
167 }
168 if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_ROOT_CA, hapAppSource.rootCa)) {
169 HAPVERIFY_LOG_ERROR("Get root ca Failed");
170 return false;
171 }
172 if (!JsonParserUtils::GetJsonInt(appSource, KEY_OF_MAX_CERTS_PATH, hapAppSource.maxCertsPath)) {
173 HAPVERIFY_LOG_ERROR("Get maxCertsPath Failed");
174 return false;
175 }
176 if (!JsonParserUtils::GetJsonStringVec(appSource, KEY_OF_CRITIALCAL_CERT_EXTENSION,
177 hapAppSource.critialcalCertExtension)) {
178 HAPVERIFY_LOG_ERROR("Get critialcalCertExtension Failed");
179 return false;
180 }
181 HAPVERIFY_LOG_INFO("trusted app source: %{public}s", EncapTrustedAppSourceString(hapAppSource).c_str());
182 trustedAppSources.push_back(hapAppSource);
183 }
184 return true;
185 }
186
EncapTrustedAppSourceString(const HapAppSourceInfo & appSourceInfo)187 std::string TrustedSourceManager::EncapTrustedAppSourceString(const HapAppSourceInfo& appSourceInfo)
188 {
189 std::string info = "sourceName: " + appSourceInfo.sourceName + "\n" +
190 "sourceNumber: " + std::to_string(static_cast<int>(appSourceInfo.source)) + "\n" +
191 "appSigningCert: " + appSourceInfo.appSigningCert + "\n" +
192 "profileSigningCertificate: " + appSourceInfo.profileSigningCertificate + "\n" +
193 "profileDebugSigningCertificate: " + appSourceInfo.profileDebugSigningCertificate + "\n" +
194 "issuer: " + appSourceInfo.issuer + "\n" +
195 "rootCa: " + appSourceInfo.rootCa + "\n" +
196 "maxCertsPath: " + std::to_string(appSourceInfo.maxCertsPath) + "\n" +
197 "critialcalCertExtension: ";
198 for (auto extension : appSourceInfo.critialcalCertExtension) {
199 info += extension + ", ";
200 }
201 return info;
202 }
203
IsTrustedSource(const std::string & certSubject,const std::string & certIssuer,HapBlobType blobType,int32_t certListPath) const204 MatchingResult TrustedSourceManager::IsTrustedSource(const std::string& certSubject,
205 const std::string& certIssuer, HapBlobType blobType, int32_t certListPath) const
206 {
207 MatchingResult ret = MatchTrustedSource(appTrustedSources, certSubject, certIssuer, blobType, certListPath);
208 if (ret.matchState != DO_NOT_MATCH) {
209 return ret;
210 }
211
212 if (isDebug) {
213 return MatchTrustedSource(appTrustedSourcesForTest, certSubject, certIssuer, blobType, certListPath);
214 }
215 return ret;
216 }
217
MatchTrustedSource(const SourceInfoVec & trustedAppSources,const std::string & certSubject,const std::string & certIssuer,HapBlobType blobType,int32_t certListPath) const218 MatchingResult TrustedSourceManager::MatchTrustedSource(const SourceInfoVec& trustedAppSources,
219 const std::string& certSubject, const std::string& certIssuer, HapBlobType blobType, int32_t certListPath) const
220 {
221 MatchingResult ret;
222 ret.matchState = DO_NOT_MATCH;
223 for (auto appSource : trustedAppSources) {
224 if (certListPath == appSource.maxCertsPath) {
225 ret.matchState = TrustedSourceListCompare(certSubject, certIssuer, appSource, blobType);
226 if (ret.matchState != DO_NOT_MATCH) {
227 ret.source = appSource.source;
228 ret.rootCa = appSource.rootCa;
229 break;
230 }
231 }
232 }
233 return ret;
234 }
235
TrustedSourceListCompare(const std::string & certSubject,const std::string & certIssuer,const HapAppSourceInfo & appSource,HapBlobType blobType) const236 MatchingStates TrustedSourceManager::TrustedSourceListCompare(const std::string& certSubject,
237 const std::string& certIssuer, const HapAppSourceInfo& appSource, HapBlobType blobType) const
238 {
239 MatchingStates ret = DO_NOT_MATCH;
240 switch (blobType) {
241 case HAP_SIGN_BLOB: {
242 if (MatchSubjectAndIssuer(appSource.appSigningCert, certSubject) &&
243 MatchSubjectAndIssuer(appSource.issuer, certIssuer)) {
244 ret = MATCH_WITH_SIGN;
245 }
246 break;
247 }
248 case PROFILE_BLOB: {
249 if (MatchSubjectAndIssuer(appSource.issuer, certIssuer)) {
250 if (MatchSubjectAndIssuer(appSource.profileSigningCertificate, certSubject)) {
251 ret = MATCH_WITH_PROFILE;
252 } else if (MatchSubjectAndIssuer(appSource.profileDebugSigningCertificate, certSubject)) {
253 ret = MATCH_WITH_PROFILE_DEBUG;
254 }
255 }
256 break;
257 }
258 default:
259 break;
260 }
261 return ret;
262 }
263
GetTrustedSource(std::string & sourceName)264 TrustedSources TrustedSourceManager::GetTrustedSource(std::string& sourceName)
265 {
266 if (APP_GALLERY_SOURCE_NAME == sourceName) {
267 return APP_GALLARY;
268 }
269
270 if (APP_SYSTEM_SOURCE_NAME == sourceName) {
271 return APP_SYSTEM;
272 }
273
274 if (APP_THIRD_PARTY_PRELOAD_SOURCE_NAME == sourceName) {
275 return APP_THIRD_PARTY_PRELOAD;
276 }
277 return OTHER_TRUSTED_SOURCE;
278 }
279
MatchSubjectAndIssuer(const std::string & trustedSource,const std::string & certSubjectOrIssuer) const280 bool TrustedSourceManager::MatchSubjectAndIssuer(const std::string& trustedSource,
281 const std::string& certSubjectOrIssuer) const
282 {
283 if (trustedSource.empty()) {
284 return false;
285 }
286
287 return trustedSource == certSubjectOrIssuer;
288 }
289 } // namespace Verify
290 } // namespace Security
291 } // namespace OHOS
292