Fixed Certificate update issue during updating RDS mode
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_certify.cpp
index 342b5f4..b3273b1 100644 (file)
@@ -33,7 +33,6 @@
 #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"
 
@@ -63,6 +62,7 @@ WidgetCertificateData toWidgetCertificateData(const SignatureData &data,
     WidgetCertificateData result;
 
     result.chainId = data.getSignatureNumber();
+    LogDebug("result.chainId : " << result.chainId);
 
     result.owner = data.isAuthorSignature() ?
         WidgetCertificateData::AUTHOR : WidgetCertificateData::DISTRIBUTOR;
@@ -93,16 +93,48 @@ WidgetCertificateData toWidgetCertificateData(const SignatureData &data,
 
     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)
+    WidgetInstallPopup(inCont),
+    m_contextData(inCont)
 {
     AddStep(&TaskCertify::stepSignature);
+    // certi comparison determines whether the update.
+    if (true == m_contextData.existingWidgetInfo.isExist) {
+        AddStep(&TaskCertify::stepVerifyUpdate);
+    }
 
     // Block until fixed popup issues
     if (!GlobalSettings::PopupsTestModeEnabled()
@@ -117,8 +149,7 @@ TaskCertify::TaskCertify(InstallerContext &inCont) :
     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
@@ -140,7 +171,7 @@ void TaskCertify::processDistributorSignature(const SignatureData &data,
     m_contextData.wacSecurity.getCertificateChainListRef().push_back(
         collection);
 
-    if (first) {
+    if (data.getSignatureNumber() == 1) {
         m_contextData.wacSecurity.getCertificateListRef().push_back(
             toWidgetCertificateData(data, true));
         m_contextData.wacSecurity.getCertificateListRef().push_back(
@@ -153,8 +184,9 @@ void TaskCertify::processAuthorSignature(const SignatureData &data)
     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(
@@ -189,8 +221,14 @@ void TaskCertify::stepSignature()
 {
     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);
@@ -203,7 +241,6 @@ void TaskCertify::stepSignature()
     SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
     LogInfo("Number of signatures: " << signatureFiles.size());
 
-    bool firstDistributorSignature = true;
     bool testCertificate = false;
 
     bool complianceMode = GlobalDAOReadOnly::getComplianceMode();
@@ -275,8 +312,7 @@ void TaskCertify::stepSignature()
                     continue;
                 }
                 // now signature _must_ be verified
-                processDistributorSignature(data, firstDistributorSignature);
-                firstDistributorSignature = false;
+                processDistributorSignature(data);
             }
 
             bool developerMode = GlobalDAOReadOnly::GetDeveloperMode();
@@ -470,6 +506,33 @@ bool TaskCertify::isTizenWebApp() const
 
     return ret;
 }
+
+void TaskCertify::stepVerifyUpdate()
+{
+    LogInfo("Step: <<Check Update>>");
+    CertificatePtr newCertificate =
+        m_contextData.wacSecurity.getAuthorCertificatePtr();
+    CertificatePtr oldCertificate =
+        getOldAuthorSignerCertificate(m_installContext.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::InvalidPackage,
+                    "Author signer certificates doesn't match \
+                    between old widget and installing widget");
+        }
+    } else {
+        if (!(NULL == newCertificate.Get() && NULL == oldCertificate.Get())) {
+            ThrowMsg(Exceptions::InvalidPackage,
+                    "Author signer certificates doesn't match \
+                    between old widget and installing widget");
+        }
+    }
+}
 } //namespace WidgetInstall
 } //namespace Jobs