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/Certificate.h>
41 #include <vcore/SignatureReader.h>
42 #include <vcore/SignatureFinder.h>
43 #include <vcore/WrtSignatureValidator.h>
44 #include <vcore/DeveloperModeValidator.h>
45 #include <dpl/utils/wrt_global_settings.h>
46 #include <dpl/wrt-dao-ro/global_dao_read_only.h>
48 #include <ITapiModem.h>
49 #include <tapi_common.h>
51 using namespace ValidationCore;
52 using namespace WrtDB;
55 const std::string LABEL_NEW_LINE = "<br>";
56 const std::string LABEL_NEW_LINE_2 = "<br><br>";
57 const std::string UNTRUSTED_WIDGET ="It is an Untrusted Widget";
58 const char *QUESTION ="Do you wanto to install?";
60 WidgetCertificateData toWidgetCertificateData(const SignatureData &data,
63 WidgetCertificateData result;
65 result.chainId = data.getSignatureNumber();
67 result.owner = data.isAuthorSignature() ?
68 WidgetCertificateData::AUTHOR : WidgetCertificateData::DISTRIBUTOR;
71 WidgetCertificateData::ROOT : WidgetCertificateData::ENDENTITY;
73 CertificatePtr certificate;
76 certificate = data.getRootCaCertificatePtr();
78 certificate = data.getEndEntityCertificatePtr();
81 Assert(certificate && !certificate->getCommonName().IsNull() &&
82 "CommonName is Null");
84 result.strCommonName = *certificate->getCommonName();
86 result.strMD5Fingerprint = std::string("md5 ") +
87 Certificate::FingerprintToColonHex(
88 certificate->getFingerprint(Certificate::FINGERPRINT_MD5));
90 result.strSHA1Fingerprint = std::string("sha-1 ") +
91 Certificate::FingerprintToColonHex(
92 certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
96 } // namespace anonymous
99 namespace WidgetInstall {
100 TaskCertify::TaskCertify(InstallerContext &inCont) :
101 DPL::TaskDecl<TaskCertify>(this),
102 m_contextData(inCont),
103 WidgetInstallPopup(inCont)
105 /* This is temporary comment for certi error
106 After security-server, cert-svc release, should remove comment
107 AddStep(&TaskCertify::stepSignature);
110 // Block until fixed popup issues
111 if (!GlobalSettings::PopupsTestModeEnabled()
112 && !m_installContext.m_quiet && !isTizenWebApp()) {
113 AddStep(&TaskCertify::stepWarningPopup);
114 AddStep(&TaskCertify::stepWarningPopupAnswer);
115 AddStep(&TaskCertify::stepAuthorInfoPopup);
116 AddStep(&TaskCertify::stepAuthorInfoPopupAnswer);
117 AddStep(&TaskCertify::StepDeletePopupWin);
119 AddStep(&TaskCertify::stepFinalize);
122 void TaskCertify::processDistributorSignature(const SignatureData &data,
125 // this signature is verified -
126 // no point in check domain WAC_ROOT and WAC_RECOGNIZED
127 m_contextData.wacSecurity.setDistributorSigned(true);
129 if (data.getStorageType().contains(CertStoreId::WAC_ROOT)) {
130 m_contextData.wacSecurity.setWacSigned(true);
133 CertificateCollection collection;
134 collection.load(data.getCertList());
135 Assert(collection.sort() &&
136 "Certificate collection can't sort");
138 Assert(collection.isChain() &&
139 "Certificate collection is not able to create chain. "
140 "It is not possible to verify this signature.");
142 m_contextData.wacSecurity.getCertificateChainListRef().push_back(
146 m_contextData.wacSecurity.getCertificateListRef().push_back(
147 toWidgetCertificateData(data, true));
148 m_contextData.wacSecurity.getCertificateListRef().push_back(
149 toWidgetCertificateData(data, false));
153 void TaskCertify::processAuthorSignature(const SignatureData &data)
155 using namespace ValidationCore;
156 LogInfo("DNS Identity match!");
157 // this signature is verified or widget is distributor signed
158 m_contextData.wacSecurity.getAuthorCertificatePtr() =
159 data.getEndEntityCertificatePtr();
160 m_contextData.wacSecurity.getCertificateListRef().push_back(
161 toWidgetCertificateData(data, true));
162 m_contextData.wacSecurity.getCertificateListRef().push_back(
163 toWidgetCertificateData(data, false));
165 // match widget_id with one from dns identity set
166 WacWidgetId widgetId(m_contextData.widgetConfig.configInfo.widget_id);
168 CertificatePtr cert = data.getEndEntityCertificatePtr();
170 Certificate::AltNameSet dnsIdentity = cert->getAlternativeNameDNS();
172 CertificateCollection collection;
173 collection.load(data.getCertList());
175 Assert(collection.isChain() &&
176 "Certificate collection is not able to create chain. "
177 "It is not possible to verify this signature.");
179 m_contextData.wacSecurity.getAuthorsCertificateChainListRef().push_back(
182 FOREACH(it, dnsIdentity){
183 if (widgetId.matchHost(*it)) {
184 m_contextData.wacSecurity.setRecognized(true);
190 void TaskCertify::stepSignature()
192 LogInfo("================ Step: <<Signature>> ENTER ===============");
194 std::string widgetPath = m_contextData.locations->getTemporaryRootDir() + "/";
196 SignatureFileInfoSet signatureFiles;
197 SignatureFinder signatureFinder(widgetPath);
198 if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) {
199 LogError("Error in Signature Finder");
200 ThrowMsg(Exceptions::InvalidPackage,
201 "Error openig temporary widget directory");
204 SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
205 LogInfo("Number of signatures: " << signatureFiles.size());
207 bool firstDistributorSignature = true;
208 bool testCertificate = false;
210 bool complianceMode = GlobalDAOReadOnly::getComplianceMode();
212 for (; iter != signatureFiles.rend(); ++iter) {
213 LogInfo("Checking signature with id=" << iter->getFileNumber());
214 SignatureData data(widgetPath + iter->getFileName(),
215 iter->getFileNumber());
219 xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
222 WrtSignatureValidator::AppType appType = WrtSignatureValidator::WAC20;
224 if (m_installContext.widgetConfig.webAppType == APP_TYPE_TIZENWEBAPP) {
225 appType = WrtSignatureValidator::TIZEN;
228 WrtSignatureValidator validator(
230 !GlobalSettings::OCSPTestModeEnabled(),
231 !GlobalSettings::CrlTestModeEnabled(),
234 WrtSignatureValidator::Result result =
235 validator.check(data, widgetPath);
237 if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
238 LogWarning("Certificate is REVOKED");
239 ThrowMsg(Exceptions::InvalidPackage,
240 "Certificate is REVOKED");
243 if (result == WrtSignatureValidator::SIGNATURE_INVALID) {
244 LogWarning("Signature is INVALID");
245 // TODO change exception name
246 ThrowMsg(Exceptions::InvalidPackage,
250 if (data.isAuthorSignature()) {
251 if (result == WrtSignatureValidator::SIGNATURE_VERIFIED ||
252 m_contextData.wacSecurity.isDistributorSigned())
254 processAuthorSignature(data);
255 } else if (result == WrtSignatureValidator::SIGNATURE_DISREGARD) {
259 if (result == WrtSignatureValidator::SIGNATURE_DISREGARD) {
262 // now signature _must_ be verified
263 processDistributorSignature(data, firstDistributorSignature);
264 firstDistributorSignature = false;
267 bool developerMode = GlobalDAOReadOnly::GetDeveloperMode();
269 std::string realMEID;
270 TapiHandle *tapiHandle = tel_init(NULL);
271 char *meid = tel_get_misc_me_sn_sync(tapiHandle);
277 tel_deinit(tapiHandle);
279 DeveloperModeValidator developerModeValidator(
282 GlobalDAOReadOnly::getComplianceFakeImei(),
283 GlobalDAOReadOnly::getComplianceFakeMeid(),
286 developerModeValidator.check(data);
289 data.getStorageType().contains(CertStoreId::DEVELOPER);
291 if (testCertificate && !developerMode) {
292 LogError("Widget signed by test certificate, "
293 "but developer mode is off.");
294 ThrowMsg(Exceptions::InvalidPackage,
295 "Widget signed by test certificate, "
296 "but developer mode is off.");
298 m_contextData.widgetConfig.isTestWidget = testCertificate;
299 } Catch(ParserSchemaException::Base) {
300 LogError("Error occured in ParserSchema.");
301 ReThrowMsg(Exceptions::InvalidPackage,
302 "Error occured in ParserSchema.");
304 Catch(DeveloperModeValidator::Exception::Base) {
305 LogError("Cannot validate developer certificate.");
306 ReThrowMsg(Exceptions::InvalidPackage,
307 "Cannot validate developer certificate.");
311 if (signatureFiles.empty()) {
312 LogInfo("No signature files has been found.");
315 LogInfo("================ Step: <<Signature>> DONE ================");
317 m_contextData.job->UpdateProgress(
318 InstallerContext::INSTALL_DIGSIG_CHECK,
319 "Widget Signature checked");
322 void TaskCertify::createInstallPopup(PopupType type, const std::string &label)
324 m_contextData.job->Pause();
327 bool ret = createPopup();
330 loadPopup(type, label);
334 void TaskCertify::StepDeletePopupWin()
339 void TaskCertify::stepWarningPopup()
341 LogInfo("Step:: <<Warning Popup>>");
342 // SP-2151: If widget is not recognized (OCSP status of any of certificates
343 // it is signed with is not recognized) WRT must notify user that
344 // widget cannot be installed as a trusted application, and let the
345 // user decide whether it should be installed as an untrusted
347 if (!m_contextData.wacSecurity.isDistributorSigned()) {
348 std::string label = UNTRUSTED_WIDGET +
351 createInstallPopup(PopupType::WIDGET_UNRECOGNIZED, label);
355 std::string TaskCertify::createAuthorWidgetInfo() const
357 std::string authorInfo;
358 if (m_contextData.wacSecurity.isRecognized()) {
359 //authorInfo += _("IDS_IM_WIDGET_RECOGNISED");
360 authorInfo += _("WIDGET RECOGNISED");
362 //authorInfo += _("IDS_IM_WIDGET_UNRECOGNISED");
363 authorInfo += _("WIDGET UNRECOGNISED");
366 authorInfo += LABEL_NEW_LINE_2;
367 ValidationCore::CertificatePtr authorCert =
368 m_contextData.wacSecurity.getAuthorCertificatePtr();
370 DPL::Optional < DPL::String > organizationName =
371 authorCert->getOrganizationName();
373 //authorInfo += _("IDS_IM_WIDGET_AUTHOR_ORGANIZATION_NAME");
374 authorInfo += _("AUTHOR ORGANIZATION NAME");
375 authorInfo += LABEL_NEW_LINE;
377 if (!organizationName.IsNull()) {
378 authorInfo += DPL::ToUTF8String(*organizationName);
380 //authorInfo += _("IDS_IM_WIDGET_ORGANIZATION_UNKNOWN");
381 authorInfo += _("WIDGET ORGANIZATION UNKNOWN");
384 authorInfo += LABEL_NEW_LINE_2;
386 DPL::Optional < DPL::String > countryName =
387 authorCert->getCountryName();
389 //authorInfo += _("IDS_IM_WIDGET_COUNTRY_NAME");
390 authorInfo += _("WIDGET COUNTRY NAME");
391 authorInfo += LABEL_NEW_LINE;
393 if (!countryName.IsNull()) {
394 authorInfo += DPL::ToUTF8String(*countryName);
396 //authorInfo += _("IDS_IM_WIDGET_COUNTRY_UNKNOWN");
397 authorInfo += _("WIDGET COUNTRY UNKNOWN");
401 //_("IDS_IM_WIDGET_DOES_NOT_CONTAIN_RECOGNIZED_AUTHOR_SIGNATURE");
402 _("Widget does not contain recognized author signature");
407 void TaskCertify::stepAuthorInfoPopup()
409 LogInfo("Step:: <<Author Popup Information>>");
411 = createAuthorWidgetInfo() + LABEL_NEW_LINE_2 + QUESTION;
412 createInstallPopup(PopupType::WIDGET_AUTHOR_INFO, label);
415 void TaskCertify::stepFinalize()
417 LogInfo("Step: <<CERTYFYING DONE>>");
419 m_contextData.job->UpdateProgress(
420 InstallerContext::INSTALL_CERT_CHECK,
421 "Widget Certification Check Finished");
425 void TaskCertify::stepWarningPopupAnswer()
427 LogInfo("Step: <<Warning Popup Answer>>");
428 if (false == m_contextData.wacSecurity.isDistributorSigned() &&
429 WRT_POPUP_BUTTON_CANCEL == m_installCancel)
431 LogWarning("User does not agreed to install unsigned widgets!");
432 m_installCancel = WRT_POPUP_BUTTON;
434 ThrowMsg(Exceptions::NotAllowed, "Widget not allowed");
438 void TaskCertify::stepAuthorInfoPopupAnswer()
440 LogInfo("Step: <<Author Info Popup Answer>>");
441 if ( WRT_POPUP_BUTTON_CANCEL == m_installCancel) {
442 LogWarning("User does not agreed to install widget!");
443 m_installCancel = WRT_POPUP_BUTTON;
445 ThrowMsg(Exceptions::NotAllowed, "Widget not allowed");
449 bool TaskCertify::isTizenWebApp() const
452 if (m_installContext.widgetConfig.webAppType.appType
453 == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
458 } //namespace WidgetInstall