2 * Copyright (c) 2011 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.cpp
18 * @author Pawel Sikorski (p.sikorski@samgsung.com)
26 #include <dpl/assert.h>
27 #include <appcore-common.h> //TODO is it necessary here?
31 #include <widget_install/task_certify.h>
32 #include <widget_install/job_widget_install.h>
33 #include <widget_install/widget_install_errors.h>
34 #include <widget_install/widget_install_context.h>
35 #include <dpl/log/log.h>
36 #include <wrt_error.h>
37 #include <dpl/wrt-dao-ro/global_config.h>
38 #include "wac_widget_id.h"
40 #include <vcore/SignatureReader.h>
41 #include <vcore/SignatureFinder.h>
42 #include <vcore/SignatureValidator.h>
43 #include <vcore/DeveloperModeValidator.h>
44 #include <dpl/utils/wrt_global_settings.h>
45 #include <dpl/wrt-dao-ro/global_dao_read_only.h>
47 #include <ITapiModem.h>
48 #include <tapi_common.h>
50 using namespace ValidationCore;
51 using namespace WrtDB;
54 const std::string LABEL_NEW_LINE = "<br>";
55 const std::string LABEL_NEW_LINE_2 = "<br><br>";
56 const std::string UNTRUSTED_WIDGET ="It is an Untrusted Widget";
57 const char *QUESTION ="Do you wanto to install?";
59 WidgetCertificateData toWidgetCertificateData(const SignatureData &data,
62 WidgetCertificateData result;
64 result.chainId = data.getSignatureNumber();
66 result.owner = data.isAuthorSignature() ?
67 WidgetCertificateData::AUTHOR : WidgetCertificateData::DISTRIBUTOR;
70 WidgetCertificateData::ROOT : WidgetCertificateData::ENDENTITY;
72 CertificatePtr certificate;
75 certificate = data.getRootCaCertificatePtr();
77 certificate = data.getEndEntityCertificatePtr();
80 Assert(certificate && !certificate->getCommonName().IsNull() &&
81 "CommonName is Null");
83 result.strCommonName = *certificate->getCommonName();
85 result.strMD5Fingerprint = std::string("md5 ") +
86 SignatureValidator::FingerprintToColonHex(
87 certificate->getFingerprint(Certificate::FINGERPRINT_MD5));
89 result.strSHA1Fingerprint = std::string("sha-1 ") +
90 SignatureValidator::FingerprintToColonHex(
91 certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
95 } // namespace anonymous
98 namespace WidgetInstall {
99 TaskCertify::TaskCertify(InstallerContext &inCont) :
100 DPL::TaskDecl<TaskCertify>(this),
101 m_contextData(inCont),
102 WidgetInstallPopup(inCont)
104 AddStep(&TaskCertify::stepSignature);
106 // Block until fixed popup issues
107 if (!GlobalSettings::TestModeEnabled()
108 && !m_installContext.m_quiet && !isTizenWebApp()) {
109 AddStep(&TaskCertify::stepWarningPopup);
110 AddStep(&TaskCertify::stepWarningPopupAnswer);
111 AddStep(&TaskCertify::stepAuthorInfoPopup);
112 AddStep(&TaskCertify::stepAuthorInfoPopupAnswer);
113 AddStep(&TaskCertify::StepDeletePopupWin);
115 AddStep(&TaskCertify::stepFinalize);
118 void TaskCertify::processDistributorSignature(const SignatureData &data,
121 // this signature is verified -
122 // no point in check domain WAC_ROOT and WAC_RECOGNIZED
123 m_contextData.wacSecurity.setDistributorSigned(true);
125 if (data.getStorageType().contains(CertStoreId::WAC_ROOT)) {
126 m_contextData.wacSecurity.setWacSigned(true);
129 CertificateCollection collection;
130 collection.load(data.getCertList());
132 Assert(collection.isChain() &&
133 "Certificate collection is not able to create chain. "
134 "It is not possible to verify this signature.");
136 m_contextData.wacSecurity.getCertificateChainListRef().push_back(
140 m_contextData.wacSecurity.getCertificateListRef().push_back(
141 toWidgetCertificateData(data, true));
142 m_contextData.wacSecurity.getCertificateListRef().push_back(
143 toWidgetCertificateData(data, false));
147 void TaskCertify::processAuthorSignature(const SignatureData &data)
149 using namespace ValidationCore;
150 LogInfo("DNS Identity match!");
151 // this signature is verified or widget is distributor signed
152 m_contextData.wacSecurity.getAuthorCertificatePtr() =
153 data.getEndEntityCertificatePtr();
154 m_contextData.wacSecurity.getCertificateListRef().push_back(
155 toWidgetCertificateData(data, true));
156 m_contextData.wacSecurity.getCertificateListRef().push_back(
157 toWidgetCertificateData(data, false));
159 // match widget_id with one from dns identity set
160 WacWidgetId widgetId(m_contextData.widgetConfig.configInfo.widget_id);
162 CertificatePtr cert = data.getEndEntityCertificatePtr();
164 Certificate::AltNameSet dnsIdentity = cert->getAlternativeNameDNS();
166 FOREACH(it, dnsIdentity){
167 if (widgetId.matchHost(*it)) {
168 m_contextData.wacSecurity.setRecognized(true);
174 void TaskCertify::stepSignature()
178 std::string widgetPath = m_contextData.tempWidgetRoot + "/";
180 SignatureFileInfoSet signatureFiles;
181 SignatureFinder signatureFinder(widgetPath);
182 if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) {
183 LogError("Error in Signature Finder");
184 ThrowMsg(Exceptions::InvalidPackage,
185 "Error openig temporary widget directory");
188 SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
189 LogInfo("No of signatures: " << signatureFiles.size());
191 bool firstDistributorSignature = true;
192 bool testCertificate = false;
194 bool complianceMode = GlobalDAOReadOnly::getComplianceMode();
196 for (; iter != signatureFiles.rend(); ++iter) {
197 LogInfo("Checking signature with id=" << iter->getFileNumber());
198 SignatureData data(widgetPath + iter->getFileName(),
199 iter->getFileNumber());
203 xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
205 SignatureValidator validator(!GlobalSettings::TestModeEnabled(),
206 !GlobalSettings::TestModeEnabled(),
208 SignatureValidator::Result result =
209 validator.check(data, widgetPath);
211 if (result == SignatureValidator::SIGNATURE_REVOKED) {
212 LogWarning("Certificate is REVOKED");
213 ThrowMsg(Exceptions::InvalidPackage,
214 "Certificate is REVOKED");
217 if (result == SignatureValidator::SIGNATURE_INVALID) {
218 LogWarning("Signature is INVALID");
219 // TODO change exception name
220 ThrowMsg(Exceptions::InvalidPackage,
224 if (data.isAuthorSignature()) {
225 if (result == SignatureValidator::SIGNATURE_VERIFIED ||
226 m_contextData.wacSecurity.isDistributorSigned())
228 processAuthorSignature(data);
229 } else if (result == SignatureValidator::SIGNATURE_DISREGARD) {
233 if (result == SignatureValidator::SIGNATURE_DISREGARD) {
236 // now signature _must_ be verified
237 processDistributorSignature(data, firstDistributorSignature);
238 firstDistributorSignature = false;
241 bool developerMode = GlobalDAOReadOnly::GetDeveloperMode();
243 std::string realMEID;
244 TapiHandle *tapiHandle = tel_init(NULL);
245 char *meid = tel_get_misc_me_sn_sync(tapiHandle);
251 tel_deinit(tapiHandle);
253 DeveloperModeValidator developerModeValidator(
256 GlobalDAOReadOnly::getComplianceFakeImei(),
257 GlobalDAOReadOnly::getComplianceFakeMeid(),
260 developerModeValidator.check(data);
263 data.getStorageType().contains(CertStoreId::DEVELOPER);
265 if (testCertificate && !developerMode) {
266 LogDebug("Widget signed by test certificate, "
267 "but developer mode is off.");
268 ThrowMsg(Exceptions::InvalidPackage,
269 "Widget signed by test certificate, "
270 "but developer mode is off.");
272 m_contextData.widgetConfig.isTestWidget = testCertificate;
273 } Catch(ParserSchemaException::Base) {
274 LogDebug("Error occured in ParserSchema.");
275 ReThrowMsg(Exceptions::InvalidPackage,
276 "Error occured in ParserSchema.");
278 Catch(DeveloperModeValidator::Exception::Base) {
279 LogDebug("Cannot validate developer certificate.");
280 ReThrowMsg(Exceptions::InvalidPackage,
281 "Cannot validate developer certificate.");
285 if (signatureFiles.empty()) {
286 LogInfo("No signature files has been found.");
289 LogInfo("================ Step: <<CSignature>> DONE ================");
291 m_contextData.job->UpdateProgress(
292 InstallerContext::INSTALL_DIGSIG_CHECK,
293 "Widget Signature checked");
296 void TaskCertify::createInstallPopup(PopupType type, const std::string &label)
298 m_contextData.job->Pause();
301 bool ret = createPopup();
304 loadPopup(type, label);
308 void TaskCertify::StepDeletePopupWin()
313 void TaskCertify::stepWarningPopup()
315 LogInfo("Step:: <<Warning Popup>>");
316 // SP-2151: If widget is not recognized (OCSP status of any of certificates
317 // it is signed with is not recognized) WRT must notify user that
318 // widget cannot be installed as a trusted application, and let the
319 // user decide whether it should be installed as an untrusted
321 if (!m_contextData.wacSecurity.isDistributorSigned()) {
322 std::string label = UNTRUSTED_WIDGET +
325 createInstallPopup(PopupType::WIDGET_UNRECOGNIZED, label);
329 std::string TaskCertify::createAuthorWidgetInfo() const
331 std::string authorInfo;
332 if (m_contextData.wacSecurity.isRecognized()) {
333 //authorInfo += _("IDS_IM_WIDGET_RECOGNISED");
334 authorInfo += _("WIDGET RECOGNISED");
336 //authorInfo += _("IDS_IM_WIDGET_UNRECOGNISED");
337 authorInfo += _("WIDGET UNRECOGNISED");
340 authorInfo += LABEL_NEW_LINE_2;
341 ValidationCore::CertificatePtr authorCert =
342 m_contextData.wacSecurity.getAuthorCertificatePtr();
344 DPL::Optional < DPL::String > organizationName =
345 authorCert->getOrganizationName();
347 //authorInfo += _("IDS_IM_WIDGET_AUTHOR_ORGANIZATION_NAME");
348 authorInfo += _("AUTHOR ORGANIZATION NAME");
349 authorInfo += LABEL_NEW_LINE;
351 if (!organizationName.IsNull()) {
352 authorInfo += DPL::ToUTF8String(*organizationName);
354 //authorInfo += _("IDS_IM_WIDGET_ORGANIZATION_UNKNOWN");
355 authorInfo += _("WIDGET ORGANIZATION UNKNOWN");
358 authorInfo += LABEL_NEW_LINE_2;
360 DPL::Optional < DPL::String > countryName =
361 authorCert->getCountryName();
363 //authorInfo += _("IDS_IM_WIDGET_COUNTRY_NAME");
364 authorInfo += _("WIDGET COUNTRY NAME");
365 authorInfo += LABEL_NEW_LINE;
367 if (!countryName.IsNull()) {
368 authorInfo += DPL::ToUTF8String(*countryName);
370 //authorInfo += _("IDS_IM_WIDGET_COUNTRY_UNKNOWN");
371 authorInfo += _("WIDGET COUNTRY UNKNOWN");
375 //_("IDS_IM_WIDGET_DOES_NOT_CONTAIN_RECOGNIZED_AUTHOR_SIGNATURE");
376 _("Widget does not contain recognized author signature");
381 void TaskCertify::stepAuthorInfoPopup()
383 LogInfo("Step:: <<Author Popup Information>>");
385 = createAuthorWidgetInfo() + LABEL_NEW_LINE_2 + QUESTION;
386 createInstallPopup(PopupType::WIDGET_AUTHOR_INFO, label);
389 void TaskCertify::stepFinalize()
391 LogInfo("Step: <<CERTYFYING DONE>>");
393 m_contextData.job->UpdateProgress(
394 InstallerContext::INSTALL_CERT_CHECK,
395 "Widget Certification Check Finished");
399 void TaskCertify::stepWarningPopupAnswer()
401 LogInfo("Step: <<Warning Popup Answer>>");
402 if (false == m_contextData.wacSecurity.isDistributorSigned() &&
403 WRT_POPUP_BUTTON_CANCEL == m_installCancel)
405 LogWarning("User does not agreed to install unsigned widgets!");
406 m_installCancel = WRT_POPUP_BUTTON;
408 ThrowMsg(Exceptions::NotAllowed, "Widget not allowed");
412 void TaskCertify::stepAuthorInfoPopupAnswer()
414 LogInfo("Step: <<Author Info Popup Answer>>");
415 if ( WRT_POPUP_BUTTON_CANCEL == m_installCancel) {
416 LogWarning("User does not agreed to install widget!");
417 m_installCancel = WRT_POPUP_BUTTON;
419 ThrowMsg(Exceptions::NotAllowed, "Widget not allowed");
423 bool TaskCertify::isTizenWebApp() const
426 if (m_installContext.widgetConfig.type.appType
427 == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
432 } //namespace WidgetInstall