[Release] wrt-installer_0.1.114
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_certify_level.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /*
17  * @file    task_certify.cpp
18  * @author  Jihoon Chung (jihoon.chung@samgsung.com)
19  * @version
20  * @brief
21  */
22
23 //SYSTEM INCLUDES
24 #include <string>
25 #include <map>
26 #include <unistd.h>
27
28 //WRT INCLUDES
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>
39
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>
46
47 using namespace ValidationCore;
48 using namespace WrtDB;
49
50 namespace Jobs {
51 namespace WidgetInstall {
52 TaskCertifyLevel::TaskCertifyLevel(InstallerContext &inCont) :
53     DPL::TaskDecl<TaskCertifyLevel>(this),
54     m_contextData(inCont)
55 {
56     AddStep(&TaskCertifyLevel::StartStep);
57     AddStep(&TaskCertifyLevel::stepCertifyLevel);
58     AddStep(&TaskCertifyLevel::EndStep);
59 }
60
61 void TaskCertifyLevel::stepCertifyLevel()
62 {
63     LogDebug("================ Step: <<Certify Level>> ENTER ===============");
64     if (!checkSettingLevel(getCertifyLevel())) {
65         ThrowMsg(Exceptions::PrivilegeLevelViolation, "setting level violate");
66     }
67     LogDebug("================ Step: <<Certify Level>> DONE ================");
68 }
69
70 void TaskCertifyLevel::getSignatureFiles(const std::string& path,
71                                          SignatureFileInfoSet& file)
72 {
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");
78     }
79 }
80
81 TaskCertifyLevel::Level TaskCertifyLevel::getCertifyLevel()
82 {
83     std::string widgetPath;
84     widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/";
85
86     if (m_contextData.mode.command == InstallMode::Command::REINSTALL) {
87         widgetPath =
88             m_contextData.locations->getPackageInstallationDir() + "/";
89     }
90
91     SignatureFileInfoSet signatureFiles;
92
93     Try {
94         getSignatureFiles(widgetPath, signatureFiles);
95
96         if (signatureFiles.size() <= 0) {
97             widgetPath += std::string(WrtDB::GlobalConfig::GetWidgetSrcPath())
98                 + "/";
99             if (0 == access(widgetPath.c_str(), F_OK)) {
100                 getSignatureFiles(widgetPath, signatureFiles);
101             }
102         }
103     } Catch(Exceptions::SignatureNotFound) {
104         ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
105     }
106
107     SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
108     LogDebug("Number of signatures: " << signatureFiles.size());
109
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());
115
116         Try {
117             SignatureReader xml;
118             xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
119             xml.read(data);
120
121             WrtSignatureValidator validator(
122                     WrtSignatureValidator::TIZEN,
123                     !GlobalSettings::
124                     OCSPTestModeEnabled(),
125                     !GlobalSettings::
126                     CrlTestModeEnabled(),
127                     false);
128
129             WrtSignatureValidator::Result result =
130                 validator.check(data, widgetPath);
131
132             if (m_contextData.mode.installTime
133                 ==  InstallMode::InstallTime::PRELOAD)
134             {
135                 result = WrtSignatureValidator::SIGNATURE_VERIFIED;
136             }
137
138             if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
139                 ThrowMsg(Exceptions::CertificateExpired,
140                          "Certificate is REVOKED");
141             }
142
143             if (result == WrtSignatureValidator::SIGNATURE_INVALID &&
144                     iter->getFileNumber() <= 1)
145             {
146                 ThrowMsg(Exceptions::SignatureInvalid, "Invalid Package");
147             }
148
149             if (data.isAuthorSignature()) {
150                 LogDebug("Skip author signature");
151             } else {
152                 Level currentCertLevel =
153                     certTypeToLevel(data.getVisibilityLevel());
154                 if (currentCertLevel == Level::UNKNOWN) {
155                     continue;
156                 }
157                 if (currentCertLevel > level) {
158                     level = currentCertLevel;
159                     LogDebug("level " << enumToString(level));
160                 }
161             }
162         } Catch(ParserSchemaException::Base) {
163             LogError("Error occured in ParserSchema.");
164             ReThrowMsg(Exceptions::SignatureInvalid,
165                        "Error occured in ParserSchema.");
166         }
167     }
168
169     return level;
170 }
171
172 bool TaskCertifyLevel::checkSettingLevel(
173     TaskCertifyLevel::Level level)
174 {
175     secureSettingMap data = {
176         {"sound-mode", Level::PARTNER}
177     };
178
179     FOREACH(it, m_contextData.widgetConfig.configInfo.settingsList) {
180         secureSettingIter ret = data.find(DPL::ToUTF8String(it->m_name));
181         if (ret != data.end()) {
182             if (level < ret->second) {
183                 LogError("\"" <<
184                          it->m_name <<
185                          "\" needs \"" <<
186                          enumToString(ret->second) <<
187                          "\" level");
188                 return false;
189             }
190         }
191     }
192     return true;
193 }
194
195 std::string TaskCertifyLevel::enumToString(
196     TaskCertifyLevel::Level level)
197 {
198     switch (level) {
199 #define X(x, y) case x: return #y;
200         X(Level::UNKNOWN, UNKNOWN)
201         X(Level::PUBLIC, PUBLIC)
202         X(Level::PARTNER, PARTNER)
203         X(Level::PLATFORM, PLATFORM)
204 #undef X
205     default:
206         return "UNKNOWN";
207     }
208 }
209
210 TaskCertifyLevel::Level TaskCertifyLevel::certTypeToLevel(
211     CertStoreId::Type type)
212 {
213     // CertStoreType.h (framework/security/cert-svc)
214     // RootCA's visibility level : public
215     // const Type VIS_PUBLIC = 1 << 6;
216     // RootCA's visibility level : partner
217     // const Type VIS_PARTNER = 1 << 7;
218     // RootCA's visibility level : platform
219     // const Type VIS_PLATFORM = 1 << 10;
220     if (type == CertStoreId::VIS_PUBLIC) {
221         return Level::PUBLIC;
222     } else if (type == CertStoreId::VIS_PARTNER) {
223         return Level::PARTNER;
224     } else if (type == CertStoreId::VIS_PLATFORM) {
225         return Level::PLATFORM;
226     }
227     return Level::UNKNOWN;
228 }
229
230 void TaskCertifyLevel::StartStep()
231 {
232     LogDebug("--------- <TaskCertifyLevel> : START ----------");
233 }
234
235 void TaskCertifyLevel::EndStep()
236 {
237     LogDebug("--------- <TaskCertifyLevel> : END ----------");
238
239     m_contextData.job->UpdateProgress(
240         InstallerContext::INSTALL_CERTIFY_LEVEL_CHECK,
241         "Application Certificate level check Finished");
242 }
243 } //namespace WidgetInstall
244 } //namespace Jobs
245