#include <widget_install/widget_install_errors.h>
#include <widget_install/widget_install_context.h>
#include <dpl/log/log.h>
-#include <wrt_error.h>
#include <dpl/wrt-dao-ro/global_config.h>
#include "wac_widget_id.h"
+#include <vcore/Certificate.h>
#include <vcore/SignatureReader.h>
#include <vcore/SignatureFinder.h>
-#include <vcore/SignatureValidator.h>
-#include <vcore/DeveloperModeValidator.h>
+#include <vcore/WrtSignatureValidator.h>
#include <dpl/utils/wrt_global_settings.h>
#include <dpl/wrt-dao-ro/global_dao_read_only.h>
using namespace WrtDB;
namespace {
-const std::string LABEL_NEW_LINE = "<br>";
-const std::string LABEL_NEW_LINE_2 = "<br><br>";
-const std::string UNTRUSTED_WIDGET ="It is an Untrusted Widget";
-const char *QUESTION ="Do you wanto to install?";
WidgetCertificateData toWidgetCertificateData(const SignatureData &data,
bool root)
WidgetCertificateData result;
result.chainId = data.getSignatureNumber();
+ LogDebug("result.chainId : " << result.chainId);
result.owner = data.isAuthorSignature() ?
WidgetCertificateData::AUTHOR : WidgetCertificateData::DISTRIBUTOR;
}
Assert(certificate && !certificate->getCommonName().IsNull() &&
- "CommonName is Null");
+ "CommonName is Null");
result.strCommonName = *certificate->getCommonName();
result.strMD5Fingerprint = std::string("md5 ") +
- SignatureValidator::FingerprintToColonHex(
+ Certificate::FingerprintToColonHex(
certificate->getFingerprint(Certificate::FINGERPRINT_MD5));
result.strSHA1Fingerprint = std::string("sha-1 ") +
- SignatureValidator::FingerprintToColonHex(
+ Certificate::FingerprintToColonHex(
certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
return result;
}
+
+CertificatePtr getOldAuthorSignerCertificate(DPL::String appid)
+{
+ WidgetDAOReadOnly dao(appid);
+ CertificateChainList chainList = dao.getWidgetCertificate(SIGNATURE_AUTHOR);
+
+ FOREACH(it, chainList)
+ {
+ ValidationCore::CertificateCollection chain;
+ if (false == chain.load(*it)) {
+ LogError("Chain is broken");
+ }
+
+ if (!chain.sort()) {
+ LogError("Chain failed at sorting");
+ }
+
+ ValidationCore::CertificateList list = chain.getCertificateList();
+
+ FOREACH(cert, list)
+ {
+ if (!(*cert)->isRootCert() && !(*cert)->isCA()) {
+ return *cert;
+ }
+ }
+ }
+ return CertificatePtr(NULL);
+}
} // namespace anonymous
namespace Jobs {
namespace WidgetInstall {
TaskCertify::TaskCertify(InstallerContext &inCont) :
DPL::TaskDecl<TaskCertify>(this),
- m_contextData(inCont),
- WidgetInstallPopup(inCont)
+ m_contextData(inCont)
{
AddStep(&TaskCertify::stepSignature);
-
- // Block until fixed popup issues
- if (!GlobalSettings::TestModeEnabled()
- && !m_installContext.m_quiet && !isTizenWebApp()) {
- AddStep(&TaskCertify::stepWarningPopup);
- AddStep(&TaskCertify::stepWarningPopupAnswer);
- AddStep(&TaskCertify::stepAuthorInfoPopup);
- AddStep(&TaskCertify::stepAuthorInfoPopupAnswer);
- AddStep(&TaskCertify::StepDeletePopupWin);
+ // certi comparison determines whether the update.
+ if (true == m_contextData.isUpdateMode) {
+ AddStep(&TaskCertify::stepVerifyUpdate);
}
AddStep(&TaskCertify::stepFinalize);
}
-void TaskCertify::processDistributorSignature(const SignatureData &data,
- bool first)
+void TaskCertify::processDistributorSignature(const SignatureData &data)
{
// this signature is verified -
// no point in check domain WAC_ROOT and WAC_RECOGNIZED
m_contextData.wacSecurity.setDistributorSigned(true);
- if (data.getStorageType().contains(CertStoreId::WAC_ROOT)) {
- m_contextData.wacSecurity.setWacSigned(true);
- }
-
CertificateCollection collection;
collection.load(data.getCertList());
- collection.sort();
+ Assert(collection.sort() &&
+ "Certificate collection can't sort");
+
Assert(collection.isChain() &&
"Certificate collection is not able to create chain. "
"It is not possible to verify this signature.");
m_contextData.wacSecurity.getCertificateChainListRef().push_back(
- collection);
+ collection);
- if (first) {
+ if (data.getSignatureNumber() == 1) {
m_contextData.wacSecurity.getCertificateListRef().push_back(
toWidgetCertificateData(data, true));
m_contextData.wacSecurity.getCertificateListRef().push_back(
using namespace ValidationCore;
LogInfo("DNS Identity match!");
// this signature is verified or widget is distributor signed
- m_contextData.wacSecurity.getAuthorCertificatePtr() =
- data.getEndEntityCertificatePtr();
+ m_contextData.wacSecurity.setAuthorCertificatePtr(data.getEndEntityCertificatePtr());
+ CertificatePtr test = m_contextData.wacSecurity.getAuthorCertificatePtr();
+
m_contextData.wacSecurity.getCertificateListRef().push_back(
toWidgetCertificateData(data, true));
m_contextData.wacSecurity.getCertificateListRef().push_back(
Assert(cert);
Certificate::AltNameSet dnsIdentity = cert->getAlternativeNameDNS();
+ CertificateCollection collection;
+ collection.load(data.getCertList());
+ collection.sort();
+ Assert(collection.isChain() &&
+ "Certificate collection is not able to create chain. "
+ "It is not possible to verify this signature.");
+
+ m_contextData.wacSecurity.getAuthorsCertificateChainListRef().push_back(
+ collection);
+
FOREACH(it, dnsIdentity){
if (widgetId.matchHost(*it)) {
m_contextData.wacSecurity.setRecognized(true);
void TaskCertify::stepSignature()
{
- LogInfo("enter");
+ LogInfo("================ Step: <<Signature>> ENTER ===============");
- std::string widgetPath = m_contextData.locations->getTemporaryRootDir() + "/";
+ std::string widgetPath;
+ if (m_contextData.widgetConfig.packagingType ==
+ WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
+ {
+ widgetPath = m_contextData.locations->getSourceDir() + "/";
+ } else {
+ widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/";
+ }
SignatureFileInfoSet signatureFiles;
SignatureFinder signatureFinder(widgetPath);
if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) {
LogError("Error in Signature Finder");
- ThrowMsg(Exceptions::InvalidPackage,
+ ThrowMsg(Exceptions::SignatureNotFound,
"Error openig temporary widget directory");
}
SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
- LogInfo("No of signatures: " << signatureFiles.size());
-
- bool firstDistributorSignature = true;
- bool testCertificate = false;
+ LogInfo("Number of signatures: " << signatureFiles.size());
bool complianceMode = GlobalDAOReadOnly::getComplianceMode();
SignatureReader xml;
xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
xml.read(data);
- SignatureValidator validator(!GlobalSettings::TestModeEnabled(),
- !GlobalSettings::TestModeEnabled(),
- complianceMode);
- SignatureValidator::Result result =
- validator.check(data, widgetPath);
- if (result == SignatureValidator::SIGNATURE_REVOKED) {
+ WrtSignatureValidator::AppType appType =
+ WrtSignatureValidator::WAC20;
+
+ if (m_contextData.widgetConfig.webAppType ==
+ APP_TYPE_TIZENWEBAPP)
+ {
+ appType = WrtSignatureValidator::TIZEN;
+ }
+
+ WrtSignatureValidator::Result result;
+
+ WrtSignatureValidator validator(
+ appType,
+ !GlobalSettings::
+ OCSPTestModeEnabled(),
+ !GlobalSettings::
+ CrlTestModeEnabled(),
+ complianceMode);
+
+ result = validator.check(data, widgetPath);
+
+ if (m_contextData.widgetConfig.packagingType
+ == WrtDB::PKG_TYPE_DIRECTORY_WEB_APP ||
+ m_contextData.job->getInstallerStruct().m_installMode
+ == InstallMode::INSTALL_MODE_PRELOAD)
+ {
+ // In directory installation mode, the validation is skipped.
+
+ result = WrtSignatureValidator::SIGNATURE_VERIFIED;
+ }
+
+ if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
LogWarning("Certificate is REVOKED");
- ThrowMsg(Exceptions::InvalidPackage,
+ ThrowMsg(Exceptions::CertificateExpired,
"Certificate is REVOKED");
}
- if (result == SignatureValidator::SIGNATURE_INVALID) {
+ if (result == WrtSignatureValidator::SIGNATURE_INVALID) {
LogWarning("Signature is INVALID");
// TODO change exception name
- ThrowMsg(Exceptions::InvalidPackage,
+ ThrowMsg(Exceptions::SignatureInvalid,
"Invalid Package");
}
if (data.isAuthorSignature()) {
- if (result == SignatureValidator::SIGNATURE_VERIFIED ||
+ if (result == WrtSignatureValidator::SIGNATURE_VERIFIED ||
m_contextData.wacSecurity.isDistributorSigned())
{
processAuthorSignature(data);
- } else if (result == SignatureValidator::SIGNATURE_DISREGARD) {
+ } else if (result ==
+ WrtSignatureValidator::SIGNATURE_DISREGARD)
+ {
continue;
}
} else {
- if (result == SignatureValidator::SIGNATURE_DISREGARD) {
- continue;
- }
// now signature _must_ be verified
- processDistributorSignature(data, firstDistributorSignature);
- firstDistributorSignature = false;
- }
-
- bool developerMode = GlobalDAOReadOnly::GetDeveloperMode();
-
- std::string realMEID;
- TapiHandle *tapiHandle = tel_init(NULL);
- char *meid = tel_get_misc_me_sn_sync(tapiHandle);
- if (meid)
- {
- realMEID = meid;
- free(meid);
+ processDistributorSignature(data);
}
- tel_deinit(tapiHandle);
-
- DeveloperModeValidator developerModeValidator(
- complianceMode,
- developerMode,
- GlobalDAOReadOnly::getComplianceFakeImei(),
- GlobalDAOReadOnly::getComplianceFakeMeid(),
- realMEID);
-
- developerModeValidator.check(data);
-
- testCertificate |=
- data.getStorageType().contains(CertStoreId::DEVELOPER);
-
- if (testCertificate && !developerMode) {
- LogDebug("Widget signed by test certificate, "
- "but developer mode is off.");
- ThrowMsg(Exceptions::InvalidPackage,
- "Widget signed by test certificate, "
- "but developer mode is off.");
- }
- m_contextData.widgetConfig.isTestWidget = testCertificate;
} Catch(ParserSchemaException::Base) {
- LogDebug("Error occured in ParserSchema.");
- ReThrowMsg(Exceptions::InvalidPackage,
+ LogError("Error occured in ParserSchema.");
+ ReThrowMsg(Exceptions::SignatureInvalid,
"Error occured in ParserSchema.");
}
- Catch(DeveloperModeValidator::Exception::Base) {
- LogDebug("Cannot validate developer certificate.");
- ReThrowMsg(Exceptions::InvalidPackage,
- "Cannot validate developer certificate.");
- }
}
if (signatureFiles.empty()) {
LogInfo("No signature files has been found.");
}
- LogInfo("================ Step: <<CSignature>> DONE ================");
+ LogInfo("================ Step: <<Signature>> DONE ================");
m_contextData.job->UpdateProgress(
InstallerContext::INSTALL_DIGSIG_CHECK,
"Widget Signature checked");
}
-void TaskCertify::createInstallPopup(PopupType type, const std::string &label)
-{
- m_contextData.job->Pause();
- if(m_popup)
- destroyPopup();
- bool ret = createPopup();
- if(ret)
- {
- loadPopup(type, label);
- showPopup();
- }
-}
-void TaskCertify::StepDeletePopupWin()
-{
- destroyPopup();
-}
-
-void TaskCertify::stepWarningPopup()
-{
- LogInfo("Step:: <<Warning Popup>>");
- // SP-2151: If widget is not recognized (OCSP status of any of certificates
- // it is signed with is not recognized) WRT must notify user that
- // widget cannot be installed as a trusted application, and let the
- // user decide whether it should be installed as an untrusted
- // application.
- if (!m_contextData.wacSecurity.isDistributorSigned()) {
- std::string label = UNTRUSTED_WIDGET +
- LABEL_NEW_LINE_2 +
- QUESTION;
- createInstallPopup(PopupType::WIDGET_UNRECOGNIZED, label);
- }
-}
-
-std::string TaskCertify::createAuthorWidgetInfo() const
-{
- std::string authorInfo;
- if (m_contextData.wacSecurity.isRecognized()) {
- //authorInfo += _("IDS_IM_WIDGET_RECOGNISED");
- authorInfo += _("WIDGET RECOGNISED");
- } else {
- //authorInfo += _("IDS_IM_WIDGET_UNRECOGNISED");
- authorInfo += _("WIDGET UNRECOGNISED");
- }
-
- authorInfo += LABEL_NEW_LINE_2;
- ValidationCore::CertificatePtr authorCert =
- m_contextData.wacSecurity.getAuthorCertificatePtr();
- if (!!authorCert) {
- DPL::Optional < DPL::String > organizationName =
- authorCert->getOrganizationName();
-
- //authorInfo += _("IDS_IM_WIDGET_AUTHOR_ORGANIZATION_NAME");
- authorInfo += _("AUTHOR ORGANIZATION NAME");
- authorInfo += LABEL_NEW_LINE;
-
- if (!organizationName.IsNull()) {
- authorInfo += DPL::ToUTF8String(*organizationName);
- } else {
- //authorInfo += _("IDS_IM_WIDGET_ORGANIZATION_UNKNOWN");
- authorInfo += _("WIDGET ORGANIZATION UNKNOWN");
- }
-
- authorInfo += LABEL_NEW_LINE_2;
-
- DPL::Optional < DPL::String > countryName =
- authorCert->getCountryName();
-
- //authorInfo += _("IDS_IM_WIDGET_COUNTRY_NAME");
- authorInfo += _("WIDGET COUNTRY NAME");
- authorInfo += LABEL_NEW_LINE;
-
- if (!countryName.IsNull()) {
- authorInfo += DPL::ToUTF8String(*countryName);
- } else {
- //authorInfo += _("IDS_IM_WIDGET_COUNTRY_UNKNOWN");
- authorInfo += _("WIDGET COUNTRY UNKNOWN");
- }
- } else {
- authorInfo +=
- //_("IDS_IM_WIDGET_DOES_NOT_CONTAIN_RECOGNIZED_AUTHOR_SIGNATURE");
- _("Widget does not contain recognized author signature");
- }
- return authorInfo;
-}
-
-void TaskCertify::stepAuthorInfoPopup()
-{
- LogInfo("Step:: <<Author Popup Information>>");
- std::string label
- = createAuthorWidgetInfo() + LABEL_NEW_LINE_2 + QUESTION;
- createInstallPopup(PopupType::WIDGET_AUTHOR_INFO, label);
-}
-
void TaskCertify::stepFinalize()
{
LogInfo("Step: <<CERTYFYING DONE>>");
"Widget Certification Check Finished");
}
-
-void TaskCertify::stepWarningPopupAnswer()
+bool TaskCertify::isTizenWebApp() const
{
- LogInfo("Step: <<Warning Popup Answer>>");
- if (false == m_contextData.wacSecurity.isDistributorSigned() &&
- WRT_POPUP_BUTTON_CANCEL == m_installCancel)
+ bool ret = FALSE;
+ if (m_contextData.widgetConfig.webAppType.appType
+ == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
{
- LogWarning("User does not agreed to install unsigned widgets!");
- m_installCancel = WRT_POPUP_BUTTON;
- destroyPopup();
- ThrowMsg(Exceptions::NotAllowed, "Widget not allowed");
+ ret = TRUE;
}
-}
-void TaskCertify::stepAuthorInfoPopupAnswer()
-{
- LogInfo("Step: <<Author Info Popup Answer>>");
- if ( WRT_POPUP_BUTTON_CANCEL == m_installCancel) {
- LogWarning("User does not agreed to install widget!");
- m_installCancel = WRT_POPUP_BUTTON;
- destroyPopup();
- ThrowMsg(Exceptions::NotAllowed, "Widget not allowed");
- }
+ return ret;
}
-bool TaskCertify::isTizenWebApp() const
+void TaskCertify::stepVerifyUpdate()
{
- bool ret = FALSE;
- if (m_installContext.widgetConfig.type.appType
- == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
- ret = TRUE;
-
- return ret;
+ LogInfo("Step: <<Check Update>>");
+ CertificatePtr newCertificate =
+ m_contextData.wacSecurity.getAuthorCertificatePtr();
+ CertificatePtr oldCertificate =
+ getOldAuthorSignerCertificate(m_contextData.widgetConfig.tzAppid);
+
+ if (!!newCertificate && !!oldCertificate) {
+ if (0 != newCertificate->getBase64().compare(oldCertificate->getBase64())) {
+ LogDebug("old widget's author signer certificate : " <<
+ oldCertificate->getBase64());
+ LogDebug("new widget's author signer certificate : " <<
+ newCertificate->getBase64());
+ ThrowMsg(Exceptions::NotMatchedCertification,
+ "Author signer certificates doesn't match \
+ between old widget and installing widget");
+ }
+ } else {
+ if (!(NULL == newCertificate.Get() && NULL == oldCertificate.Get())) {
+ ThrowMsg(Exceptions::NotMatchedCertification,
+ "Author signer certificates doesn't match \
+ between old widget and installing widget");
+ }
+ }
}
} //namespace WidgetInstall
} //namespace Jobs