#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);
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
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;