1 /*
2 * Copyright (C) 2021 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_ticket_manager.h"
17
18 #include <regex>
19
20 #include "common/hap_verify_log.h"
21
22 namespace OHOS {
23 namespace Security {
24 namespace Verify {
25 const std::string TrustedTicketManager::TICKET_TRUSTED_SOURCE_FILE_PATH =
26 "/system/etc/security/trusted_tickets_sources.json";
27 const std::string TrustedTicketManager::KEY_OF_TICKET_TRUSTED_SOURCE = "trust-app-source";
28 const std::string TrustedTicketManager::KEY_OF_TICKET_TRUSTED_SOURCE_VERSION = "version";
29 const std::string TrustedTicketManager::KEY_OF_TICKET_TRUSTED_SOURCE_RELEASETIME = "release-time";
30 const std::string TrustedTicketManager::KEY_OF_SOURCE_NAME = "name";
31 const std::string TrustedTicketManager::KEY_OF_TICKET_SIGNING_CERT = "ticket-signing-cert";
32 const std::string TrustedTicketManager::KEY_OF_ISSUER = "issuer-ca";
33 const std::string TrustedTicketManager::KEY_OF_MAX_CERTS_PATH = "max-certs-path";
34 const std::string TrustedTicketManager::KEY_OF_CRITIALCAL_CERT_EXTENSION = "critialcal-cert-extension";
35
GetInstance()36 TrustedTicketManager& TrustedTicketManager::GetInstance()
37 {
38 static TrustedTicketManager singleTrustedTicketManager;
39 return singleTrustedTicketManager;
40 }
41
TrustedTicketManager()42 TrustedTicketManager::TrustedTicketManager()
43 : TicketTrustedSources(), version(), releaseTime(), isInit(false)
44 {
45 }
46
~TrustedTicketManager()47 TrustedTicketManager::~TrustedTicketManager()
48 {
49 }
50
Init()51 bool TrustedTicketManager::Init()
52 {
53 if (isInit) {
54 return true;
55 }
56
57 isInit = GetTicketTrustedSources(TicketTrustedSources, version, releaseTime, TICKET_TRUSTED_SOURCE_FILE_PATH);
58 if (isInit) {
59 HAPVERIFY_LOG_INFO("trusted ticket source version: %{public}s, releaseTime: %{public}s, Size:"
60 " %{public}zu", version.c_str(), releaseTime.c_str(), TicketTrustedSources.size());
61 }
62 return isInit;
63 }
64
Recovery()65 void TrustedTicketManager::Recovery()
66 {
67 isInit = false;
68 TicketTrustedSources.clear();
69 }
70
GetTicketTrustedSources(TicketSourceInfoVec & trustedTicketSources,std::string & sourcesVersion,std::string & sourcesReleaseTime,const std::string & filePath)71 bool TrustedTicketManager::GetTicketTrustedSources(TicketSourceInfoVec& trustedTicketSources,
72 std::string& sourcesVersion, std::string& sourcesReleaseTime, const std::string& filePath)
73 {
74 cJSON* trustedSourceJson = NULL;
75 std::string errorInfo;
76 if (!JsonParserUtils::ReadTrustedRootCAFromJson(&trustedSourceJson, filePath, errorInfo)) {
77 HAPVERIFY_LOG_ERROR("get jsonObj from %{public}s failed, because %{public}s",
78 filePath.c_str(), errorInfo.c_str());
79 return false;
80 }
81 if (!JsonParserUtils::GetJsonString(trustedSourceJson, KEY_OF_TICKET_TRUSTED_SOURCE_VERSION, sourcesVersion)) {
82 HAPVERIFY_LOG_ERROR("get version failed");
83 cJSON_Delete(trustedSourceJson);
84 return false;
85 }
86 if (!JsonParserUtils::GetJsonString(trustedSourceJson,
87 KEY_OF_TICKET_TRUSTED_SOURCE_RELEASETIME, sourcesReleaseTime)) {
88 HAPVERIFY_LOG_ERROR("get releaseTime failed");
89 cJSON_Delete(trustedSourceJson);
90 return false;
91 }
92 JsonObjVec trustedTicketJson;
93 if (!JsonParserUtils::ParseJsonToObjVec(trustedSourceJson, KEY_OF_TICKET_TRUSTED_SOURCE, trustedTicketJson)) {
94 HAPVERIFY_LOG_ERROR("get JsonObjVec failed");
95 cJSON_Delete(trustedSourceJson);
96 return false;
97 }
98 if (!ParseTrustedTicketSourceJson(trustedTicketSources, trustedTicketJson)) {
99 HAPVERIFY_LOG_ERROR("parse JsonObjVec failed");
100 cJSON_Delete(trustedSourceJson);
101 return false;
102 }
103 if (trustedTicketSources.empty()) {
104 HAPVERIFY_LOG_ERROR("no ticket trusted source");
105 cJSON_Delete(trustedSourceJson);
106 return false;
107 }
108 cJSON_Delete(trustedSourceJson);
109 return true;
110 }
111
ParseTrustedTicketSourceJson(TicketSourceInfoVec & trustedTicketSources,const JsonObjVec & trustedTicketJson)112 bool TrustedTicketManager::ParseTrustedTicketSourceJson(TicketSourceInfoVec& trustedTicketSources,
113 const JsonObjVec& trustedTicketJson)
114 {
115 for (auto TicketSource : trustedTicketJson) {
116 HapTicketSourceInfo hapTicketSource;
117 if (!JsonParserUtils::GetJsonString(TicketSource, KEY_OF_SOURCE_NAME, hapTicketSource.sourceName)) {
118 HAPVERIFY_LOG_ERROR("Get sourceName Failed");
119 return false;
120 }
121 hapTicketSource.source = OTHER_TRUSTED_SOURCE;
122 if (!JsonParserUtils::GetJsonString(TicketSource, KEY_OF_TICKET_SIGNING_CERT,
123 hapTicketSource.ticketSigningCert)) {
124 HAPVERIFY_LOG_ERROR("Get ticketSigningCert Failed");
125 return false;
126 }
127 if (!JsonParserUtils::GetJsonString(TicketSource, KEY_OF_ISSUER, hapTicketSource.issuer)) {
128 HAPVERIFY_LOG_ERROR("Get issuer Failed");
129 return false;
130 }
131 if (!JsonParserUtils::GetJsonInt(TicketSource, KEY_OF_MAX_CERTS_PATH, hapTicketSource.maxCertsPath)) {
132 HAPVERIFY_LOG_ERROR("Get maxCertsPath Failed");
133 return false;
134 }
135 if (!JsonParserUtils::GetJsonStringVec(TicketSource, KEY_OF_CRITIALCAL_CERT_EXTENSION,
136 hapTicketSource.critialcalCertExtension)) {
137 HAPVERIFY_LOG_ERROR("Get critialcalCertExtension Failed");
138 return false;
139 }
140 HAPVERIFY_LOG_INFO("trusted ticket source: %{private}s",
141 EncapTrustedTicketSourceString(hapTicketSource).c_str());
142 trustedTicketSources.push_back(hapTicketSource);
143 }
144 return true;
145 }
146
EncapTrustedTicketSourceString(const HapTicketSourceInfo & ticketSourceInfo)147 std::string TrustedTicketManager::EncapTrustedTicketSourceString(const HapTicketSourceInfo& ticketSourceInfo)
148 {
149 std::string info = "sourceName: " + ticketSourceInfo.sourceName + "\n" +
150 "sourceNumber: " + std::to_string(static_cast<int>(ticketSourceInfo.source)) + "\n" +
151 "ticketSigningCert: " + ticketSourceInfo.ticketSigningCert + "\n" +
152 "issuer: " + ticketSourceInfo.issuer + "\n" +
153 "maxCertsPath: " + std::to_string(ticketSourceInfo.maxCertsPath) + "\n" +
154 "critialcalCertExtension: ";
155 for (auto extension : ticketSourceInfo.critialcalCertExtension) {
156 info += extension + ", ";
157 }
158 return info;
159 }
160
IsTrustedSource(const std::string & certSubject,const std::string & certIssuer,int32_t certListPath) const161 MatchingResult TrustedTicketManager::IsTrustedSource(const std::string& certSubject,
162 const std::string& certIssuer, int32_t certListPath) const
163 {
164 MatchingResult ret = MatchTrustedSource(TicketTrustedSources, certSubject, certIssuer, certListPath);
165 if (ret.matchState != DO_NOT_MATCH) {
166 return ret;
167 }
168 return ret;
169 }
170
MatchTrustedSource(const TicketSourceInfoVec & trustedTicketSources,const std::string & certSubject,const std::string & certIssuer,int32_t certListPath) const171 MatchingResult TrustedTicketManager::MatchTrustedSource(const TicketSourceInfoVec& trustedTicketSources,
172 const std::string& certSubject, const std::string& certIssuer, int32_t certListPath) const
173 {
174 MatchingResult ret;
175 ret.matchState = DO_NOT_MATCH;
176 for (auto TicketSource : trustedTicketSources) {
177 if (certListPath == TicketSource.maxCertsPath) {
178 ret.matchState = TrustedSourceListCompare(certSubject, certIssuer, TicketSource);
179 if (ret.matchState != DO_NOT_MATCH) {
180 ret.source = TicketSource.source;
181 break;
182 }
183 }
184 }
185 return ret;
186 }
187
TrustedSourceListCompare(const std::string & certSubject,const std::string & certIssuer,const HapTicketSourceInfo & TicketSource) const188 MatchingStates TrustedTicketManager::TrustedSourceListCompare(const std::string& certSubject,
189 const std::string& certIssuer, const HapTicketSourceInfo& TicketSource) const
190 {
191 MatchingStates ret = DO_NOT_MATCH;
192 if (MatchSubject(TicketSource.ticketSigningCert, certSubject) &&
193 MatchIssuer(TicketSource.issuer, certIssuer)) {
194 ret = MATCH_WITH_TICKET;
195 }
196 return ret;
197 }
198
MatchSubject(const std::string & trustedSource,const std::string & certSubject) const199 bool TrustedTicketManager::MatchSubject(const std::string& trustedSource,
200 const std::string& certSubject) const
201 {
202 if (trustedSource.empty()) {
203 return false;
204 }
205 return std::regex_match(certSubject, std::regex(trustedSource));
206 }
207
MatchIssuer(const std::string & trustedSource,const std::string & certIssuer) const208 bool TrustedTicketManager::MatchIssuer(const std::string& trustedSource,
209 const std::string& certIssuer) const
210 {
211 if (trustedSource.empty()) {
212 return false;
213 }
214 return trustedSource == certIssuer;
215 }
216 } // namespace Verify
217 } // namespace Security
218 } // namespace OHOS
219