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