Implement cert checker for boot-seqeucner plugin parser 67/271867/4
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 2 Mar 2022 23:23:20 +0000 (08:23 +0900)
committerHwanKyu Jhun <h.jhun@samsung.com>
Thu, 3 Mar 2022 00:03:51 +0000 (00:03 +0000)
If the package is not a preloaded package or platform level signed package,
the plugin does not store the information into the database.
The feature is available for preloaded packages or platform level signed packages.

Change-Id: I482b3a69881323226f4e3fb38213a07820fec190
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
CMakeLists.txt
packaging/aul.spec
parser/boot-sequencer/CMakeLists.txt
parser/boot-sequencer/cert_checker.cc [new file with mode: 0644]
parser/boot-sequencer/cert_checker.hh [new file with mode: 0644]
parser/boot-sequencer/parser_plugin.cc

index 75def48..7bae609 100644 (file)
@@ -39,6 +39,7 @@ INCLUDE(ApplyPkgConfig)
 
 PKG_CHECK_MODULES(BUNDLE_DEPS REQUIRED bundle)
 PKG_CHECK_MODULES(CAPI_SYSTEM_INFO_DEPS REQUIRED capi-system-info)
+PKG_CHECK_MODULES(CERT_SVC_VCORE_DEPS REQUIRED cert-svc-vcore)
 PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
 PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0)
 PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
index 0754fdf..a81204a 100644 (file)
@@ -37,6 +37,7 @@ BuildRequires:  pkgconfig(uuid)
 BuildRequires:  pkgconfig(libsmack)
 BuildRequires:  pkgconfig(gmock)
 BuildRequires:  pkgconfig(parcel)
+BuildRequires:  pkgconfig(cert-svc-vcore)
 
 %if 0%{?gcov:1}
 BuildRequires:  lcov
index b4818d6..d1f6f90 100644 (file)
@@ -15,6 +15,7 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_BOOT_SEQUENCER_PARSER_PLUGIN}
 
 APPLY_PKG_CONFIG(${TARGET_BOOT_SEQUENCER_PARSER_PLUGIN} PUBLIC
   BUNDLE_DEPS
+  CERT_SVC_VCORE_DEPS
   DLOG_DEPS
   GLIB_DEPS
   LIBTZPLATFORM_CONFIG_DEPS
diff --git a/parser/boot-sequencer/cert_checker.cc b/parser/boot-sequencer/cert_checker.cc
new file mode 100644 (file)
index 0000000..4c23a91
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cert_checker.hh"
+
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+#include <pkgmgr-info.h>
+
+#include <memory>
+
+#include "log_private.hh"
+
+namespace boot_sequencer {
+namespace {
+
+bool IsPreload(const std::string& pkgid, uid_t uid) {
+  pkgmgrinfo_pkginfo_h handle;
+  int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid.c_str(), uid, &handle);
+  if (ret != PMINFO_R_OK) {
+    _E("pkgmgrinfo_pkginfo_get_usr_pkginfo() is failed. error(%d)", ret);
+    return false;
+  }
+
+  bool preload = false;
+  ret = pkgmgrinfo_pkginfo_is_preload(handle, &preload);
+  if (ret != PMINFO_R_OK)
+    _E("pkgmgrinfo_pkginfo_is_preload() is failed. error(%d)", ret);
+
+  pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+  return preload;
+}
+
+std::string GetCertValueFromPkgInfo(const std::string& pkgid, uid_t uid) {
+  pkgmgrinfo_certinfo_h certinfo;
+  int ret = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
+  if (ret != PMINFO_R_OK) {
+    _E("pkgmgrinfo_pkginfo_create_certinfo() is failed. error(%d)", ret);
+    return {};
+  }
+  auto certinfo_auto = std::unique_ptr<
+      std::remove_pointer<pkgmgrinfo_certinfo_h>::type,
+      decltype(pkgmgrinfo_pkginfo_destroy_certinfo)*>(
+          certinfo, pkgmgrinfo_pkginfo_destroy_certinfo);
+
+  ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), certinfo, uid);
+  if (ret != PMINFO_R_OK) {
+    _E("pkgmgrinfo_pkginfo_load_certinfo() is failed. error(%d)", ret);
+    return {};
+  }
+
+  const char* cert_value;
+  ret = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
+      PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
+  if (ret != PMINFO_R_OK || cert_value == nullptr) {
+    _E("pkgmgrinfo_pkginfo_get_cert_value() is failed. error(%d)", ret);
+    return {};
+  }
+
+  return std::string(cert_value);
+}
+
+int GetVisibilityFromCertSvc(const std::string& cert_value) {
+  if (cert_value.empty())
+    return CERTSVC_VISIBILITY_PUBLIC;
+
+  CertSvcInstance instance;
+  int ret = certsvc_instance_new(&instance);
+  if (ret != CERTSVC_SUCCESS) {
+    _E("certsvc_instance_new() is failed. error(%d)", ret);
+    return CERTSVC_VISIBILITY_PUBLIC;
+  }
+
+  CertSvcCertificate certificate;
+  ret = certsvc_certificate_new_from_memory(instance,
+      reinterpret_cast<const unsigned char*>(cert_value.c_str()),
+      cert_value.length(), CERTSVC_FORM_DER_BASE64, &certificate);
+  if (ret != CERTSVC_SUCCESS) {
+    _E("certsvc_certificate_new_from_memory() is failed. error(%d)", ret);
+    certsvc_instance_free(instance);
+    return CERTSVC_VISIBILITY_PUBLIC;
+  }
+
+  CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
+  ret = certsvc_certificate_get_visibility(certificate, &visibility);
+  if (ret != CERTSVC_SUCCESS)
+    _E("certsvc_certificate_get_visibility() is failed. error(%d)", ret);
+
+  certsvc_certificate_free(certificate);
+  certsvc_instance_free(instance);
+  return static_cast<int>(visibility);
+}
+
+}  // namespace
+
+
+bool CertChecker::IsPlatform(const std::string& pkgid, uid_t uid) {
+  if (IsPreload(pkgid, uid)) {
+    _W("%s is preload package", pkgid.c_str());
+    return true;
+  }
+
+  int visibility = GetVisibilityFromCertSvc(
+      GetCertValueFromPkgInfo(pkgid, uid));
+  if (visibility & CERTSVC_VISIBILITY_PLATFORM)
+    return true;
+
+  return false;
+}
+
+}  // namespace boot_sequencer
diff --git a/parser/boot-sequencer/cert_checker.hh b/parser/boot-sequencer/cert_checker.hh
new file mode 100644 (file)
index 0000000..c19ecc6
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CERT_CHECKER_HH_
+#define CERT_CHECKER_HH_
+
+#include <sys/types.h>
+
+#include <string>
+
+namespace boot_sequencer {
+
+class CertChecker {
+ public:
+  static bool IsPlatform(const std::string& pkgid, uid_t uid);
+};
+
+}  // namespace boot_sequencer
+
+#endif  // CERT_CHECKER_HH_
index 8e50c7c..ae28bf6 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <bundle_cpp.h>
 
+#include "cert_checker.hh"
 #include "log_private.hh"
 
 namespace boot_sequencer {
@@ -135,6 +136,11 @@ int ParserPlugin::StepBackup() {
 }
 
 int ParserPlugin::StepInstall() {
+  if (!CertChecker::IsPlatform(args_->GetPackage(), GetTargetUid())) {
+    _W("%s is not a platform package", args_->GetPackage().c_str());
+    return 0;
+  }
+
   int ret = Parse();
   if (ret != 0)
     return ret;