2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file task_certify_level.cpp
18 * @author Jihoon Chung (jihoon.chung@samgsung.com)
29 #include <widget_install/task_certify_level.h>
30 #include <widget_install/job_widget_install.h>
31 #include <widget_install/widget_install_errors.h>
32 #include <widget_install/widget_install_context.h>
33 #include <dpl/assert.h>
34 #include <dpl/log/log.h>
35 #include <dpl/exception.h>
36 #include <dpl/string.h>
37 #include <dpl/foreach.h>
38 #include <dpl/wrt-dao-ro/global_config.h>
40 #include <vcore/CertStoreType.h>
41 #include <vcore/SignatureReader.h>
42 #include <vcore/SignatureFinder.h>
43 #include <vcore/WrtSignatureValidator.h>
44 #include <dpl/utils/wrt_global_settings.h>
45 #include <dpl/wrt-dao-ro/global_dao_read_only.h>
47 using namespace ValidationCore;
48 using namespace WrtDB;
51 namespace WidgetInstall {
52 TaskCertifyLevel::TaskCertifyLevel(InstallerContext &inCont) :
53 DPL::TaskDecl<TaskCertifyLevel>(this),
56 AddStep(&TaskCertifyLevel::StartStep);
57 AddStep(&TaskCertifyLevel::stepCertifyLevel);
58 AddStep(&TaskCertifyLevel::EndStep);
61 void TaskCertifyLevel::stepCertifyLevel()
63 LogDebug("================ Step: <<Certify Level>> ENTER ===============");
64 if (!checkConfigurationLevel(getCertifyLevel())) {
65 ThrowMsg(Exceptions::PrivilegeLevelViolation, "setting level violate");
67 LogDebug("================ Step: <<Certify Level>> DONE ================");
70 void TaskCertifyLevel::getSignatureFiles(const std::string& path,
71 SignatureFileInfoSet& file)
73 SignatureFileInfoSet signatureFiles;
74 SignatureFinder signatureFinder(path);
75 if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) {
76 LogError("Error in Signature Finder : " << path);
77 ThrowMsg(Exceptions::SignatureNotFound, "Signature not found");
81 TaskCertifyLevel::Level TaskCertifyLevel::getCertifyLevel()
83 std::string widgetPath;
84 widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/";
86 if (m_contextData.mode.command == InstallMode::Command::REINSTALL) {
88 m_contextData.locations->getPackageInstallationDir() + "/";
91 SignatureFileInfoSet signatureFiles;
94 getSignatureFiles(widgetPath, signatureFiles);
96 if (signatureFiles.size() <= 0) {
97 widgetPath += std::string(WrtDB::GlobalConfig::GetWidgetSrcPath())
99 if (0 == access(widgetPath.c_str(), F_OK)) {
100 getSignatureFiles(widgetPath, signatureFiles);
103 } Catch(Exceptions::SignatureNotFound) {
104 ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
107 SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
108 LogDebug("Number of signatures: " << signatureFiles.size());
110 Level level = Level::UNKNOWN;
111 for (; iter != signatureFiles.rend(); ++iter) {
112 LogDebug("Checking signature with id=" << iter->getFileNumber());
113 SignatureData data(widgetPath + iter->getFileName(),
114 iter->getFileNumber());
118 xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
121 WrtSignatureValidator validator(
122 WrtSignatureValidator::TIZEN,
124 OCSPTestModeEnabled(),
126 CrlTestModeEnabled(),
129 WrtSignatureValidator::Result result =
130 validator.check(data, widgetPath);
132 if (m_contextData.mode.installTime
133 == InstallMode::InstallTime::PRELOAD)
135 result = WrtSignatureValidator::SIGNATURE_VERIFIED;
138 if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
139 ThrowMsg(Exceptions::CertificateExpired,
140 "Certificate is REVOKED");
143 if (result == WrtSignatureValidator::SIGNATURE_INVALID &&
144 iter->getFileNumber() <= 1)
146 ThrowMsg(Exceptions::SignatureInvalid, "Invalid Package");
149 if (data.isAuthorSignature()) {
150 LogDebug("Skip author signature");
152 Level currentCertLevel =
153 certTypeToLevel(data.getVisibilityLevel());
154 if (currentCertLevel == Level::UNKNOWN) {
157 if (currentCertLevel > level) {
158 level = currentCertLevel;
159 LogDebug("level " << enumToString(level));
162 } Catch(ParserSchemaException::Base) {
163 LogError("Error occured in ParserSchema.");
164 ReThrowMsg(Exceptions::SignatureInvalid,
165 "Error occured in ParserSchema.");
172 bool TaskCertifyLevel::checkConfigurationLevel(
173 TaskCertifyLevel::Level level)
175 if (!checkSettingLevel(level)) {
178 if (!checkAppcontrolHasDisposition(level)) {
184 bool TaskCertifyLevel::checkSettingLevel(
185 TaskCertifyLevel::Level level)
187 secureSettingMap data = {
188 {"sound-mode", Level::PARTNER}
191 FOREACH(it, m_contextData.widgetConfig.configInfo.settingsList) {
192 secureSettingIter ret = data.find(DPL::ToUTF8String(it->m_name));
193 if (ret != data.end()) {
194 if (level < ret->second) {
198 enumToString(ret->second) <<
207 bool TaskCertifyLevel::checkAppcontrolHasDisposition(
208 TaskCertifyLevel::Level level)
210 // tizen:disposition -> platform
211 FOREACH(it, m_contextData.widgetConfig.configInfo.appControlList) {
212 if (ConfigParserData::AppControlInfo::Disposition::UNDEFINE !=
215 if (level < Level::PLATFORM) {
216 LogError("\"tizen:disposition\" needs \"" <<
217 enumToString(Level::PLATFORM) <<
226 std::string TaskCertifyLevel::enumToString(
227 TaskCertifyLevel::Level level)
230 #define X(x, y) case x: return #y;
231 X(Level::UNKNOWN, UNKNOWN)
232 X(Level::PUBLIC, PUBLIC)
233 X(Level::PARTNER, PARTNER)
234 X(Level::PLATFORM, PLATFORM)
241 TaskCertifyLevel::Level TaskCertifyLevel::certTypeToLevel(
242 CertStoreId::Type type)
244 // CertStoreType.h (framework/security/cert-svc)
245 // RootCA's visibility level : public
246 // const Type VIS_PUBLIC = 1 << 6;
247 // RootCA's visibility level : partner
248 // const Type VIS_PARTNER = 1 << 7;
249 // RootCA's visibility level : platform
250 // const Type VIS_PLATFORM = 1 << 10;
251 if (type == CertStoreId::VIS_PUBLIC) {
252 return Level::PUBLIC;
253 } else if (type == CertStoreId::VIS_PARTNER) {
254 return Level::PARTNER;
255 } else if (type == CertStoreId::VIS_PLATFORM) {
256 return Level::PLATFORM;
258 return Level::UNKNOWN;
261 void TaskCertifyLevel::StartStep()
263 LogDebug("--------- <TaskCertifyLevel> : START ----------");
266 void TaskCertifyLevel::EndStep()
268 LogDebug("--------- <TaskCertifyLevel> : END ----------");
270 m_contextData.job->UpdateProgress(
271 InstallerContext::INSTALL_CERTIFY_LEVEL_CHECK,
272 "Application Certificate level check Finished");
274 } //namespace WidgetInstall