From: sung-su.kim Date: Wed, 30 Sep 2015 02:47:21 +0000 (+0900) Subject: Add resource decryption X-Git-Tag: accepted/tizen/mobile/20151005.055326~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3e5018079b1a4589df004ca337eef83dcce02ec7;p=platform%2Fframework%2Fweb%2Fcrosswalk-tizen.git Add resource decryption - If `` 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. --- diff --git a/common/common.gyp b/common/common.gyp index c39de75..9c886cb 100644 --- a/common/common.gyp +++ b/common/common.gyp @@ -45,12 +45,15 @@ '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': { diff --git a/common/resource_manager.cc b/common/resource_manager.cc old mode 100755 new mode 100644 index fce50ce..3de778f --- a/common/resource_manager.cc +++ b/common/resource_manager.cc @@ -16,21 +16,27 @@ #include "common/resource_manager.h" -#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include #include -#include -#include -#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 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 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(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 diff --git a/common/resource_manager.h b/common/resource_manager.h old mode 100755 new mode 100644 index 19d0af0..da030f9 --- a/common/resource_manager.h +++ b/common/resource_manager.h @@ -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: diff --git a/common/string_utils.cc b/common/string_utils.cc index ee115d3..5036524 100644 --- a/common/string_utils.cc +++ b/common/string_utils.cc @@ -16,18 +16,18 @@ #include "common/string_utils.h" -#include -#include -#include #include +#include +#include +#include +#include -#include -#include -#include -#include #include +#include #include - +#include +#include +#include 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 encoded_ptr {encoded, g_free}; + return std::string(encoded); +} + } // namespace utils } // namespace common diff --git a/common/string_utils.h b/common/string_utils.h index 1532b27..0d76cb7 100644 --- a/common/string_utils.h +++ b/common/string_utils.h @@ -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 diff --git a/packaging/crosswalk-tizen.spec b/packaging/crosswalk-tizen.spec index 67f6fda..291049f 100644 --- a/packaging/crosswalk-tizen.spec +++ b/packaging/crosswalk-tizen.spec @@ -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 diff --git a/runtime/renderer/injected_bundle.cc b/runtime/renderer/injected_bundle.cc old mode 100755 new mode 100644 index cad7811..c628d05 --- a/runtime/renderer/injected_bundle.cc +++ b/runtime/renderer/injected_bundle.cc @@ -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*/) {