• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "nlohmann/json.hpp"
19 
20 #include "common/hap_verify_log.h"
21 
22 namespace OHOS {
23 namespace Security {
24 namespace Verify {
25 const std::string TrustedSourceManager::APP_TRUSTED_SOURCE_FILE_PATH =
26     "/system/etc/security/trusted_apps_sources.json";
27 const std::string TrustedSourceManager::APP_TRUSTED_SOURCE_TEST_FILE_PATH =
28     "/system/etc/security/trusted_apps_sources_test.json";
29 const std::string TrustedSourceManager::KEY_OF_APP_TRUSTED_SOURCE = "trust-app-source";
30 const std::string TrustedSourceManager::KEY_OF_APP_TRUSTED_SOURCE_VERSION = "version";
31 const std::string TrustedSourceManager::KEY_OF_APP_TRUSTED_SOURCE_RELEASETIME = "release-time";
32 const std::string TrustedSourceManager::KEY_OF_SOURCE_NAME = "name";
33 const std::string TrustedSourceManager::KEY_OF_APP_SIGNING_CERT = "app-signing-cert";
34 const std::string TrustedSourceManager::KEY_OF_PROFILE_SIGNING_CERTIFICATE = "profile-signing-certificate";
35 const std::string TrustedSourceManager::KEY_OF_PROFILE_DEBUG_SIGNING_CERTIFICATE = "profile-debug-signing-certificate";
36 const std::string TrustedSourceManager::KEY_OF_ISSUER = "issuer-ca";
37 const std::string TrustedSourceManager::KEY_OF_MAX_CERTS_PATH = "max-certs-path";
38 const std::string TrustedSourceManager::KEY_OF_CRITIALCAL_CERT_EXTENSION = "critialcal-cert-extension";
39 const std::string TrustedSourceManager::APP_GALLERY_SOURCE_NAME = "huawei app gallery";
40 const std::string TrustedSourceManager::APP_SYSTEM_SOURCE_NAME = "huawei system apps";
41 const std::string TrustedSourceManager::APP_THIRD_PARTY_PRELOAD_SOURCE_NAME = "third_party app preload";
42 
GetInstance()43 TrustedSourceManager& TrustedSourceManager::GetInstance()
44 {
45     static TrustedSourceManager singleTrustedSourceManager;
46     return singleTrustedSourceManager;
47 }
48 
TrustedSourceManager()49 TrustedSourceManager::TrustedSourceManager()
50     : appTrustedSources(), appTrustedSourcesForTest(), version(), versionForTest(), releaseTime(),
51       releaseTimeForTest(), isInit(false), isDebug(false)
52 {
53 }
54 
~TrustedSourceManager()55 TrustedSourceManager::~TrustedSourceManager()
56 {
57 }
58 
EnableDebug()59 bool TrustedSourceManager::EnableDebug()
60 {
61     if (isDebug) {
62         return true;
63     }
64 
65     isDebug = GetAppTrustedSources(appTrustedSourcesForTest, versionForTest,
66         releaseTimeForTest, APP_TRUSTED_SOURCE_TEST_FILE_PATH);
67     if (isDebug) {
68         HAPVERIFY_LOG_INFO(LABEL, "trusted app source test version: %{public}s, releaseTime: %{public}s, Size:"
69             " %{public}zu", versionForTest.c_str(), releaseTimeForTest.c_str(), appTrustedSourcesForTest.size());
70     }
71     return isDebug;
72 }
73 
DisableDebug()74 void TrustedSourceManager::DisableDebug()
75 {
76     isDebug = false;
77     appTrustedSourcesForTest.clear();
78 }
79 
Init()80 bool TrustedSourceManager::Init()
81 {
82     if (isInit) {
83         return true;
84     }
85 
86     isInit = GetAppTrustedSources(appTrustedSources, version, releaseTime, APP_TRUSTED_SOURCE_FILE_PATH);
87     if (isInit) {
88         HAPVERIFY_LOG_INFO(LABEL, "trusted app source version: %{public}s, releaseTime: %{public}s, Size:"
89             " %{public}zu", version.c_str(), releaseTime.c_str(), appTrustedSources.size());
90     }
91     return isInit;
92 }
93 
Recovery()94 void TrustedSourceManager::Recovery()
95 {
96     appTrustedSources.clear();
97     isInit = false;
98 }
99 
GetAppTrustedSources(SourceInfoVec & trustedAppSources,std::string & souucesVersion,std::string & souucesReleaseTime,const std::string & filePath)100 bool TrustedSourceManager::GetAppTrustedSources(SourceInfoVec& trustedAppSources, std::string& souucesVersion,
101     std::string& souucesReleaseTime, const std::string& filePath)
102 {
103     nlohmann::json trustedSourceJson;
104     std::string errorInfo;
105     if (!JsonParserUtils::ReadTrustedRootCAFromJson(trustedSourceJson, filePath, errorInfo)) {
106         HAPVERIFY_LOG_ERROR(LABEL, "get jsonObj from %{public}s failed, because %{public}s",
107             filePath.c_str(), errorInfo.c_str());
108         return false;
109     }
110     if (!JsonParserUtils::GetJsonString(trustedSourceJson, KEY_OF_APP_TRUSTED_SOURCE_VERSION, souucesVersion)) {
111         HAPVERIFY_LOG_ERROR(LABEL, "get version failed");
112         return false;
113     }
114     if (!JsonParserUtils::GetJsonString(trustedSourceJson,
115         KEY_OF_APP_TRUSTED_SOURCE_RELEASETIME, souucesReleaseTime)) {
116         HAPVERIFY_LOG_ERROR(LABEL, "get releaseTime failed");
117         return false;
118     }
119     JsonObjVec trustedAppSourceJson;
120     if (!JsonParserUtils::ParseJsonToObjVec(trustedSourceJson, KEY_OF_APP_TRUSTED_SOURCE, trustedAppSourceJson)) {
121         HAPVERIFY_LOG_ERROR(LABEL, "get JsonObjVec failed");
122         return false;
123     }
124     if (!ParseTrustedAppSourceJson(trustedAppSources, trustedAppSourceJson)) {
125         HAPVERIFY_LOG_ERROR(LABEL, "parse JsonObjVec failed");
126         return false;
127     }
128     if (trustedAppSources.empty()) {
129         HAPVERIFY_LOG_ERROR(LABEL, "no app trusted source");
130         return false;
131     }
132     return true;
133 }
134 
ParseTrustedAppSourceJson(SourceInfoVec & trustedAppSources,const JsonObjVec & trustedAppSourceJson)135 bool TrustedSourceManager::ParseTrustedAppSourceJson(SourceInfoVec& trustedAppSources,
136     const JsonObjVec& trustedAppSourceJson)
137 {
138     for (auto appSource : trustedAppSourceJson) {
139         HapAppSourceInfo hapAppSource;
140         if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_SOURCE_NAME, hapAppSource.sourceName)) {
141             HAPVERIFY_LOG_ERROR(LABEL, "Get sourceName Failed");
142             return false;
143         }
144         hapAppSource.source = GetTrustedSource(hapAppSource.sourceName);
145         if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_APP_SIGNING_CERT, hapAppSource.appSigningCert)) {
146             HAPVERIFY_LOG_ERROR(LABEL, "Get appSigningCert Failed");
147             return false;
148         }
149         if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_PROFILE_SIGNING_CERTIFICATE,
150             hapAppSource.profileSigningCertificate)) {
151             HAPVERIFY_LOG_ERROR(LABEL, "Get profileSigningCertificate Failed");
152             return false;
153         }
154         if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_PROFILE_DEBUG_SIGNING_CERTIFICATE,
155             hapAppSource.profileDebugSigningCertificate)) {
156             HAPVERIFY_LOG_ERROR(LABEL, "Get profileDebugSigningCertificate Failed");
157             return false;
158         }
159         if (!JsonParserUtils::GetJsonString(appSource, KEY_OF_ISSUER, hapAppSource.issuer)) {
160             HAPVERIFY_LOG_ERROR(LABEL, "Get issuer Failed");
161             return false;
162         }
163         if (!JsonParserUtils::GetJsonInt(appSource, KEY_OF_MAX_CERTS_PATH, hapAppSource.maxCertsPath)) {
164             HAPVERIFY_LOG_ERROR(LABEL, "Get maxCertsPath Failed");
165             return false;
166         }
167         if (!JsonParserUtils::GetJsonStringVec(appSource, KEY_OF_CRITIALCAL_CERT_EXTENSION,
168             hapAppSource.critialcalCertExtension)) {
169             HAPVERIFY_LOG_ERROR(LABEL, "Get critialcalCertExtension Failed");
170             return false;
171         }
172         HAPVERIFY_LOG_INFO(LABEL, "trusted app source: %{public}s", EncapTrustedAppSourceString(hapAppSource).c_str());
173         trustedAppSources.push_back(hapAppSource);
174     }
175     return true;
176 }
177 
EncapTrustedAppSourceString(const HapAppSourceInfo & appSourceInfo)178 std::string TrustedSourceManager::EncapTrustedAppSourceString(const HapAppSourceInfo& appSourceInfo)
179 {
180     std::string info =  "sourceName: " + appSourceInfo.sourceName + "\n" +
181         "sourceNumber: " + std::to_string(static_cast<int>(appSourceInfo.source)) + "\n" +
182         "appSigningCert: " + appSourceInfo.appSigningCert + "\n" +
183         "profileSigningCertificate: " + appSourceInfo.profileSigningCertificate + "\n" +
184         "profileDebugSigningCertificate: " + appSourceInfo.profileDebugSigningCertificate + "\n" +
185         "issuer: " + appSourceInfo.issuer + "\n" +
186         "maxCertsPath: " + std::to_string(appSourceInfo.maxCertsPath) + "\n" +
187         "critialcalCertExtension: ";
188     for (auto extension : appSourceInfo.critialcalCertExtension) {
189         info += extension + ", ";
190     }
191     return info;
192 }
193 
IsTrustedSource(const std::string & certSubject,const std::string & certIssuer,HapBlobType blobType,int certListPath) const194 MatchingResult TrustedSourceManager::IsTrustedSource(const std::string& certSubject,
195     const std::string& certIssuer, HapBlobType blobType, int certListPath) const
196 {
197     MatchingResult ret = MatchTrustedSource(appTrustedSources, certSubject, certIssuer, blobType, certListPath);
198     if (ret.matchState != DO_NOT_MATCH) {
199         return ret;
200     }
201 
202     if (isDebug) {
203         return MatchTrustedSource(appTrustedSourcesForTest, certSubject, certIssuer, blobType, certListPath);
204     }
205     return ret;
206 }
207 
MatchTrustedSource(const SourceInfoVec & trustedAppSources,const std::string & certSubject,const std::string & certIssuer,HapBlobType blobType,int certListPath) const208 MatchingResult TrustedSourceManager::MatchTrustedSource(const SourceInfoVec& trustedAppSources,
209     const std::string& certSubject, const std::string& certIssuer, HapBlobType blobType, int certListPath) const
210 {
211     MatchingResult ret;
212     ret.matchState = DO_NOT_MATCH;
213     for (auto appSource : trustedAppSources) {
214         if (certListPath == appSource.maxCertsPath) {
215             ret.matchState = TrustedSourceListCompare(certSubject, certIssuer, appSource, blobType);
216             if (ret.matchState != DO_NOT_MATCH) {
217                 ret.source = appSource.source;
218                 break;
219             }
220         }
221     }
222     return ret;
223 }
224 
TrustedSourceListCompare(const std::string & certSubject,const std::string & certIssuer,const HapAppSourceInfo & appSource,HapBlobType blobType) const225 MatchingStates TrustedSourceManager::TrustedSourceListCompare(const std::string& certSubject,
226     const std::string& certIssuer, const HapAppSourceInfo& appSource, HapBlobType blobType) const
227 {
228     MatchingStates ret = DO_NOT_MATCH;
229     switch (blobType) {
230         case HAP_SIGN_BLOB: {
231             if (MatchSubjectAndIssuer(appSource.appSigningCert, certSubject) &&
232                 MatchSubjectAndIssuer(appSource.issuer, certIssuer)) {
233                 ret = MATCH_WITH_SIGN;
234             }
235             break;
236         }
237         case PROFILE_BLOB: {
238             if (MatchSubjectAndIssuer(appSource.issuer, certIssuer)) {
239                 if (MatchSubjectAndIssuer(appSource.profileSigningCertificate, certSubject)) {
240                     ret = MATCH_WITH_PROFILE;
241                 } else if (MatchSubjectAndIssuer(appSource.profileDebugSigningCertificate, certSubject)) {
242                     ret = MATCH_WITH_PROFILE_DEBUG;
243                 }
244             }
245             break;
246         }
247         default:
248             break;
249     }
250     return ret;
251 }
252 
GetTrustedSource(std::string & sourceName)253 TrustedSources TrustedSourceManager::GetTrustedSource(std::string& sourceName)
254 {
255     if (APP_GALLERY_SOURCE_NAME == sourceName) {
256         return APP_GALLARY;
257     }
258 
259     if (APP_SYSTEM_SOURCE_NAME == sourceName) {
260         return APP_SYSTEM;
261     }
262 
263     if (APP_THIRD_PARTY_PRELOAD_SOURCE_NAME == sourceName) {
264         return APP_THIRD_PARTY_PRELOAD;
265     }
266     return OTHER_TRUSTED_SOURCE;
267 }
268 
MatchSubjectAndIssuer(const std::string & trustedSource,const std::string & certSubjectOrIssuer) const269 bool TrustedSourceManager::MatchSubjectAndIssuer(const std::string& trustedSource,
270                                                  const std::string& certSubjectOrIssuer) const
271 {
272     if (trustedSource.empty()) {
273         return false;
274     }
275 
276     return trustedSource == certSubjectOrIssuer;
277 }
278 } // namespace Verify
279 } // namespace Security
280 } // namespace OHOS
281