Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / certificate_validation.cc
index 9c2fa40..4975f96 100644 (file)
@@ -4,22 +4,22 @@
 
 #include "common/certificate_validation.h"
 
-#include <boost/format.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/scope_exit.hpp>
+#include <vcore/Certificate.h>
 #include <vcore/SignatureValidator.h>
 
 #include <algorithm>
+#include <filesystem>
 #include <fstream>
 #include <regex>
 #include <utility>
 
 #include "common/privileges.h"
 #include "common/utils/base64.h"
+#include "common/utils/file_util.h"
 #include "common/utils/glist_range.h"
 
-namespace bf = boost::filesystem;
 namespace ci = common_installer;
+namespace fs = std::filesystem;
 
 namespace {
 
@@ -61,37 +61,67 @@ static bool SetAuthorCertificate(const ValidationCore::SignatureData& data,
     LOG(ERROR) << "No certificates in certificate list";
     return false;
   }
-  unsigned char* public_key;
+  unsigned char* public_key = nullptr;
   size_t len;
   (*it)->getPublicKeyDER(&public_key, &len);
   std::string author_id =
       ci::EncodeBase64(public_key, len);
   cert_info->author_id.set(author_id);
+  free(public_key);
+
   return SetCertificate(data,
-      &cert_info->author_certificate,
-      &cert_info->author_intermediate_certificate,
-      &cert_info->author_root_certificate,
+      &cert_info->auth_cert,
+      &cert_info->auth_im_cert,
+      &cert_info->auth_root_cert,
       true);
 }
 
 bool SetDistributorCertificate(const ValidationCore::SignatureData& data,
     common_installer::CertificateInfo* cert_info) {
   return SetCertificate(data,
-      &cert_info->distributor_certificate,
-      &cert_info->distributor_intermediate_certificate,
-      &cert_info->distributor_root_certificate,
+      &cert_info->dist_cert,
+      &cert_info->dist_im_cert,
+      &cert_info->dist_root_cert,
       true);
 }
 
 bool SetDistributor2Certificate(const ValidationCore::SignatureData& data,
     common_installer::CertificateInfo* cert_info) {
   return SetCertificate(data,
-      &cert_info->distributor2_certificate,
-      &cert_info->distributor2_intermediate_certificate,
-      &cert_info->distributor2_root_certificate,
+      &cert_info->dist2_cert,
+      &cert_info->dist2_im_cert,
+      &cert_info->dist2_root_cert,
       false);
 }
 
+bool SetSignature(std::ifstream* ifs,
+    ValidationCore::CertificatePtr* certificate,
+    std::string* cert_str) {
+  std::string cert;
+  std::getline(*ifs, cert);
+  if (cert.length() != 0) {
+    ValidationCore::CertificatePtr cert_ptr(
+        new ValidationCore::Certificate(
+            cert, ValidationCore::Certificate::FormType::FORM_BASE64));
+    *certificate = std::move(cert_ptr);
+    *cert_str = std::move(cert);
+  }
+
+  return true;
+}
+
+bool ReadSignature(std::ifstream* ifs,
+    ValidationCore::CertificatePtr* cert,
+    ValidationCore::CertificatePtr* im_cert,
+    ValidationCore::CertificatePtr* root_cert,
+    std::string* root_cert_str) {
+
+  SetSignature(ifs, cert, root_cert_str);
+  SetSignature(ifs, im_cert, root_cert_str);
+  SetSignature(ifs, root_cert, root_cert_str);
+  return true;
+}
+
 }  // namespace
 
 namespace common_installer {
@@ -133,7 +163,7 @@ void SetPrivilegeLevel(const ValidationCore::SignatureData& data,
 }
 
 bool ValidateSignatureFile(
-    const bf::path& base_path,
+    const fs::path& base_path,
     const ValidationCore::SignatureFileInfo& file_info,
     common_installer::PrivilegeLevel* level,
     common_installer::CertificateInfo* cert_info,
@@ -195,11 +225,11 @@ bool CheckAuthorSignature(const ValidationCore::SignatureFileInfo& file_info) {
 
 bool CheckDistSignature(const ValidationCore::SignatureFileInfo& file_info) {
   std::regex distributor_regex(kRegexDistributorSignature);
-  bf::path file_path(file_info.getFileName());
+  fs::path file_path(file_info.getFileName());
   return std::regex_search(file_path.filename().string(), distributor_regex);
 }
 
-bool ValidateSignatures(const bf::path& base_path,
+bool ValidateSignatures(const fs::path& base_path,
     PrivilegeLevel* level, common_installer::CertificateInfo* cert_info,
     bool check_reference, std::string* error_message) {
   // Find signature files
@@ -218,8 +248,8 @@ bool ValidateSignatures(const bf::path& base_path,
   bool distributor_signatures = std::any_of(
       signature_files.begin(), signature_files.end(), CheckDistSignature);
 
-  /* For platform update from 2.4.  signature1.xml of user app has deleted */
-  if (getuid() != 0 && (!author_signatures || !distributor_signatures)) {
+  if (getuid() != 0 && (!author_signatures || !distributor_signatures) &&
+      check_reference) {
     LOG(ERROR) << "Author or distribuor signature is missing.";
     return false;
   }
@@ -236,24 +266,38 @@ bool ValidateSignatures(const bf::path& base_path,
   return true;
 }
 
-bool CheckPrivLevelFromFile(const std::string& pkgid, PrivilegeLevel* level) {
+bool GetSignatureFromFile(const std::string& pkgid,
+    bool is_readonly_package, PrivilegeLevel* level,
+    ci::CertificateInfo* cert_info) {
   CertSvcInstance instance;
   CertSvcCertificate certificate;
   CertSvcVisibility visibility = CERTSVC_VISIBILITY_DEVELOPER;
-  std::string dist_root;
-
-  bf::path file_path("/tmp/");
-  file_path /= std::string(pkgid + ".txt");
-  if (!bf::exists(file_path))
+  std::string root_cert;
+
+  fs::path file_path((is_readonly_package) ?
+      tzplatform_getenv(TZ_SYS_RO_SHARE) : tzplatform_getenv(TZ_SYS_SHARE));
+  file_path /= std::string("signatures/" + pkgid + ".txt");
+  std::ifstream ifs(file_path.c_str(), std::ifstream::in);
+  if (!ifs.is_open()) {
+    LOG(INFO) << "Failed to open file : " << file_path;
     return false;
+  }
 
-  std::ifstream ifs(file_path.c_str(),
-      std::ifstream::in | std::ifstream::binary);
-  if (!ifs)
-    return false;
-  getline(ifs, dist_root);
-  if (dist_root.length() == 0)
+  if (!ReadSignature(&ifs,
+          &cert_info->dist2_cert.get(),
+          &cert_info->dist2_im_cert.get(),
+          &cert_info->dist2_root_cert.get(),
+          &root_cert) ||
+      !ReadSignature(&ifs,
+          &cert_info->dist_cert.get(),
+          &cert_info->dist_im_cert.get(),
+          &cert_info->dist_root_cert.get(),
+          &root_cert))
     return false;
+  if (root_cert.length() == 0) {
+      LOG(INFO) << "Dist root cert not exists";
+      return false;
+  }
 
   int ret = certsvc_instance_new(&instance);
   if (ret != CERTSVC_SUCCESS) {
@@ -261,8 +305,8 @@ bool CheckPrivLevelFromFile(const std::string& pkgid, PrivilegeLevel* level) {
     return false;
   }
   ret = certsvc_certificate_new_from_memory(instance,
-      reinterpret_cast<const unsigned char *>(dist_root.c_str()),
-      strlen(dist_root.c_str()),
+      reinterpret_cast<const unsigned char *>(root_cert.c_str()),
+      strlen(root_cert.c_str()),
       CERTSVC_FORM_DER_BASE64,
       &certificate);
   if (ret != CERTSVC_SUCCESS) {
@@ -286,6 +330,10 @@ bool CheckPrivLevelFromFile(const std::string& pkgid, PrivilegeLevel* level) {
   return true;
 }
 
+void FreePrivilegeList(GList* priv) {
+  g_list_free_full(priv, free);
+}
+
 bool ValidatePrivilegeLevel(common_installer::PrivilegeLevel level,
     uid_t uid, const char* api_version, GList* privileges,
     std::string* error_message) {
@@ -300,14 +348,12 @@ bool ValidatePrivilegeLevel(common_installer::PrivilegeLevel level,
 
   GList* native_privileges =
       ci::PrivilegeXToPrivilege(privileges, ci::kNativePrivilegeType);
-  BOOST_SCOPE_EXIT_ALL(&) {
-    g_list_free_full(native_privileges, free);
-  };
+  std::unique_ptr<GList, decltype(FreePrivilegeList)*> native_privs_deleter(
+      native_privileges, FreePrivilegeList);
   GList* web_privileges =
       ci::PrivilegeXToPrivilege(privileges, ci::kWebPrivilegeType);
-  BOOST_SCOPE_EXIT_ALL(&) {
-    g_list_free_full(web_privileges, free);
-  };
+  std::unique_ptr<GList, decltype(FreePrivilegeList)*> web_privs_deleter(
+      web_privileges, FreePrivilegeList);
 
   for (const std::pair<GList*, bool>& pair :
        std::initializer_list<std::pair<GList*, bool>>{