Remove explicit dependency of cert-svc-vcore library 21/272021/2
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 7 Mar 2022 01:38:43 +0000 (10:38 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 7 Mar 2022 01:50:14 +0000 (10:50 +0900)
Currently, the aul package has a circular dependency as below:
aul->cert-svc->key-manager->uci->hwcrypto->trustzone-nwd->capi-appfw-app-common->aul

This patch removes an explicit dependency about cert-svc-vcore library.
And, the boot sequencer parser plugin calls functions of cert-svc-vcore using
dlopen() & dlsym().

Change-Id: I752dd5b4e09e4e1ccc294f60e87147f16b845405
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

index 7bae609..75def48 100644 (file)
@@ -39,7 +39,6 @@ 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 9fa6844..470e3c2 100644 (file)
@@ -37,7 +37,6 @@ BuildRequires:  pkgconfig(uuid)
 BuildRequires:  pkgconfig(libsmack)
 BuildRequires:  pkgconfig(gmock)
 BuildRequires:  pkgconfig(parcel)
-BuildRequires:  pkgconfig(cert-svc-vcore)
 
 %if 0%{?gcov:1}
 BuildRequires:  lcov
index d1f6f90..0c43967 100644 (file)
@@ -13,9 +13,10 @@ ADD_LIBRARY(${TARGET_BOOT_SEQUENCER_PARSER_PLUGIN} SHARED
 TARGET_INCLUDE_DIRECTORIES(${TARGET_BOOT_SEQUENCER_PARSER_PLUGIN}
   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
 
+TARGET_LINK_LIBRARIES(${TARGET_BOOT_SEQUENCER_PARSER_PLUGIN} PUBLIC "-ldl")
+
 APPLY_PKG_CONFIG(${TARGET_BOOT_SEQUENCER_PARSER_PLUGIN} PUBLIC
   BUNDLE_DEPS
-  CERT_SVC_VCORE_DEPS
   DLOG_DEPS
   GLIB_DEPS
   LIBTZPLATFORM_CONFIG_DEPS
index 5050c3d..87e0881 100644 (file)
@@ -16,8 +16,7 @@
 
 #include "cert_checker.hh"
 
-#include <cert-svc/ccert.h>
-#include <cert-svc/cinstance.h>
+#include <dlfcn.h>
 #include <pkgmgr-info.h>
 
 #include <memory>
 namespace boot_sequencer {
 namespace {
 
+constexpr const char LIBCERT_SVC_VCORE[] = "/usr/lib/libcert-svc-vcore.so.2";
+
+typedef struct {
+  void* privatePtr;
+} CertSvcInstance;
+
+typedef struct {
+  size_t privateHandler;
+  CertSvcInstance privateInstance;
+} CertSvcCertificate;
+
+typedef enum {
+  CERTSVC_FORM_DER,
+  CERTSVC_FORM_DER_BASE64,
+} CertSvcCertificateFrom;
+
+typedef enum {
+  CERTSVC_VISIBILITY_DEVELOPER            = 1,
+  CERTSVC_VISIBILITY_PUBLIC               = 1 << 6,
+  CERTSVC_VISIBILITY_PARTNER              = 1 << 7,
+  CERTSVC_VISIBILITY_PLATFORM             = 1 << 10
+} CertSvcVisibility;
+
+class CertSvc {
+ public:
+  static CertSvc& GetInst() {
+    static CertSvc inst;
+    if (inst.disposed_)
+      inst.Init();
+
+    return inst;
+  }
+
+  void Dispose() {
+    if (disposed_)
+      return;
+
+    certsvc_certificate_free_ = nullptr;
+    certsvc_certificate_get_visibility_ = nullptr;
+    certsvc_certificate_new_from_memory_ = nullptr;
+    certsvc_instance_free_ = nullptr;
+    certsvc_instance_new_ = nullptr;
+
+    if (handle_ != nullptr) {
+      dlclose(handle_);
+      handle_ = nullptr;
+    }
+
+    disposed_ = true;
+  }
+
+  int GetVisibility(const std::string& cert_value) {
+    if (disposed_ || cert_value.empty())
+      return CERTSVC_VISIBILITY_PUBLIC;
+
+    CertSvcInstance instance;
+    int ret = certsvc_instance_new_(&instance);
+    if (ret != 1) {
+      _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 != 1) {
+      _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 != 1)
+      _E("certsvc_certificate_get_visibility() is failed. error(%d)", ret);
+
+    certsvc_certificate_free_(certificate);
+    certsvc_instance_free_(instance);
+    return static_cast<int>(visibility);
+  }
+
+ private:
+  using CertSvcInstanceNew = int (*)(CertSvcInstance*);
+  using CertSvcInstanceFree = int (*)(CertSvcInstance);
+  using CertSvcCertificateNewFromMemory =
+      int (*)(CertSvcInstance, const unsigned char*, size_t,
+          CertSvcCertificateFrom, CertSvcCertificate*);
+  using CertSvcCertificateGetVisibility =
+    int (*)(CertSvcCertificate, CertSvcVisibility*);
+  using CertSvcCertificateFree = int (*)(CertSvcCertificate);
+
+  CertSvc() = default;
+
+  ~CertSvc() {
+    Dispose();
+  }
+
+  void Init() {
+    void* handle = dlopen(LIBCERT_SVC_VCORE, RTLD_LAZY | RTLD_LOCAL);
+    if (handle == nullptr) {
+      _E("dlopen() is failed. error(%s)", dlerror());
+      return;
+    }
+    auto dlcloser = [](void* p) { dlclose(p); };
+    std::unique_ptr<void, decltype(dlcloser)> handle_auto(handle, dlcloser);
+
+    certsvc_instance_new_ = reinterpret_cast<CertSvcInstanceNew>(
+        dlsym(handle, "certsvc_instance_new"));
+    if (certsvc_instance_new_ == nullptr) {
+      _E("dlsym() is failed. 'certsvc_isntance_new'");
+      return;
+    }
+
+    certsvc_instance_free_ = reinterpret_cast<CertSvcInstanceFree>(
+        dlsym(handle, "certsvc_instance_free"));
+    if (certsvc_instance_free_ == nullptr) {
+      _E("dlsym() is failed. 'certsvc_instance_free'");
+      return;
+    }
+
+    certsvc_certificate_new_from_memory_ =
+        reinterpret_cast<CertSvcCertificateNewFromMemory>(
+            dlsym(handle, "certsvc_certificate_new_from_memory"));
+    if (certsvc_certificate_new_from_memory_ == nullptr) {
+      _E("dlsym() is failed. 'certsvc_certificate_new_from_memory'");
+      return;
+    }
+
+    certsvc_certificate_get_visibility_ =
+        reinterpret_cast<CertSvcCertificateGetVisibility>(
+            dlsym(handle, "certsvc_certificate_get_visibility"));
+    if (certsvc_certificate_get_visibility_ == nullptr) {
+      _E("dlsym() is failed. 'certsvc_certificate_get_visibility'");
+      return;
+    }
+
+    certsvc_certificate_free_ = reinterpret_cast<CertSvcCertificateFree>(
+        dlsym(handle, "certsvc_certificate_free"));
+    if (certsvc_certificate_free_ == nullptr) {
+      _E("dlsym() is failed. 'certsvc_certificate_free'");
+      return;
+    }
+
+    handle_ = handle_auto.release();
+    disposed_ = false;
+  }
+
+ private:
+  bool disposed_ = true;
+  void* handle_ = nullptr;
+  CertSvcInstanceNew certsvc_instance_new_ = nullptr;
+  CertSvcInstanceFree certsvc_instance_free_ = nullptr;
+  CertSvcCertificateNewFromMemory certsvc_certificate_new_from_memory_ = nullptr;
+  CertSvcCertificateGetVisibility certsvc_certificate_get_visibility_ = nullptr;
+  CertSvcCertificateFree certsvc_certificate_free_ = nullptr;
+};
+
 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);
@@ -73,37 +230,6 @@ std::string GetCertValueFromPkgInfo(const std::string& pkgid, uid_t uid) {
   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
 
 
@@ -113,8 +239,9 @@ bool CertChecker::IsPrivilegedPackage(const std::string& pkgid, uid_t uid) {
     return true;
   }
 
-  int visibility = GetVisibilityFromCertSvc(
+  int visibility = CertSvc::GetInst().GetVisibility(
       GetCertValueFromPkgInfo(pkgid, uid));
+  _D("Visibility: %d", visibility);
   if (visibility & CERTSVC_VISIBILITY_PLATFORM ||
       visibility & CERTSVC_VISIBILITY_PARTNER)
     return true;