Add resource decryption
authorsung-su.kim <sung-su.kim@samsung.com>
Wed, 30 Sep 2015 02:47:21 +0000 (11:47 +0900)
committersung-su.kim <sung-su.kim@samsung.com>
Thu, 1 Oct 2015 11:05:10 +0000 (20:05 +0900)
- If `<tizen:setting encryption="enable">` case,
  the app-installers should be encrypted and saved the resource.
  (.html, .htm, .js, .css extensions files)
- When the web-engine requests the encrypted resource,
  web-runtime should be return the decrypted resource
  to the web-engine through the data scheme.

common/common.gyp
common/resource_manager.cc [changed mode: 0755->0644]
common/resource_manager.h [changed mode: 0755->0644]
common/string_utils.cc
common/string_utils.h
packaging/crosswalk-tizen.spec
runtime/renderer/injected_bundle.cc [changed mode: 0755->0644]

index c39de75..9c886cb 100644 (file)
           'uuid',
           'aul',
           'appsvc',
+          'pkgmgr-info',
           'manifest-parser',
           'manifest-handlers',
           'capi-appfw-package-manager',
           'capi-appfw-application',
           'capi-system-system-settings',
-          'libcurl'
+          'libcurl',
+          'libwebappenc',
+          'glib-2.0',
         ],
       },
       'direct_dependent_settings': {
old mode 100755 (executable)
new mode 100644 (file)
index fce50ce..3de778f
 
 #include "common/resource_manager.h"
 
-#include <stdio.h>
+#include <sys/types.h>
 #include <aul.h>
+#include <pkgmgr-info.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <web_app_enc.h>
 
+#include <algorithm>
+#include <functional>
 #include <memory>
+#include <set>
+#include <sstream>
 #include <vector>
-#include <functional>
-#include <algorithm>
 
-#include "common/logger.h"
+#include "common/application_data.h"
+#include "common/app_control.h"
 #include "common/file_utils.h"
+#include "common/locale_manager.h"
+#include "common/logger.h"
 #include "common/string_utils.h"
 #include "common/url.h"
-#include "common/app_control.h"
-#include "common/application_data.h"
-#include "common/locale_manager.h"
 
 using wgt::parse::AppControlInfo;
 
@@ -52,16 +58,19 @@ const int kSchemeIdLen = 3;
 
 // Default Start Files
 const char* kDefaultStartFiles[] = {
-  "index.htm",
-  "index.html",
-  "index.svg",
-  "index.xhtml",
-  "index.xht"
-};
+    "index.htm",
+    "index.html",
+    "index.svg",
+    "index.xhtml",
+    "index.xht"};
 
 // Default Encoding
 const char* kDefaultEncoding = "UTF-8";
 
+// EncryptedFileExtensions
+const std::set<std::string> kEncryptedFileExtensions{
+    ".html", ".htm", ".css", ".js"};
+
 static std::string GetMimeFromUri(const std::string& uri) {
   // checking passed uri is local file
   std::string file_uri_case(kSchemeTypeFile);
@@ -541,4 +550,133 @@ bool ResourceManager::CheckAllowNavigation(const std::string& url) {
   return result = false;
 }
 
+bool ResourceManager::IsEncrypted(const std::string& path) {
+  auto setting = application_data_->setting_info();
+  if (setting.get() == NULL)
+    return false;
+
+  if (setting->encryption_enabled()) {
+    std::string ext = utils::ExtName(path);
+    if (kEncryptedFileExtensions.count(ext) > 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+std::string ResourceManager::DecryptResource(const std::string& path) {
+  // read file and make a buffer
+  std::string src_path(path);
+  if (utils::StartsWith(src_path, kSchemeTypeFile)) {
+    src_path.erase(0, strlen(kSchemeTypeFile));
+  }
+
+  FILE *src = fopen(src_path.c_str(), "rb");
+  if (!src) {
+    LOGGER(ERROR) << "Cannot open file for decryption: " << src_path;
+    return path;
+  }
+
+  // Read filesize
+  fseek(src, 0, SEEK_END);
+  size_t src_len = ftell(src);
+  rewind(src);
+
+  // Read buffer from the source file
+  std::unique_ptr<char> src_buf(new char[src_len]);
+  if (src_len != fread(src_buf.get(), sizeof(char), src_len, src)) {
+    LOGGER(ERROR) << "Read error, file: " << src_path;
+    fclose(src);
+    return path;
+  }
+  fclose(src);
+
+  // checking web app type
+  static bool inited = false;
+  static bool is_global = false;
+  static bool is_preload = false;
+
+  int ret;
+  std::string pkg_id = application_data_->pkg_id();
+  if (!inited) {
+    inited = true;
+    pkgmgrinfo_pkginfo_h handle;
+    ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(), &handle);
+    if (ret != PMINFO_R_OK) {
+      LOGGER(ERROR) << "Could not get handle for pkginfo : pkg_id = "
+                    << pkg_id;
+      return path;
+    } else {
+      ret = pkgmgrinfo_pkginfo_is_global(handle, &is_global);
+      if (ret != PMINFO_R_OK) {
+        LOGGER(ERROR) << "Could not check is_global : pkg_id = "
+                      << pkg_id;
+        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+        return path;
+      }
+      ret = pkgmgrinfo_pkginfo_is_preload(handle, &is_preload);
+      if (ret != PMINFO_R_OK) {
+        LOGGER(ERROR) << "Could not check is_preload : pkg_id = "
+                      << pkg_id;
+        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+        return path;
+      }
+      pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+    }
+  }
+
+  wae_app_type_e app_type = WAE_DOWNLOADED_NORMAL_APP;
+  if (is_global) {
+    app_type = WAE_DOWNLOADED_GLOBAL_APP;
+  } else if (is_preload) {
+    app_type = WAE_PRELOADED_APP;
+  }
+
+  // decrypt buffer with wae functions
+  uint8_t* dst_buf = nullptr;
+  size_t dst_len = 0;
+  ret = wae_decrypt_web_application(pkg_id.c_str(),
+                                    app_type,
+                                    reinterpret_cast<uint8_t*>(src_buf.get()),
+                                    src_len,
+                                    &dst_buf,
+                                    &dst_len);
+  if (WAE_ERROR_NONE != ret) {
+    switch (ret) {
+    case WAE_ERROR_INVALID_PARAMETER:
+      LOGGER(ERROR) << "Error during decryption: WAE_ERROR_INVALID_PARAMETER";
+      break;
+    case WAE_ERROR_PERMISSION_DENIED:
+      LOGGER(ERROR) << "Error during decryption: WAE_ERROR_PERMISSION_DENIED";
+      break;
+    case WAE_ERROR_NO_KEY:
+      LOGGER(ERROR) << "Error during decryption: WAE_ERROR_NO_KEY";
+      break;
+    case WAE_ERROR_KEY_MANAGER:
+      LOGGER(ERROR) << "Error during decryption: WAE_ERROR_KEY_MANAGER";
+      break;
+    case WAE_ERROR_CRYPTO:
+      LOGGER(ERROR) << "Error during decryption: WAE_ERROR_CRYPTO";
+      break;
+    case WAE_ERROR_UNKNOWN:
+      LOGGER(ERROR) << "Error during decryption: WAE_ERROR_UNKNOWN";
+      break;
+    default:
+      LOGGER(ERROR) << "Error during decryption: UNKNOWN";
+      break;
+    }
+    return path;
+  }
+
+  // change to data schem
+  std::stringstream dst_str;
+  std::string content_type = GetMimeFromUri(path);
+  std::string encoded = utils::Base64Encode(dst_buf, dst_len);
+  dst_str << "data:" << content_type << ";base64," << encoded;
+
+  std::free(dst_buf);
+
+  return dst_str.str();
+}
+
 }  // namespace common
old mode 100755 (executable)
new mode 100644 (file)
index 19d0af0..da030f9
@@ -75,6 +75,9 @@ class ResourceManager {
   bool AllowNavigation(const std::string& url);
   bool AllowedResource(const std::string& url);
 
+  bool IsEncrypted(const std::string& url);
+  std::string DecryptResource(const std::string& path);
+
   void set_base_resource_path(const std::string& base_path);
 
  private:
index ee115d3..5036524 100644 (file)
 
 #include "common/string_utils.h"
 
-#include <time.h>
-#include <math.h>
-#include <uuid/uuid.h>
 #include <curl/curl.h>
+#include <uuid/uuid.h>
+#include <glib.h>
+#include <math.h>
+#include <time.h>
 
-#include <string>
-#include <vector>
-#include <sstream>
-#include <iomanip>
 #include <algorithm>
+#include <iomanip>
 #include <memory>
-
+#include <sstream>
+#include <string>
+#include <vector>
 
 namespace common {
 namespace utils {
@@ -111,5 +111,11 @@ std::string UrlEncode(const std::string& url) {
   return encoded_str.get() != nullptr ? std::string(encoded_str.get()) : url;
 }
 
+std::string Base64Encode(const unsigned char* data, size_t len) {
+  gchar* encoded = g_base64_encode(data, len);
+  std::unique_ptr<gchar, decltype(g_free)*> encoded_ptr {encoded, g_free};
+  return std::string(encoded);
+}
+
 }  // namespace utils
 }  // namespace common
index 1532b27..0d76cb7 100644 (file)
@@ -31,9 +31,9 @@ std::string ReplaceAll(const std::string& replace,
 std::string GetCurrentMilliSeconds();
 bool SplitString(const std::string &str,
                  std::string *part_1, std::string *part_2, const char delim);
-
 std::string UrlEncode(const std::string& url);
 std::string UrlDecode(const std::string& url);
+std::string Base64Encode(const unsigned char* data, size_t len);
 
 }  // namespace utils
 }  // namespace common
index 67f6fda..291049f 100644 (file)
@@ -34,6 +34,7 @@ BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(capi-appfw-application)
 BuildRequires: pkgconfig(manifest-parser)
 BuildRequires: pkgconfig(manifest-handlers)
+BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: pkgconfig(capi-appfw-package-manager)
 BuildRequires: pkgconfig(efl-extension)
 BuildRequires: pkgconfig(deviced)
@@ -47,6 +48,8 @@ BuildRequires: pkgconfig(sqlite3)
 BuildRequires: pkgconfig(ecore-wayland)
 BuildRequires: pkgconfig(chromium-efl)
 BuildRequires: pkgconfig(libcurl)
+BuildRequires: pkgconfig(libwebappenc)
+BuildRequires: pkgconfig(glib-2.0)
 
 %description
 Crosswalk Runtime and AppShell for Tizen 3.0 and later
old mode 100755 (executable)
new mode 100644 (file)
index cad7811..c628d05
@@ -140,11 +140,17 @@ extern "C" void DynamicUrlParsing(
     *new_url = "about:blank";
     return;
   }
+  // convert to localized path
   if (common::utils::StartsWith(*old_url, "file:/") ||
-      common::utils::StartsWith(*old_url, "app:/"))
+      common::utils::StartsWith(*old_url, "app:/")) {
     *new_url = res_manager->GetLocalizedPath(*old_url);
-  else
+  } else {
     *new_url = *old_url;
+  }
+  // check encryption
+  if (res_manager->IsEncrypted(*new_url)) {
+    *new_url = res_manager->DecryptResource(*new_url);
+  }
 }
 
 extern "C" void DynamicDatabaseAttach(int /*attach*/) {