Author signature match check during update installation 50/41950/2
authorTomasz Iwanek <t.iwanek@samsung.com>
Thu, 11 Jun 2015 13:06:15 +0000 (15:06 +0200)
committerTomasz Iwanek <t.iwanek@samsung.com>
Mon, 29 Jun 2015 12:48:07 +0000 (14:48 +0200)
Author certificate of updated version of widget must match
the author certificate of already installed version.

Change-Id: Id86d2330ecbdb2b22bcfb6154f6f1b350b37c9f1

src/common/CMakeLists.txt
src/common/step/step_check_old_certificate.cc [new file with mode: 0644]
src/common/step/step_check_old_certificate.h [new file with mode: 0644]
src/common/step/step_check_signature.cc
src/tpk/task.cc
src/wgt/wgt_backend.cc

index cbbf1dd..9baeff3 100644 (file)
@@ -9,6 +9,7 @@ SET(SRCS
   step/step_backup_icons.cc
   step/step_backup_manifest.cc
   step/step_unzip.cc
+  step/step_check_old_certificate.cc
   step/step_check_signature.cc
   step/step_configure.cc
   step/step_copy.cc
diff --git a/src/common/step/step_check_old_certificate.cc b/src/common/step/step_check_old_certificate.cc
new file mode 100644 (file)
index 0000000..2d2fc6e
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/step_check_old_certificate.h"
+
+#include <pkgmgr-info.h>
+#include <unistd.h>
+
+#include <cstdlib>
+#include <string>
+
+#include "common/utils/logging.h"
+
+namespace {
+
+std::string QueryOldCertificateAuthorCertificate(const std::string& pkgid) {
+  pkgmgrinfo_certinfo_h handle;
+  int ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
+  if (ret != PMINFO_R_OK) {
+    LOG(ERROR) << "pkgmgrinfo_pkginfo_create_certinfo failed with error: "
+               << ret;
+    return {};
+  }
+  ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), handle, getuid());
+  if (ret != PMINFO_R_OK) {
+    LOG(ERROR) << "pkgmgrinfo_pkginfo_load_certinfo failed with error: " << ret;
+    pkgmgrinfo_pkginfo_destroy_certinfo(handle);
+    return {};
+  }
+  const char* author_cert = nullptr;
+  ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT,
+                                          &author_cert);
+  if (ret != PMINFO_R_OK) {
+    LOG(ERROR) << "pkgmgrinfo_pkginfo_get_cert_value failed with error: "
+               << ret;
+    pkgmgrinfo_pkginfo_destroy_certinfo(handle);
+    return {};
+  }
+  std::string old_author_certificate;
+  if (author_cert)
+    old_author_certificate = author_cert;
+  pkgmgrinfo_pkginfo_destroy_certinfo(handle);
+  return old_author_certificate;
+}
+
+}  // namespace
+
+namespace common_installer {
+namespace old_certificate {
+
+Step::Status StepCheckOldCertificate::process() {
+  std::string old_author_certificate =
+      QueryOldCertificateAuthorCertificate(context_->pkgid.get());
+  if (old_author_certificate.empty())
+    return Status::OK;
+
+  const auto& cert = context_->certificate_info.get().author_certificate.get();
+  if (!cert) {
+    LOG(ERROR) << "Trying to update package without signature is not allowed "
+               << "when the previous version of package has signature";
+    return Status::ERROR;
+  }
+  if (old_author_certificate != cert->getBase64()) {
+    LOG(ERROR) << "Author signature doesn't match the previous one. "
+               << "Update must be aborted";
+    return Status::ERROR;
+  }
+
+  return Status::OK;
+}
+
+}  // namespace old_certificate
+}  // namespace common_installer
diff --git a/src/common/step/step_check_old_certificate.h b/src/common/step/step_check_old_certificate.h
new file mode 100644 (file)
index 0000000..20a873f
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_STEP_CHECK_OLD_CERTIFICATE_H_
+#define COMMON_STEP_STEP_CHECK_OLD_CERTIFICATE_H_
+
+#include "common/context_installer.h"
+#include "common/step/step.h"
+#include "common/utils/logging.h"
+
+namespace common_installer {
+namespace old_certificate {
+
+class StepCheckOldCertificate : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status undo() override { return Status::OK; }
+  Status clean() override { return Status::OK; }
+  Status precheck() override { return Status::OK; }
+
+  SCOPE_LOG_TAG(CheckOldCertificate)
+};
+
+}  // namespace old_certificate
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_STEP_CHECK_OLD_CERTIFICATE_H_
index 36f8841..ccdad36 100644 (file)
@@ -226,8 +226,6 @@ Step::Status StepCheckSignature::process() {
       context_->manifest_data.get()->privileges))
     return Status::ERROR;
 
-  // TODO(t.iwanek): check old certificate during update...
-
   LOG(INFO) << "Signature done";
   return Status::OK;
 }
index d817fff..4e07239 100644 (file)
@@ -3,8 +3,8 @@
 #ifdef HOSTTEST
 #include "test/mock_pkgmgr_installer.h"
 #else
-#include "common/pkgmgr_interface.h"
 #include "common/app_installer.h"
+#include "common/pkgmgr_interface.h"
 #include "common/step/step_configure.h"
 #include "common/step/step_backup_icons.h"
 #include "common/step/step_backup_manifest.h"
 #include "common/step/step_unzip.h"
 #include "common/step/step_update_app.h"
 #include "common/step/step_update_security.h"
+#include "common/step/step_check_old_certificate.h"
+#include "common/utils/logging.h"
+
 #include "tpk/step/step_parse.h"
 #include "tpk/step/step_create_symbolic_link.h"
-#include "common/utils/logging.h"
 #endif
 
-
 namespace ci = common_installer;
 
 namespace {
@@ -113,6 +114,7 @@ int Task::Update() {
   ai.AddStep<ci::unzip::StepUnzip>();
   ai.AddStep<tpk::step::StepParse>();
   ai.AddStep<ci::signature::StepCheckSignature>();
+  ai.AddStep<ci::old_certificate::StepCheckOldCertificate>();
   ai.AddStep<ci::old_manifest::StepOldManifest>();
   ai.AddStep<ci::backup_manifest::StepBackupManifest>();
   ai.AddStep<ci::backup_icons::StepBackupIcons>();
index ea62696..422ace9 100644 (file)
@@ -26,6 +26,7 @@
 #include "common/step/step_unzip.h"
 #include "common/step/step_update_app.h"
 #include "common/step/step_update_security.h"
+#include "common/step/step_check_old_certificate.h"
 
 #include "wgt/step/step_create_symbolic_link.h"
 #include "wgt/step/step_check_settings_level.h"
@@ -68,6 +69,7 @@ int main(int argc, char** argv) {
       installer.AddStep<wgt::parse::StepParse>();
       installer.AddStep<ci::signature::StepCheckSignature>();
       installer.AddStep<wgt::check_settings::StepCheckSettingsLevel>();
+      installer.AddStep<ci::old_certificate::StepCheckOldCertificate>();
       installer.AddStep<ci::old_manifest::StepOldManifest>();
       installer.AddStep<ci::backup_manifest::StepBackupManifest>();
       installer.AddStep<ci::backup_icons::StepBackupIcons>();