From a025df2ca4ae9a4e13b5b803674da4dd1bd133e9 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 3 Aug 2016 13:17:17 +0900 Subject: [PATCH 01/16] Set uid/gid to wae initializer service Change-Id: I15ee0cb42c05cf19d875b4b9acf96e78939a240f Signed-off-by: Kyungwook Tak --- systemd/webappenc-initializer.service.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/systemd/webappenc-initializer.service.in b/systemd/webappenc-initializer.service.in index 976a877..768552e 100644 --- a/systemd/webappenc-initializer.service.in +++ b/systemd/webappenc-initializer.service.in @@ -5,6 +5,8 @@ Requires=central-key-manager.service After=central-key-manager.service [Service] +User=security_fw +Group=security_fw Type=oneshot ExecStart=/usr/bin/wae_initializer SmackProcessLabel=System -- 2.7.4 From cc76acebe224f4b8a273752b2400190ab0aab679 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 27 Jul 2016 16:54:50 +0900 Subject: [PATCH 02/16] [API changed] Add uid parameter Installer will be run as system (from user) so we cannot retrieve user id from client credential(by key-manager). Change-Id: I1e091bfc0b88fce418cd209a7a1adab021b6c0d2 Signed-off-by: Kyungwook Tak --- CMakeLists.txt | 1 - include/web_app_enc.h | 109 +++++++++++++++++---- packaging/libwebappenc-test.manifest.in | 2 +- packaging/libwebappenc.spec | 4 +- srcs/key_handler.c | 165 ++++++++++++++++++++++---------- srcs/key_handler.h | 14 +-- srcs/key_manager.c | 50 ++++------ srcs/key_manager.h | 8 +- srcs/types.h | 9 ++ srcs/web_app_enc.c | 70 ++++++++++---- tests/internals.cpp | 12 +-- tests/non-normals.cpp | 3 +- tests/normals.cpp | 3 +- tests/test-helper.cpp | 77 +++++++++++---- tests/test-helper.h | 2 +- 15 files changed, 362 insertions(+), 167 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84dd0d5..436eb74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,6 @@ ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"") ADD_DEFINITIONS("-DSMACK_ENABLED") ADD_DEFINITIONS("-DSQLCIPHER_HAS_CODEC") ADD_DEFINITIONS("-DBINDIR=\"${BINDIR}\"") -ADD_DEFINITIONS("-DINSTALLER_LABEL=\"${INSTALLER_LABEL}\"") # IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") ADD_DEFINITIONS("-DTIZEN_DEBUG_ENABLE") diff --git a/include/web_app_enc.h b/include/web_app_enc.h index c876792..47cbe78 100644 --- a/include/web_app_enc.h +++ b/include/web_app_enc.h @@ -14,7 +14,7 @@ * limitations under the License * * @file web_app_enc.h - * @version 1.0 + * @version 2.0 * @brief APIs of WEB_APP_ENC module. */ #ifndef __WEB_APP_ENC__ @@ -25,6 +25,8 @@ extern "C" { #endif #include +#include +#include /** * @addtogroup CAPI_WEB_APP_ENC_MODULE @@ -49,24 +51,40 @@ typedef enum { } wae_error_e; /** - * @brief Application Type. + * @brief Encrypts web application data + * * @since_tizen 3.0 + * @param[in] uid User id of the application being encrypted + * @param[in] pkg_id The package id of an application + * @param[in] data The data block to be encrypted + * @param[in] data_len The length of @a data + * @param[out] pencrypted_data The encrypted data block which must be freed by free() + * @param[out] pencrypted_data_len The length of data pointed by @a pencrypted_data + * + * @return #WAE_ERROR_NONE on success, otherwise a negative error value + * @retval #WAE_ERROR_INVALID_PARAMETER Invalid input parameter + * @retval #WAE_ERROR_PERMISSION_DENIED Non-authenticated application request + * @retval #WAE_ERROR_NO_KEY No internal key + * @retval #WAE_ERROR_KEY_MANAGER key-manager internal error + * @retval #WAE_ERROR_CRYPTO failed in crypto operation + * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason + * + * @see wae_decrypt_web_application() + * @see wae_remove_app_dek() */ -typedef enum { - WAE_DOWNLOADED_NORMAL_APP = 0, /**< Downloaded Normal Application*/ - WAE_DOWNLOADED_GLOBAL_APP = 1, /**< Downloaded Global Application*/ - WAE_PRELOADED_APP = 2 /**< Preloaded Application*/ -} wae_app_type_e; +int wae_encrypt_web_application(uid_t uid, const char *pkg_id, + const unsigned char *data, size_t data_len, + unsigned char **pencrypted_data, size_t *pencrypted_data_len); /** - * @brief Encrypts web application data with internal key(APP DEK: Application Data Encryption Key). + * @brief Encrypts global web application data * * @since_tizen 3.0 * @param[in] pkg_id The package id of an application - * @param[in] app_type The application type + * @param[in] is_preloaded Whether the package is preloaded or not * @param[in] data The data block to be encrypted * @param[in] data_len The length of @a data - * @param[out] pencrypted_data The data block contaning encrypted data block which must be freed by free() + * @param[out] pencrypted_data The encrypted data block which must be freed by free() * @param[out] pencrypted_data_len The length of data pointed by @a pencrypted_data * * @return #WAE_ERROR_NONE on success, otherwise a negative error value @@ -77,21 +95,22 @@ typedef enum { * @retval #WAE_ERROR_CRYPTO failed in crypto operation * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason * - * @see wae_decrypt_web_application() + * @see wae_decrypt_global_web_application() + * @see wae_remove_global_app_dek() */ -int wae_encrypt_web_application(const char *pkg_id, wae_app_type_e app_type, - const unsigned char *data, size_t data_len, - unsigned char **pencrypted_data, size_t *pencrypted_data_len); +int wae_encrypt_global_web_application(const char *pkg_id, bool is_preloaded, + const unsigned char *data, size_t data_len, + unsigned char **pencrypted_data, size_t *pencrypted_data_len); /** - * @brief Encrypts web application data with internal key. + * @brief Decrypts web application data. * * @since_tizen 3.0 + * @param[in] uid User id of the application being decrypted * @param[in] pkg_id The package id of an application - * @param[in] app_type The application type * @param[in] data The data block to be decrypted * @param[in] data_len The length of @a data - * @param[out] pdecrypted_data Data block contaning decrypted data block which must be freed by free() + * @param[out] pdecrypted_data The decrypted data block which must be freed by free() * @param[out] pdecrypted_data_len The length of data pointed by @a pdecrypted_data * * @return #WAE_ERROR_NONE on success, otherwise a negative error value @@ -103,17 +122,44 @@ int wae_encrypt_web_application(const char *pkg_id, wae_app_type_e app_type, * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason * * @see wae_encrypt_web_application() + * @see wae_remove_app_dek() */ -int wae_decrypt_web_application(const char *pkg_id, wae_app_type_e app_type, +int wae_decrypt_web_application(uid_t uid, const char *pkg_id, const unsigned char *data, size_t data_len, unsigned char **pdecrypted_data, size_t *pdecrypted_data_len); /** - * @brief Remove a APP DEK(Application Data Encryption Key) used for encrytpion and decryption of a web application. + * @brief Decrypts global web application data. + * + * @since_tizen 3.0 + * @param[in] pkg_id The package id of an application + * @param[in] is_preloaded Whether the package is preloaded or not + * @param[in] data The data block to be decrypted + * @param[in] data_len The length of @a data + * @param[out] pdecrypted_data The decrypted data block which must be freed by free() + * @param[out] pdecrypted_data_len The length of data pointed by @a pdecrypted_data + * + * @return #WAE_ERROR_NONE on success, otherwise a negative error value + * @retval #WAE_ERROR_INVALID_PARAMETER Invalid input parameter + * @retval #WAE_ERROR_PERMISSION_DENIED Non-authenticated application request + * @retval #WAE_ERROR_NO_KEY No internal key + * @retval #WAE_ERROR_KEY_MANAGER key-manager internal error + * @retval #WAE_ERROR_CRYPTO failed in crypto operation + * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason + * + * @see wae_encrypt_global_web_application() + * @see wae_remove_global_app_dek() + */ +int wae_decrypt_global_web_application(const char *pkg_id, bool is_preloaded, + const unsigned char *data, size_t data_len, + unsigned char **pdecrypted_data, size_t *pdecrypted_data_len); + +/** + * @brief Remove key used for encryption the web application. * * @since_tizen 3.0 + * @param[in] uid User id of the application being uninstalled * @param[in] pkg_id The package id of an application - * @param[in] app_type The application type * * @return #WAE_ERROR_NONE on success, otherwise a negative error value * @retval #WAE_ERROR_INVALID_PARAMETER Invalid input parameter @@ -122,8 +168,29 @@ int wae_decrypt_web_application(const char *pkg_id, wae_app_type_e app_type, * @retval #WAE_ERROR_KEY_MANAGER key-manager internal error * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason * + * @see wae_encrypt_web_application() + * @see wae_decrypt_web_application() + */ +int wae_remove_app_dek(uid_t uid, const char *pkg_id); + +/** + * @brief Remove key used for encryption the global web application. + * + * @since_tizen 3.0 + * @param[in] pkg_id The package id of an application + * @param[in] is_preloaded Whether the package is preloaded or not + * + * @return #WAE_ERROR_NONE on success, otherwise a negative error value + * @retval #WAE_ERROR_INVALID_PARAMETER Invalid input parameter + * @retval #WAE_ERROR_PERMISSION_DENIED Non-authenticated application request + * @retval #WAE_ERROR_NO_KEY No internal key + * @retval #WAE_ERROR_KEY_MANAGER key-manager internal error + * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason + * + * @see wae_encrypt_global_web_application() + * @see wae_decrypt_global_web_application() */ -int wae_remove_app_dek(const char *pkg_id, wae_app_type_e app_type); +int wae_remove_global_app_dek(const char *pkg_id, bool is_preloaded); /** * @} diff --git a/packaging/libwebappenc-test.manifest.in b/packaging/libwebappenc-test.manifest.in index 13d4d92..0e22627 100644 --- a/packaging/libwebappenc-test.manifest.in +++ b/packaging/libwebappenc-test.manifest.in @@ -3,6 +3,6 @@ - + diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index ed5434a..7d796f9 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -37,7 +37,6 @@ Requires: %{name} = %{version}-%{release} %description test Web application encryption and decryption service (test) -%define installer_label "User" %define bin_dir %TZ_SYS_BIN %define rw_share_dir %TZ_SYS_SHARE @@ -53,8 +52,7 @@ Web application encryption and decryption service (test) -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DCMAKE_BUILD_TYPE=%{build_type} \ -DRW_SHARE_DIR=%rw_share_dir \ - -DBINDIR=%bin_dir \ - -DINSTALLER_LABEL=%installer_label + -DBINDIR=%bin_dir make %{?jobs:-j%jobs} diff --git a/srcs/key_handler.c b/srcs/key_handler.c index af7280b..cf3de1d 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -29,6 +29,7 @@ #include +#include "web_app_enc.h" #include "wae_log.h" #include "crypto_service.h" #include "key_manager.h" @@ -56,19 +57,28 @@ static void deinit_lib(void) crypto_element_map_destroy(_map); } -static const crypto_element_s *_get_app_ce_from_cache(const char *pkg_id) +char *_create_map_key(uid_t uid, const char *pkg_id) { - return crypto_element_map_get(_map, pkg_id); + char *key = NULL; + + int ret = asprintf(&key, "%u-%s", uid, pkg_id); + + return (ret == -1) ? NULL : key; } -static int _add_app_ce_to_cache(const char *pkg_id, crypto_element_s *ce) +static const crypto_element_s *_get_app_ce_from_cache(const char *key) { - return crypto_element_map_add(&_map, pkg_id, ce); + return crypto_element_map_get(_map, key); } -void _remove_app_ce_from_cache(const char *pkg_id) +static int _add_app_ce_to_cache(const char *key, crypto_element_s *ce) { - crypto_element_map_remove(&_map, pkg_id); + return crypto_element_map_add(&_map, key, ce); +} + +void _remove_app_ce_from_cache(const char *key) +{ + crypto_element_map_remove(&_map, key); } int _get_random(raw_buffer_s *rb) @@ -110,13 +120,13 @@ static const char *_get_dek_store_path() static int _write_to_file(const char *path, const raw_buffer_s *data) { - if (path == NULL || data == NULL || data->buf == NULL || data->size == 0) + if (path == NULL || !is_buffer_valid(data)) return WAE_ERROR_INVALID_PARAMETER; FILE *f = fopen(path, "w"); if (f == NULL) { - WAE_SLOGE("WAE: Fail to open a file. file=%s", path); + WAE_SLOGE("Failed to open a file(%s)", path); return WAE_ERROR_FILE; } @@ -125,7 +135,7 @@ static int _write_to_file(const char *path, const raw_buffer_s *data) fclose(f); if (write_len != (int)data->size) { - WAE_SLOGE("WAE: Fail to write a file. file=%s", path); + WAE_SLOGE("Failed to write a file(%s)", path); return WAE_ERROR_FILE; } @@ -226,110 +236,145 @@ int _write_encrypted_app_dek_to_file(const char *pkg_id, const raw_buffer_s *enc return _write_to_file(path, encrypted); } -int get_app_ce(const char *pkg_id, wae_app_type_e app_type, bool create_for_migrated_app, - const crypto_element_s **pce) +int get_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type, + bool create_for_migrated_app, const crypto_element_s **pce) { if (pkg_id == NULL || pce == NULL) return WAE_ERROR_INVALID_PARAMETER; - const crypto_element_s *cached_ce = _get_app_ce_from_cache(pkg_id); + if (uid == 0 && app_type == WAE_DOWNLOADED_NORMAL_APP) + return WAE_ERROR_INVALID_PARAMETER; + + const char *key = NULL; + char *_key_per_user = NULL; + + if (app_type == WAE_DOWNLOADED_NORMAL_APP) { + _key_per_user = _create_map_key(uid, pkg_id); + if (_key_per_user == NULL) + return WAE_ERROR_MEMORY; + + key = _key_per_user; + } else { + key = pkg_id; + } + + int ret = WAE_ERROR_NONE; + const crypto_element_s *cached_ce = _get_app_ce_from_cache(key); if (cached_ce != NULL) { - WAE_SLOGD("cache hit of app ce for pkg_id(%s)", pkg_id); + WAE_SLOGD("cache hit of app ce for key(%s)", key); *pce = cached_ce; - return WAE_ERROR_NONE; + goto finish; } - WAE_SLOGD("cache miss of app ce for pkg_id(%s)", pkg_id); + WAE_SLOGD("cache miss of app ce for key(%s)", key); crypto_element_s *ce = NULL; - int ret = get_from_key_manager(pkg_id, app_type, &ce); + ret = get_from_key_manager(key, app_type, &ce); if (create_for_migrated_app && (ret == WAE_ERROR_NO_KEY && app_type == WAE_DOWNLOADED_GLOBAL_APP)) { - WAE_SLOGI("No dek found for pkg_id(%s)! It should be migrated app.", pkg_id); + WAE_SLOGI("No dek found for key(%s)! It should be migrated app.", key); - if ((ret = get_old_ss_crypto_element(pkg_id, &ce)) != WAE_ERROR_NONE) - goto error; + if ((ret = get_old_ss_crypto_element(key, &ce)) != WAE_ERROR_NONE) + goto finish; // (k.tak) disable to save ce to key-maanger for migrated app because of permission issue. - //ret = save_to_key_manager(pkg_id, app_type, ce); + //ret = save_to_key_manager(key, pkg_id, app_type, ce); //if (ret != WAE_ERROR_NONE) { // WAE_SLOGW("Failed to save migrated app ce to key-manager with ret(%d). " // "Ignore this error because we can create ce later again.", ret); // ret = WAE_ERROR_NONE; //} } else if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to get crypto element from key-manager. pkg_id=%s, ret=%d", - pkg_id, ret); - goto error; + WAE_SLOGE("Failed to get crypto element from key-manager. key(%s) ret(%d)", + key, ret); + goto finish; } - ret = _add_app_ce_to_cache(pkg_id, ce); + ret = _add_app_ce_to_cache(key, ce); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to add ce to cache for pkg_id(%s) ret(%d)", pkg_id, ret); - goto error; + WAE_SLOGE("Failed to add ce to cache for key(%s) ret(%d)", key, ret); + goto finish; } *pce = ce; - WAE_SLOGD("Successfully get ce! pkgid(%s)", pkg_id); + WAE_SLOGD("Successfully get ce! key(%s)", key); - return WAE_ERROR_NONE; +finish: + free(_key_per_user); -error: - crypto_element_destroy(ce); + if (ret != WAE_ERROR_NONE) + crypto_element_destroy(ce); return ret; } -int create_app_ce(const char *pkg_id, wae_app_type_e app_type, const crypto_element_s **pce) +int create_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type, + const crypto_element_s **pce) { raw_buffer_s *dek = buffer_create(DEK_LEN); raw_buffer_s *iv = buffer_create(IV_LEN); crypto_element_s *ce = crypto_element_create(dek, iv); int ret = WAE_ERROR_NONE; + const char *key = NULL; + char *_key_per_user = NULL; if (ce == NULL) { ret = WAE_ERROR_MEMORY; goto error; } + if (app_type == WAE_DOWNLOADED_NORMAL_APP) { + _key_per_user = _create_map_key(uid, pkg_id); + if (_key_per_user == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } + + key = _key_per_user; + } else { + key = pkg_id; + } + memcpy(ce->iv->buf, AES_CBC_IV, ce->iv->size); ret = _get_random(dek); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to get random for dek. pkg_id(%s) ret(%d)", pkg_id, ret); + WAE_SLOGE("Failed to get random for dek. key(%s) ret(%d)", key, ret); goto error; } - ret = save_to_key_manager(pkg_id, app_type, ce); + ret = save_to_key_manager(key, pkg_id, app_type, ce); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to save ce to key-manager. pkg_id(%s) app_type(%d) ret(%d)", - pkg_id, app_type, ret); + WAE_SLOGE("Failed to save ce to key-manager. key(%s) app_type(%d) ret(%d)", + key, app_type, ret); goto error; } - ret = _add_app_ce_to_cache(pkg_id, ce); + ret = _add_app_ce_to_cache(key, ce); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to add ce to cache for pkg_id(%s) ret(%d)", pkg_id, ret); + WAE_SLOGE("Failed to add ce to cache for key(%s) ret(%d)", key, ret); goto error; } *pce = ce; - WAE_SLOGI("Success to create dek/iv and store it in key-manager. pkg_id(%s)", pkg_id); - - return WAE_ERROR_NONE; + WAE_SLOGI("Success to create dek/iv and store it in key-manager. key(%s)", key); error: - if (ce == NULL) { - buffer_destroy(dek); - buffer_destroy(iv); - } else { - crypto_element_destroy(ce); + if (ret != WAE_ERROR_NONE) { + if (ce == NULL) { + buffer_destroy(dek); + buffer_destroy(iv); + } else { + crypto_element_destroy(ce); + } } + free(_key_per_user); + return ret; } @@ -542,7 +587,7 @@ int load_preloaded_app_deks(bool reload) continue; } - ret = save_to_key_manager(pkg_id, WAE_PRELOADED_APP, ce); + ret = save_to_key_manager(pkg_id, pkg_id, WAE_PRELOADED_APP, ce); if (ret == WAE_ERROR_KEY_EXISTS) { WAE_SLOGI("Key Manager already has dek. It will be ignored. file=%s", @@ -574,16 +619,34 @@ error: return ret; } -int remove_app_ce(const char *pkg_id, wae_app_type_e app_type) +int remove_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type) { - int ret = remove_from_key_manager(pkg_id, app_type); + if (uid == 0 && app_type == WAE_DOWNLOADED_NORMAL_APP) + return WAE_ERROR_INVALID_PARAMETER; + + const char *key = NULL; + char *_key_per_user = NULL; + + if (app_type == WAE_DOWNLOADED_NORMAL_APP) { + _key_per_user = _create_map_key(uid, pkg_id); + if (_key_per_user == NULL) + return WAE_ERROR_MEMORY; + + key = _key_per_user; + } else { + key = pkg_id; + } + + int ret = remove_from_key_manager(key, app_type); if (ret != WAE_ERROR_NONE) - WAE_SLOGE("Failed to remove app ce for pkg_id(%s) ret(%d)", pkg_id, ret); + WAE_SLOGE("Failed to remove app ce for key(%s) ret(%d)", key, ret); else - WAE_SLOGI("Success to remove app ce for pkg_id(%s)", pkg_id); + WAE_SLOGI("Success to remove app ce for key(%s)", key); + + _remove_app_ce_from_cache(key); - _remove_app_ce_from_cache(pkg_id); + free(_key_per_user); return ret; } diff --git a/srcs/key_handler.h b/srcs/key_handler.h index e64d81c..791e149 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -28,28 +28,30 @@ extern "C" { #include #include +#include -#include "web_app_enc.h" #include "types.h" #define MAX_PATH_LEN 512 /* functions with "_" prefix are internal static functions but declared here for testing */ -void _remove_app_ce_from_cache(const char *pkg_id); +char *_create_map_key(uid_t uid, const char *pkg_id); +void _remove_app_ce_from_cache(const char *key); int _get_random(raw_buffer_s *rb); int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path); int _read_encrypted_app_dek_from_file(const char *pkg_id, raw_buffer_s **pencrypted); int _write_encrypted_app_dek_to_file(const char *pkg_id, const raw_buffer_s *encrypted); /* functions for interface */ -int get_app_ce(const char *pkg_id, wae_app_type_e app_type, bool create_for_migrated_app, - const crypto_element_s **pce); -int create_app_ce(const char *pkg_id, wae_app_type_e app_type, +int get_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type, + bool create_for_migrated_app, const crypto_element_s **pce); +int create_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type, const crypto_element_s **pce); +int remove_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type); + int get_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce); int create_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce); int load_preloaded_app_deks(bool reload); -int remove_app_ce(const char *pkg_id, wae_app_type_e app_type); #ifdef __cplusplus } diff --git a/srcs/key_manager.c b/srcs/key_manager.c index 4ef5b8a..aeee748 100644 --- a/srcs/key_manager.c +++ b/srcs/key_manager.c @@ -27,6 +27,7 @@ #include +#include "web_app_enc.h" #include "wae_log.h" #define MAX_ALIAS_LEN 256 @@ -192,28 +193,14 @@ error: return ret; } -static void _get_alias(const char *pkg_id, wae_app_type_e type, bool forSave, +static void _get_alias(const char *name, UNUSED wae_app_type_e type, UNUSED bool forSave, char *alias, size_t buff_len) { - if (type == WAE_DOWNLOADED_NORMAL_APP) { - if (forSave) { - snprintf(alias, buff_len, "%s%s", - APP_DEK_ALIAS_PFX, - pkg_id); - } else { - snprintf(alias, buff_len, "%c%s%s%s%s", - '/', INSTALLER_LABEL, - ckmc_owner_id_separator, - APP_DEK_ALIAS_PFX, - pkg_id); - } - } else { // system alias - snprintf(alias, buff_len, "%s%s%s%s", - ckmc_owner_id_system, - ckmc_owner_id_separator, - APP_DEK_ALIAS_PFX, - pkg_id); - } + snprintf(alias, buff_len, "%s%s%s%s", + ckmc_owner_id_system, + ckmc_owner_id_separator, + APP_DEK_ALIAS_PFX, + name); } static void _get_dek_loading_done_alias(char *alias, size_t buff_len) @@ -276,16 +263,17 @@ int clear_app_deks_loaded_from_key_manager() return _to_wae_error(ckmc_remove_alias(alias)); } -int save_to_key_manager(const char *pkg_id, wae_app_type_e type, const crypto_element_s *ce) +int save_to_key_manager(const char *name, const char *pkg_id, wae_app_type_e type, + const crypto_element_s *ce) { char alias[MAX_ALIAS_LEN] = {0, }; - _get_alias(pkg_id, type, true, alias, sizeof(alias)); + _get_alias(name, type, true, alias, sizeof(alias)); ckmc_raw_buffer_s *buf = NULL; int ret = _serialize(ce, &buf); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to serialize crypto element of pkg_id: %s", pkg_id); + WAE_SLOGE("Failed to serialize crypto element of name(%s)", name); return ret; } @@ -298,8 +286,8 @@ int save_to_key_manager(const char *pkg_id, wae_app_type_e type, const crypto_el ckmc_buffer_free(buf); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to add crypto element to ckm: pkg_id(%s) alias(%s) ret(%d)", - pkg_id, alias, ret); + WAE_SLOGE("Failed to add crypto element to ckm: name(%s) alias(%s) ret(%d)", + name, alias, ret); return ret; } @@ -312,19 +300,19 @@ int save_to_key_manager(const char *pkg_id, wae_app_type_e type, const crypto_el return ret; } - WAE_SLOGI("Success to save crypto element to key-manager. pkg_id(%s)", pkg_id); + WAE_SLOGI("Success to save crypto element to key-manager. name(%s)", name); return WAE_ERROR_NONE; } -int get_from_key_manager(const char *pkg_id, wae_app_type_e type, crypto_element_s **pce) +int get_from_key_manager(const char *name, wae_app_type_e type, crypto_element_s **pce) { - if (pkg_id == NULL || pce == NULL) + if (name == NULL || pce == NULL) return WAE_ERROR_INVALID_PARAMETER; char alias[MAX_ALIAS_LEN] = {0, }; - _get_alias(pkg_id, type, false, alias, sizeof(alias)); + _get_alias(name, type, false, alias, sizeof(alias)); ckmc_raw_buffer_s *buf = NULL; int ret = _to_wae_error(ckmc_get_data(alias, NULL, &buf)); @@ -338,11 +326,11 @@ int get_from_key_manager(const char *pkg_id, wae_app_type_e type, crypto_element return ret; } -int remove_from_key_manager(const char *pkg_id, wae_app_type_e type) +int remove_from_key_manager(const char *name, wae_app_type_e type) { char alias[MAX_ALIAS_LEN] = {0, }; - _get_alias(pkg_id, type, true, alias, sizeof(alias)); + _get_alias(name, type, true, alias, sizeof(alias)); return _to_wae_error(ckmc_remove_alias(alias)); } diff --git a/srcs/key_manager.h b/srcs/key_manager.h index ec84561..4566b09 100644 --- a/srcs/key_manager.h +++ b/srcs/key_manager.h @@ -28,12 +28,12 @@ extern "C" { #include -#include "web_app_enc.h" #include "types.h" -int save_to_key_manager(const char *pkg_id, wae_app_type_e type, const crypto_element_s *ce); -int get_from_key_manager(const char *pkg_id, wae_app_type_e type, crypto_element_s **pce); -int remove_from_key_manager(const char *pkg_id, wae_app_type_e type); +int save_to_key_manager(const char *name, const char *pkg_id, wae_app_type_e type, + const crypto_element_s *ce); +int get_from_key_manager(const char *name, wae_app_type_e type, crypto_element_s **pce); +int remove_from_key_manager(const char *name, wae_app_type_e type); bool is_app_deks_loaded_in_key_manager(); int set_app_deks_loaded_to_key_manager(); diff --git a/srcs/types.h b/srcs/types.h index 7e27aeb..51ed9fc 100644 --- a/srcs/types.h +++ b/srcs/types.h @@ -29,6 +29,15 @@ extern "C" { #include #include +#define API __attribute__ ((visibility("default"))) +#define UNUSED __attribute__ ((unused)) + +typedef enum { + WAE_DOWNLOADED_NORMAL_APP = 0, + WAE_DOWNLOADED_GLOBAL_APP = 1, + WAE_PRELOADED_APP = 2 +} wae_app_type_e; + typedef struct _raw_buffer_s { unsigned char *buf; size_t size; diff --git a/srcs/web_app_enc.c b/srcs/web_app_enc.c index 22da420..5846105 100644 --- a/srcs/web_app_enc.c +++ b/srcs/web_app_enc.c @@ -30,7 +30,7 @@ #include "wae_log.h" int _wae_encrypt_downloaded_web_application( - const char *pkg_id, wae_app_type_e app_type, + uid_t uid, const char *pkg_id, wae_app_type_e app_type, const unsigned char *data, size_t data_len, unsigned char **pencrypted_data, size_t *pencrypted_data_len) { @@ -39,10 +39,10 @@ int _wae_encrypt_downloaded_web_application( return WAE_ERROR_INVALID_PARAMETER; const crypto_element_s *e = NULL; - int ret = get_app_ce(pkg_id, app_type, false, &e); + int ret = get_app_ce(uid, pkg_id, app_type, false, &e); if (ret == WAE_ERROR_NO_KEY) - ret = create_app_ce(pkg_id, app_type, &e); + ret = create_app_ce(uid, pkg_id, app_type, &e); if (ret != WAE_ERROR_NONE) return ret; @@ -64,7 +64,8 @@ int _wae_encrypt_downloaded_web_application( return WAE_ERROR_NONE; } -int _wae_decrypt_downloaded_web_application(const char *pkg_id, wae_app_type_e app_type, +int _wae_decrypt_downloaded_web_application( + uid_t uid, const char *pkg_id, wae_app_type_e app_type, const unsigned char *data, size_t data_len, unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) { @@ -77,7 +78,7 @@ int _wae_decrypt_downloaded_web_application(const char *pkg_id, wae_app_type_e a _data.size = data_len; const crypto_element_s *ce = NULL; - int ret = get_app_ce(pkg_id, app_type, true, &ce); + int ret = get_app_ce(uid, pkg_id, app_type, true, &ce); if (ret != WAE_ERROR_NONE) return ret; @@ -134,40 +135,69 @@ int _wae_encrypt_preloaded_web_application(const char *pkg_id, return WAE_ERROR_NONE; } -int _wae_decrypt_preloaded_web_application(const char *pkg_id, wae_app_type_e app_type, +int _wae_decrypt_preloaded_web_application(const char *pkg_id, const unsigned char *data, size_t data_len, unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) { // same with the decryption of downloaded web application - return _wae_decrypt_downloaded_web_application(pkg_id, app_type, + return _wae_decrypt_downloaded_web_application(0, pkg_id, WAE_PRELOADED_APP, data, data_len, pdecrypted_data, pdecrypted_data_len); } -int wae_encrypt_web_application(const char *pkg_id, wae_app_type_e app_type, - const unsigned char *data, size_t data_len, - unsigned char **pencrypted_data, size_t *pencrypted_data_len) +int wae_encrypt_web_application( + uid_t uid, const char *pkg_id, + const unsigned char *data, size_t data_len, + unsigned char **pencrypted_data, size_t *pencrypted_data_len) { - if (app_type == WAE_PRELOADED_APP) + return _wae_encrypt_downloaded_web_application( + uid, pkg_id, WAE_DOWNLOADED_NORMAL_APP, + data, data_len, pencrypted_data, pencrypted_data_len); +} + +int wae_encrypt_global_web_application( + const char *pkg_id, bool is_preloaded, + const unsigned char *data, size_t data_len, + unsigned char **pencrypted_data, size_t *pencrypted_data_len) +{ + if (is_preloaded) return _wae_encrypt_preloaded_web_application(pkg_id, data, data_len, pencrypted_data, pencrypted_data_len); else - return _wae_encrypt_downloaded_web_application(pkg_id, app_type, + return _wae_encrypt_downloaded_web_application( + 0, pkg_id, WAE_DOWNLOADED_GLOBAL_APP, data, data_len, pencrypted_data, pencrypted_data_len); } -int wae_decrypt_web_application(const char *pkg_id, wae_app_type_e app_type, - const unsigned char *data, size_t data_len, - unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) +int wae_decrypt_web_application( + uid_t uid, const char *pkg_id, + const unsigned char *data, size_t data_len, + unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) +{ + return _wae_decrypt_downloaded_web_application( + uid, pkg_id, WAE_DOWNLOADED_NORMAL_APP, + data, data_len, pdecrypted_data, pdecrypted_data_len); +} + +int wae_decrypt_global_web_application( + const char *pkg_id, bool is_preloaded, + const unsigned char *data, size_t data_len, + unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) { - if (app_type == WAE_PRELOADED_APP) - return _wae_decrypt_preloaded_web_application(pkg_id, app_type, + if (is_preloaded) + return _wae_decrypt_preloaded_web_application(pkg_id, data, data_len, pdecrypted_data, pdecrypted_data_len); else - return _wae_decrypt_downloaded_web_application(pkg_id, app_type, + return _wae_decrypt_downloaded_web_application( + 0, pkg_id, WAE_DOWNLOADED_GLOBAL_APP, data, data_len, pdecrypted_data, pdecrypted_data_len); } -int wae_remove_app_dek(const char *pkg_id, wae_app_type_e app_type) +int wae_remove_app_dek(uid_t uid, const char *pkg_id) +{ + return remove_app_ce(uid, pkg_id, WAE_DOWNLOADED_NORMAL_APP); +} + +int wae_remove_global_app_dek(const char *pkg_id, bool is_preloaded) { - return remove_app_ce(pkg_id, app_type); + return remove_app_ce(0, pkg_id, is_preloaded ? WAE_PRELOADED_APP : WAE_DOWNLOADED_GLOBAL_APP); } diff --git a/tests/internals.cpp b/tests/internals.cpp index b5c106d..1fa9aff 100644 --- a/tests/internals.cpp +++ b/tests/internals.cpp @@ -310,8 +310,8 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) _get_preloaded_app_dek_file_path(pkg_id2, sizeof(path2), path2); // remove old test data - remove_app_ce(pkg_id1, WAE_PRELOADED_APP); - remove_app_ce(pkg_id2, WAE_PRELOADED_APP); + remove_app_ce(0, pkg_id1, WAE_PRELOADED_APP); + remove_app_ce(0, pkg_id2, WAE_PRELOADED_APP); unlink(path1); unlink(path2); @@ -331,20 +331,20 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) "Failed to load_preloaded_app_deks. ec: " << ret); const crypto_element_s *readed1 = nullptr; - ret = get_app_ce(pkg_id1, WAE_PRELOADED_APP, false, &readed1); + ret = get_app_ce(0, pkg_id1, WAE_PRELOADED_APP, false, &readed1); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); const crypto_element_s *readed2 = nullptr; - ret = get_app_ce(pkg_id2, WAE_PRELOADED_APP, false, &readed2); + ret = get_app_ce(0, pkg_id2, WAE_PRELOADED_APP, false, &readed2); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); BOOST_REQUIRE_MESSAGE(readed1 == ce1, "cached ce and actual address is different!"); BOOST_REQUIRE_MESSAGE(readed2 == ce2, "cached ce and actual address is different!"); - ret = remove_app_ce(pkg_id1, WAE_PRELOADED_APP); + ret = remove_app_ce(0, pkg_id1, WAE_PRELOADED_APP); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret); - ret = remove_app_ce(pkg_id2, WAE_PRELOADED_APP); + ret = remove_app_ce(0, pkg_id2, WAE_PRELOADED_APP); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret); } diff --git a/tests/non-normals.cpp b/tests/non-normals.cpp index 81c0173..78c2197 100644 --- a/tests/non-normals.cpp +++ b/tests/non-normals.cpp @@ -20,10 +20,9 @@ * @version 2.0 * @brief API test for preloaded/global apps */ -#include "web_app_enc.h" - #include +#include "types.h" #include "test-helper.h" BOOST_AUTO_TEST_SUITE(SYSTEM) diff --git a/tests/normals.cpp b/tests/normals.cpp index 5d67910..fad04f1 100644 --- a/tests/normals.cpp +++ b/tests/normals.cpp @@ -20,10 +20,9 @@ * @version 2.0 * @brief test for normal downloaded app */ -#include "web_app_enc.h" - #include +#include "types.h" #include "test-helper.h" BOOST_AUTO_TEST_SUITE(USER) diff --git a/tests/test-helper.cpp b/tests/test-helper.cpp index f303b75..d0ca263 100644 --- a/tests/test-helper.cpp +++ b/tests/test-helper.cpp @@ -23,6 +23,7 @@ #include #include +#include "web_app_enc.h" #include "key_handler.h" #include "crypto_service.h" #include "types.h" @@ -32,32 +33,39 @@ namespace Wae { namespace Test { +namespace { + +const uid_t UID_OWNER = 5001; + +} // namespace anonymous void add_get_remove_ce(wae_app_type_e app_type) { const char *pkg_id = "TEST_PKG_ID"; const crypto_element_s *ce = nullptr; - int tmp = create_app_ce(pkg_id, app_type, &ce); + uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0; + + int tmp = create_app_ce(uid, pkg_id, app_type, &ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp); const crypto_element_s *stored_ce = nullptr; - tmp = get_app_ce(pkg_id, app_type, true, &stored_ce); + tmp = get_app_ce(uid, pkg_id, app_type, true, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp); BOOST_REQUIRE_MESSAGE(ce == stored_ce, "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!"); - tmp = remove_app_ce(pkg_id, app_type); + tmp = remove_app_ce(uid, pkg_id, app_type); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp); if (app_type == WAE_DOWNLOADED_GLOBAL_APP) { - tmp = get_app_ce(pkg_id, app_type, true, &stored_ce); + tmp = get_app_ce(uid, pkg_id, app_type, true, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE && stored_ce->is_migrated_app, "when getting app ce which is there isn't, it should be migrated case! " "ret("<< tmp << ") and is_migrated_app(" << stored_ce->is_migrated_app << ")"); } else { - tmp = get_app_ce(pkg_id, app_type, false, &stored_ce); + tmp = get_app_ce(uid, pkg_id, app_type, false, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY, "removed app ce is still remaining. ret(" << tmp << ")"); } @@ -65,28 +73,30 @@ void add_get_remove_ce(wae_app_type_e app_type) void create_app_ce(wae_app_type_e app_type) { + uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0; const char *pkg_id = "TEST_PKG_ID"; - remove_app_ce(pkg_id, app_type); + remove_app_ce(uid, pkg_id, app_type); const crypto_element_s *ce = nullptr; - int tmp = create_app_ce(pkg_id, app_type, &ce); + int tmp = create_app_ce(uid, pkg_id, app_type, &ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp); const crypto_element_s *stored_ce = nullptr; - tmp = get_app_ce(pkg_id, app_type, false, &stored_ce); + tmp = get_app_ce(uid, pkg_id, app_type, false, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp); BOOST_REQUIRE_MESSAGE(ce == stored_ce, "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!"); - tmp = remove_app_ce(pkg_id, app_type); + tmp = remove_app_ce(uid, pkg_id, app_type); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp); } void encrypt_decrypt_web_app(wae_app_type_e app_type) { + uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0; const char *pkg_id1 = "testpkg_for_normal"; const char *pkg_id2 = "testpkg_for_global"; const char *pkg_id3 = "testpkg_for_preloaded"; @@ -108,7 +118,10 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) } // remove old test data - wae_remove_app_dek(pkg_id, app_type); + if (app_type == WAE_DOWNLOADED_NORMAL_APP) + wae_remove_app_dek(uid, pkg_id); + else + wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP); if (app_type == WAE_PRELOADED_APP) clear_app_deks_loaded_from_key_manager(); @@ -121,30 +134,55 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) // test for downloaded web application unsigned char *_encrypted = nullptr; size_t _enc_len = 0; - int tmp = wae_encrypt_web_application(pkg_id, app_type, plaintext.data(), - plaintext.size(), &_encrypted, &_enc_len); + int tmp = 0; + if (app_type == WAE_DOWNLOADED_NORMAL_APP) + tmp = wae_encrypt_web_application(uid, pkg_id, plaintext.data(), plaintext.size(), + &_encrypted, &_enc_len); + else + tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP, + plaintext.data(), plaintext.size(), + &_encrypted, &_enc_len); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_encrypt_web_application. ec: " << tmp); free(_encrypted); // encrypt test twice - tmp = wae_encrypt_web_application(pkg_id, app_type, plaintext.data(), - plaintext.size(), &_encrypted, &_enc_len); + if (app_type == WAE_DOWNLOADED_NORMAL_APP) + tmp = wae_encrypt_web_application(uid, pkg_id, plaintext.data(), + plaintext.size(), &_encrypted, &_enc_len); + else + tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP, + plaintext.data(), plaintext.size(), + &_encrypted, &_enc_len); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_encrypt_web_application second time. ec: " << tmp); auto encrypted = bytearr_to_vec(_encrypted, _enc_len); free(_encrypted); - _remove_app_ce_from_cache(pkg_id); + if (app_type == WAE_DOWNLOADED_NORMAL_APP) { + char *key_per_user = _create_map_key(uid, pkg_id); + _remove_app_ce_from_cache(key_per_user); + free(key_per_user); + } else { + _remove_app_ce_from_cache(pkg_id); + } if (app_type == WAE_PRELOADED_APP) load_preloaded_app_deks(true); unsigned char *_decrypted = nullptr; size_t _dec_len = 0; - tmp = wae_decrypt_web_application(pkg_id, app_type, encrypted.data(), - encrypted.size(), &_decrypted, &_dec_len); + if (app_type == WAE_DOWNLOADED_NORMAL_APP) + tmp = wae_decrypt_web_application(uid, pkg_id, encrypted.data(), encrypted.size(), + &_decrypted, &_dec_len); + else + tmp = wae_decrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP, + encrypted.data(), encrypted.size(), + &_decrypted, &_dec_len); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_decrypt_web_application. ec: " << tmp); @@ -155,7 +193,10 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) "plaintext(" << bytes_to_hex(plaintext) << ") " "decrypted(" << bytes_to_hex(decrypted) << ")"); - tmp = wae_remove_app_dek(pkg_id, app_type); + if (app_type == WAE_DOWNLOADED_NORMAL_APP) + tmp = wae_remove_app_dek(uid, pkg_id); + else + tmp = wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_remove_app_dek. ec: " << tmp); } diff --git a/tests/test-helper.h b/tests/test-helper.h index c0c77f6..b4d1f42 100644 --- a/tests/test-helper.h +++ b/tests/test-helper.h @@ -20,7 +20,7 @@ */ #pragma once -#include "web_app_enc.h" +#include "types.h" namespace Wae { namespace Test { -- 2.7.4 From f327e9fca40ad1cf62ac18e052f09c65debac72b Mon Sep 17 00:00:00 2001 From: "sangwan.kwon" Date: Thu, 11 Aug 2016 15:15:12 +0900 Subject: [PATCH 03/16] [HOTFIX] Fix build break on 64bit arch [Problem] * EVP_Digest parameter type is unsigned int * size_t is differ between 32bit and 64bit [Solution] * Use unsigned int instead of size_t Change-Id: Ib398532c7148bcd9d736c7282e0b74c8042a2ede Signed-off-by: sangwan.kwon --- srcs/decrypt_migrated_wgt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srcs/decrypt_migrated_wgt.c b/srcs/decrypt_migrated_wgt.c index 1012a35..4eae90b 100644 --- a/srcs/decrypt_migrated_wgt.c +++ b/srcs/decrypt_migrated_wgt.c @@ -82,11 +82,13 @@ static int _get_old_iv(const raw_buffer_s *src, raw_buffer_s **piv) if (iv == NULL) return WAE_ERROR_MEMORY; - if (EVP_Digest(src->buf, src->size, iv->buf, &iv->size, EVP_sha1(), NULL) != 1) { + unsigned int _size; + if (EVP_Digest(src->buf, src->size, iv->buf, &_size, EVP_sha1(), NULL) != 1) { buffer_destroy(iv); return WAE_ERROR_CRYPTO; } + iv->size = _size; *piv = iv; WAE_SLOGD("get old iv of length: %d", iv->size); -- 2.7.4 From 8ccec6785ee30fb7c9e06a3421f5b460364b2968 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Tue, 6 Sep 2016 15:55:08 +0900 Subject: [PATCH 04/16] Add upgrade script Change-Id: I4d38443cf3880b50215aa36e084445cc8bbb60be Signed-off-by: Kyungwook Tak --- CMakeLists.txt | 1 + packaging/libwebappenc.manifest.in | 5 +++++ packaging/libwebappenc.spec | 23 +++++++++++++++++---- resources/CMakeLists.txt | 35 +++++++++++++++++++++++++------- scripts/CMakeLists.txt | 16 +++++++++++++++ scripts/wae-upgrade.sh.in | 30 +++++++++++++++++++++++++++ systemd/CMakeLists.txt | 24 ++++++++++++++-------- systemd/webappenc-initializer.service.in | 8 ++++---- 8 files changed, 119 insertions(+), 23 deletions(-) create mode 100644 scripts/CMakeLists.txt create mode 100755 scripts/wae-upgrade.sh.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 436eb74..96efdbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,3 +93,4 @@ ADD_SUBDIRECTORY(resources) ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(systemd) +ADD_SUBDIRECTORY(scripts) diff --git a/packaging/libwebappenc.manifest.in b/packaging/libwebappenc.manifest.in index 86dbb26..5451c22 100644 --- a/packaging/libwebappenc.manifest.in +++ b/packaging/libwebappenc.manifest.in @@ -2,4 +2,9 @@ + + + + + diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index 7d796f9..9f8faef 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -37,8 +37,14 @@ Requires: %{name} = %{version}-%{release} %description test Web application encryption and decryption service (test) -%define bin_dir %TZ_SYS_BIN -%define rw_share_dir %TZ_SYS_SHARE +%define user_name security_fw +%define group_name security_fw +%define smack_domain System +%define bin_dir %TZ_SYS_BIN +%define rw_share_dir %TZ_SYS_SHARE +%define upgrade_dir %TZ_SYS_RO_SHARE/upgrade +%define upgrade_script_dir %{upgrade_dir}/scripts +%define upgrade_data_dir %{upgrade_dir}/data %prep %setup -q @@ -52,6 +58,11 @@ Web application encryption and decryption service (test) -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DCMAKE_BUILD_TYPE=%{build_type} \ -DRW_SHARE_DIR=%rw_share_dir \ + -DUPGRADE_DATA_DIR=%upgrade_data_dir \ + -DUPGRADE_SCRIPT_DIR=%upgrade_script_dir \ + -DUSER_NAME=%user_name \ + -DGROUP_NAME=%group_name \ + -DSMACK_DOMAIN=%smack_domain \ -DBINDIR=%bin_dir make %{?jobs:-j%jobs} @@ -88,8 +99,12 @@ fi %{_unitdir}/webappenc-initializer.service %{_unitdir}/multi-user.target.wants/webappenc-initializer.service %{bin_dir}/wae_initializer -%{rw_share_dir}/wae/app_dek/WAE_APPDEK_KEK_PrivateKey.pem -%{rw_share_dir}/wae/app_dek/WAE_APPDEK_KEK_PublicKey.pem +%dir %attr(770, %user_name, %group_name) %{rw_share_dir}/wae +%dir %attr(770, %user_name, %group_name) %{rw_share_dir}/wae/app_dek +%attr(660, %user_name, %group_name) %{rw_share_dir}/wae/app_dek/* + +%attr(775,root,root) %{upgrade_script_dir}/wae-upgrade.sh +%{upgrade_data_dir}/wae/app_dek/* %files devel %{_includedir}/* diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index ae2bc8b..030553c 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -1,12 +1,33 @@ -################################################################################ -# for resource install -################################################################################ - +# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Dongsun Lee (ds73.lee@samsung.com) +# @brief Resource install cmake +# INSTALL(FILES - ${PROJECT_SOURCE_DIR}/resources/WAE_APPDEK_KEK_PublicKey.pem - ${PROJECT_SOURCE_DIR}/resources/WAE_APPDEK_KEK_PrivateKey.pem - DESTINATION ${RW_SHARE_DIR}/wae/app_dek/ + WAE_APPDEK_KEK_PublicKey.pem + WAE_APPDEK_KEK_PrivateKey.pem + DESTINATION ${RW_SHARE_DIR}/wae/app_dek PERMISSIONS OWNER_READ OWNER_WRITE ) +INSTALL(FILES + WAE_APPDEK_KEK_PublicKey.pem + WAE_APPDEK_KEK_PrivateKey.pem + DESTINATION ${UPGRADE_DATA_DIR}/wae/app_dek + PERMISSIONS OWNER_READ + OWNER_WRITE +) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt new file mode 100644 index 0000000..c73467e --- /dev/null +++ b/scripts/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIGURE_FILE(wae-upgrade.sh.in wae-upgrade.sh @ONLY) +INSTALL(FILES wae-upgrade.sh DESTINATION ${UPGRADE_SCRIPT_DIR}) diff --git a/scripts/wae-upgrade.sh.in b/scripts/wae-upgrade.sh.in new file mode 100755 index 0000000..652962b --- /dev/null +++ b/scripts/wae-upgrade.sh.in @@ -0,0 +1,30 @@ +#!/bin/bash +PATH=/bin:/usr/bin:/sbin:/usr/sbin + +# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file wae-upgrade.sh.in +# @author Kyungwook Tak (k.tak@samsung.com) +# @brief Platform upgrade support + +WAE_DIR=@RW_SHARE_DIR@/wae + +mv @UPGRADE_DATA_DIR@/wae $WAE_DIR + +chsmack -a "@SMACK_DOMAIN@" $WAE_DIR -r +chown -R @USER_NAME@:@GROUP_NAME@ $WAE_DIR +chmod 770 $WAE_DIR +chmod 770 $WAE_DIR/app_dek +chmod 660 $WAE_DIR/app_dek/* diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt index bf7bb79..99eafd5 100644 --- a/systemd/CMakeLists.txt +++ b/systemd/CMakeLists.txt @@ -1,8 +1,16 @@ -CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/systemd/webappenc-initializer.service.in - ${CMAKE_SOURCE_DIR}/systemd/webappenc-initializer.service @ONLY) - -INSTALL(FILES - ${CMAKE_SOURCE_DIR}/systemd/webappenc-initializer.service - DESTINATION - ${SYSTEMD_UNIT_DIR} -) +# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIGURE_FILE(webappenc-initializer.service.in webappenc-initializer.service @ONLY) +INSTALL(FILES webappenc-initializer.service DESTINATION ${SYSTEMD_UNIT_DIR}) diff --git a/systemd/webappenc-initializer.service.in b/systemd/webappenc-initializer.service.in index 768552e..ed0bebe 100644 --- a/systemd/webappenc-initializer.service.in +++ b/systemd/webappenc-initializer.service.in @@ -5,11 +5,11 @@ Requires=central-key-manager.service After=central-key-manager.service [Service] -User=security_fw -Group=security_fw +User=@USER_NAME@ +Group=@GROUP_NAME@ Type=oneshot -ExecStart=/usr/bin/wae_initializer -SmackProcessLabel=System +ExecStart=@BINDIR@/wae_initializer +SmackProcessLabel=@SMACK_DOMAIN@ [Install] WantedBy=multi-user.target -- 2.7.4 From 0780d62047e7d7472c65c791866e7a5fa9be7863 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Mon, 28 Nov 2016 20:25:03 +0900 Subject: [PATCH 05/16] Fix svace defects 1) Missing returned value checking. 2) variable misused (start -> end). 3) Dead code exist in preloaded app dek loading while loop. Make subroutine to simplify loop codes/resource managed. Change-Id: Ic775e336e6480dfb56539e382edf292f2101ec8b Signed-off-by: Kyungwook Tak --- srcs/key_handler.c | 147 +++++++++++++++++++++++++---------------------------- 1 file changed, 70 insertions(+), 77 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index cf3de1d..4607fdd 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -211,7 +211,7 @@ static int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) start = start + strlen(APP_DEK_FILE_PFX) + 1; char *end = strstr(file_name, ".adek"); - if (start == NULL) { + if (end == NULL) { WAE_SLOGE("WAE: Fail to extract pkgid from APP_DEK file. file_name=%s", file_name); return WAE_ERROR_FILE; } @@ -236,6 +236,60 @@ int _write_encrypted_app_dek_to_file(const char *pkg_id, const raw_buffer_s *enc return _write_to_file(path, encrypted); } +int _load_preloaded_app_dek( + const raw_buffer_s *prikey, const char *filepath, const char *pkg_id) +{ + raw_buffer_s *encrypted_dek = NULL; + raw_buffer_s *dek = NULL; + raw_buffer_s *iv = NULL; + crypto_element_s *ce = NULL; + + int ret = _read_from_file(filepath, &encrypted_dek); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGW("Failed to read file. It will be ignored. file=%s", filepath); + return ret; + } + + ret = decrypt_app_dek(prikey, APP_DEK_KEK_PRIKEY_PASSWORD, encrypted_dek, &dek); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGW("Failed to decrypt dek. It will be ignored. file=%s", filepath); + goto finish; + } + + iv = buffer_create(IV_LEN); + if (iv == NULL) { + ret = WAE_ERROR_MEMORY; + goto finish; + } + + memcpy(iv->buf, AES_CBC_IV, iv->size); + + ce = crypto_element_create(dek, iv); + if (ce == NULL) { + ret = WAE_ERROR_MEMORY; + goto finish; + } + + ret = save_to_key_manager(pkg_id, pkg_id, WAE_PRELOADED_APP, ce); + if (ret == WAE_ERROR_KEY_EXISTS) { + WAE_SLOGI("Key Manager already has dek. It will be ignored. file=%s", filepath); + } else if (ret != WAE_ERROR_NONE) { + WAE_SLOGW("Fail to add APP DEK to key-manager. file=%s", filepath); + } + +finish: + buffer_destroy(encrypted_dek); + + if (ce == NULL) { + buffer_destroy(dek); + buffer_destroy(iv); + } else { + crypto_element_destroy(ce); + } + + return ret; +} + int get_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type, bool create_for_migrated_app, const crypto_element_s **pce) { @@ -438,7 +492,7 @@ int create_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce) } // store APP_DEK in cache - _add_app_ce_to_cache(pkg_id, ce); + ret = _add_app_ce_to_cache(pkg_id, ce); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("Failed to add ce to cache for pkg_id(%s) ret(%d)", pkg_id, ret); goto error; @@ -479,15 +533,7 @@ int load_preloaded_app_deks(bool reload) int ret = WAE_ERROR_NONE; char pkg_id[MAX_PKGID_LEN] = {0, }; - char file_path_buff[MAX_PATH_LEN]; - raw_buffer_s *encrypted_dek = NULL; - raw_buffer_s *dek = NULL; - raw_buffer_s *iv = NULL; - raw_buffer_s *prikey = NULL; - crypto_element_s *ce = NULL; - - int error_during_loading = 0; if (!reload) { // check if all deks were already loaded into key-manager. @@ -497,6 +543,7 @@ int load_preloaded_app_deks(bool reload) return ret; } + raw_buffer_s *prikey = NULL; ret = _get_app_dek_kek(&prikey); if (ret != WAE_ERROR_NONE) { @@ -508,6 +555,7 @@ int load_preloaded_app_deks(bool reload) if (dir == NULL) { WAE_SLOGE("Fail to open dir. dir=%s", _get_dek_store_path()); + buffer_destroy(prikey); return WAE_ERROR_FILE; } @@ -515,11 +563,9 @@ int load_preloaded_app_deks(bool reload) struct dirent *result = NULL; while (true) { - int error = readdir_r(dir, &entry, &result); - - if (error != 0) { + if (readdir_r(dir, &entry, &result) != 0) { ret = WAE_ERROR_FILE; - goto error; + break; } // readdir_r returns NULL in *result if the end @@ -537,7 +583,7 @@ int load_preloaded_app_deks(bool reload) if (ret < 0) { WAE_SLOGE("Failed to make file path by snprintf."); ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ - goto error; + break; } ret = _extract_pkg_id_from_file_name(entry.d_name, pkg_id); @@ -548,75 +594,22 @@ int load_preloaded_app_deks(bool reload) continue; } - ret = _read_from_file(file_path_buff, &encrypted_dek); - - if (ret != WAE_ERROR_NONE || encrypted_dek == NULL) { - ++error_during_loading; - WAE_SLOGW("Failed to read file. It will be ignored. file=%s", file_path_buff); - continue; - } - - ret = decrypt_app_dek(prikey, APP_DEK_KEK_PRIKEY_PASSWORD, encrypted_dek, &dek); - - buffer_destroy(encrypted_dek); - encrypted_dek = NULL; - - if (ret != WAE_ERROR_NONE || dek == NULL) { - ++error_during_loading; - WAE_SLOGW("Failed to decrypt dek. It will be ignored. file=%s", - file_path_buff); - continue; - } - iv = buffer_create(IV_LEN); - if (iv == NULL) { - ++error_during_loading; - buffer_destroy(dek); - dek = NULL; - continue; - } - - memcpy(iv->buf, AES_CBC_IV, iv->size); - - ce = crypto_element_create(dek, iv); - if (ce == NULL) { - ++error_during_loading; - buffer_destroy(iv); - iv = NULL; - buffer_destroy(dek); - dek = NULL; - continue; - } - - ret = save_to_key_manager(pkg_id, pkg_id, WAE_PRELOADED_APP, ce); - - if (ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("Key Manager already has dek. It will be ignored. file=%s", - file_path_buff); - } else if (ret != WAE_ERROR_NONE) { - ++error_during_loading; - WAE_SLOGW("Fail to add APP DEK to key-manager. file=%s", file_path_buff); - } - - crypto_element_destroy(ce); - ce = NULL; - } - - ret = set_app_deks_loaded_to_key_manager(); - -error: - if (ret != WAE_ERROR_NONE) { - if (ce) { - crypto_element_destroy(ce); + ret = _load_preloaded_app_dek(prikey, file_path_buff, pkg_id); + if (ret != WAE_ERROR_NONE && ret != WAE_ERROR_KEY_EXISTS) { + WAE_SLOGW("Failed to load app dek(%s) ret(%d)", file_path_buff, ret); } else { - buffer_destroy(dek); - buffer_destroy(iv); + WAE_SLOGI("Successfully load app dek(%s)", file_path_buff); + ret = WAE_ERROR_NONE; } } buffer_destroy(prikey); closedir(dir); - return ret; + if (ret != WAE_ERROR_NONE) + return ret; + else + return set_app_deks_loaded_to_key_manager(); } int remove_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type) -- 2.7.4 From 99e3231e9112039e45e42c186ed8d77a939ae0a7 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Mon, 5 Dec 2016 17:10:20 +0900 Subject: [PATCH 06/16] Numbering upgrade script wae-upgrade.sh -> 200.wae.sh Change-Id: I77f59c43be20cdb7eb808ca5e7a754287bcdfcb0 Signed-off-by: Kyungwook Tak --- packaging/libwebappenc.spec | 2 +- scripts/{wae-upgrade.sh.in => 200.wae.sh.in} | 2 +- scripts/CMakeLists.txt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename scripts/{wae-upgrade.sh.in => 200.wae.sh.in} (96%) diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index 9f8faef..760f3e2 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -103,7 +103,7 @@ fi %dir %attr(770, %user_name, %group_name) %{rw_share_dir}/wae/app_dek %attr(660, %user_name, %group_name) %{rw_share_dir}/wae/app_dek/* -%attr(775,root,root) %{upgrade_script_dir}/wae-upgrade.sh +%attr(775,root,root) %{upgrade_script_dir}/200.wae.sh %{upgrade_data_dir}/wae/app_dek/* %files devel diff --git a/scripts/wae-upgrade.sh.in b/scripts/200.wae.sh.in similarity index 96% rename from scripts/wae-upgrade.sh.in rename to scripts/200.wae.sh.in index 652962b..5552f74 100755 --- a/scripts/wae-upgrade.sh.in +++ b/scripts/200.wae.sh.in @@ -15,7 +15,7 @@ PATH=/bin:/usr/bin:/sbin:/usr/sbin # See the License for the specific language governing permissions and # limitations under the License. # -# @file wae-upgrade.sh.in +# @file 200.wae.sh.in # @author Kyungwook Tak (k.tak@samsung.com) # @brief Platform upgrade support diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index c73467e..f4098fc 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -12,5 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. # -CONFIGURE_FILE(wae-upgrade.sh.in wae-upgrade.sh @ONLY) -INSTALL(FILES wae-upgrade.sh DESTINATION ${UPGRADE_SCRIPT_DIR}) +CONFIGURE_FILE(200.wae.sh.in 200.wae.sh @ONLY) +INSTALL(FILES 200.wae.sh DESTINATION ${UPGRADE_SCRIPT_DIR}) -- 2.7.4 From 0778e0964f8fecd8ce06c307eddc2ccf1632fc2b Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Mon, 5 Dec 2016 17:13:40 +0900 Subject: [PATCH 07/16] Use cp instead of mv in upgrade script RO partition shouldn't be modified Change-Id: I70b8de4051cd4295b5431b77fd5eb82f1e518731 Signed-off-by: Kyungwook Tak --- scripts/200.wae.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/200.wae.sh.in b/scripts/200.wae.sh.in index 5552f74..29d9497 100755 --- a/scripts/200.wae.sh.in +++ b/scripts/200.wae.sh.in @@ -21,7 +21,7 @@ PATH=/bin:/usr/bin:/sbin:/usr/sbin WAE_DIR=@RW_SHARE_DIR@/wae -mv @UPGRADE_DATA_DIR@/wae $WAE_DIR +cp -rf @UPGRADE_DATA_DIR@/wae $WAE_DIR chsmack -a "@SMACK_DOMAIN@" $WAE_DIR -r chown -R @USER_NAME@:@GROUP_NAME@ $WAE_DIR -- 2.7.4 From 9efcb91aed4e7365aa945fc9c6ffe2d111ca1496 Mon Sep 17 00:00:00 2001 From: Bartlomiej Kunikowski Date: Mon, 5 Dec 2016 08:49:59 +0100 Subject: [PATCH 08/16] Fix for wae_initializer There is a bug in if statement, it don't allow to properly work of this initializer if there are no --reload flag. Other way to do it is simply use wae_initializer always as it is with --reload flag. Change-Id: I9622373c914f8c0f1f22d3f810417251cced81ba Signed-off-by: Bartlomiej Kunikowski (cherry picked from commit 1fcac8945420537f89d24a0e8e52ec99cc432674) --- srcs/key_handler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 4607fdd..905538e 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -539,8 +539,8 @@ int load_preloaded_app_deks(bool reload) // check if all deks were already loaded into key-manager. ret = is_app_deks_loaded_in_key_manager(); - if (ret == WAE_ERROR_NONE) - return ret; + if (ret == true) + return WAE_ERROR_NONE; } raw_buffer_s *prikey = NULL; -- 2.7.4 From 66f4515064566676869fd3c3a8970fcf24b00b5f Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 7 Dec 2016 17:22:40 +0900 Subject: [PATCH 09/16] Remove reload option to wae initializer service Reload option is not needed anymore. To be secure, remove all KEKs from dek store (also adek) after loading preloaded adeks once. Loaded adeks are stored in key-manager so they're useless. Related test cases are added. (load preloaded app deks) (TODO) To use key-manager initial value feature is highly considered to store KEK private key more securely. Change-Id: I2f6c645398277968cd7d480236d1802a07fa33df Signed-off-by: Kyungwook Tak --- packaging/libwebappenc.spec | 1 + srcs/key_handler.c | 164 +++++++++++++++++++++++++++++++---------- srcs/key_handler.h | 6 +- srcs/key_manager.c | 61 --------------- srcs/wae_initializer.c | 9 +-- tests/CMakeLists.txt | 2 + tests/internals.cpp | 103 ++++++++++++++++++++++---- tests/resources/CMakeLists.txt | 19 +++++ tests/resources/prikey.pem | 30 ++++++++ tests/resources/pubkey.pem | 9 +++ tests/test-helper.cpp | 72 ++++++++++++++++-- tests/test-helper.h | 3 + 12 files changed, 352 insertions(+), 127 deletions(-) create mode 100644 tests/resources/CMakeLists.txt create mode 100644 tests/resources/prikey.pem create mode 100644 tests/resources/pubkey.pem diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index 760f3e2..4184b84 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -117,3 +117,4 @@ fi %license LICENSE.BSL-1.0 %{bin_dir}/wae_tests %{_libdir}/libwae_tests_common.so* +%attr(660, %user_name, %group_name) %{rw_share_dir}/wae/test/app_dek/* diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 905538e..d77016f 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -103,17 +103,17 @@ int _get_random(raw_buffer_s *rb) return WAE_ERROR_NONE; } -static const char *_get_dek_kek_pub_key_path() +const char *_get_dek_kek_pub_key_path() { return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PublicKey.pem"); } -static const char *_get_dek_kek_pri_key_path() +const char *_get_dek_kek_pri_key_path() { return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PrivateKey.pem"); } -static const char *_get_dek_store_path() +const char *_get_dek_store_path() { return tzplatform_mkpath3(TZ_SYS_SHARE, "wae", "app_dek"); } @@ -188,6 +188,52 @@ error: return ret; } +static void _remove_file(const char *path) +{ + unlink(path); +} + +void _remove_directory(const char *path) +{ + char file_path_buff[MAX_PATH_LEN] = {0, }; + DIR *dir = opendir(path); + if (dir == NULL) { + if (errno == ENOENT) + WAE_SLOGI("directory is not exist already(%s)", path); + else + WAE_SLOGE("Failed to open dir(%s)", path); + + return; + } + + struct dirent entry; + struct dirent *result = NULL; + while (true) { + if (readdir_r(dir, &entry, &result) != 0) { + break; + } else if (result == NULL) { + break; + } else if (strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0) { + continue; + } + + if (snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", path, entry.d_name) + < 0) + continue; + + if (entry.d_type == DT_DIR) { + _remove_directory(file_path_buff); + } else { + WAE_SLOGD("remove file(%s)", file_path_buff); + _remove_file(file_path_buff); + } + } + + WAE_SLOGD("remove directory(%s)", path); + closedir(dir); + rmdir(path); +} + int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path) { int ret = snprintf(path, size, "%s/%s_%s.adek", @@ -528,43 +574,53 @@ int _get_app_dek_kek(raw_buffer_s **pdek_kek) #endif } -int load_preloaded_app_deks(bool reload) +int load_preloaded_app_deks() { - int ret = WAE_ERROR_NONE; + WAE_SLOGI("load_preloaded_app_deks start"); - char pkg_id[MAX_PKGID_LEN] = {0, }; - char file_path_buff[MAX_PATH_LEN]; + int global_ret = WAE_ERROR_NONE; - if (!reload) { - // check if all deks were already loaded into key-manager. - ret = is_app_deks_loaded_in_key_manager(); + char pkg_id[MAX_PKGID_LEN] = {0, }; + char file_path_buff[MAX_PATH_LEN] = {0, }; - if (ret == true) - return WAE_ERROR_NONE; - } + const char *dek_store_path = _get_dek_store_path(); + const char *dek_kek_pub_key_path = _get_dek_kek_pub_key_path(); + const char *dek_kek_pri_key_path = _get_dek_kek_pri_key_path(); raw_buffer_s *prikey = NULL; - ret = _get_app_dek_kek(&prikey); + DIR *dir = NULL; - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); - return ret; + // check if all deks were already loaded into key-manager. + // TODO: instead of checking key-manager, check based on file existance + dir = opendir(dek_store_path); + if (dir == NULL) { + if (errno == ENOENT) { + WAE_SLOGI( + "dek store doesn't exist. " + "It might be loading preloaded app deks already done"); + + return WAE_ERROR_NONE; + } else { + WAE_SLOGE("Fail to open dir. dir=%s", dek_store_path); + global_ret = WAE_ERROR_FILE; + goto out; + } } - DIR *dir = opendir(_get_dek_store_path()); + global_ret = _get_app_dek_kek(&prikey); - if (dir == NULL) { - WAE_SLOGE("Fail to open dir. dir=%s", _get_dek_store_path()); - buffer_destroy(prikey); - return WAE_ERROR_FILE; + if (global_ret != WAE_ERROR_NONE) { + WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); + goto out; } struct dirent entry; struct dirent *result = NULL; while (true) { + int ret = WAE_ERROR_NONE; if (readdir_r(dir, &entry, &result) != 0) { - ret = WAE_ERROR_FILE; + global_ret = WAE_ERROR_FILE; break; } @@ -573,43 +629,77 @@ int load_preloaded_app_deks(bool reload) if (result == NULL) break; - // regular file && start with KEY_MANAGER_INITIAL_VALUE_FILE_PFX - if (entry.d_type != DT_REG || strstr(entry.d_name, APP_DEK_FILE_PFX) == NULL) + if (strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0) continue; - ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", - _get_dek_store_path(), entry.d_name); - - if (ret < 0) { + if (snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", + dek_store_path, entry.d_name) < 0) { WAE_SLOGE("Failed to make file path by snprintf."); - ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ + global_ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ break; } + // skip for KEKs. They'll be deleted after all akek loaded to key-manager. + if (strcmp(file_path_buff, dek_kek_pub_key_path) == 0 || + strcmp(file_path_buff, dek_kek_pri_key_path) == 0) { + WAE_SLOGD("Skip KEK file...(%s)", file_path_buff); + continue; + } + + // regular file && start with KEY_MANAGER_INITIAL_VALUE_FILE_PFX + // clear all invalid cases silently + if (entry.d_type != DT_REG || strstr(entry.d_name, APP_DEK_FILE_PFX) == NULL) { + if (entry.d_type == DT_DIR) { + WAE_SLOGW( + "Invalid file in dek store(%s). Directory shouldn't be here.", + dek_store_path); + global_ret = WAE_ERROR_FILE; + } else { + WAE_SLOGW( + "Invalid file in dek store(%s). " + "Not regular file or prefix(%s) is invalid.", + dek_store_path, APP_DEK_FILE_PFX); + global_ret = WAE_ERROR_FILE; + } + + continue; + } + ret = _extract_pkg_id_from_file_name(entry.d_name, pkg_id); if (ret != WAE_ERROR_NONE) { WAE_SLOGW("Failed to extract pkgid from file. It will be ignored. file=%s", file_path_buff); + global_ret = ret; continue; } ret = _load_preloaded_app_dek(prikey, file_path_buff, pkg_id); if (ret != WAE_ERROR_NONE && ret != WAE_ERROR_KEY_EXISTS) { WAE_SLOGW("Failed to load app dek(%s) ret(%d)", file_path_buff, ret); + global_ret = ret; } else { WAE_SLOGI("Successfully load app dek(%s)", file_path_buff); - ret = WAE_ERROR_NONE; } } - buffer_destroy(prikey); - closedir(dir); +out: + if (prikey != NULL) + buffer_destroy(prikey); - if (ret != WAE_ERROR_NONE) - return ret; - else - return set_app_deks_loaded_to_key_manager(); + if (dir != NULL) + closedir(dir); + + // remove dek store after loade done even though it's partially failed + // because malware can still put the file in dek store if it still system service's + // ownership and they can break this logic by inserting any file to dek store path. + // If KEK private key is inserted to key-manager with initial-value feature, malware + // cannot insert/encrypt/decrypt app dek so it's fine on preloaded app security but + // if we handle errors related loading file, malware can at least occur webappenc + // initializer service failure. + _remove_directory(dek_store_path); + + return global_ret; } int remove_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type) diff --git a/srcs/key_handler.h b/srcs/key_handler.h index 791e149..f5ce3e4 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -41,6 +41,10 @@ int _get_random(raw_buffer_s *rb); int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path); int _read_encrypted_app_dek_from_file(const char *pkg_id, raw_buffer_s **pencrypted); int _write_encrypted_app_dek_to_file(const char *pkg_id, const raw_buffer_s *encrypted); +void _remove_directory(const char *path); +const char *_get_dek_kek_pub_key_path(); +const char *_get_dek_kek_pri_key_path(); +const char *_get_dek_store_path(); /* functions for interface */ int get_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type, @@ -51,7 +55,7 @@ int remove_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type); int get_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce); int create_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce); -int load_preloaded_app_deks(bool reload); +int load_preloaded_app_deks(); #ifdef __cplusplus } diff --git a/srcs/key_manager.c b/srcs/key_manager.c index aeee748..ac42db2 100644 --- a/srcs/key_manager.c +++ b/srcs/key_manager.c @@ -32,7 +32,6 @@ #define MAX_ALIAS_LEN 256 #define APP_DEK_ALIAS_PFX "APP_DEK_" -#define APP_DEK_LOADING_DONE_ALIAS "APP_DEKS_LOADING_FINISHED" #define APP_DEK_KEK_ALIAS "WAE_APP_DEK_KEK" static int _to_wae_error(int key_manager_error) @@ -203,66 +202,6 @@ static void _get_alias(const char *name, UNUSED wae_app_type_e type, UNUSED bool name); } -static void _get_dek_loading_done_alias(char *alias, size_t buff_len) -{ - snprintf(alias, buff_len, "%s%s%s", - ckmc_owner_id_system, - ckmc_owner_id_separator, - APP_DEK_LOADING_DONE_ALIAS); -} - -bool is_app_deks_loaded_in_key_manager() -{ - char alias[MAX_ALIAS_LEN] = {0, }; - - _get_dek_loading_done_alias(alias, sizeof(alias)); - - ckmc_raw_buffer_s *buf = NULL; - int ret = _to_wae_error(ckmc_get_data(alias, NULL, &buf)); - - ckmc_buffer_free(buf); - - switch (ret) { - case WAE_ERROR_NONE: - return true; - case WAE_ERROR_NO_KEY: - WAE_SLOGI("app dek loading isn't done yet"); - return false; - default: - WAE_SLOGE("Failed to get dek loading flag data from key-manager. ret(%d)", ret); - return false; - } -} - -int set_app_deks_loaded_to_key_manager() -{ - unsigned char dummy_data[1] = {0}; - ckmc_raw_buffer_s buf; - buf.data = dummy_data; - buf.size = sizeof(dummy_data); - - ckmc_policy_s policy; - policy.password = NULL; - policy.extractable = true; - - char alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(alias, sizeof(alias)); - - int ret = _to_wae_error(ckmc_save_data(alias, buf, policy)); - if (ret == WAE_ERROR_KEY_EXISTS) - ret = WAE_ERROR_NONE; - - return ret; -} - -int clear_app_deks_loaded_from_key_manager() -{ - char alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(alias, sizeof(alias)); - - return _to_wae_error(ckmc_remove_alias(alias)); -} - int save_to_key_manager(const char *name, const char *pkg_id, wae_app_type_e type, const crypto_element_s *ce) { diff --git a/srcs/wae_initializer.c b/srcs/wae_initializer.c index 956b04d..f01c8e8 100644 --- a/srcs/wae_initializer.c +++ b/srcs/wae_initializer.c @@ -23,14 +23,9 @@ #include "web_app_enc.h" #include "wae_log.h" -int main(int argc, char *argv[]) +int main() { - bool reload = false; - - if (argc == 2 && strcmp(argv[1], "--reload") == 0) - reload = true; - - int ret = load_preloaded_app_deks(reload); + int ret = load_preloaded_app_deks(); if (ret == WAE_ERROR_NONE) { WAE_SLOGI("WAE INITIALIZER was finished successfully."); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7c9e2c9..07d2082 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -97,3 +97,5 @@ INSTALL(TARGETS ${TARGET_WAE_TEST} WORLD_READ WORLD_EXECUTE ) + +ADD_SUBDIRECTORY(resources) diff --git a/tests/internals.cpp b/tests/internals.cpp index 1fa9aff..7a13df7 100644 --- a/tests/internals.cpp +++ b/tests/internals.cpp @@ -24,7 +24,12 @@ #include #include +#include +#include +#include #include +#include +#include #include @@ -32,6 +37,7 @@ #include "crypto_service.h" #include "test-common.h" +#include "test-helper.h" namespace { @@ -76,7 +82,7 @@ crypto_element_s *_create_ce(void) return ce; } -} +} // namespace anonymous BOOST_AUTO_TEST_SUITE(SYSTEM) @@ -261,6 +267,15 @@ BOOST_AUTO_TEST_CASE(read_write_encrypted_app_dek) BOOST_REQUIRE(dek != nullptr); BOOST_REQUIRE(_get_random(dek) == WAE_ERROR_NONE); + // precondition + // dek store is removed after preloaded app deks loaded so dek store + // does not exists as default. To test write/read app dek test(they're working on + // dek store), dek store directory should be made + Wae::Test::restore_dek_store(); + // make unique_ptr to remove directory automatically + std::unique_ptr> scoped_store( + reinterpret_cast(1), [](void *) { Wae::Test::remove_dek_store(); }); + int ret = _write_encrypted_app_dek_to_file(pkg_id, dek); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to write_encrypted_app_dek_to_file. ec: " << ret); @@ -276,7 +291,7 @@ BOOST_AUTO_TEST_CASE(read_write_encrypted_app_dek) "readed(" << Wae::Test::bytes_to_hex(readed) << ")"); } -BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1) +BOOST_AUTO_TEST_CASE(cache_create_preloaded_app_dek) { const char *pkg_id = "TEST_PKG_ID_FOR_CREATE"; @@ -287,7 +302,22 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1) "preloaded app ce to create is already exist. ec: " << ret); const crypto_element_s *ce = nullptr; - ret = create_preloaded_app_ce(pkg_id, &ce); + + { + // precondition: + // for create_preloaded_app_ce, public key(kek) is needed + Wae::Test::restore_dummy_preloaded_app_dek_keks(); + // postcondition: + // get_preloaded_app_ce retrieves app ce from cache which is created on + // create_preloaded_app_ce so private key in dek store shouldn't be needed + // make unique_ptr to remove directory automatically + std::unique_ptr> scoped_store( + reinterpret_cast(1), [](void *) { Wae::Test::remove_dek_store(); }); + + // created preloaded app ce is just written in file, not into key-manager repo so + // no need to call remove_app_ce. + ret = create_preloaded_app_ce(pkg_id, &ce); + } BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to create_preloaded_app_ce. ec: " << ret); @@ -299,22 +329,21 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1) BOOST_REQUIRE_MESSAGE(readed == ce, "cached ce address and actual is different!"); } -BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) +BOOST_AUTO_TEST_CASE(load_preloaded_app_dek) { + // steps + // 1) restore KEKs : restore_dummy_preloaded_app_dek_keks + // 2) create app deks based on KEK (public key) : create_preloaded_app_ce + // -> originally this step runs in image server so result(adek) is written to file + // 3) load preloaded app deks (.adek) in file : load_preloaded_app_deks + // -> After load, pri/pub key pair and adek in file is no longer needed so they're + // automatically cleared by load_preloaded_app_deks() + // 4) clear app deks from key-manager for remove it (associated to TEST_PKG_ID_*) + Wae::Test::restore_dummy_preloaded_app_dek_keks(); + const char *pkg_id1 = "TEST_PKGID_1"; const char *pkg_id2 = "TEST_PKGID_2"; - char path1[MAX_PATH_LEN] = {0, }; - char path2[MAX_PATH_LEN] = {0, }; - _get_preloaded_app_dek_file_path(pkg_id1, sizeof(path1), path1); - _get_preloaded_app_dek_file_path(pkg_id2, sizeof(path2), path2); - - // remove old test data - remove_app_ce(0, pkg_id1, WAE_PRELOADED_APP); - remove_app_ce(0, pkg_id2, WAE_PRELOADED_APP); - unlink(path1); - unlink(path2); - // create 2 ces for preloaded app const crypto_element_s *ce1 = nullptr; int ret = create_preloaded_app_ce(pkg_id1, &ce1); @@ -326,7 +355,7 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to create_preloaded_app_ce. ec: " << ret); - ret = load_preloaded_app_deks(true); + ret = load_preloaded_app_deks(); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to load_preloaded_app_deks. ec: " << ret); @@ -348,6 +377,48 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret); } +BOOST_AUTO_TEST_CASE(load_preloaded_app_dek_tolerances) +{ + std::function does_dek_store_exist = []() { + if (DIR *dir = opendir(_get_dek_store_path())) { + closedir(dir); + return true; + } else if (errno != ENOENT) { + return true; + } else { + return false; + } + }; + + // without dek store directory + BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_NONE); + BOOST_REQUIRE(does_dek_store_exist() == false); + + // without kek(private key) + Wae::Test::restore_dek_store(); + BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_FILE); + BOOST_REQUIRE(does_dek_store_exist() == false); + + // with invalid file in dek store + Wae::Test::restore_dummy_preloaded_app_dek_keks(); + std::ofstream dst; + dst.exceptions(std::ofstream::failbit | std::ofstream::badbit); + dst.open(std::string(_get_dek_store_path()) + "/invalids", std::ofstream::binary); + dst << "touch invalid file to dek store"; + // std::ofstream destructor will call close automatically so no need to handle + // close in the exception cases + dst.close(); + BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_FILE); + BOOST_REQUIRE(does_dek_store_exist() == false); + + // with invalid directory in dek store + Wae::Test::restore_dummy_preloaded_app_dek_keks(); + std::string invalid_dir = std::string(_get_dek_store_path()) + "/invalid_dir"; + mkdir(invalid_dir.c_str(), S_IRUSR | S_IWUSR | S_IXUSR); + BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_FILE); + BOOST_REQUIRE(does_dek_store_exist() == false); +} + BOOST_AUTO_TEST_SUITE_END() // INTERNALS BOOST_AUTO_TEST_SUITE_END() // SYSTEM diff --git a/tests/resources/CMakeLists.txt b/tests/resources/CMakeLists.txt new file mode 100644 index 0000000..fa0856f --- /dev/null +++ b/tests/resources/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +INSTALL( + FILES pubkey.pem prikey.pem + DESTINATION ${RW_SHARE_DIR}/wae/test/app_dek + PERMISSIONS OWNER_READ +) diff --git a/tests/resources/prikey.pem b/tests/resources/prikey.pem new file mode 100644 index 0000000..e27950c --- /dev/null +++ b/tests/resources/prikey.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,F4C783D75B0679F29398E9A3CAB4733D + +kxgW1wGX3TZZ/wtv3g4AOLlZCHoQ6uXVQ0h2ofWjnJs8tas/alR6o8UBRIqCw44t +znUvQ8HlThvzhGgxje/yDDSxCy9mqhgsi2XeTtAeUbMhFL6UArb3cs6M4a37lYoT +llZdFyYkRWJ3vRS33TDrhXDV6GjZWQ05SJ0OYdPJsmA1ENwdH+5NE/xLnqLdTtWr +O3Mn2vi6P9CVqZroCvYBzUaypGcmFhjTIbWmB6inXjoXyddzerh7PTDBDWWacBab +C7gcZC5SrK5YOt6f54ANsVQO8jnkLDx95gUSHYthX1hrQ3Da5Gb6nfYP9RNrHCum +O8RKxSOvv8zwbMlzqtld8xCOb7Nh04f8bofrzZVLZ0T92FcyFQmt1F4U6DNQqHsn +AAqxRxUWsC5k2dX9uZ6RCpEzNYWyPvNe24I/Kt01Geoh1NtCns8CVZcrxyMMtZRK +ZJnYhvNDXDQCDtMJjRBiEXXE++AdA2O6uFoGX3alKwtxAIjGI++pSRlz1GTps26x +5mmLil5wb3KGBfMN4L0R0heDOeiPQrNv7CwX8OlHtA1OKFBtViWdd/uZ2hAko1Tz +YkoYpHPQOV5LZ7dem/XNnwwel9g6AkHhLNJv5ih4Y0CQfPBSs+iiLbMHh/NaGDD9 ++kbcf5Lk4FQGVbJDW9nDAXT6jjMyliTI+hIh5fM2k22qbq6OqBkW6EbOQDMP/R2P +LhFqTgHceNt0mqpcDJdJQ0YKbxVpdkv5f1C4rW+pgUEeHDCQ7vPe4p44xQJ/Z/7Y +AtPwPKzPPJze2cfoUkZd9jXN9g2v2555xnQZU78IEm1nPVBA+hLIaqN1hu1Lkzxy +CwFNo7bMVh3FSBmZVtJlcLsyLxZ9UdoaSr+anfA0lWJPiBzE0whQljZp56l1rL1V +1K8m/dc9rLJ3uDQmYoSRmBZG5zZlVWCip+R9VAHMxRi1x29dFk1jbtQscr63dMI8 +0eOUf28Mw719WWUZVzD08b431DPqWiqrpexUKEXPW8EsrINPfIg180QYt1VUoshs +Tqi/LKM0OV6nlMGh9ieCK8WzVDW8F16krSLo6eJpIPYPZgkHE7fC7Jws1kpUrSnF +GgT6rBA97tJ0EalinuFXbip1X087Quz5USURq18f7/B6nFu0Kd4GhlICsR24j3eB +75SsTNmfUcko8s5QT4rwONEwtRffkGbbNEisCPcleJV68zHvN58mfD7Dl8W3zIO4 +Qk6B1Xy0C4EEniKFfjxIaMEaxrqntBIc+nZE6/+UoGp/Hj9r5ZdzQX2j4837IIdR +CxT4tjXiWBA6u3WaLAZUSM0W0SEORUF9NwzlId1b8A3WxA8XewhAKPaJEr677vzZ +083+neUOuXqqs597romLH1omuffxmHxBzmP+koUtemP78XxCBVWUAB1T+fBRJMz6 +9ZEgDWrMntJ1IaFoGdOWZELgwcXJ0KwWFuk+sieZ5WCCzNmFli9WPN/xSqwmdYw6 +RK9er5Vc8D9mAlmGlz2mpAmzNJHH30zYKT/d0XzBS8z6WBRthaTS3NLsiSeWdELH +b5+WEMOiKvZ19AXU2unHw/XpeVnAISOHhumAqFCwXkjVoMt8LMDawt6ra8N8G+gD +-----END RSA PRIVATE KEY----- diff --git a/tests/resources/pubkey.pem b/tests/resources/pubkey.pem new file mode 100644 index 0000000..f0dfcea --- /dev/null +++ b/tests/resources/pubkey.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kWtjpRO7Zh2KX2naVE/ +BDJdrfwK9xexfNA0MkY2VJ4J2AKMYTj1D1jntceryupCEHOvP3rum+WsFvPXduz9 ++VKnSsSqj4jcTUubtpDUGA5G79IqLEPFuSBaqI8Uwkzd08pE+s30oaJDnNazMhSq +8JkqBPoCCwtUs73ruE9VbtsBO/kTlASIAfe8nXqcJLcDQgWYhizjJw0Pi6d74oCw +S2OTvQDNvsXfFnA0ZJEEYw/rZLirj7OHoOjz+Sh5N+1uA3Up6SPPEbHuP6L12Yxq +Hdy7gnJXodLhvE/cR4SN9VW7+qmCMBjmLkBejGrEX3STS9sLI7MZHu9Y26dwuYb4 ++wIDAQAB +-----END PUBLIC KEY----- diff --git a/tests/test-helper.cpp b/tests/test-helper.cpp index d0ca263..b7fdf6a 100644 --- a/tests/test-helper.cpp +++ b/tests/test-helper.cpp @@ -22,6 +22,9 @@ #include #include +#include +#include +#include #include "web_app_enc.h" #include "key_handler.h" @@ -37,6 +40,25 @@ namespace { const uid_t UID_OWNER = 5001; +void copy_file(const char *src_path, const char *dst_path) +{ + std::ifstream src; + std::ofstream dst; + + src.exceptions(std::ifstream::failbit | std::ifstream::badbit); + dst.exceptions(std::ofstream::failbit | std::ofstream::badbit); + + src.open(src_path, std::ifstream::binary); + dst.open(dst_path, std::ofstream::binary); + + dst << src.rdbuf(); + + // std::ofstream destructor will call close automatically so no need to handle + // close in the exception cases + src.close(); + dst.close(); +} + } // namespace anonymous void add_get_remove_ce(wae_app_type_e app_type) @@ -123,15 +145,29 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) else wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP); - if (app_type == WAE_PRELOADED_APP) - clear_app_deks_loaded_from_key_manager(); - std::vector plaintext = { 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', 'o', 'q', '2', 'e', 'v', '0', '1', 'x' }; - // test for downloaded web application + // precondition for preloaded app: + // for preloaded app encryption, preloaded app dek kek(pub) is needed. + // dek store is removed after preloaded app deks loaded so dek store + // does not exists as default. To test encrypt/decrypt(write/read ce) app test, + // dek store directory should be made. + std::unique_ptr> scoped_store( + reinterpret_cast(1), [](void *ptr) { + if (ptr == reinterpret_cast(1)) + return; + else + remove_dek_store(); // remove dek store automatically in case of error + }); + + if (app_type == WAE_PRELOADED_APP) { + restore_dummy_preloaded_app_dek_keks(); + scoped_store.reset(reinterpret_cast(2)); + } + unsigned char *_encrypted = nullptr; size_t _enc_len = 0; int tmp = 0; @@ -171,7 +207,7 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) } if (app_type == WAE_PRELOADED_APP) - load_preloaded_app_deks(true); + load_preloaded_app_deks(); unsigned char *_decrypted = nullptr; size_t _dec_len = 0; @@ -201,5 +237,31 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) "Failed to wae_remove_app_dek. ec: " << tmp); } +void restore_dek_store() +{ + mkdir( + _get_dek_store_path(), + S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP); +} + +void remove_dek_store() +{ + _remove_directory(_get_dek_store_path()); +} + +void restore_dummy_preloaded_app_dek_keks() +{ + // Generate pri/pub key pair. Private key is protected + // with assigned password: APP_DEK_KEK_PRIKEY_PASSWORD) which is same to password + // of real private key because it's built in source of srcs/key_handler.c + // It should be removed after private key goes into key-manager initial-value. + restore_dek_store(); + + copy_file("/opt/share/wae/test/app_dek/prikey.pem", _get_dek_kek_pri_key_path()); + copy_file("/opt/share/wae/test/app_dek/pubkey.pem", _get_dek_kek_pub_key_path()); + + BOOST_MESSAGE("copying dummy pri/pub key pair to dek store done"); +} + } // namespace Test } // namespace Wae diff --git a/tests/test-helper.h b/tests/test-helper.h index b4d1f42..cd2fae2 100644 --- a/tests/test-helper.h +++ b/tests/test-helper.h @@ -29,5 +29,8 @@ void add_get_remove_ce(wae_app_type_e app_type); void create_app_ce(wae_app_type_e app_type); void encrypt_decrypt_web_app(wae_app_type_e app_type); +void remove_dek_store(); +void restore_dek_store(); +void restore_dummy_preloaded_app_dek_keks(); } // namespace Test } // namespace Wae -- 2.7.4 From 9fddab9e58ccd9acdecdbfcf12770c50feac4d2b Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Thu, 8 Dec 2016 10:12:11 +0900 Subject: [PATCH 10/16] Refine directory traversing: registering callback There's two part of directory traversing(removing all files in directory and loading preloaded app deks). So duplicated code can be compressed to traverse_directory with entry callback registered. Change-Id: I654bed7f3b4efff75b2853fceb3f9d97b51a85b5 Signed-off-by: Kyungwook Tak --- srcs/key_handler.c | 218 +++++++++++++++++++++++++++-------------------------- 1 file changed, 110 insertions(+), 108 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index d77016f..cdc96af 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -188,61 +188,87 @@ error: return ret; } -static void _remove_file(const char *path) +typedef int(*entry_callback)(const char *path, const struct dirent *entry, void *user_data); +static int traverse_directory(const char *path, entry_callback ecb, void *user_data) { - unlink(path); -} - -void _remove_directory(const char *path) -{ - char file_path_buff[MAX_PATH_LEN] = {0, }; DIR *dir = opendir(path); if (dir == NULL) { - if (errno == ENOENT) - WAE_SLOGI("directory is not exist already(%s)", path); - else + if (errno == ENOENT) { + // it's not error for current cases of using traverse_directory. + // To open dek store directory for load/remove can be occured in some + // exception(or attacked) cases but we can just ignore it if it isn't the + // first time call load_preloaded_app_deks. + WAE_SLOGI("directory isn't exist(%s).", path); + return WAE_ERROR_NONE; + } else { WAE_SLOGE("Failed to open dir(%s)", path); - - return; + return WAE_ERROR_FILE; + } } + int ret = WAE_ERROR_NONE; struct dirent entry; struct dirent *result = NULL; while (true) { if (readdir_r(dir, &entry, &result) != 0) { + WAE_SLOGE("readdir_r error on dir(%s) errno(%d)", path, errno); break; } else if (result == NULL) { - break; + break; // end of directory } else if (strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0) { continue; } - if (snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", path, entry.d_name) - < 0) - continue; + int _ret = ecb(path, result, user_data); + if (_ret != WAE_ERROR_NONE) + ret = _ret; + } - if (entry.d_type == DT_DIR) { - _remove_directory(file_path_buff); - } else { - WAE_SLOGD("remove file(%s)", file_path_buff); - _remove_file(file_path_buff); - } + closedir(dir); + return ret; +} + +static void _remove_file(const char *path) +{ + unlink(path); +} + +static int _entry_callback_remove_all( + const char *path, const struct dirent *entry, void *user_data) +{ + (void) user_data; // TODO: use UNUSED macro + + char file_path_buff[MAX_PATH_LEN] = {0, }; + if (snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", path, entry->d_name) < 0) + return WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ + + int ret = WAE_ERROR_NONE; + if (entry->d_type == DT_DIR) { + int _ret = traverse_directory(file_path_buff, _entry_callback_remove_all, NULL); + if (_ret != WAE_ERROR_NONE) + ret = _ret; + rmdir(file_path_buff); + } else { + _remove_file(file_path_buff); } + return ret; +} + +void _remove_directory(const char *path) +{ + traverse_directory(path, _entry_callback_remove_all, NULL); WAE_SLOGD("remove directory(%s)", path); - closedir(dir); rmdir(path); } int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path) { - int ret = snprintf(path, size, "%s/%s_%s.adek", - _get_dek_store_path(), APP_DEK_FILE_PFX, pkg_id); - - if (ret < 0) + if (snprintf(path, size, "%s/%s_%s.adek", + _get_dek_store_path(), APP_DEK_FILE_PFX, pkg_id) < 0) return WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ - - return WAE_ERROR_NONE; + else + return WAE_ERROR_NONE; } static int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) @@ -574,18 +600,56 @@ int _get_app_dek_kek(raw_buffer_s **pdek_kek) #endif } -int load_preloaded_app_deks() +static int _entry_callback_load_preloaded_adeks( + const char *path, const struct dirent *entry, void *prikey) { - WAE_SLOGI("load_preloaded_app_deks start"); + const char *pub_key_path = _get_dek_kek_pub_key_path(); + const char *pri_key_path = _get_dek_kek_pri_key_path(); + + char file_path_buff[MAX_PATH_LEN] = {0, }; + if (snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", path, entry->d_name) < 0) + return WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ + + if (strcmp(file_path_buff, pub_key_path) == 0 || + strcmp(file_path_buff, pri_key_path) == 0) + return WAE_ERROR_NONE; /* skip KEK files */ - int global_ret = WAE_ERROR_NONE; + if (entry->d_type != DT_REG || strstr(entry->d_name, APP_DEK_FILE_PFX) == NULL) { + if (entry->d_type == DT_DIR) + WAE_SLOGW( + "Invalid file in dek store(%s). Directory shouldn't be here.", path); + else + WAE_SLOGW( + "Invalid file in dek store(%s). " + "Not regular file or prefix(%s) is invalid.", path, APP_DEK_FILE_PFX); + + return WAE_ERROR_FILE; + } char pkg_id[MAX_PKGID_LEN] = {0, }; - char file_path_buff[MAX_PATH_LEN] = {0, }; + int ret = _extract_pkg_id_from_file_name(entry->d_name, pkg_id); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGW("Failed to extract pkgid from file(%s). It will be ignored.", file_path_buff); + return ret; + } + + ret = _load_preloaded_app_dek((raw_buffer_s *)prikey, file_path_buff, pkg_id); + if (ret == WAE_ERROR_NONE || ret == WAE_ERROR_KEY_EXISTS) { + WAE_SLOGI("Successfully load app dek(%s)", file_path_buff); + return WAE_ERROR_NONE; + } else { + WAE_SLOGW("Failed to load app dek(%s) ret(%d)", file_path_buff, ret); + return ret; + } +} + +int load_preloaded_app_deks() +{ + WAE_SLOGI("load_preloaded_app_deks start"); + + int ret = WAE_ERROR_NONE; const char *dek_store_path = _get_dek_store_path(); - const char *dek_kek_pub_key_path = _get_dek_kek_pub_key_path(); - const char *dek_kek_pri_key_path = _get_dek_kek_pri_key_path(); raw_buffer_s *prikey = NULL; DIR *dir = NULL; @@ -602,86 +666,24 @@ int load_preloaded_app_deks() return WAE_ERROR_NONE; } else { WAE_SLOGE("Fail to open dir. dir=%s", dek_store_path); - global_ret = WAE_ERROR_FILE; + ret = WAE_ERROR_FILE; goto out; } } - global_ret = _get_app_dek_kek(&prikey); - - if (global_ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); + ret = _get_app_dek_kek(&prikey); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Fail to get APP_DEK_KEK Private Key. ret(%d)", ret); goto out; } - struct dirent entry; - struct dirent *result = NULL; - - while (true) { - int ret = WAE_ERROR_NONE; - if (readdir_r(dir, &entry, &result) != 0) { - global_ret = WAE_ERROR_FILE; - break; - } - - // readdir_r returns NULL in *result if the end - // of the directory stream is reached - if (result == NULL) - break; - - if (strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0) - continue; - - if (snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", - dek_store_path, entry.d_name) < 0) { - WAE_SLOGE("Failed to make file path by snprintf."); - global_ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ - break; - } - - // skip for KEKs. They'll be deleted after all akek loaded to key-manager. - if (strcmp(file_path_buff, dek_kek_pub_key_path) == 0 || - strcmp(file_path_buff, dek_kek_pri_key_path) == 0) { - WAE_SLOGD("Skip KEK file...(%s)", file_path_buff); - continue; - } - - // regular file && start with KEY_MANAGER_INITIAL_VALUE_FILE_PFX - // clear all invalid cases silently - if (entry.d_type != DT_REG || strstr(entry.d_name, APP_DEK_FILE_PFX) == NULL) { - if (entry.d_type == DT_DIR) { - WAE_SLOGW( - "Invalid file in dek store(%s). Directory shouldn't be here.", - dek_store_path); - global_ret = WAE_ERROR_FILE; - } else { - WAE_SLOGW( - "Invalid file in dek store(%s). " - "Not regular file or prefix(%s) is invalid.", - dek_store_path, APP_DEK_FILE_PFX); - global_ret = WAE_ERROR_FILE; - } - - continue; - } - - ret = _extract_pkg_id_from_file_name(entry.d_name, pkg_id); - - if (ret != WAE_ERROR_NONE) { - WAE_SLOGW("Failed to extract pkgid from file. It will be ignored. file=%s", - file_path_buff); - global_ret = ret; - continue; - } + // close dek store dir fd not to affect the traverse_directory call + closedir(dir); + dir = NULL; - ret = _load_preloaded_app_dek(prikey, file_path_buff, pkg_id); - if (ret != WAE_ERROR_NONE && ret != WAE_ERROR_KEY_EXISTS) { - WAE_SLOGW("Failed to load app dek(%s) ret(%d)", file_path_buff, ret); - global_ret = ret; - } else { - WAE_SLOGI("Successfully load app dek(%s)", file_path_buff); - } - } + ret = traverse_directory(dek_store_path, _entry_callback_load_preloaded_adeks, prikey); + if (ret != WAE_ERROR_NONE) + WAE_SLOGE("Fail when traverse dek store directory. ret(%d)", ret); out: if (prikey != NULL) @@ -699,7 +701,7 @@ out: // initializer service failure. _remove_directory(dek_store_path); - return global_ret; + return ret; } int remove_app_ce(uid_t uid, const char *pkg_id, wae_app_type_e app_type) -- 2.7.4 From 66e03d5f1993d5bdf9c0c0b778afdf99eefff847 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Tue, 20 Dec 2016 19:49:27 +0900 Subject: [PATCH 11/16] Replace deprecated readdir_r with readdir Change-Id: Ic5649cafedfcb3a91c839c33f261c6da7475a9a9 Signed-off-by: Kyungwook Tak --- srcs/key_handler.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index cdc96af..c5a2f95 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -207,15 +208,15 @@ static int traverse_directory(const char *path, entry_callback ecb, void *user_d } int ret = WAE_ERROR_NONE; - struct dirent entry; - struct dirent *result = NULL; while (true) { - if (readdir_r(dir, &entry, &result) != 0) { - WAE_SLOGE("readdir_r error on dir(%s) errno(%d)", path, errno); + errno = 0; + struct dirent *result = readdir(dir); + if (result == NULL) { + if (errno != 0) + WAE_SLOGE("readdir error on dir(%s) errno(%d)", path, errno); break; - } else if (result == NULL) { - break; // end of directory - } else if (strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0) { + } else if (strcmp(result->d_name, ".") == 0 || + strcmp(result->d_name, "..") == 0) { continue; } -- 2.7.4 From 0eecf5c7803707224969d71a7ca3c06838b787bd Mon Sep 17 00:00:00 2001 From: "sangwan.kwon" Date: Fri, 12 May 2017 14:11:02 +0900 Subject: [PATCH 12/16] Fix log fomatter according to boost version upgrade Change-Id: I45ebc7ad1e47ae1c6be71be50a50d5ad4a1330c9 Signed-off-by: sangwan.kwon --- tests/colour_log_formatter.cpp | 112 ++++++++++++++++++++++++++++++++++++----- tests/colour_log_formatter.h | 10 ++++ tests/test-helper.h | 5 ++ 3 files changed, 115 insertions(+), 12 deletions(-) diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp index 50bd43c..087951f 100644 --- a/tests/colour_log_formatter.cpp +++ b/tests/colour_log_formatter.cpp @@ -14,7 +14,12 @@ #include #include +#include +#if BOOST_VERSION >= 105900 +#include +#else #include +#endif #include #include #include @@ -37,11 +42,29 @@ const char *BOLD_YELLOW_BEGIN = "\033[1;33m"; const char *COLOR_END = "\033[m"; const_string +test_unit_type_name(const test_unit &tu) +{ +#if BOOST_VERSION >= 105900 + return const_string(tu.p_type_name); +#else + return tu.p_type_name.get(); +#endif +} + +const_string +test_unit_name(const test_unit &tu) +{ +#if BOOST_VERSION >= 105900 + return const_string(tu.p_name); +#else + return tu.p_name.get(); +#endif +} + +const_string test_phase_identifier() { - return framework::is_initialized() - ? const_string(framework::current_test_case().p_name.get()) - : BOOST_TEST_L("Test setup"); + return test_unit_name(framework::current_test_case()); } const_string @@ -56,6 +79,12 @@ get_basename(const std::string &file_name) return basename(file_name.c_str()); } +bool +test_unit_type_name_contains(const test_unit &tu, const std::string &substr) +{ + return test_unit_type_name(tu).find(const_string(substr)) == 0; +} + } // local namespace //____________________________________________________________________________// @@ -98,11 +127,12 @@ colour_log_formatter::test_unit_start( std::ostream &output, test_unit const &tu) { - if (tu.p_type_name->find(const_string("suite")) == 0) - output << "Starting test " << tu.p_type_name << " \"" << tu.p_name << "\"" << - std::endl; - else - output << "Running test " << tu.p_type_name << " \"" << tu.p_name << "\"" << + if (test_unit_type_name_contains(tu, "suite")) { + output << "Starting test "; + } else { + output << "Running test "; + } + output << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"" << std::endl; } @@ -114,8 +144,8 @@ colour_log_formatter::test_unit_finish( test_unit const &tu, unsigned long elapsed) { - if (tu.p_type_name->find(const_string("suite")) == 0) { - output << "Finished test " << tu.p_type_name << " \"" << tu.p_name << "\"" << + if (test_unit_type_name_contains(tu, "suite")) { + output << "Finished test " << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"" << std::endl; return; } @@ -152,8 +182,8 @@ colour_log_formatter::test_unit_skipped( std::ostream &output, test_unit const &tu) { - output << "Test " << tu.p_type_name << " \"" << tu.p_name << "\"" << - "is skipped" << std::endl; + output << "Test " << test_unit_type_name(tu) << " \"" << test_unit_name(tu) + << "\"" << "is skipped" << std::endl; } //____________________________________________________________________________// @@ -187,6 +217,41 @@ colour_log_formatter::log_exception( m_isTestCaseFailed = true; } +void +colour_log_formatter::log_exception_start( + std::ostream &output, + log_checkpoint_data const &checkpoint_data, + boost::execution_exception const &ex) +{ + boost::execution_exception::location const &loc = ex.where(); + output << '\t' << BOLD_YELLOW_BEGIN << get_basename(loc.m_file_name) + << '(' << loc.m_line_num << "), "; + + output << "fatal error in \"" + << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function) << + "\": "; + + output << COLOR_END << ex.what(); + + if (!checkpoint_data.m_file_name.is_empty()) { + output << '\n'; + output << "\tlast checkpoint : " << get_basename(checkpoint_data.m_file_name) + << '(' << checkpoint_data.m_line_num << ")"; + + if (!checkpoint_data.m_message.empty()) + output << ": " << checkpoint_data.m_message; + } + + output << std::endl; + m_isTestCaseFailed = true; +} + +void +colour_log_formatter::log_exception_finish(std::ostream &os) +{ + os.flush(); +} + //____________________________________________________________________________// void @@ -260,6 +325,29 @@ colour_log_formatter::log_entry_finish( //____________________________________________________________________________// +void +colour_log_formatter::entry_context_start( + std::ostream& output, + boost::unit_test::log_level l) +{ + output << (l == log_successful_tests ? "\nAssertion" : "\nFailure") + << " occurred in a following context:"; +} + +void +colour_log_formatter::log_entry_context( + std::ostream& output, + boost::unit_test::const_string value) +{ + output << "\n " << value; +} + +void +colour_log_formatter::entry_context_finish(std::ostream& output) +{ + output.flush(); +} + //____________________________________________________________________________// } // namespace Test } // namespace Wae diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h index 7c5dee3..968f6be 100644 --- a/tests/colour_log_formatter.h +++ b/tests/colour_log_formatter.h @@ -41,6 +41,11 @@ public: std::ostream &, boost::unit_test::log_checkpoint_data const &, boost::execution_exception const &ex); + void log_exception_start( + std::ostream &, + boost::unit_test::log_checkpoint_data const &, + boost::execution_exception const &ex); + void log_exception_finish(std::ostream &os); void log_entry_start( std::ostream &, @@ -54,6 +59,11 @@ public: boost::unit_test::lazy_ostream const &value); void log_entry_finish(std::ostream &); + void entry_context_start(std::ostream& os, boost::unit_test::log_level l); + void log_entry_context(std::ostream& os, + boost::unit_test::const_string value); + void entry_context_finish(std::ostream& os); + private: bool m_isTestCaseFailed; }; diff --git a/tests/test-helper.h b/tests/test-helper.h index cd2fae2..8ec45c0 100644 --- a/tests/test-helper.h +++ b/tests/test-helper.h @@ -22,6 +22,11 @@ #include "types.h" +#ifndef BOOST_MESSAGE +#include +#define BOOST_MESSAGE(x) std::cout << x << std::endl; +#endif + namespace Wae { namespace Test { -- 2.7.4 From 84c60acc6b62da2e0c34e3e5c87f619c9ff34c14 Mon Sep 17 00:00:00 2001 From: "sangwan.kwon" Date: Tue, 16 May 2017 19:19:13 +0900 Subject: [PATCH 13/16] Upgrade version to 0.1.1 Change-Id: I8d042124bd7bed693c9914ac1aec10c21a606235 Signed-off-by: sangwan.kwon --- packaging/libwebappenc.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index 4184b84..101e64b 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -1,6 +1,6 @@ Name: libwebappenc Summary: Web application encryption service -Version: 0.1.0 +Version: 0.1.1 Release: 1 Group: Security/Libraries License: Apache-2.0 and BSL-1.0 -- 2.7.4 From 7b017af752c4d75065871fa732259ee0a08ae57a Mon Sep 17 00:00:00 2001 From: "sangwan.kwon" Date: Fri, 30 Jun 2017 17:01:59 +0900 Subject: [PATCH 14/16] Fix upgrade script number * Accordig to OS upgrade team's guide, this script would be run as 240. Change-Id: I96d0a68915acc21cf82f48ff5704fc11a1989653 Signed-off-by: sangwan.kwon (cherry picked from commit ec1709d20c9c6a243f1b2b1976819e4017601c18) --- packaging/libwebappenc.spec | 2 +- scripts/{200.wae.sh.in => 240.wae.sh.in} | 2 +- scripts/CMakeLists.txt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename scripts/{200.wae.sh.in => 240.wae.sh.in} (97%) diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index 101e64b..94dd937 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -103,7 +103,7 @@ fi %dir %attr(770, %user_name, %group_name) %{rw_share_dir}/wae/app_dek %attr(660, %user_name, %group_name) %{rw_share_dir}/wae/app_dek/* -%attr(775,root,root) %{upgrade_script_dir}/200.wae.sh +%attr(775,root,root) %{upgrade_script_dir}/240.wae.sh %{upgrade_data_dir}/wae/app_dek/* %files devel diff --git a/scripts/200.wae.sh.in b/scripts/240.wae.sh.in similarity index 97% rename from scripts/200.wae.sh.in rename to scripts/240.wae.sh.in index 29d9497..68f99f9 100755 --- a/scripts/200.wae.sh.in +++ b/scripts/240.wae.sh.in @@ -15,7 +15,7 @@ PATH=/bin:/usr/bin:/sbin:/usr/sbin # See the License for the specific language governing permissions and # limitations under the License. # -# @file 200.wae.sh.in +# @file 240.wae.sh.in # @author Kyungwook Tak (k.tak@samsung.com) # @brief Platform upgrade support diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index f4098fc..0920103 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -12,5 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. # -CONFIGURE_FILE(200.wae.sh.in 200.wae.sh @ONLY) -INSTALL(FILES 200.wae.sh DESTINATION ${UPGRADE_SCRIPT_DIR}) +CONFIGURE_FILE(240.wae.sh.in 240.wae.sh @ONLY) +INSTALL(FILES 240.wae.sh DESTINATION ${UPGRADE_SCRIPT_DIR}) -- 2.7.4 From bb1d90909f7185b436204a1fde5da99a902788c1 Mon Sep 17 00:00:00 2001 From: "sangwan.kwon" Date: Thu, 17 Aug 2017 05:13:57 -0400 Subject: [PATCH 15/16] Remove deprecated upgrade script Change-Id: I8907a60bb513edd1021b510c37be64f6d37c3caf Signed-off-by: sangwan.kwon --- CMakeLists.txt | 1 - packaging/libwebappenc.spec | 8 -------- resources/CMakeLists.txt | 8 -------- scripts/240.wae.sh.in | 30 ------------------------------ scripts/CMakeLists.txt | 16 ---------------- 5 files changed, 63 deletions(-) delete mode 100755 scripts/240.wae.sh.in delete mode 100644 scripts/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 96efdbe..436eb74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,4 +93,3 @@ ADD_SUBDIRECTORY(resources) ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(systemd) -ADD_SUBDIRECTORY(scripts) diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index 94dd937..8db7728 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -42,9 +42,6 @@ Web application encryption and decryption service (test) %define smack_domain System %define bin_dir %TZ_SYS_BIN %define rw_share_dir %TZ_SYS_SHARE -%define upgrade_dir %TZ_SYS_RO_SHARE/upgrade -%define upgrade_script_dir %{upgrade_dir}/scripts -%define upgrade_data_dir %{upgrade_dir}/data %prep %setup -q @@ -58,8 +55,6 @@ Web application encryption and decryption service (test) -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DCMAKE_BUILD_TYPE=%{build_type} \ -DRW_SHARE_DIR=%rw_share_dir \ - -DUPGRADE_DATA_DIR=%upgrade_data_dir \ - -DUPGRADE_SCRIPT_DIR=%upgrade_script_dir \ -DUSER_NAME=%user_name \ -DGROUP_NAME=%group_name \ -DSMACK_DOMAIN=%smack_domain \ @@ -103,9 +98,6 @@ fi %dir %attr(770, %user_name, %group_name) %{rw_share_dir}/wae/app_dek %attr(660, %user_name, %group_name) %{rw_share_dir}/wae/app_dek/* -%attr(775,root,root) %{upgrade_script_dir}/240.wae.sh -%{upgrade_data_dir}/wae/app_dek/* - %files devel %{_includedir}/* %{_libdir}/pkgconfig/%{name}.pc diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 030553c..ffc566e 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -23,11 +23,3 @@ INSTALL(FILES PERMISSIONS OWNER_READ OWNER_WRITE ) - -INSTALL(FILES - WAE_APPDEK_KEK_PublicKey.pem - WAE_APPDEK_KEK_PrivateKey.pem - DESTINATION ${UPGRADE_DATA_DIR}/wae/app_dek - PERMISSIONS OWNER_READ - OWNER_WRITE -) diff --git a/scripts/240.wae.sh.in b/scripts/240.wae.sh.in deleted file mode 100755 index 68f99f9..0000000 --- a/scripts/240.wae.sh.in +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# @file 240.wae.sh.in -# @author Kyungwook Tak (k.tak@samsung.com) -# @brief Platform upgrade support - -WAE_DIR=@RW_SHARE_DIR@/wae - -cp -rf @UPGRADE_DATA_DIR@/wae $WAE_DIR - -chsmack -a "@SMACK_DOMAIN@" $WAE_DIR -r -chown -R @USER_NAME@:@GROUP_NAME@ $WAE_DIR -chmod 770 $WAE_DIR -chmod 770 $WAE_DIR/app_dek -chmod 660 $WAE_DIR/app_dek/* diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt deleted file mode 100644 index 0920103..0000000 --- a/scripts/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -CONFIGURE_FILE(240.wae.sh.in 240.wae.sh @ONLY) -INSTALL(FILES 240.wae.sh DESTINATION ${UPGRADE_SCRIPT_DIR}) -- 2.7.4 From f297606be5e13711c2889a09797413f62e146b79 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Wed, 18 Jul 2018 14:00:02 +0200 Subject: [PATCH 16/16] Adjust build to boost 1.65.0 and up Change-Id: I4f541900316f3419827fa3e3f66bcdf81e40f44e --- tests/colour_log_formatter.cpp | 15 +++++++++++++++ tests/colour_log_formatter.h | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp index 087951f..041fef8 100644 --- a/tests/colour_log_formatter.cpp +++ b/tests/colour_log_formatter.cpp @@ -348,6 +348,21 @@ colour_log_formatter::entry_context_finish(std::ostream& output) output.flush(); } +#if BOOST_VERSION >= 106500 +void +colour_log_formatter::log_entry_context(std::ostream& os, log_level l, const_string value) +{ + (void)l; + os << "\n " << value; +} +void +colour_log_formatter::entry_context_finish(std::ostream& os, log_level l) +{ + (void)l; + os.flush(); +} +#endif + //____________________________________________________________________________// } // namespace Test } // namespace Wae diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h index 968f6be..3de5899 100644 --- a/tests/colour_log_formatter.h +++ b/tests/colour_log_formatter.h @@ -63,6 +63,15 @@ public: void log_entry_context(std::ostream& os, boost::unit_test::const_string value); void entry_context_finish(std::ostream& os); +#if BOOST_VERSION >= 106500 + void log_entry_context( + std::ostream& os, + boost::unit_test::log_level l, + boost::unit_test::const_string value); + void entry_context_finish( + std::ostream& os, + boost::unit_test::log_level l); +#endif private: bool m_isTestCaseFailed; -- 2.7.4