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