Get package cert level if there's no cert level given 11/238011/2
authorYunjin Lee <yunjin-.lee@samsung.com>
Tue, 7 Jul 2020 10:28:03 +0000 (19:28 +0900)
committerYunjin Lee <yunjin-.lee@samsung.com>
Thu, 9 Jul 2020 08:18:07 +0000 (08:18 +0000)
- To check whether the package is privacy whitelisted or not, get pkg
cert level from input param. If the given cert level is
PRVMGR_PACKAGE_VISIBILITY_NONE then get package cert level from
pkgmgr-info and certsvc.

Change-Id: I85ca805867a7a17a49eccfd3f6d6cc6edb44fc54
Signed-off-by: Yunjin Lee <yunjin-.lee@samsung.com>
capi/CMakeLists.txt
capi/src/privilege_info.c
packaging/privilege-checker.spec

index bf16a6ca8a5c0081d09e85015690bff3f6f2830c..33016a5e0d8892f4c8c7b0b5beac77e98e87c5c7 100644 (file)
@@ -13,7 +13,7 @@ INCLUDE_DIRECTORIES(${INC_DIR})
 SET(pc_requires "glib-2.0")
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_name} REQUIRED dlog pkgmgr-info glib-2.0 sqlite3 libtzplatform-config iniparser)
+pkg_check_modules(${fw_name} REQUIRED dlog pkgmgr-info glib-2.0 sqlite3 libtzplatform-config iniparser cert-svc-vcore)
 FOREACH(flag ${${fw_name}_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
index 3cef4a3e2a3c8aa32e43c057ee0721c0f6df14b7..45bc379c90448840b2ecd8b5a5186536a13540e6 100755 (executable)
@@ -24,6 +24,9 @@
 #include "privilege_info_types.h"
 #include "privilege_private.h"
 
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+
 #ifdef LOG_TAG
 #undef LOG_TAG
 #define LOG_TAG "PRIVILEGE_INFO"
@@ -470,10 +473,98 @@ static int __get_pkg_type(uid_t uid, const char *pkgid, privilege_manager_packag
        return 0;
 }
 
+static int __is_preloaded_pkg(const char* pkgid)
+{
+       pkgmgrinfo_pkginfo_h handle;
+
+       int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
+       TryReturn(ret == PMINFO_R_OK, , -1, "pkgmgrinfo_pkginfo_get_usr_pkginfo() failed for pkgid <%s>", pkgid);
+
+       bool is_preload = false;
+       ret = pkgmgrinfo_pkginfo_is_preload(handle, &is_preload);
+       TryReturn(ret == PMINFO_R_OK, pkgmgrinfo_pkginfo_destroy_pkginfo(handle), -1, "pkgmgrinfo_pkginfo_is_preload() failed. Failed to check whether %s is preloaded.", pkgid);
+
+       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+
+       if (is_preload)
+               return 1;
+       else
+               return 0;
+}
+
+static privilege_manager_visibility_e __get_pkg_cert_level(uid_t uid, const char* pkgid)
+{
+       const char* cert_value;
+       pkgmgrinfo_certinfo_h certinfo;
+
+       int ret = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
+       TryReturn(ret == PMINFO_R_OK, pkgmgrinfo_pkginfo_destroy_certinfo(certinfo), PRVMGR_PACKAGE_VISIBILITY_NONE, "pkgmgrinfo_pkginfo_create_certinfo() failed. ret = %d", ret);
+
+       ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
+       TryReturn(ret == PMINFO_R_OK, pkgmgrinfo_pkginfo_destroy_certinfo(certinfo), PRVMGR_PACKAGE_VISIBILITY_NONE, "pkgmgrinfo_pkginfo_load_certinfo() failed. ret = %d", ret);
+
+       ret = pkgmgrinfo_pkginfo_get_cert_value(certinfo, PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
+       TryReturn(ret == PMINFO_R_OK, pkgmgrinfo_pkginfo_destroy_certinfo(certinfo), PRVMGR_PACKAGE_VISIBILITY_NONE, "pkgmgrinfo_pkginfo_get_cert_value() failed. ret = %d", ret);
+
+       if (cert_value == NULL) {
+               pkgmgrinfo_pkginfo_destroy_pkginfo(certinfo);
+               // Check whether the given app is preloaded app
+               // -> Assume preloaded app to have platform level certificate (by appfw's guide)
+               ret = __is_preloaded_pkg(pkgid);
+               if (ret == 1) {
+                       ret = PRVMGR_PACKAGE_VISIBILITY_PLATFORM;
+               } else {
+                       LOGE("%s is not preloaded app and have no cert value", pkgid);
+                       ret = PRVMGR_PACKAGE_VISIBILITY_NONE;
+               }
+               return ret;
+       }
+
+       char* temp_cert = g_strdup(cert_value);
+       TryReturn(temp_cert != NULL, pkgmgrinfo_pkginfo_destroy_certinfo(certinfo), PRVMGR_PACKAGE_VISIBILITY_NONE, "g_strdup() of cert_value failed.");
+
+       pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+
+       CertSvcInstance instance;
+       CertSvcCertificate certificate;
+       CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
+
+       ret = certsvc_instance_new(&instance);
+       TryReturn(ret == CERTSVC_SUCCESS, , PRVMGR_PACKAGE_VISIBILITY_NONE, "certsvc_instance_new() failed. ret = %d", ret);
+
+       ret = certsvc_certificate_new_from_memory(instance, (const unsigned char *)temp_cert, strlen(temp_cert), CERTSVC_FORM_DER_BASE64, &certificate);
+       TryReturn(ret == CERTSVC_SUCCESS, certsvc_instance_free(instance), PRVMGR_PACKAGE_VISIBILITY_NONE, "certsvc_certificate_new_from_memory() failed. ret = %d", ret);
+
+       g_free(temp_cert);
+
+       ret = certsvc_certificate_get_visibility(certificate, &visibility);
+       if (ret != CERTSVC_SUCCESS)
+               LOGE("certsvc_certificate_get_visibility() is failed.");
+
+       certsvc_certificate_free(certificate);
+       certsvc_instance_free(instance);
+
+       if (visibility & CERTSVC_VISIBILITY_PUBLIC)
+               return PRVMGR_PACKAGE_VISIBILITY_PUBLIC;
+       if (visibility & CERTSVC_VISIBILITY_PARTNER)
+               return PRVMGR_PACKAGE_VISIBILITY_PARTNER;
+       if (visibility & CERTSVC_VISIBILITY_PLATFORM)
+               return PRVMGR_PACKAGE_VISIBILITY_PLATFORM;
+       LOGE("cert level is not public/partner/platform");
+       if (visibility & CERTSVC_VISIBILITY_DEVELOPER)
+               LOGD("cert level developer");
+       return PRVMGR_PACKAGE_VISIBILITY_NONE;
+}
+
 int privilege_info_get_privilege_type(uid_t uid, const char* pkgid, privilege_manager_package_type_e package_type, privilege_manager_visibility_e cert_level, const char* privilege, privilege_manager_privilege_type_e *type)
 {
        TryReturn(pkgid != NULL && privilege != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] pkgid or privilege is NULL");
 
+       if (cert_level == PRVMGR_PACKAGE_VISIBILITY_NONE)
+               cert_level = __get_pkg_cert_level(uid, pkgid);
+
+       TryReturn(cert_level != PRVMGR_PACKAGE_VISIBILITY_NONE, , PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] Can't get %s's cert level", pkgid);
+
        LOGD("get privilege type for uid: %d, package id: %s, type: %d, cert level: %d, privilege: %s", (int)uid, pkgid, package_type, cert_level, privilege);
 
        int ret = PRVMGR_ERR_NONE;
index 7ea06a910e03f63dc2f689a0f95e0c0181613eb0..ec10fdf43b2a7d8cd49bb5e9bb2aafdb46afac50 100644 (file)
@@ -36,6 +36,7 @@ BuildRequires:  pkgconfig(pkgmgr-info)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(sqlite3)
 BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(cert-svc-vcore)
 Requires: security-config
 Requires: tizen-platform-config
 Requires: pkgmgr