From 4ba1b26fcea5409a5b27ab24e2f8b5dfb9f497b8 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 2 Mar 2016 20:06:36 +0900 Subject: [PATCH 01/16] Add gitignore file Change-Id: I79f9c4e40c72bcbe29fd1bb662566a7c614cb2ca Signed-off-by: Kyungwook Tak --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44d6a2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# cscope/ctag data # +#################### +/cscope.files +/cscope.out +/tags + +# Temporary files # +################### +*.swp +*~ -- 2.7.4 From b4ea2b8348e45f355cdf1140b666f0897fc63644 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 2 Mar 2016 20:13:42 +0900 Subject: [PATCH 02/16] Refine spec file - Fix groups - Remove non-used definition - Use macros Change-Id: I109ebe1280138c23bbd12f7f97e7665110cdd646 Signed-off-by: Kyungwook Tak --- LICENSE.Apache-2.0 => LICENSE | 0 packaging/libwebappenc.spec | 28 +++++----------------------- 2 files changed, 5 insertions(+), 23 deletions(-) rename LICENSE.Apache-2.0 => LICENSE (100%) diff --git a/LICENSE.Apache-2.0 b/LICENSE similarity index 100% rename from LICENSE.Apache-2.0 rename to LICENSE diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index ec61ff1..342d1f3 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -2,7 +2,7 @@ Name: libwebappenc Summary: Web application encryption service Version: 0.1.0 Release: 1 -Group: System/Libraries +Group: Security/Libraries License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1001: %{name}.manifest @@ -21,7 +21,7 @@ Web application encryption and decryption service %package devel Summary: Web application encryption service (development files) -Group: Development/Libraries +Group: Security/Development Requires: %{name} = %{version}-%{release} %description devel @@ -29,14 +29,12 @@ Web application encryption and decryption service (development files) %package test Summary: Web application encryption service (test) -Group: Development +Group: Security/Development Requires: %{name} = %{version}-%{release} %description test Web application encryption and decryption service (test) - - %prep %setup -q cp %{SOURCE1001} . @@ -50,23 +48,13 @@ cp %{SOURCE1001} . -DBINDIR=%TZ_SYS_BIN \ -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DCMAKE_BUILD_TYPE=%{build_type} \ - -DTZ_SYS_BIN=%TZ_SYS_BIN \ -DTZ_SYS_SHARE=%TZ_SYS_SHARE make %{?jobs:-j%jobs} - %install -rm -rf %{buildroot} -mkdir -p %{buildroot}%{TZ_SYS_SHARE}/license -cp LICENSE.Apache-2.0 %{buildroot}%{TZ_SYS_SHARE}/license/%{name} %make_install -mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants -ln -s ../webappenc-initializer.service %{buildroot}%{_unitdir}/multi-user.target.wants/webappenc-initializer.service - - -%clean -rm -rf %{buildroot} +%install_service multi-user.target.wants webappenc-initializer.service %post /sbin/ldconfig @@ -88,11 +76,9 @@ if [ $1 = 0 ]; then systemctl daemon-reload fi - %files -%defattr(-,root,root,-) %manifest %{name}.manifest -%{TZ_SYS_SHARE}/license/%{name} +%license LICENSE %{_libdir}/%{name}.so.* %{_unitdir}/webappenc-initializer.service %{_unitdir}/multi-user.target.wants/webappenc-initializer.service @@ -101,13 +87,9 @@ fi %{TZ_SYS_SHARE}/wae/app_dek/WAE_APPDEK_KEK_PublicKey.pem %files devel -%defattr(-,root,root,-) %{_includedir}/* %{_libdir}/pkgconfig/%{name}.pc %{_libdir}/%{name}.so %files test -%defattr(-,root,root,-) %{TZ_SYS_BIN}/wae_tests - - -- 2.7.4 From 4ac21f065674dd7c1b11a0918953fc552ec9a924 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 2 Mar 2016 20:45:52 +0900 Subject: [PATCH 03/16] Use snprintf instead of sprintf to be safe Change-Id: I664d9f039b09b576c4ebe84c29d8a7c459bc1384 Signed-off-by: Kyungwook Tak --- srcs/key_handler.c | 23 ++++++++++++++++++----- srcs/key_handler.h | 2 +- tests/wae_tests.c | 6 +++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 7c986c0..7b050d6 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -231,9 +231,16 @@ error: } -int _get_preloaded_app_dek_file_path(const char* pPkgId, char *path) +int _get_preloaded_app_dek_file_path(const char* pPkgId, size_t size, char *path) { - sprintf(path, "%s/%s_%s.adek", _get_dek_store_path(), APP_DEK_FILE_PFX, pPkgId); + int ret = -1; + + ret = snprintf(path, size, "%s/%s_%s.adek", + _get_dek_store_path(), APP_DEK_FILE_PFX, pPkgId); + + if (ret < 0) + return WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ + return WAE_ERROR_NONE; } @@ -258,14 +265,14 @@ int _extract_pkg_id_from_file_name(const char* fileName, char* pkgId) int _read_encrypted_app_dek_from_file(const char* pPkgId, unsigned char** encrypted_app_dek, size_t *len) { char path[MAX_PATH_LEN] = {0,}; - _get_preloaded_app_dek_file_path(pPkgId, path); + _get_preloaded_app_dek_file_path(pPkgId, sizeof(path), path); return _read_from_file(path, encrypted_app_dek, len); } int _write_encrypted_app_dek_to_file(const char* pPkgId, const unsigned char* encrypted_app_dek, size_t len) { char path[MAX_PATH_LEN] = {0,}; - _get_preloaded_app_dek_file_path(pPkgId, path); + _get_preloaded_app_dek_file_path(pPkgId, sizeof(path), path); return _write_to_file( path, encrypted_app_dek, len); } @@ -683,7 +690,13 @@ int load_preloaded_app_deks(int reload) // 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) { memset(file_path_buff, 0, sizeof(file_path_buff)); - sprintf(file_path_buff, "%s/%s", _get_dek_store_path(), entry.d_name); + ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", + _get_dek_store_path(), entry.d_name); + if(ret < 0) { + WAE_SLOGE("Failed to make file path by snprintf."); + ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ + goto error; + } ret = _extract_pkg_id_from_file_name(entry.d_name, pkgId); if(ret != WAE_ERROR_NONE) { diff --git a/srcs/key_handler.h b/srcs/key_handler.h index 03de1ab..a417fdd 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -61,7 +61,7 @@ const char* _get_dek_kek_pub_key_path(); const char* _get_dek_kek_pri_key_path(); const char* _get_dek_store_path(); int _add_dek_to_key_manager(const char* pPkgId, wae_app_type_e appType, const unsigned char* pDek, size_t len); -int _get_preloaded_app_dek_file_path(const char* pPkgId, char *path); +int _get_preloaded_app_dek_file_path(const char* pPkgId, size_t size, char *path); int _extract_pkg_id_from_file_name(const char* fileName, char* pkgId); int _read_encrypted_app_dek_from_file(const char* pPkgId, unsigned char** encrypted_app_dek, size_t*len); int _write_encrypted_app_dek_to_file(const char* pPkgId, const unsigned char* encrypted_app_dek, size_t len); diff --git a/tests/wae_tests.c b/tests/wae_tests.c index 631e9ea..0b584e5 100644 --- a/tests/wae_tests.c +++ b/tests/wae_tests.c @@ -430,7 +430,7 @@ int wae_tc_get_preloaded_app_dek_file_path() char path[256]; FPRINTF("...expected path : %s\n", expectedPath); - ret = _get_preloaded_app_dek_file_path(pkgId, path); + ret = _get_preloaded_app_dek_file_path(pkgId, sizeof(path), path); FPRINTF("...returned path : %s\n", path); if(ret != WAE_ERROR_NONE || strncmp(expectedPath, path, strlen(expectedPath)) != 0) { @@ -623,8 +623,8 @@ int wae_tc_load_preloaded_app_deks() char path2[MAX_PATH_LEN] = {0, }; FILE *f2 = NULL; - _get_preloaded_app_dek_file_path(pkgId1, path1); - _get_preloaded_app_dek_file_path(pkgId2, path2); + _get_preloaded_app_dek_file_path(pkgId1, sizeof(path1), path1); + _get_preloaded_app_dek_file_path(pkgId2, sizeof(path2), path2); // remove old test data remove_app_dek(pkgId1, WAE_PRELOADED_APP); -- 2.7.4 From daa79b8ea309dbf39dcd47cce82cee0e3ba1e4c9 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Fri, 11 Mar 2016 15:00:47 +0900 Subject: [PATCH 04/16] Fix SVACE defects Remove unused values in test code Handle negative return value from ftell Change-Id: I331e1335ad900ef9e5ec4523a832ec2c38dfb7f8 Signed-off-by: Kyungwook Tak --- srcs/key_handler.c | 6 ++++++ tests/wae_tests.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 7b050d6..714be0f 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -294,6 +294,12 @@ int _read_from_file(const char* path, unsigned char** data, size_t* len) fseek(f, 0, SEEK_END); // move to the end of a file file_len = ftell(f); + if (file_len <= 0) { + WAE_SLOGE("WAE: Failed to get file size by ftell. ret: %d", file_len); + ret = WAE_ERROR_FILE; + goto error; + } + fseek(f, 0, SEEK_SET); // move to the start of a file file_contents = (unsigned char*) malloc(file_len); diff --git a/tests/wae_tests.c b/tests/wae_tests.c index 0b584e5..a40b301 100644 --- a/tests/wae_tests.c +++ b/tests/wae_tests.c @@ -613,7 +613,6 @@ int wae_tc_load_preloaded_app_deks() unsigned char* readDek1 = NULL; size_t readDekLen1 = 0; char path1[MAX_PATH_LEN] = {0, }; - FILE *f1 = NULL; const char* pkgId2 = "TEST_PKGID_2"; unsigned char* dek2 = NULL; @@ -621,7 +620,6 @@ int wae_tc_load_preloaded_app_deks() unsigned char* readDek2 = NULL; size_t readDekLen2 = 0; char path2[MAX_PATH_LEN] = {0, }; - FILE *f2 = NULL; _get_preloaded_app_dek_file_path(pkgId1, sizeof(path1), path1); _get_preloaded_app_dek_file_path(pkgId2, sizeof(path2), path2); @@ -691,14 +689,10 @@ error: free(dek1); if(readDek1 != NULL) free(readDek1); - if(f1 != NULL) - fclose(f1); if(dek2 != NULL) free(dek2); if(readDek2 != NULL) free(readDek2); - if(f2 != NULL) - fclose(f2); return ret; } -- 2.7.4 From d1da2aa31e64a93d1e1f5b3c7586c6a4186df4f3 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Tue, 21 Jun 2016 13:04:32 +0900 Subject: [PATCH 05/16] change installer smack label from User to System Change-Id: I1522806cb2b7511455821134f8ae42a53a575e6e Signed-off-by: Dongsun Lee --- srcs/key_handler.c | 23 ++++++++--------------- srcs/key_handler.h | 2 +- tests/wae_tests.c | 8 ++++---- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 714be0f..4a8ee53 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -35,7 +35,7 @@ #define APP_DEK_KEK_PRIKEY_PASSWORD "wae_appdek_kek_1q2w3e4r" -#define WRT_INSTALLER_LABEL "/User" +#define WRT_INSTALLER_LABEL "/System" typedef struct _dek_cache_element{ char pkgId[MAX_PKGID_LEN]; @@ -139,22 +139,15 @@ int _get_random(size_t length, unsigned char* random) return WAE_ERROR_NONE; } -void _get_alias(const char* pPkgId, wae_app_type_e appType, int forSave, char* alias, size_t buff_len) +void _get_alias(const char* pPkgId, wae_app_type_e appType, char* alias, size_t buff_len) { if(appType == WAE_DOWNLOADED_NORMAL_APP) { - if(forSave == WAE_TRUE) { - snprintf(alias, buff_len, "%s%s", - APP_DEK_ALIAS_PFX, - pPkgId); - }else{ - snprintf(alias, buff_len, "%s%s%s%s", + snprintf(alias, buff_len, "%s%s%s%s", WRT_INSTALLER_LABEL, ckmc_owner_id_separator, APP_DEK_ALIAS_PFX, pPkgId); - } }else { // system alias - (void) appType; snprintf(alias, buff_len, "%s%s%s%s", ckmc_owner_id_system, ckmc_owner_id_separator, @@ -208,7 +201,7 @@ int _add_dek_to_key_manager(const char* pPkgId, wae_app_type_e appType, const un policy.extractable = true; // save app_dek in key_manager - _get_alias(pPkgId, appType, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pPkgId, appType, alias, sizeof(alias)); // even if it fails to remove, ignore it. ret = _to_wae_error( ckmc_remove_alias(alias)); @@ -367,12 +360,12 @@ int get_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDe cached_dek = _get_app_dek_from_cache(pPkgId); if(cached_dek == NULL) { // get APP_DEK from system database - _get_alias(pPkgId, appType, WAE_FALSE, alias, sizeof(alias)); + _get_alias(pPkgId, appType, alias, sizeof(alias)); ret = _to_wae_error(ckmc_get_data(alias, password, &pDekBuffer)); if(ret != WAE_ERROR_NONE) { - WAE_SLOGI("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", - pPkgId, alias, ret); + WAE_SLOGI("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, appType=%d, ret=%d", + pPkgId, alias, appType, ret); goto error; } } @@ -765,7 +758,7 @@ int remove_app_dek(const char* pPkgId, wae_app_type_e appType) int ret = CKMC_ERROR_NONE; char alias[MAX_ALIAS_LEN] = {0,}; - _get_alias(pPkgId, appType, WAE_TRUE, alias,sizeof(alias)); + _get_alias(pPkgId, appType, alias,sizeof(alias)); ret = _to_wae_error(ckmc_remove_alias(alias)); if(ret != WAE_ERROR_NONE) { diff --git a/srcs/key_handler.h b/srcs/key_handler.h index a417fdd..a8e4012 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -54,7 +54,7 @@ unsigned char* _get_app_dek_from_cache(const char* pkgId); void _add_app_dek_to_cache(const char* pkgId, unsigned char* dek); void _remove_app_dek_from_cache(const char* pkgId); int _get_random(size_t length, unsigned char* random); -void _get_alias(const char* pPkgId, wae_app_type_e appType, int forSave, char* alias, size_t buff_len); +void _get_alias(const char* pPkgId, wae_app_type_e appType, char* alias, size_t buff_len); void _get_dek_kek_alias(char* alias, size_t buff_len); void _get_dek_loading_done_alias(char* alias, size_t buff_len); const char* _get_dek_kek_pub_key_path(); diff --git a/tests/wae_tests.c b/tests/wae_tests.c index a40b301..eb90bdf 100644 --- a/tests/wae_tests.c +++ b/tests/wae_tests.c @@ -336,16 +336,16 @@ int wae_tc_get_alias() const char* pkgId = "TEST_PKG_ID"; char alias[256] = {0, }; - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for normal for save. app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, WAE_FALSE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for normal for get. app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_DOWNLOADED_GLOBAL_APP, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_GLOBAL_APP, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for global app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_PRELOADED_APP, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_PRELOADED_APP, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for preloaded app=%s\n", pkgId, alias); return ret; -- 2.7.4 From 6f18da83631e06509b2f14a729c7b6ac05aa4046 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Mon, 27 Jun 2016 10:09:00 +0900 Subject: [PATCH 06/16] Revert "change installer smack label from User to System" This reverts commit d1da2aa31e64a93d1e1f5b3c7586c6a4186df4f3. The smack labels of xxx-backend was changed into User label again. Change-Id: Ic50ef8739d9e39914d518d1e063eec9a62a7831d --- srcs/key_handler.c | 23 +++++++++++++++-------- srcs/key_handler.h | 2 +- tests/wae_tests.c | 8 ++++---- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 4a8ee53..714be0f 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -35,7 +35,7 @@ #define APP_DEK_KEK_PRIKEY_PASSWORD "wae_appdek_kek_1q2w3e4r" -#define WRT_INSTALLER_LABEL "/System" +#define WRT_INSTALLER_LABEL "/User" typedef struct _dek_cache_element{ char pkgId[MAX_PKGID_LEN]; @@ -139,15 +139,22 @@ int _get_random(size_t length, unsigned char* random) return WAE_ERROR_NONE; } -void _get_alias(const char* pPkgId, wae_app_type_e appType, char* alias, size_t buff_len) +void _get_alias(const char* pPkgId, wae_app_type_e appType, int forSave, char* alias, size_t buff_len) { if(appType == WAE_DOWNLOADED_NORMAL_APP) { - snprintf(alias, buff_len, "%s%s%s%s", + if(forSave == WAE_TRUE) { + snprintf(alias, buff_len, "%s%s", + APP_DEK_ALIAS_PFX, + pPkgId); + }else{ + snprintf(alias, buff_len, "%s%s%s%s", WRT_INSTALLER_LABEL, ckmc_owner_id_separator, APP_DEK_ALIAS_PFX, pPkgId); + } }else { // system alias + (void) appType; snprintf(alias, buff_len, "%s%s%s%s", ckmc_owner_id_system, ckmc_owner_id_separator, @@ -201,7 +208,7 @@ int _add_dek_to_key_manager(const char* pPkgId, wae_app_type_e appType, const un policy.extractable = true; // save app_dek in key_manager - _get_alias(pPkgId, appType, alias, sizeof(alias)); + _get_alias(pPkgId, appType, WAE_TRUE, alias, sizeof(alias)); // even if it fails to remove, ignore it. ret = _to_wae_error( ckmc_remove_alias(alias)); @@ -360,12 +367,12 @@ int get_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDe cached_dek = _get_app_dek_from_cache(pPkgId); if(cached_dek == NULL) { // get APP_DEK from system database - _get_alias(pPkgId, appType, alias, sizeof(alias)); + _get_alias(pPkgId, appType, WAE_FALSE, alias, sizeof(alias)); ret = _to_wae_error(ckmc_get_data(alias, password, &pDekBuffer)); if(ret != WAE_ERROR_NONE) { - WAE_SLOGI("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, appType=%d, ret=%d", - pPkgId, alias, appType, ret); + WAE_SLOGI("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", + pPkgId, alias, ret); goto error; } } @@ -758,7 +765,7 @@ int remove_app_dek(const char* pPkgId, wae_app_type_e appType) int ret = CKMC_ERROR_NONE; char alias[MAX_ALIAS_LEN] = {0,}; - _get_alias(pPkgId, appType, alias,sizeof(alias)); + _get_alias(pPkgId, appType, WAE_TRUE, alias,sizeof(alias)); ret = _to_wae_error(ckmc_remove_alias(alias)); if(ret != WAE_ERROR_NONE) { diff --git a/srcs/key_handler.h b/srcs/key_handler.h index a8e4012..a417fdd 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -54,7 +54,7 @@ unsigned char* _get_app_dek_from_cache(const char* pkgId); void _add_app_dek_to_cache(const char* pkgId, unsigned char* dek); void _remove_app_dek_from_cache(const char* pkgId); int _get_random(size_t length, unsigned char* random); -void _get_alias(const char* pPkgId, wae_app_type_e appType, char* alias, size_t buff_len); +void _get_alias(const char* pPkgId, wae_app_type_e appType, int forSave, char* alias, size_t buff_len); void _get_dek_kek_alias(char* alias, size_t buff_len); void _get_dek_loading_done_alias(char* alias, size_t buff_len); const char* _get_dek_kek_pub_key_path(); diff --git a/tests/wae_tests.c b/tests/wae_tests.c index eb90bdf..a40b301 100644 --- a/tests/wae_tests.c +++ b/tests/wae_tests.c @@ -336,16 +336,16 @@ int wae_tc_get_alias() const char* pkgId = "TEST_PKG_ID"; char alias[256] = {0, }; - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, WAE_TRUE, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for normal for save. app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, WAE_FALSE, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for normal for get. app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_DOWNLOADED_GLOBAL_APP, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_GLOBAL_APP, WAE_TRUE, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for global app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_PRELOADED_APP, alias, sizeof(alias)); + _get_alias(pkgId, WAE_PRELOADED_APP, WAE_TRUE, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for preloaded app=%s\n", pkgId, alias); return ret; -- 2.7.4 From 4ea2f0ebe530415109e408cb96f81cc0a0b6b3f7 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Fri, 15 Jul 2016 11:52:13 +0900 Subject: [PATCH 07/16] Use stdbool instead of macro for boolean Change-Id: I6d95a582cd8d2ec52adb314a167bd42dd386ac0b Signed-off-by: Kyungwook Tak --- CMakeLists.txt | 8 ++++---- srcs/CMakeLists.txt | 1 + srcs/crypto_service.c | 11 +++++------ srcs/crypto_service.h | 12 ++++-------- srcs/key_handler.c | 36 +++++++++++++++++++++++------------- srcs/key_handler.h | 33 ++++++++------------------------- srcs/wae_initializer.c | 5 +++-- tests/wae_tests.c | 12 ++++++------ 8 files changed, 54 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9fec0e..31e000b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,13 +31,13 @@ INCLUDE(FindPkgConfig) ############################# compiler flags ################################## -SET(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_C_FLAGS_PROFILING "-g -std=c99 -O0 -pg -Wp,-U_FORTIFY_SOURCE") SET(CMAKE_CXX_FLAGS_PROFILING "-g -std=c++0x -O0 -pg -Wp,-U_FORTIFY_SOURCE") -SET(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_C_FLAGS_DEBUG "-g -std=c99 -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") SET(CMAKE_CXX_FLAGS_DEBUG "-g -std=c++0x -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") -SET(CMAKE_C_FLAGS_RELEASE "-g -O2") +SET(CMAKE_C_FLAGS_RELEASE "-g -std=c99 -O2") SET(CMAKE_CXX_FLAGS_RELEASE "-g -std=c++0x -O2") -SET(CMAKE_C_FLAGS_CCOV "-g -O2 --coverage") +SET(CMAKE_C_FLAGS_CCOV "-g -std=c99 -O2 --coverage") SET(CMAKE_CXX_FLAGS_CCOV "-g -std=c++0x -O2 --coverage") # If supported for the target machine, emit position-independent code,suitable diff --git a/srcs/CMakeLists.txt b/srcs/CMakeLists.txt index e94a7d4..9eb766c 100644 --- a/srcs/CMakeLists.txt +++ b/srcs/CMakeLists.txt @@ -18,6 +18,7 @@ ADD_LIBRARY(${TARGET_WEBAPPENC} SHARED ${WEB_APP_ENC_SOURCES}) SET_TARGET_PROPERTIES(${TARGET_WEBAPPENC} PROPERTIES SOVERSION ${SO_VERSION} VERSION ${VERSION} + COMPILE_FLAGS "-D_GNU_SOURCE" ) TARGET_LINK_LIBRARIES(${TARGET_WEBAPPENC} diff --git a/srcs/crypto_service.c b/srcs/crypto_service.c index eb1fc20..1c52cc5 100644 --- a/srcs/crypto_service.c +++ b/srcs/crypto_service.c @@ -19,7 +19,9 @@ * @version 1.0 * @brief provides encryption and decription operations. */ +#include "crypto_service.h" +#include #include #include #include @@ -34,20 +36,17 @@ #define AES_256_KEY_SIZE 32 -#define WAE_FALSE 0 -#define WAE_TRUE 1 - static unsigned char AES_CBC_IV[16] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; -static int __initialized = WAE_FALSE; +static bool __initialized = false; void _initialize() { - if(__initialized != WAE_TRUE) { + if(!__initialized) { ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); - __initialized = WAE_TRUE; + __initialized = true; } } diff --git a/srcs/crypto_service.h b/srcs/crypto_service.h index c49c34b..fcdb0fe 100644 --- a/srcs/crypto_service.h +++ b/srcs/crypto_service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -17,11 +17,8 @@ * @file crypto_service.h * @author Dongsun Lee (ds73.lee@samsung.com) * @version 1.0 - * @brief a header for key manupulatation. + * @brief provides encryption and decription operations. */ - - - #ifndef __TIZEN_CORE_WAE_CRYPTO_SERVICE_H #define __TIZEN_CORE_WAE_CRYPTO_SERVICE_H @@ -31,9 +28,8 @@ extern "C" { #include - int encrypt_app_dek(const unsigned char* rsaPublicKey, size_t pubKeyLen, - const unsigned char* dek, const int dekLen, + const unsigned char* dek, size_t dekLen, unsigned char** encryptedDek, size_t* encryptedDekLen); int decrypt_app_dek(const unsigned char* rsaPrivateKey, size_t priKeyLen, @@ -53,5 +49,5 @@ int decrypt_aes_cbc(const unsigned char* pKey, size_t keyLen, #ifdef __cplusplus } #endif -#endif /* __TIZEN_CORE_WAE_CRYPTO_SERVICE_H */ +#endif /* __TIZEN_CORE_WAE_CRYPTO_SERVICE_H */ diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 714be0f..bf98c5d 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -17,25 +17,35 @@ * @file key_handler.c * @author Dongsun Lee (ds73.lee@samsung.com) * @version 1.0 - * @brief a header for key manupulatation. + * @brief Key manupulatation. */ +#include "key_handler.h" #include #include #include #include #include + #include +#include + #include "wae_log.h" #include "web_app_enc.h" -#include "key_handler.h" #include "crypto_service.h" -#include - +#define RANDOM_FILE "/dev/urandom" +#define WRT_INSTALLER_LABEL "/User" #define APP_DEK_KEK_PRIKEY_PASSWORD "wae_appdek_kek_1q2w3e4r" +#define APP_DEK_ALIAS_PFX "APP_DEK_" +#define APP_DEK_LOADING_DONE_ALIAS "APP_DEKS_LOADING_FINISHED" +#define APP_DEK_FILE_PFX "WAE_APP_DEK" +#define APP_DEK_KEK_ALIAS "WAE_APP_DEK_KEK" -#define WRT_INSTALLER_LABEL "/User" +#define DEK_LEN 32 +#define MAX_ALIAS_LEN 256 +#define MAX_PKGID_LEN 256 +#define MAX_CACHE_SIZE 100 typedef struct _dek_cache_element{ char pkgId[MAX_PKGID_LEN]; @@ -139,10 +149,10 @@ int _get_random(size_t length, unsigned char* random) return WAE_ERROR_NONE; } -void _get_alias(const char* pPkgId, wae_app_type_e appType, int forSave, char* alias, size_t buff_len) +void _get_alias(const char* pPkgId, wae_app_type_e appType, bool forSave, char* alias, size_t buff_len) { if(appType == WAE_DOWNLOADED_NORMAL_APP) { - if(forSave == WAE_TRUE) { + if(forSave) { snprintf(alias, buff_len, "%s%s", APP_DEK_ALIAS_PFX, pPkgId); @@ -208,7 +218,7 @@ int _add_dek_to_key_manager(const char* pPkgId, wae_app_type_e appType, const un policy.extractable = true; // save app_dek in key_manager - _get_alias(pPkgId, appType, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pPkgId, appType, true, alias, sizeof(alias)); // even if it fails to remove, ignore it. ret = _to_wae_error( ckmc_remove_alias(alias)); @@ -367,7 +377,7 @@ int get_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDe cached_dek = _get_app_dek_from_cache(pPkgId); if(cached_dek == NULL) { // get APP_DEK from system database - _get_alias(pPkgId, appType, WAE_FALSE, alias, sizeof(alias)); + _get_alias(pPkgId, appType, false, alias, sizeof(alias)); ret = _to_wae_error(ckmc_get_data(alias, password, &pDekBuffer)); if(ret != WAE_ERROR_NONE) { @@ -641,7 +651,7 @@ int _clear_app_deks_loaded() return ret; } -int load_preloaded_app_deks(int reload) +int load_preloaded_app_deks(bool reload) { int ret = WAE_ERROR_NONE; @@ -661,7 +671,7 @@ int load_preloaded_app_deks(int reload) int error_during_loading = 0; - if(reload != WAE_TRUE) { + if(!reload) { // check if all deks were already loaded into key-manager. ret = _get_app_deks_loaded(); if(ret == WAE_ERROR_NONE) { @@ -765,7 +775,7 @@ int remove_app_dek(const char* pPkgId, wae_app_type_e appType) int ret = CKMC_ERROR_NONE; char alias[MAX_ALIAS_LEN] = {0,}; - _get_alias(pPkgId, appType, WAE_TRUE, alias,sizeof(alias)); + _get_alias(pPkgId, appType, true, alias,sizeof(alias)); ret = _to_wae_error(ckmc_remove_alias(alias)); if(ret != WAE_ERROR_NONE) { diff --git a/srcs/key_handler.h b/srcs/key_handler.h index a417fdd..2d3af65 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -17,11 +17,8 @@ * @file key_handler.h * @author Dongsun Lee (ds73.lee@samsung.com) * @version 1.0 - * @brief a header for key manupulatation. + * @brief Key manupulatation. */ - - - #ifndef __TIZEN_CORE_WAE_KEY_HANDLER_H #define __TIZEN_CORE_WAE_KEY_HANDLER_H @@ -29,32 +26,19 @@ extern "C" { #endif +#include #include #include "web_app_enc.h" -#define APP_DEK_ALIAS_PFX "APP_DEK_" -#define APP_DEK_LOADING_DONE_ALIAS "APP_DEKS_LOADING_FINISHED" - -#define DEK_LEN 32 -#define MAX_ALIAS_LEN 256 -#define MAX_PKGID_LEN 256 #define MAX_PATH_LEN 512 -#define MAX_CACHE_SIZE 100 - - -#define RANDOM_FILE "/dev/urandom" -#define APP_DEK_FILE_PFX "WAE_APP_DEK" -#define APP_DEK_KEK_ALIAS "WAE_APP_DEK_KEK" - -#define WAE_TRUE 1 -#define WAE_FALSE 0 +/* functions with "_" prefix are internal static functions but declared here for testing */ void _initialize_cache(); unsigned char* _get_app_dek_from_cache(const char* pkgId); void _add_app_dek_to_cache(const char* pkgId, unsigned char* dek); void _remove_app_dek_from_cache(const char* pkgId); int _get_random(size_t length, unsigned char* random); -void _get_alias(const char* pPkgId, wae_app_type_e appType, int forSave, char* alias, size_t buff_len); +void _get_alias(const char* pPkgId, wae_app_type_e appType, bool forSave, char* alias, size_t buff_len); void _get_dek_kek_alias(char* alias, size_t buff_len); void _get_dek_loading_done_alias(char* alias, size_t buff_len); const char* _get_dek_kek_pub_key_path(); @@ -67,21 +51,20 @@ int _read_encrypted_app_dek_from_file(const char* pPkgId, unsigned char** encryp int _write_encrypted_app_dek_to_file(const char* pPkgId, const unsigned char* encrypted_app_dek, size_t len); int _read_from_file(const char* path, unsigned char** data, size_t* len); int _write_to_file(const char* path, const unsigned char* data, size_t len); -int _get_app_dek_kek_from_key_manager(unsigned char** ppDekKek, size_t* kekLen); int _get_app_deks_loaded(); int _set_app_deks_loaded(); int _clear_app_deks_loaded(); +/* functions for interface */ int get_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDek, size_t *dekLen); int create_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDek, size_t *dekLen); int get_preloaded_app_dek(const char* pPkgId, unsigned char** ppDek, size_t* dekLen); int create_preloaded_app_dek(const char* pPkgId, unsigned char** ppDek, size_t *dekLen); -int load_preloaded_app_deks(int reload); +int load_preloaded_app_deks(bool reload); int remove_app_dek(const char* pPkgId, wae_app_type_e appType); - #ifdef __cplusplus } #endif -#endif /* __TIZEN_CORE_WAE_KEY_HANDLER_H */ +#endif /* __TIZEN_CORE_WAE_KEY_HANDLER_H */ diff --git a/srcs/wae_initializer.c b/srcs/wae_initializer.c index 011c8a0..4022f48 100644 --- a/srcs/wae_initializer.c +++ b/srcs/wae_initializer.c @@ -23,15 +23,16 @@ #include "key_handler.h" #include "web_app_enc.h" #include "wae_log.h" + #include int main(int argc, char* argv[]) { int ret = WAE_ERROR_NONE; - int reload = WAE_FALSE; + bool reload = false; if(argc == 2 && strcmp(argv[1], "--reload")==0) { - reload = WAE_TRUE; + reload = true; } ret = load_preloaded_app_deks(reload); diff --git a/tests/wae_tests.c b/tests/wae_tests.c index a40b301..abaf4aa 100644 --- a/tests/wae_tests.c +++ b/tests/wae_tests.c @@ -336,16 +336,16 @@ int wae_tc_get_alias() const char* pkgId = "TEST_PKG_ID"; char alias[256] = {0, }; - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, true, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for normal for save. app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, WAE_FALSE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, false, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for normal for get. app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_DOWNLOADED_GLOBAL_APP, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_DOWNLOADED_GLOBAL_APP, true, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for global app=%s\n", pkgId, alias); - _get_alias(pkgId, WAE_PRELOADED_APP, WAE_TRUE, alias, sizeof(alias)); + _get_alias(pkgId, WAE_PRELOADED_APP, true, alias, sizeof(alias)); FPRINTF("...pkgid=%s, alias for preloaded app=%s\n", pkgId, alias); return ret; @@ -644,7 +644,7 @@ int wae_tc_load_preloaded_app_deks() } // load_preloaded_app_deks - ret = load_preloaded_app_deks(WAE_TRUE); + ret = load_preloaded_app_deks(true); if(ret != WAE_ERROR_NONE) { FPRINTF("...FAIL: load_preloaded_app_deks. ret=%d\n", ret); goto error; @@ -752,7 +752,7 @@ int _wae_tc_encrypt_decrypt_web_app(wae_app_type_e appType) _remove_app_dek_from_cache(pkgId); if(appType == WAE_PRELOADED_APP) { - load_preloaded_app_deks(WAE_TRUE); + load_preloaded_app_deks(true); } ret = wae_decrypt_web_application(pkgId, appType, encrypted, encLen, &decrypted, &decLen); -- 2.7.4 From 99523c9b37751cc9188dacc2d24fd775da02e180 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Fri, 15 Jul 2016 13:27:01 +0900 Subject: [PATCH 08/16] Apply coding style of tizen by astyle Change-Id: I495bcdeae8705c2bb8b605762e31458919736926 Signed-off-by: Kyungwook Tak --- CMakeLists.txt | 4 +- build/libwebappenc.pc.in | 1 - include/web_app_enc.h | 48 +- srcs/crypto_service.c | 640 ++++++++++----------- srcs/crypto_service.h | 32 +- srcs/key_handler.c | 1264 +++++++++++++++++++++--------------------- srcs/key_handler.h | 50 +- srcs/wae_initializer.c | 36 +- srcs/wae_log.h | 9 +- srcs/web_app_enc.c | 333 +++++------ tests/wae_tests.c | 1374 ++++++++++++++++++++++++---------------------- 11 files changed, 1955 insertions(+), 1836 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31e000b..4c5a1bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# 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. @@ -89,5 +89,3 @@ ADD_SUBDIRECTORY(resources) ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(systemd) - - diff --git a/build/libwebappenc.pc.in b/build/libwebappenc.pc.in index 2af6c92..b530dcf 100644 --- a/build/libwebappenc.pc.in +++ b/build/libwebappenc.pc.in @@ -8,4 +8,3 @@ Version: @VERSION@ Requires: @PC_REQUIRED@ Libs: @PC_LDFLAGS@ Cflags: @PC_CFLAGS@ - diff --git a/include/web_app_enc.h b/include/web_app_enc.h index 68a1fd9..7cadf7b 100644 --- a/include/web_app_enc.h +++ b/include/web_app_enc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -15,9 +15,8 @@ * * @file web_app_enc.h * @version 1.0 - * @brief This file contains APIs of WEB_APP_ENC module. + * @brief APIs of WEB_APP_ENC module. */ - #ifndef __WEB_APP_ENC__ #define __WEB_APP_ENC__ @@ -25,39 +24,38 @@ extern "C" { #endif +#include + /** * @addtogroup CAPI_WEB_APP_ENC_MODULE * @{ */ - /** * @brief WAE Errors. * @since_tizen 3.0 */ -typedef enum -{ - WAE_ERROR_NONE = 0x00, /**< Successful */ - WAE_ERROR_INVALID_PARAMETER = - 0x01, /**< Invalid function parameter */ - WAE_ERROR_PERMISSION_DENIED = - 0x02, /**< Permission denied */ - WAE_ERROR_NO_KEY = - 0x03, /**< No key */ - WAE_ERROR_KEY_EXISTS = - 0x04, /**< key already exists*/ - WAE_ERROR_KEY_MANAGER = - 0x05, /**< key-manager internal error */ - WAE_ERROR_CRYPTO = - 0x06, /**< failed in crypto operation */ - WAE_ERROR_MEMORY = - 0x07, /**< failed to allocate memory */ - WAE_ERROR_FILE = - 0x08, /**< failed to read or write a file*/ - WAE_ERROR_UNKNOWN = - 0x09 /** < Unknown error */ +typedef enum { + WAE_ERROR_NONE = 0x00, /**< Successful */ + WAE_ERROR_INVALID_PARAMETER = -0x01, /**< Invalid function parameter */ + WAE_ERROR_PERMISSION_DENIED = -0x02, /**< Permission denied */ + WAE_ERROR_NO_KEY = -0x03, /**< No key */ + WAE_ERROR_KEY_EXISTS = -0x04, /**< key already exists*/ + WAE_ERROR_KEY_MANAGER = -0x05, /**< key-manager internal error */ + WAE_ERROR_CRYPTO = -0x06, /**< failed in crypto operation */ + WAE_ERROR_MEMORY = -0x07, /**< failed to allocate memory */ + WAE_ERROR_FILE = -0x08, /**< failed to read or write a file*/ + WAE_ERROR_UNKNOWN = -0x09 /** < Unknown error */ } wae_error_e; /** * @brief Application Type. * @since_tizen 3.0 */ -typedef enum -{ - WAE_DOWNLOADED_NORMAL_APP = 0, /**< Downloaded Normal Application*/ - WAE_DOWNLOADED_GLOBAL_APP = 1, /**< Downloaded Global Application*/ - WAE_PRELOADED_APP = 2 /**< Preloaded Application*/ +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; /** @@ -81,7 +79,7 @@ typedef enum * * @see wae_decrypt_web_application() */ -int wae_encrypt_web_application(const char* pPkgId, wae_app_type_e appType, const unsigned char* pData, size_t dataLen, unsigned char** ppEncryptedData, size_t* pEncDataLen); +int wae_encrypt_web_application(const char *pPkgId, wae_app_type_e appType, const unsigned char *pData, size_t dataLen, unsigned char **ppEncryptedData, size_t *pEncDataLen); /** * @brief Encrypts web application data with internal key. @@ -104,7 +102,7 @@ int wae_encrypt_web_application(const char* pPkgId, wae_app_type_e appType, cons * * @see wae_encrypt_web_application() */ -int wae_decrypt_web_application(const char* pPkgId, wae_app_type_e appType, const unsigned char* pData, size_t dataLen, unsigned char** ppDecryptedData, size_t* pDecDataLen); +int wae_decrypt_web_application(const char *pPkgId, wae_app_type_e appType, const unsigned char *pData, size_t dataLen, unsigned char **ppDecryptedData, size_t *pDecDataLen); /** * @brief Remove a APP DEK(Application Data Encryption Key) used for encrytpion and decryption of a web application. @@ -121,8 +119,7 @@ int wae_decrypt_web_application(const char* pPkgId, wae_app_type_e appType, cons * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason * */ -int wae_remove_app_dek(const char* pPkgId, wae_app_type_e appType); - +int wae_remove_app_dek(const char *pPkgId, wae_app_type_e appType); /** * @} @@ -133,4 +130,3 @@ int wae_remove_app_dek(const char* pPkgId, wae_app_type_e appType); #endif #endif /* __WEB_APP_ENC__ */ - diff --git a/srcs/crypto_service.c b/srcs/crypto_service.c index 1c52cc5..7d90190 100644 --- a/srcs/crypto_service.c +++ b/srcs/crypto_service.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -36,336 +36,358 @@ #define AES_256_KEY_SIZE 32 -static unsigned char AES_CBC_IV[16] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; +static unsigned char AES_CBC_IV[16] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; static bool __initialized = false; void _initialize() { - if(!__initialized) { - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - __initialized = true; - } + if (!__initialized) { + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + __initialized = true; + } } - - -int encrypt_app_dek(const unsigned char* rsaPublicKey, size_t pubKeyLen, - const unsigned char* dek, size_t dekLen, - unsigned char** encryptedDek, size_t* encryptedDekLen) +int encrypt_app_dek(const unsigned char *rsaPublicKey, size_t pubKeyLen, + const unsigned char *dek, size_t dekLen, + unsigned char **encryptedDek, size_t *encryptedDekLen) { - int ret = WAE_ERROR_NONE; - EVP_PKEY *pKey = NULL; - BIO* bio = NULL; - EVP_PKEY_CTX *ctx = NULL; - unsigned char* out = NULL; - size_t outLen = 0; - - _initialize(); - - bio = BIO_new(BIO_s_mem()); - BIO_write(bio, rsaPublicKey, pubKeyLen); - pKey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); - - if(pKey == NULL){ - BIO_reset(bio); - BIO_write(bio, rsaPublicKey, pubKeyLen); - pKey = d2i_PUBKEY_bio(bio, NULL); - } - - if(pKey == NULL) { - ret = WAE_ERROR_FILE; - WAE_SLOGE("Failt to convert to public key."); - goto error; - } - - ctx = EVP_PKEY_CTX_new(pKey, NULL); - if(ctx == NULL) { - WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_CTX_new failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - if (EVP_PKEY_encrypt_init(ctx) <= 0) { - WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt_init failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) { - WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_CTX_set_rsa_padding failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - /* Determine buffer length */ - if (EVP_PKEY_encrypt(ctx, NULL, &outLen, dek, dekLen) <= 0) { - WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - out = OPENSSL_malloc(outLen); - if(out == NULL) { - WAE_SLOGE("Encrypt APP DEK Failed. OPENSSL_malloc failed"); - ret = WAE_ERROR_MEMORY; - goto error; - } - - if (EVP_PKEY_encrypt(ctx, out, &outLen, dek, dekLen) <= 0) { - WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - *encryptedDek = out; - *encryptedDekLen = outLen; + int ret = WAE_ERROR_NONE; + EVP_PKEY *pKey = NULL; + BIO *bio = NULL; + EVP_PKEY_CTX *ctx = NULL; + unsigned char *out = NULL; + size_t outLen = 0; + + _initialize(); + + bio = BIO_new(BIO_s_mem()); + BIO_write(bio, rsaPublicKey, pubKeyLen); + pKey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + + if (pKey == NULL) { + BIO_reset(bio); + BIO_write(bio, rsaPublicKey, pubKeyLen); + pKey = d2i_PUBKEY_bio(bio, NULL); + } + + if (pKey == NULL) { + ret = WAE_ERROR_FILE; + WAE_SLOGE("Failt to convert to public key."); + goto error; + } + + ctx = EVP_PKEY_CTX_new(pKey, NULL); + + if (ctx == NULL) { + WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_CTX_new failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + if (EVP_PKEY_encrypt_init(ctx) <= 0) { + WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt_init failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) { + WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_CTX_set_rsa_padding failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + /* Determine buffer length */ + if (EVP_PKEY_encrypt(ctx, NULL, &outLen, dek, dekLen) <= 0) { + WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + out = OPENSSL_malloc(outLen); + + if (out == NULL) { + WAE_SLOGE("Encrypt APP DEK Failed. OPENSSL_malloc failed"); + ret = WAE_ERROR_MEMORY; + goto error; + } + + if (EVP_PKEY_encrypt(ctx, out, &outLen, dek, dekLen) <= 0) { + WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + *encryptedDek = out; + *encryptedDekLen = outLen; error: - if(bio != NULL) - BIO_free(bio); - if(pKey != NULL) - EVP_PKEY_free(pKey); - if(ctx != NULL) - EVP_PKEY_CTX_free(ctx); - if(ret != WAE_ERROR_NONE && out != NULL) - OPENSSL_free(out); - - return ret; + if (bio != NULL) + BIO_free(bio); + + if (pKey != NULL) + EVP_PKEY_free(pKey); + + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); + + if (ret != WAE_ERROR_NONE && out != NULL) + OPENSSL_free(out); + + return ret; } -int decrypt_app_dek(const unsigned char* rsaPrivateKey, size_t priKeyLen, - const char* priKeyPassword, - const unsigned char* encryptedDek, size_t dencryptedDekLen, - unsigned char** decryptedDek, size_t* decryptedDekLen) +int decrypt_app_dek(const unsigned char *rsaPrivateKey, size_t priKeyLen, + const char *priKeyPassword, + const unsigned char *encryptedDek, size_t dencryptedDekLen, + unsigned char **decryptedDek, size_t *decryptedDekLen) { - int ret = WAE_ERROR_NONE; - EVP_PKEY *pKey = NULL; - BIO* bio = NULL; - EVP_PKEY_CTX *ctx = NULL; - unsigned char* out = NULL; - size_t outLen = 0; - - _initialize(); - - bio = BIO_new(BIO_s_mem()); - BIO_write(bio, rsaPrivateKey, priKeyLen); - pKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)priKeyPassword); - - if(pKey == NULL) { - BIO_reset(bio); - BIO_write(bio, rsaPrivateKey, priKeyLen); - pKey = d2i_PrivateKey_bio(bio, NULL); - } - - if(pKey == NULL) { - ret = WAE_ERROR_FILE; - WAE_SLOGE("Failt to convert to public key."); - goto error; - } - - ctx = EVP_PKEY_CTX_new(pKey, NULL); - if(ctx == NULL) { - WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_CTX_new failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - if (EVP_PKEY_decrypt_init(ctx) <= 0) { - WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt_init failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) { - WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_CTX_set_rsa_padding failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - /* Determine buffer length */ - if (EVP_PKEY_decrypt(ctx, NULL, &outLen, encryptedDek, dencryptedDekLen) <= 0) { - WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - out = OPENSSL_malloc(outLen); - if(out == NULL) { - WAE_SLOGE("Decrypt APP DEK Failed. OPENSSL_malloc failed"); - ret = WAE_ERROR_MEMORY; - goto error; - } - - if (EVP_PKEY_decrypt(ctx, out, &outLen, encryptedDek, dencryptedDekLen) <= 0) { - WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_decrypt failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - *decryptedDek = out; - *decryptedDekLen = outLen; + int ret = WAE_ERROR_NONE; + EVP_PKEY *pKey = NULL; + BIO *bio = NULL; + EVP_PKEY_CTX *ctx = NULL; + unsigned char *out = NULL; + size_t outLen = 0; + + _initialize(); + + bio = BIO_new(BIO_s_mem()); + BIO_write(bio, rsaPrivateKey, priKeyLen); + pKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)priKeyPassword); + + if (pKey == NULL) { + BIO_reset(bio); + BIO_write(bio, rsaPrivateKey, priKeyLen); + pKey = d2i_PrivateKey_bio(bio, NULL); + } + + if (pKey == NULL) { + ret = WAE_ERROR_FILE; + WAE_SLOGE("Failt to convert to public key."); + goto error; + } + + ctx = EVP_PKEY_CTX_new(pKey, NULL); + + if (ctx == NULL) { + WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_CTX_new failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + if (EVP_PKEY_decrypt_init(ctx) <= 0) { + WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt_init failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) { + WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_CTX_set_rsa_padding failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + /* Determine buffer length */ + if (EVP_PKEY_decrypt(ctx, NULL, &outLen, encryptedDek, dencryptedDekLen) <= 0) { + WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + out = OPENSSL_malloc(outLen); + + if (out == NULL) { + WAE_SLOGE("Decrypt APP DEK Failed. OPENSSL_malloc failed"); + ret = WAE_ERROR_MEMORY; + goto error; + } + + if (EVP_PKEY_decrypt(ctx, out, &outLen, encryptedDek, dencryptedDekLen) <= 0) { + WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_decrypt failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + *decryptedDek = out; + *decryptedDekLen = outLen; error: - if(bio != NULL) - BIO_free(bio); - if(pKey != NULL) - EVP_PKEY_free(pKey); - if(ctx != NULL) - EVP_PKEY_CTX_free(ctx); - if(ret != WAE_ERROR_NONE && out != NULL) - OPENSSL_free(out); - - return ret; + if (bio != NULL) + BIO_free(bio); + + if (pKey != NULL) + EVP_PKEY_free(pKey); + + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); + + if (ret != WAE_ERROR_NONE && out != NULL) + OPENSSL_free(out); + + return ret; } -int encrypt_aes_cbc(const unsigned char* pKey, size_t keyLen, - const unsigned char* pData, size_t dataLen, - unsigned char** ppEncryptedData, size_t* pEncDataLen) +int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, + const unsigned char *pData, size_t dataLen, + unsigned char **ppEncryptedData, size_t *pEncDataLen) { - EVP_CIPHER_CTX *ctx; - int len; - unsigned char *ciphertext = NULL; - size_t ciphertext_len; - unsigned char *iv = AES_CBC_IV; - int ret = WAE_ERROR_NONE; - - _initialize(); - - WAE_SLOGI("Encryption Started. size=%d", dataLen); - /* check input paramter */ - if( keyLen != 32 ) { - WAE_SLOGE("Encryption Failed. Invalid Key Length. keyLen=%d", keyLen); - return WAE_ERROR_INVALID_PARAMETER; - } - - // assing a enough memory for decryption. - ciphertext = (unsigned char*) malloc(dataLen + 32); - - /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) { - WAE_SLOGE("Encryption Failed. EVP_CIPHER_CTX_new failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - /* Initialise the encryption operation. IMPORTANT - ensure you use a key - * and IV size appropriate for your cipher - * In this example we are using 256 bit AES (i.e. a 256 bit key). The - * IV size for *most* modes is the same as the block size. For AES this - * is 128 bits */ - if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) { - WAE_SLOGE("Encryption Failed. EVP_EncryptInit_ex failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - /* Provide the message to be encrypted, and obtain the encrypted output. - * EVP_EncryptUpdate can be called multiple times if necessary - */ - if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, pData, dataLen)) { - WAE_SLOGE("Encryption Failed. EVP_EncryptUpdate failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - ciphertext_len = len; - - /* Finalise the encryption. Further ciphertext bytes may be written at - * this stage. - */ - if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { - WAE_SLOGE("Encryption Failed. EVP_EncryptFinal_ex failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - ciphertext_len += len; - - *ppEncryptedData = ciphertext; - *pEncDataLen = ciphertext_len; - - ret = WAE_ERROR_NONE; - WAE_SLOGI("Encryption Ended Successfully. encrypted_len", ciphertext_len); + EVP_CIPHER_CTX *ctx; + int len; + unsigned char *ciphertext = NULL; + size_t ciphertext_len; + unsigned char *iv = AES_CBC_IV; + int ret = WAE_ERROR_NONE; + + _initialize(); + + WAE_SLOGI("Encryption Started. size=%d", dataLen); + + /* check input paramter */ + if (keyLen != 32) { + WAE_SLOGE("Encryption Failed. Invalid Key Length. keyLen=%d", keyLen); + return WAE_ERROR_INVALID_PARAMETER; + } + + // assing a enough memory for decryption. + ciphertext = (unsigned char *) malloc(dataLen + 32); + + /* Create and initialise the context */ + if (!(ctx = EVP_CIPHER_CTX_new())) { + WAE_SLOGE("Encryption Failed. EVP_CIPHER_CTX_new failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + /* Initialise the encryption operation. IMPORTANT - ensure you use a key + * and IV size appropriate for your cipher + * In this example we are using 256 bit AES (i.e. a 256 bit key). The + * IV size for *most* modes is the same as the block size. For AES this + * is 128 bits */ + if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) { + WAE_SLOGE("Encryption Failed. EVP_EncryptInit_ex failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + /* Provide the message to be encrypted, and obtain the encrypted output. + * EVP_EncryptUpdate can be called multiple times if necessary + */ + if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, pData, dataLen)) { + WAE_SLOGE("Encryption Failed. EVP_EncryptUpdate failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + ciphertext_len = len; + + /* Finalise the encryption. Further ciphertext bytes may be written at + * this stage. + */ + if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { + WAE_SLOGE("Encryption Failed. EVP_EncryptFinal_ex failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + ciphertext_len += len; + + *ppEncryptedData = ciphertext; + *pEncDataLen = ciphertext_len; + + ret = WAE_ERROR_NONE; + WAE_SLOGI("Encryption Ended Successfully. encrypted_len", ciphertext_len); + error: - if(ctx != NULL) - EVP_CIPHER_CTX_free(ctx); - if(ret != WAE_ERROR_NONE && ciphertext != NULL) - free(ciphertext); - return ret; + if (ctx != NULL) + EVP_CIPHER_CTX_free(ctx); + + if (ret != WAE_ERROR_NONE && ciphertext != NULL) + free(ciphertext); + + return ret; } -int decrypt_aes_cbc(const unsigned char* pKey, size_t keyLen, - const unsigned char* pData, size_t dataLen, - unsigned char** ppDecryptedData, size_t* pDecDataLen) +int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, + const unsigned char *pData, size_t dataLen, + unsigned char **ppDecryptedData, size_t *pDecDataLen) { - EVP_CIPHER_CTX *ctx; - int len; - unsigned char* plaintext = NULL; - size_t plaintext_len; - unsigned char *iv = AES_CBC_IV; - int ret = WAE_ERROR_NONE; - - _initialize(); - - WAE_SLOGI("Decryption Started. size=%d", dataLen); - - /* check input paramter */ - if( keyLen != 32 ) { - WAE_SLOGE("Decryption Failed. Invalid Key Length. keyLen=%d", keyLen); - return WAE_ERROR_INVALID_PARAMETER; - } - - // assing a enough memory for decryption. - plaintext = (unsigned char*) malloc(dataLen); - - /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) { - WAE_SLOGE("Decryption Failed. EVP_CIPHER_CTX_new failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - /* Initialise the decryption operation. IMPORTANT - ensure you use a key - * and IV size appropriate for your cipher - * In this example we are using 256 bit AES (i.e. a 256 bit key). The - * IV size for *most* modes is the same as the block size. For AES this - * is 128 bits */ - if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) { - WAE_SLOGE("Decryption Failed. EVP_DecryptInit_ex failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - /* Provide the message to be decrypted, and obtain the plaintext output. - * EVP_DecryptUpdate can be called multiple times if necessary - */ - if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, pData, dataLen)) { - WAE_SLOGE("Decryption Failed. EVP_DecryptUpdate failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - plaintext_len = len; - - /* Finalise the decryption. Further plaintext bytes may be written at - * this stage. - */ - if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) { - WAE_SLOGE("Decryption Failed. EVP_DecryptFinal_ex failed"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - plaintext_len += len; - - *ppDecryptedData = plaintext; - *pDecDataLen = plaintext_len; - - ret = WAE_ERROR_NONE; - WAE_SLOGI("Decryption Ended Successfully. decrypted_len", plaintext_len); + EVP_CIPHER_CTX *ctx; + int len; + unsigned char *plaintext = NULL; + size_t plaintext_len; + unsigned char *iv = AES_CBC_IV; + int ret = WAE_ERROR_NONE; + + _initialize(); + + WAE_SLOGI("Decryption Started. size=%d", dataLen); + + /* check input paramter */ + if (keyLen != 32) { + WAE_SLOGE("Decryption Failed. Invalid Key Length. keyLen=%d", keyLen); + return WAE_ERROR_INVALID_PARAMETER; + } + + // assing a enough memory for decryption. + plaintext = (unsigned char *) malloc(dataLen); + + /* Create and initialise the context */ + if (!(ctx = EVP_CIPHER_CTX_new())) { + WAE_SLOGE("Decryption Failed. EVP_CIPHER_CTX_new failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + /* Initialise the decryption operation. IMPORTANT - ensure you use a key + * and IV size appropriate for your cipher + * In this example we are using 256 bit AES (i.e. a 256 bit key). The + * IV size for *most* modes is the same as the block size. For AES this + * is 128 bits */ + if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) { + WAE_SLOGE("Decryption Failed. EVP_DecryptInit_ex failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + /* Provide the message to be decrypted, and obtain the plaintext output. + * EVP_DecryptUpdate can be called multiple times if necessary + */ + if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, pData, dataLen)) { + WAE_SLOGE("Decryption Failed. EVP_DecryptUpdate failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + plaintext_len = len; + + /* Finalise the decryption. Further plaintext bytes may be written at + * this stage. + */ + if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) { + WAE_SLOGE("Decryption Failed. EVP_DecryptFinal_ex failed"); + ret = WAE_ERROR_CRYPTO; + goto error; + } + + plaintext_len += len; + + *ppDecryptedData = plaintext; + *pDecDataLen = plaintext_len; + + ret = WAE_ERROR_NONE; + WAE_SLOGI("Decryption Ended Successfully. decrypted_len", plaintext_len); + error: - if(ctx != NULL) - EVP_CIPHER_CTX_free(ctx); - if(ret != WAE_ERROR_NONE && plaintext != NULL) - free(plaintext); - return ret; -} + if (ctx != NULL) + EVP_CIPHER_CTX_free(ctx); + if (ret != WAE_ERROR_NONE && plaintext != NULL) + free(plaintext); + + return ret; +} diff --git a/srcs/crypto_service.h b/srcs/crypto_service.h index fcdb0fe..61f4d0b 100644 --- a/srcs/crypto_service.h +++ b/srcs/crypto_service.h @@ -19,8 +19,8 @@ * @version 1.0 * @brief provides encryption and decription operations. */ -#ifndef __TIZEN_CORE_WAE_CRYPTO_SERVICE_H -#define __TIZEN_CORE_WAE_CRYPTO_SERVICE_H +#ifndef __WAE_CRYPTO_SERVICE_H +#define __WAE_CRYPTO_SERVICE_H #ifdef __cplusplus extern "C" { @@ -28,26 +28,26 @@ extern "C" { #include -int encrypt_app_dek(const unsigned char* rsaPublicKey, size_t pubKeyLen, - const unsigned char* dek, size_t dekLen, - unsigned char** encryptedDek, size_t* encryptedDekLen); +int encrypt_app_dek(const unsigned char *rsaPublicKey, size_t pubKeyLen, + const unsigned char *dek, size_t dekLen, + unsigned char **encryptedDek, size_t *encryptedDekLen); -int decrypt_app_dek(const unsigned char* rsaPrivateKey, size_t priKeyLen, - const char* priKeyPassword, - const unsigned char* encryptedDek, size_t dencryptedDekLen, - unsigned char** decryptedDek, size_t* decryptedDekLen); +int decrypt_app_dek(const unsigned char *rsaPrivateKey, size_t priKeyLen, + const char *priKeyPassword, + const unsigned char *encryptedDek, size_t dencryptedDekLen, + unsigned char **decryptedDek, size_t *decryptedDekLen); -int encrypt_aes_cbc(const unsigned char* pKey, size_t keyLen, - const unsigned char* pData, size_t dataLen, - unsigned char** ppEncryptedData, size_t* pEncDataLen); +int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, + const unsigned char *pData, size_t dataLen, + unsigned char **ppEncryptedData, size_t *pEncDataLen); -int decrypt_aes_cbc(const unsigned char* pKey, size_t keyLen, - const unsigned char* pData, size_t dataLen, - unsigned char** ppDecryptedData, size_t* pDecDataLen); +int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, + const unsigned char *pData, size_t dataLen, + unsigned char **ppDecryptedData, size_t *pDecDataLen); #ifdef __cplusplus } #endif -#endif /* __TIZEN_CORE_WAE_CRYPTO_SERVICE_H */ +#endif /* __WAE_CRYPTO_SERVICE_H */ diff --git a/srcs/key_handler.c b/srcs/key_handler.c index bf98c5d..929d282 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -47,9 +47,9 @@ #define MAX_PKGID_LEN 256 #define MAX_CACHE_SIZE 100 -typedef struct _dek_cache_element{ - char pkgId[MAX_PKGID_LEN]; - unsigned char dek[DEK_LEN]; +typedef struct _dek_cache_element { + char pkgId[MAX_PKGID_LEN]; + unsigned char dek[DEK_LEN]; } dek_cache_element; dek_cache_element APP_DEK_CACHE[MAX_CACHE_SIZE]; @@ -57,734 +57,762 @@ int NEXT_CACHE_IDX = -1; void _initialize_cache() { - NEXT_CACHE_IDX = 0; - memset(APP_DEK_CACHE, 0, sizeof(dek_cache_element)*MAX_CACHE_SIZE); + NEXT_CACHE_IDX = 0; + memset(APP_DEK_CACHE, 0, sizeof(dek_cache_element)*MAX_CACHE_SIZE); } -unsigned char* _get_app_dek_from_cache(const char* pkgId) +unsigned char *_get_app_dek_from_cache(const char *pkgId) { - int i = 0; - - if(NEXT_CACHE_IDX < 0) - _initialize_cache(); - - for(i =0; i= MAX_CACHE_SIZE) - NEXT_CACHE_IDX = 0; + if (NEXT_CACHE_IDX < 0) + _initialize_cache(); + + // if existing one has the same pkgid + for (int i = 0; i < MAX_CACHE_SIZE; i++) { + if (strlen(APP_DEK_CACHE[i].pkgId) == strlen(pkgId) && + strncmp(pkgId, APP_DEK_CACHE[i].pkgId, strlen(pkgId)) == 0) { + memcpy(APP_DEK_CACHE[i].dek, dek, DEK_LEN); + return; + } + } + + // for new pkgid + strncpy(APP_DEK_CACHE[NEXT_CACHE_IDX].pkgId, pkgId, strlen(pkgId)); + memcpy(APP_DEK_CACHE[NEXT_CACHE_IDX].dek, dek, DEK_LEN); + + NEXT_CACHE_IDX++; + + if (NEXT_CACHE_IDX >= MAX_CACHE_SIZE) + NEXT_CACHE_IDX = 0; } -void _remove_app_dek_from_cache(const char* pkgId) +void _remove_app_dek_from_cache(const char *pkgId) { - int i = 0; - - for(i =0; idata, DEK_LEN); - - *ppDek = pDek; - *dekLen = DEK_LEN; - WAE_SLOGI("WAE: Success to get APP_DEK from key-manager. pkgId=%s, alias=%s", pPkgId, alias); + int ret = WAE_ERROR_NONE; + + char *password = NULL; + ckmc_raw_buffer_s *pDekBuffer = NULL; + char alias[MAX_ALIAS_LEN] = {0,}; + unsigned char *pDek = NULL; + + unsigned char *cached_dek = _get_app_dek_from_cache(pPkgId); + + if (cached_dek == NULL) { + // get APP_DEK from system database + _get_alias(pPkgId, appType, false, alias, sizeof(alias)); + + ret = _to_wae_error(ckmc_get_data(alias, password, &pDekBuffer)); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGI("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", + pPkgId, alias, ret); + goto error; + } + } + + pDek = (unsigned char *) malloc(DEK_LEN); + + if (pDek == NULL) { + WAE_SLOGE("Fail to allocate a memory"); + ret = WAE_ERROR_MEMORY; + goto error; + } + + memcpy(pDek, (cached_dek != NULL) ? cached_dek : pDekBuffer->data, DEK_LEN); + + *ppDek = pDek; + *dekLen = DEK_LEN; + WAE_SLOGI("WAE: Success to get APP_DEK from key-manager. pkgId=%s, alias=%s", pPkgId, alias); + error: - if(pDekBuffer != NULL) - ckmc_buffer_free(pDekBuffer); - if(ret != WAE_ERROR_NONE && pDek != NULL) - free(pDek); + if (pDekBuffer != NULL) + ckmc_buffer_free(pDekBuffer); + + if (ret != WAE_ERROR_NONE && pDek != NULL) + free(pDek); - return ret; + return ret; } -int create_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDek, size_t* dekLen) +int create_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen) { - int ret = WAE_ERROR_NONE; - unsigned char *dek= NULL; - - dek = (unsigned char*) malloc(DEK_LEN); - if(dek == NULL) { - ret = WAE_ERROR_MEMORY; - goto error; - } - - ret = _get_random(DEK_LEN, dek); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to get random for APP_DEK. pkgId=%s, ret=%d", pPkgId, ret); - goto error; - } - - // save app_dek in key_manager - ret = _add_dek_to_key_manager(pPkgId, appType, dek, DEK_LEN); - if(ret != WAE_ERROR_NONE) { - goto error; - } - - // store APP_DEK in cache - _add_app_dek_to_cache(pPkgId, dek); - - *ppDek = dek; - *dekLen = DEK_LEN; - - WAE_SLOGI("WAE: Success to create APP_DEK and store it in key-manager. pkgId=%s", pPkgId); + unsigned char *dek = (unsigned char *) malloc(DEK_LEN); + + if (dek == NULL) + return WAE_ERROR_MEMORY; + + int ret = _get_random(DEK_LEN, dek); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("WAE: Fail to get random for APP_DEK. pkgId=%s, ret=%d", pPkgId, ret); + goto error; + } + + // save app_dek in key_manager + ret = _add_dek_to_key_manager(pPkgId, appType, dek, DEK_LEN); + + if (ret != WAE_ERROR_NONE) { + goto error; + } + + // store APP_DEK in cache + _add_app_dek_to_cache(pPkgId, dek); + + *ppDek = dek; + *dekLen = DEK_LEN; + + WAE_SLOGI("WAE: Success to create APP_DEK and store it in key-manager. pkgId=%s", pPkgId); + error: - if(ret != WAE_ERROR_NONE && dek != NULL) - free(dek); + if (ret != WAE_ERROR_NONE && dek != NULL) + free(dek); - return ret; + return ret; } -int get_preloaded_app_dek(const char* pPkgId, unsigned char** ppDek, size_t* dekLen) +int get_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen) { - int ret = WAE_ERROR_NONE; - unsigned char* cached_dek= NULL; - unsigned char* dek = NULL; - - // get dek from cache - cached_dek = _get_app_dek_from_cache(pPkgId); - if(cached_dek == NULL) { - WAE_SLOGE("WAE: Fail to get APP_DEK from cache for preloaded app"); - ret = WAE_ERROR_NO_KEY; - goto error; - } - - dek = (unsigned char*) malloc(DEK_LEN); - if(dek == NULL) { - WAE_SLOGE("WAE: Fail to allocate memory for preloaded app dek"); - ret = WAE_ERROR_MEMORY; - goto error; - } - memcpy(dek, cached_dek, DEK_LEN); - - *ppDek = dek; - *dekLen = DEK_LEN; + int ret = WAE_ERROR_NONE; + + unsigned char *cached_dek = _get_app_dek_from_cache(pPkgId); + + if (cached_dek == NULL) { + WAE_SLOGE("WAE: Fail to get APP_DEK from cache for preloaded app"); + return WAE_ERROR_NO_KEY; + } + + unsigned char *dek = (unsigned char *) malloc(DEK_LEN); + + if (dek == NULL) { + WAE_SLOGE("WAE: Fail to allocate memory for preloaded app dek"); + ret = WAE_ERROR_MEMORY; + goto error; + } + + memcpy(dek, cached_dek, DEK_LEN); + + *ppDek = dek; + *dekLen = DEK_LEN; + error: - if(ret != WAE_ERROR_NONE && dek != NULL) - free(dek); + if (ret != WAE_ERROR_NONE && dek != NULL) + free(dek); - return ret; + return ret; } -int create_preloaded_app_dek(const char* pPkgId, unsigned char** ppDek, size_t* dekLen) +int create_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen) { - int ret = WAE_ERROR_NONE; - unsigned char* dek = NULL; - unsigned char* encrypted_app_dek = NULL; - size_t encrypted_app_dek_len = 0; - unsigned char* pubKey = NULL; - size_t pubKeyLen = 0; - - // create APP_DEK - dek = (unsigned char*) malloc(DEK_LEN); - if(dek == NULL) { - ret = WAE_ERROR_MEMORY; - goto error; - } - - ret = _get_random(DEK_LEN, dek); - if(ret != WAE_ERROR_NONE) { - goto error; - } - - // encrypt APP_DEK with APP_DEK_KEK - ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubKey, &pubKeyLen); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Public Key"); - goto error; - } - - ret = encrypt_app_dek(pubKey, pubKeyLen, dek, DEK_LEN, &encrypted_app_dek, &encrypted_app_dek_len); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to encrypt APP_DEK with APP_DEK_KEK"); - goto error; - } - - // write APP_DEK in a file - ret = _write_encrypted_app_dek_to_file(pPkgId, encrypted_app_dek, encrypted_app_dek_len); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to write encrypted APP_DEK. pkgId=%s", pPkgId); - goto error; - } - - // store APP_DEK in cache - _add_app_dek_to_cache(pPkgId, dek); - - *ppDek = dek; - *dekLen = DEK_LEN; - WAE_SLOGI("WAE: Success to create preleaded APP_DEK and write it in initail value file. pkgId=%s", pPkgId); + unsigned char *encrypted_app_dek = NULL; + size_t encrypted_app_dek_len = 0; + unsigned char *pubKey = NULL; + size_t pubKeyLen = 0; -error: - if(pubKey != NULL) - free(pubKey); - if(encrypted_app_dek != NULL) - free(encrypted_app_dek); - if(ret != WAE_ERROR_NONE && dek != NULL) - free(dek); - return ret; -} + // create APP_DEK + unsigned char *dek = (unsigned char *)malloc(DEK_LEN); + if (dek == NULL) + return WAE_ERROR_MEMORY; -int _get_app_dek_kek(unsigned char** ppDekKek, size_t* kekLen) -{ - int ret = WAE_ERROR_NONE; + int ret = _get_random(DEK_LEN, dek); + + if (ret != WAE_ERROR_NONE) + goto error; + + // encrypt APP_DEK with APP_DEK_KEK + ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubKey, &pubKeyLen); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Public Key"); + goto error; + } + + ret = encrypt_app_dek(pubKey, pubKeyLen, dek, DEK_LEN, &encrypted_app_dek, &encrypted_app_dek_len); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("WAE: Fail to encrypt APP_DEK with APP_DEK_KEK"); + goto error; + } + + // write APP_DEK in a file + ret = _write_encrypted_app_dek_to_file(pPkgId, encrypted_app_dek, encrypted_app_dek_len); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("WAE: Fail to write encrypted APP_DEK. pkgId=%s", pPkgId); + goto error; + } + + // store APP_DEK in cache + _add_app_dek_to_cache(pPkgId, dek); + + *ppDek = dek; + *dekLen = DEK_LEN; + WAE_SLOGI("WAE: Success to create preleaded APP_DEK and write it in initail value file. pkgId=%s", pPkgId); - ret = _read_from_file(_get_dek_kek_pri_key_path(), ppDekKek, kekLen); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Private Key"); - return ret; - } -/* - char* password = NULL; - ckmc_raw_buffer_s *pKekBuffer = NULL; - unsigned char* pKek = NULL; - - char dek_kek_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_kek_alias(dek_kek_alias, sizeof(dek_kek_alias)); - - ret = _to_wae_error(ckmc_get_data(dek_kek_alias, password, &pKekBuffer)); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to get APP_DEK_KEK from key-manager. alias=%s, ret=%d", APP_DEK_KEK_ALIAS, ret); - goto error; - } - - pKek = (unsigned char*) malloc(pKekBuffer->size); - if(pKek == NULL) { - WAE_SLOGE("Fail to allocate a memory"); - ret = WAE_ERROR_MEMORY; - goto error; - } - memcpy(pKek, pKekBuffer->data, pKekBuffer->size); - - *ppDekKek = pKek; - *kekLen = pKekBuffer->size; - WAE_SLOGI("Success to get APP_DEK_KEK from key-manager."); error: - if(pKekBuffer != NULL) - ckmc_buffer_free(pKekBuffer); - if(ret != WAE_ERROR_NONE && pKek != NULL) - free(pKek); -*/ - return ret; + if (pubKey != NULL) + free(pubKey); + + if (encrypted_app_dek != NULL) + free(encrypted_app_dek); + + if (ret != WAE_ERROR_NONE && dek != NULL) + free(dek); + + return ret; } +int _get_app_dek_kek(unsigned char **ppDekKek, size_t *kekLen) +{ + int ret = _read_from_file(_get_dek_kek_pri_key_path(), ppDekKek, kekLen); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Private Key"); + return ret; + } + + /* + char* password = NULL; + ckmc_raw_buffer_s *pKekBuffer = NULL; + unsigned char* pKek = NULL; + + char dek_kek_alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_kek_alias(dek_kek_alias, sizeof(dek_kek_alias)); + + ret = _to_wae_error(ckmc_get_data(dek_kek_alias, password, &pKekBuffer)); + if(ret != WAE_ERROR_NONE) { + WAE_SLOGE("Fail to get APP_DEK_KEK from key-manager. alias=%s, ret=%d", APP_DEK_KEK_ALIAS, ret); + goto error; + } + + pKek = (unsigned char*) malloc(pKekBuffer->size); + if(pKek == NULL) { + WAE_SLOGE("Fail to allocate a memory"); + ret = WAE_ERROR_MEMORY; + goto error; + } + memcpy(pKek, pKekBuffer->data, pKekBuffer->size); + + *ppDekKek = pKek; + *kekLen = pKekBuffer->size; + WAE_SLOGI("Success to get APP_DEK_KEK from key-manager."); + error: + if(pKekBuffer != NULL) + ckmc_buffer_free(pKekBuffer); + if(ret != WAE_ERROR_NONE && pKek != NULL) + free(pKek); + */ + return ret; +} int _get_app_deks_loaded() { - int ret = WAE_ERROR_NONE; - - ckmc_raw_buffer_s *pBuffer = NULL; - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; + char loading_done_alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); + ckmc_raw_buffer_s *pBuffer = NULL; + int ret = _to_wae_error(ckmc_get_data(loading_done_alias, NULL, &pBuffer)); - ret = _to_wae_error(ckmc_get_data(loading_done_alias, NULL, &pBuffer)); - if(ret == WAE_ERROR_NO_KEY) { - WAE_SLOGI("WAE: APP_DEK_LOADING was not done"); - } else if(ret == WAE_ERROR_NONE) { - WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); - } else { - WAE_SLOGE("WAE: Fail to get information from key-manager about APP_DEK_LOADING_DONE_ALIAS. ret=%d", ret); - goto error; - } + if (ret == WAE_ERROR_NO_KEY) + WAE_SLOGI("WAE: APP_DEK_LOADING was not done"); + else if (ret == WAE_ERROR_NONE) + WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); + else + WAE_SLOGE("WAE: Fail to get information from key-manager about APP_DEK_LOADING_DONE_ALIAS. ret=%d", ret); -error: - if(pBuffer != NULL) - ckmc_buffer_free(pBuffer); + if (pBuffer != NULL) + ckmc_buffer_free(pBuffer); - return ret; + return ret; } int _set_app_deks_loaded() { - int ret = WAE_ERROR_NONE; - ckmc_raw_buffer_s buff; - ckmc_policy_s policy; - unsigned char dummyData[1] = {0}; - - buff.data = dummyData; - buff.size = sizeof(dummyData); - - policy.password = NULL; - policy.extractable = true; - - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - ret = _to_wae_error(ckmc_save_data(loading_done_alias, buff, policy)); - if(ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); - ret = WAE_ERROR_NONE; - } else if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to set APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); - goto error; - } - - WAE_SLOGI("Success to set APP_DEK_LOADING_DONE_ALIAS to key-manager."); -error: - return ret; + ckmc_raw_buffer_s buff; + ckmc_policy_s policy; + unsigned char dummyData[1] = {0}; + + buff.data = dummyData; + buff.size = sizeof(dummyData); + + policy.password = NULL; + policy.extractable = true; + + char loading_done_alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); + + int ret = _to_wae_error(ckmc_save_data(loading_done_alias, buff, policy)); + + if (ret == WAE_ERROR_KEY_EXISTS) { + WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); + ret = WAE_ERROR_NONE; + } else if (ret == WAE_ERROR_NONE) { + WAE_SLOGI("Success to set APP_DEK_LOADING_DONE_ALIAS to key-manager."); + } else { + WAE_SLOGE("WAE: Fail to set APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); + } + + return ret; } int _clear_app_deks_loaded() { - int ret = WAE_ERROR_NONE; - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - ret = _to_wae_error(ckmc_remove_alias(loading_done_alias)); - if(ret == WAE_ERROR_NO_KEY) { - WAE_SLOGI("APP_DEK_LOADING_DONE_ALIAS was not set to key-manager before."); - ret = WAE_ERROR_NONE; - }else if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to clear APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); - } - - return ret; + char loading_done_alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); + + int ret = _to_wae_error(ckmc_remove_alias(loading_done_alias)); + + if (ret == WAE_ERROR_NO_KEY) { + WAE_SLOGI("APP_DEK_LOADING_DONE_ALIAS was not set to key-manager before."); + ret = WAE_ERROR_NONE; + } else if (ret == WAE_ERROR_NONE) { + WAE_SLOGI("Success to clear app deks loaded"); + } else { + WAE_SLOGE("Fail to clear APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); + } + + return ret; } int load_preloaded_app_deks(bool reload) { - int ret = WAE_ERROR_NONE; - - char pkgId[MAX_PKGID_LEN] = {0, }; - - DIR *dir = NULL; - struct dirent entry; - struct dirent *result; - int error; - char file_path_buff[MAX_PATH_LEN]; - unsigned char* encrypted_app_dek = NULL; - size_t encrypted_app_dek_len = 0; - unsigned char* app_dek = NULL; - size_t app_dek_len = 0; - unsigned char* priKey = NULL; - size_t priKeyLen = 0; - - int error_during_loading = 0; - - if(!reload) { - // check if all deks were already loaded into key-manager. - ret = _get_app_deks_loaded(); - if(ret == WAE_ERROR_NONE) { - return ret; - } - } - - ret = _get_app_dek_kek(&priKey, &priKeyLen); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); - return ret; - } - - dir = opendir(_get_dek_store_path()); - if(dir == NULL) { - WAE_SLOGE("Fail to open dir. dir=%s", _get_dek_store_path()); - ret = WAE_ERROR_FILE; - goto error; - } - - for(;;) { - error = readdir_r(dir, &entry, &result); - if( error != 0 ) { - ret = WAE_ERROR_FILE; - goto error; - } - // readdir_r returns NULL in *result if the end - // of the directory stream is reached - 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) { - memset(file_path_buff, 0, sizeof(file_path_buff)); - ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", - _get_dek_store_path(), entry.d_name); - if(ret < 0) { - WAE_SLOGE("Failed to make file path by snprintf."); - ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ - goto error; - } - - ret = _extract_pkg_id_from_file_name(entry.d_name, pkgId); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGW("Fail to extract pkgid from file. It will be ignored. file=%s",file_path_buff); - continue; - } - - ret = _read_from_file(file_path_buff, &encrypted_app_dek, &encrypted_app_dek_len); - if(ret != WAE_ERROR_NONE || encrypted_app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to read file. It will be ignored. file=%s",file_path_buff); - continue; - } - - ret = decrypt_app_dek(priKey, priKeyLen, APP_DEK_KEK_PRIKEY_PASSWORD, - encrypted_app_dek, encrypted_app_dek_len, - &app_dek, &app_dek_len); - if(ret != WAE_ERROR_NONE || app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to decrypt APP DEK. It will be ignored. file=%s",file_path_buff); - continue; - } - - // save app_dek in key_manager - ret = _add_dek_to_key_manager(pkgId, WAE_PRELOADED_APP, app_dek, app_dek_len); - // free temp objects - free(app_dek); - free(encrypted_app_dek); - app_dek = NULL; - encrypted_app_dek = NULL; - - if(ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("Key Manager already has APP_DEK. It will be ignored. file=%s",file_path_buff); - continue; - }else if(ret != WAE_ERROR_NONE) { - error_during_loading++; - WAE_SLOGW("Fail to add APP DEK to key-manager. file=%s",file_path_buff); - continue; - } - } - } - - ret = _set_app_deks_loaded(); - if(ret == WAE_ERROR_NONE) { - WAE_SLOGI("Success to load_preloaded_app_deks"); - ret = WAE_ERROR_NONE; - }else { - WAE_SLOGW("Fail to _set_app_deks_loaded to key-manager. ret=%d", ret); - } + int ret = WAE_ERROR_NONE; + + char pkgId[MAX_PKGID_LEN] = {0, }; + + DIR *dir = NULL; + struct dirent entry; + struct dirent *result; + int error; + char file_path_buff[MAX_PATH_LEN]; + unsigned char *encrypted_app_dek = NULL; + size_t encrypted_app_dek_len = 0; + unsigned char *app_dek = NULL; + size_t app_dek_len = 0; + unsigned char *priKey = NULL; + size_t priKeyLen = 0; + + int error_during_loading = 0; + + if (!reload) { + // check if all deks were already loaded into key-manager. + ret = _get_app_deks_loaded(); + + if (ret == WAE_ERROR_NONE) + return ret; + } + + ret = _get_app_dek_kek(&priKey, &priKeyLen); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); + return ret; + } + + dir = opendir(_get_dek_store_path()); + + if (dir == NULL) { + WAE_SLOGE("Fail to open dir. dir=%s", _get_dek_store_path()); + ret = WAE_ERROR_FILE; + goto error; + } + + while (true) { + error = readdir_r(dir, &entry, &result); + + if (error != 0) { + ret = WAE_ERROR_FILE; + goto error; + } + + // readdir_r returns NULL in *result if the end + // of the directory stream is reached + 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) { + memset(file_path_buff, 0, sizeof(file_path_buff)); + ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", + _get_dek_store_path(), entry.d_name); + + if (ret < 0) { + WAE_SLOGE("Failed to make file path by snprintf."); + ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ + goto error; + } + + ret = _extract_pkg_id_from_file_name(entry.d_name, pkgId); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGW("Fail to extract pkgid from file. It will be ignored. file=%s", file_path_buff); + continue; + } + + ret = _read_from_file(file_path_buff, &encrypted_app_dek, &encrypted_app_dek_len); + + if (ret != WAE_ERROR_NONE || encrypted_app_dek == NULL) { + error_during_loading++; + WAE_SLOGW("Fail to read file. It will be ignored. file=%s", file_path_buff); + continue; + } + + ret = decrypt_app_dek(priKey, priKeyLen, APP_DEK_KEK_PRIKEY_PASSWORD, + encrypted_app_dek, encrypted_app_dek_len, + &app_dek, &app_dek_len); + + if (ret != WAE_ERROR_NONE || app_dek == NULL) { + error_during_loading++; + WAE_SLOGW("Fail to decrypt APP DEK. It will be ignored. file=%s", file_path_buff); + continue; + } + + // save app_dek in key_manager + ret = _add_dek_to_key_manager(pkgId, WAE_PRELOADED_APP, app_dek, app_dek_len); + // free temp objects + free(app_dek); + free(encrypted_app_dek); + app_dek = NULL; + encrypted_app_dek = NULL; + + if (ret == WAE_ERROR_KEY_EXISTS) { + WAE_SLOGI("Key Manager already has APP_DEK. It will be ignored. file=%s", file_path_buff); + continue; + } else if (ret != WAE_ERROR_NONE) { + error_during_loading++; + WAE_SLOGW("Fail to add APP DEK to key-manager. file=%s", file_path_buff); + continue; + } + } + } + + ret = _set_app_deks_loaded(); + + if (ret == WAE_ERROR_NONE) { + WAE_SLOGI("Success to load_preloaded_app_deks"); + ret = WAE_ERROR_NONE; + } else { + WAE_SLOGW("Fail to _set_app_deks_loaded to key-manager. ret=%d", ret); + } + error: - if(priKey != NULL) - free(priKey); + if (priKey != NULL) + free(priKey); - return ret; + return ret; } - -int remove_app_dek(const char* pPkgId, wae_app_type_e appType) +int remove_app_dek(const char *pPkgId, wae_app_type_e appType) { - int ret = CKMC_ERROR_NONE; - char alias[MAX_ALIAS_LEN] = {0,}; + char alias[MAX_ALIAS_LEN] = {0,}; - _get_alias(pPkgId, appType, true, alias,sizeof(alias)); + _get_alias(pPkgId, appType, true, alias, sizeof(alias)); - ret = _to_wae_error(ckmc_remove_alias(alias)); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to remove APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", pPkgId, alias, ret); - goto error; - } + int ret = _to_wae_error(ckmc_remove_alias(alias)); - _remove_app_dek_from_cache(pPkgId); - WAE_SLOGI("Success to remove APP_DEK from key-manager. pkgId=%s", pPkgId); -error: - return WAE_ERROR_NONE; + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Fail to remove APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", pPkgId, alias, ret); + return ret; + } + + _remove_app_dek_from_cache(pPkgId); + WAE_SLOGI("Success to remove APP_DEK from key-manager. pkgId=%s", pPkgId); + + return WAE_ERROR_NONE; } diff --git a/srcs/key_handler.h b/srcs/key_handler.h index 2d3af65..e1ad727 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -19,8 +19,8 @@ * @version 1.0 * @brief Key manupulatation. */ -#ifndef __TIZEN_CORE_WAE_KEY_HANDLER_H -#define __TIZEN_CORE_WAE_KEY_HANDLER_H +#ifndef __WAE_KEY_HANDLER_H +#define __WAE_KEY_HANDLER_H #ifdef __cplusplus extern "C" { @@ -34,37 +34,37 @@ extern "C" { /* functions with "_" prefix are internal static functions but declared here for testing */ void _initialize_cache(); -unsigned char* _get_app_dek_from_cache(const char* pkgId); -void _add_app_dek_to_cache(const char* pkgId, unsigned char* dek); -void _remove_app_dek_from_cache(const char* pkgId); -int _get_random(size_t length, unsigned char* random); -void _get_alias(const char* pPkgId, wae_app_type_e appType, bool forSave, char* alias, size_t buff_len); -void _get_dek_kek_alias(char* alias, size_t buff_len); -void _get_dek_loading_done_alias(char* alias, size_t buff_len); -const char* _get_dek_kek_pub_key_path(); -const char* _get_dek_kek_pri_key_path(); -const char* _get_dek_store_path(); -int _add_dek_to_key_manager(const char* pPkgId, wae_app_type_e appType, const unsigned char* pDek, size_t len); -int _get_preloaded_app_dek_file_path(const char* pPkgId, size_t size, char *path); -int _extract_pkg_id_from_file_name(const char* fileName, char* pkgId); -int _read_encrypted_app_dek_from_file(const char* pPkgId, unsigned char** encrypted_app_dek, size_t*len); -int _write_encrypted_app_dek_to_file(const char* pPkgId, const unsigned char* encrypted_app_dek, size_t len); -int _read_from_file(const char* path, unsigned char** data, size_t* len); -int _write_to_file(const char* path, const unsigned char* data, size_t len); +unsigned char *_get_app_dek_from_cache(const char *pkgId); +void _add_app_dek_to_cache(const char *pkgId, unsigned char *dek); +void _remove_app_dek_from_cache(const char *pkgId); +int _get_random(size_t length, unsigned char *random); +void _get_alias(const char *pPkgId, wae_app_type_e appType, bool forSave, char *alias, size_t buff_len); +void _get_dek_kek_alias(char *alias, size_t buff_len); +void _get_dek_loading_done_alias(char *alias, size_t buff_len); +const char *_get_dek_kek_pub_key_path(); +const char *_get_dek_kek_pri_key_path(); +const char *_get_dek_store_path(); +int _add_dek_to_key_manager(const char *pPkgId, wae_app_type_e appType, const unsigned char *pDek, size_t len); +int _get_preloaded_app_dek_file_path(const char *pPkgId, size_t size, char *path); +int _extract_pkg_id_from_file_name(const char *fileName, char *pkgId); +int _read_encrypted_app_dek_from_file(const char *pPkgId, unsigned char **encrypted_app_dek, size_t *len); +int _write_encrypted_app_dek_to_file(const char *pPkgId, const unsigned char *encrypted_app_dek, size_t len); +int _read_from_file(const char *path, unsigned char **data, size_t *len); +int _write_to_file(const char *path, const unsigned char *data, size_t len); int _get_app_deks_loaded(); int _set_app_deks_loaded(); int _clear_app_deks_loaded(); /* functions for interface */ -int get_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDek, size_t *dekLen); -int create_app_dek(const char* pPkgId, wae_app_type_e appType, unsigned char** ppDek, size_t *dekLen); -int get_preloaded_app_dek(const char* pPkgId, unsigned char** ppDek, size_t* dekLen); -int create_preloaded_app_dek(const char* pPkgId, unsigned char** ppDek, size_t *dekLen); +int get_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen); +int create_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen); +int get_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen); +int create_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen); int load_preloaded_app_deks(bool reload); -int remove_app_dek(const char* pPkgId, wae_app_type_e appType); +int remove_app_dek(const char *pPkgId, wae_app_type_e appType); #ifdef __cplusplus } #endif -#endif /* __TIZEN_CORE_WAE_KEY_HANDLER_H */ +#endif /* __WAE_KEY_HANDLER_H */ diff --git a/srcs/wae_initializer.c b/srcs/wae_initializer.c index 4022f48..b9d7ce8 100644 --- a/srcs/wae_initializer.c +++ b/srcs/wae_initializer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -19,30 +19,30 @@ * @version 1.0 * @brief tool for importing APP DEKs during booting */ - #include "key_handler.h" #include "web_app_enc.h" #include "wae_log.h" #include -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - int ret = WAE_ERROR_NONE; - bool reload = false; + int ret = WAE_ERROR_NONE; + bool reload = false; + + if (argc == 2 && strcmp(argv[1], "--reload") == 0) { + reload = true; + } - if(argc == 2 && strcmp(argv[1], "--reload")==0) { - reload = true; - } + ret = load_preloaded_app_deks(reload); - ret = load_preloaded_app_deks(reload); - if(ret == WAE_ERROR_NONE) { - printf("WAE INITIALIZER was finished successfully.\n"); - WAE_SLOGI("WAE INITIALIZER was finished successfully."); - return 0; - }else { - printf("WAE INITIALIZER was finished with error. ret=%d\n", ret); - WAE_SLOGE("WAE INITIALIZER was finished with error. ret=%d", ret); - return -1; - } + if (ret == WAE_ERROR_NONE) { + printf("WAE INITIALIZER was finished successfully.\n"); + WAE_SLOGI("WAE INITIALIZER was finished successfully."); + return 0; + } else { + printf("WAE INITIALIZER was finished with error. ret=%d\n", ret); + WAE_SLOGE("WAE INITIALIZER was finished with error. ret=%d", ret); + return -1; + } } diff --git a/srcs/wae_log.h b/srcs/wae_log.h index 6dfe44a..732557f 100644 --- a/srcs/wae_log.h +++ b/srcs/wae_log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -17,16 +17,14 @@ * @file wae_log.h * @author Dongsun Lee (ds73.lee@samsung.com) * @version 1.0 - * @brief a header for loggin. + * @brief logging. */ - #ifndef __WAE_LOG_H__ #define __WAE_LOG_H__ -/* Use DLOG logging mechanism */ #include -#define TAG_WAE "WAE" +#define TAG_WAE "WAE" #define WAE_SLOGD(format, arg...) SLOG(LOG_DEBUG, TAG_WAE, format, ##arg) #define WAE_SLOGI(format, arg...) SLOG(LOG_INFO, TAG_WAE, format, ##arg) @@ -35,4 +33,3 @@ #define WAE_SLOGF(format, arg...) SLOG(LOG_FATAL, TAG_WAE, format, ##arg) #endif /* __WAE_LOG_H__*/ - diff --git a/srcs/web_app_enc.c b/srcs/web_app_enc.c index 39865bc..0e31c30 100644 --- a/srcs/web_app_enc.c +++ b/srcs/web_app_enc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -19,200 +19,213 @@ * @version 1.0 * @brief provides fucntions for encryption and decryption of web application. */ +#include "web_app_enc.h" #include #include -#include "web_app_enc.h" #include "key_handler.h" #include "crypto_service.h" #include "wae_log.h" - -int _wae_encrypt_downloaded_web_application(const char* pPkgId, wae_app_type_e appType, - const unsigned char* pData, size_t dataLen, - unsigned char** ppEncryptedData, size_t* pEncDataLen) +int _wae_encrypt_downloaded_web_application(const char *pPkgId, wae_app_type_e appType, + const unsigned char *pData, size_t dataLen, + unsigned char **ppEncryptedData, size_t *pEncDataLen) { - int ret = WAE_ERROR_NONE; - unsigned char *pDek = NULL; - size_t dekLen = -1; - - if(pPkgId == NULL) { - WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - if(pData == NULL || dataLen <= 0) { - WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - if(ppEncryptedData == NULL || pEncDataLen == NULL) { - WAE_SLOGE("Invalid Parameter. ppEncryptedData or pEncDataLen is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - // get APP_DEK. - // if not exists, create APP_DEK - ret = get_app_dek(pPkgId, appType, &pDek, &dekLen); - if(ret == WAE_ERROR_NO_KEY) { - ret = create_app_dek(pPkgId, appType, &pDek, &dekLen); - } - if(ret != WAE_ERROR_NONE) { - goto error; - } - - // encrypt - ret = encrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppEncryptedData, pEncDataLen); - if(ret != WAE_ERROR_NONE) { - goto error; - } + int ret = WAE_ERROR_NONE; + unsigned char *pDek = NULL; + size_t dekLen = -1; + + if (pPkgId == NULL) { + WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + if (pData == NULL || dataLen <= 0) { + WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + if (ppEncryptedData == NULL || pEncDataLen == NULL) { + WAE_SLOGE("Invalid Parameter. ppEncryptedData or pEncDataLen is NULL"); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + // get APP_DEK. + // if not exists, create APP_DEK + ret = get_app_dek(pPkgId, appType, &pDek, &dekLen); + + if (ret == WAE_ERROR_NO_KEY) { + ret = create_app_dek(pPkgId, appType, &pDek, &dekLen); + } + + if (ret != WAE_ERROR_NONE) { + goto error; + } + + // encrypt + ret = encrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppEncryptedData, pEncDataLen); + + if (ret != WAE_ERROR_NONE) { + goto error; + } error: - if(pDek != NULL) - free(pDek); + if (pDek != NULL) + free(pDek); - return ret; + return ret; } -int _wae_decrypt_downloaded_web_application(const char* pPkgId, wae_app_type_e appType, - const unsigned char* pData, size_t dataLen, - unsigned char** ppDecryptedData, size_t* pDecDataLen) +int _wae_decrypt_downloaded_web_application(const char *pPkgId, wae_app_type_e appType, + const unsigned char *pData, size_t dataLen, + unsigned char **ppDecryptedData, size_t *pDecDataLen) { - int ret = WAE_ERROR_NONE; - unsigned char *pDek = NULL; - size_t dekLen = -1; - - if(pPkgId == NULL) { - WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - if(pData == NULL || dataLen <= 0) { - WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - if(ppDecryptedData == NULL || pDecDataLen == NULL) { - WAE_SLOGE("Invalid Parameter. ppDecryptedData or pDecDataLen is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - ret = get_app_dek(pPkgId, appType, &pDek, &dekLen); - if(ret != WAE_ERROR_NONE) { - goto error; - } - - // decrypt - ret = decrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppDecryptedData, pDecDataLen); - if(ret != WAE_ERROR_NONE) { - goto error; - } + int ret = WAE_ERROR_NONE; + unsigned char *pDek = NULL; + size_t dekLen = -1; + + if (pPkgId == NULL) { + WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + if (pData == NULL || dataLen <= 0) { + WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + if (ppDecryptedData == NULL || pDecDataLen == NULL) { + WAE_SLOGE("Invalid Parameter. ppDecryptedData or pDecDataLen is NULL"); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + ret = get_app_dek(pPkgId, appType, &pDek, &dekLen); + + if (ret != WAE_ERROR_NONE) { + goto error; + } + + // decrypt + ret = decrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppDecryptedData, pDecDataLen); + + if (ret != WAE_ERROR_NONE) { + goto error; + } error: - if(pDek != NULL) - free(pDek); + if (pDek != NULL) + free(pDek); - return ret; + return ret; } -int _wae_encrypt_preloaded_web_application(const char* pPkgId, - const unsigned char* pData, size_t dataLen, - unsigned char** ppEncryptedData, size_t* pEncDataLen) +int _wae_encrypt_preloaded_web_application(const char *pPkgId, + const unsigned char *pData, size_t dataLen, + unsigned char **ppEncryptedData, size_t *pEncDataLen) { - int ret = WAE_ERROR_NONE; - unsigned char *pDek = NULL; - size_t dekLen = -1; - - if(pPkgId == NULL) { - WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - if(pData == NULL || dataLen <= 0) { - WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - if(ppEncryptedData == NULL || pEncDataLen == NULL) { - WAE_SLOGE("Invalid Parameter. ppEncryptedData or pEncDataLen is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - ret = get_preloaded_app_dek(pPkgId, &pDek, &dekLen); - if(ret == WAE_ERROR_NO_KEY) { - ret = create_preloaded_app_dek(pPkgId, &pDek, &dekLen); - } - if(ret != WAE_ERROR_NONE) { - goto error; - } - - // encrypt - ret = encrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppEncryptedData, pEncDataLen); - if(ret != WAE_ERROR_NONE) { - goto error; - } + int ret = WAE_ERROR_NONE; + unsigned char *pDek = NULL; + size_t dekLen = -1; + + if (pPkgId == NULL) { + WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + if (pData == NULL || dataLen <= 0) { + WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + if (ppEncryptedData == NULL || pEncDataLen == NULL) { + WAE_SLOGE("Invalid Parameter. ppEncryptedData or pEncDataLen is NULL"); + ret = WAE_ERROR_INVALID_PARAMETER; + goto error; + } + + ret = get_preloaded_app_dek(pPkgId, &pDek, &dekLen); + + if (ret == WAE_ERROR_NO_KEY) { + ret = create_preloaded_app_dek(pPkgId, &pDek, &dekLen); + } + + if (ret != WAE_ERROR_NONE) { + goto error; + } + + // encrypt + ret = encrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppEncryptedData, pEncDataLen); + + if (ret != WAE_ERROR_NONE) { + goto error; + } + error: - if(pDek != NULL) - free(pDek); + if (pDek != NULL) + free(pDek); - return ret; + return ret; } -int _wae_decrypt_preloaded_web_application(const char* pPkgId, wae_app_type_e appType, - const unsigned char* pData, size_t dataLen, - unsigned char** ppDecryptedData, size_t* pDecDataLen) +int _wae_decrypt_preloaded_web_application(const char *pPkgId, wae_app_type_e appType, + const unsigned char *pData, size_t dataLen, + unsigned char **ppDecryptedData, size_t *pDecDataLen) { - // same with the decryption of downloaded web application - return _wae_decrypt_downloaded_web_application(pPkgId, appType, - pData, dataLen, ppDecryptedData, pDecDataLen); + // same with the decryption of downloaded web application + return _wae_decrypt_downloaded_web_application(pPkgId, appType, + pData, dataLen, ppDecryptedData, pDecDataLen); } -int wae_encrypt_web_application(const char* pPkgId, wae_app_type_e appType, - const unsigned char* pData, size_t dataLen, - unsigned char** ppEncryptedData, size_t* pEncDataLen) +int wae_encrypt_web_application(const char *pPkgId, wae_app_type_e appType, + const unsigned char *pData, size_t dataLen, + unsigned char **ppEncryptedData, size_t *pEncDataLen) { - int ret = WAE_ERROR_NONE; - - if(appType == WAE_PRELOADED_APP) - ret = _wae_encrypt_preloaded_web_application(pPkgId, - pData, dataLen, ppEncryptedData, pEncDataLen); - else - ret = _wae_encrypt_downloaded_web_application(pPkgId, appType, - pData, dataLen, ppEncryptedData, pEncDataLen); - - WAE_SLOGI("Encrypt Web App. pkgId=%s, appType=%d, dataLen=%d, ret=%d", - pPkgId, appType, dataLen, ret); - return ret; + int ret = WAE_ERROR_NONE; + + if (appType == WAE_PRELOADED_APP) + ret = _wae_encrypt_preloaded_web_application(pPkgId, + pData, dataLen, ppEncryptedData, pEncDataLen); + else + ret = _wae_encrypt_downloaded_web_application(pPkgId, appType, + pData, dataLen, ppEncryptedData, pEncDataLen); + + WAE_SLOGI("Encrypt Web App. pkgId=%s, appType=%d, dataLen=%d, ret=%d", + pPkgId, appType, dataLen, ret); + return ret; } -int wae_decrypt_web_application(const char* pPkgId, wae_app_type_e appType, - const unsigned char* pData, size_t dataLen, - unsigned char** ppDecryptedData, size_t* pDecDataLen) +int wae_decrypt_web_application(const char *pPkgId, wae_app_type_e appType, + const unsigned char *pData, size_t dataLen, + unsigned char **ppDecryptedData, size_t *pDecDataLen) { - int ret = WAE_ERROR_NONE; - - if(appType == WAE_PRELOADED_APP) - ret = _wae_decrypt_preloaded_web_application(pPkgId, appType, - pData, dataLen, ppDecryptedData, pDecDataLen); - else - ret = _wae_decrypt_downloaded_web_application(pPkgId, appType, - pData, dataLen, ppDecryptedData, pDecDataLen); - - WAE_SLOGI("Decrypt Web App. pkgId=%s, appType=%d, dataLen=%d, ret=%d", - pPkgId, appType, dataLen, ret); - return ret; + int ret = WAE_ERROR_NONE; + + if (appType == WAE_PRELOADED_APP) + ret = _wae_decrypt_preloaded_web_application(pPkgId, appType, + pData, dataLen, ppDecryptedData, pDecDataLen); + else + ret = _wae_decrypt_downloaded_web_application(pPkgId, appType, + pData, dataLen, ppDecryptedData, pDecDataLen); + + WAE_SLOGI("Decrypt Web App. pkgId=%s, appType=%d, dataLen=%d, ret=%d", + pPkgId, appType, dataLen, ret); + return ret; } -int wae_remove_app_dek(const char* pPkgId, wae_app_type_e appType) +int wae_remove_app_dek(const char *pPkgId, wae_app_type_e appType) { - int ret = WAE_ERROR_NONE; - ret = remove_app_dek(pPkgId, appType); - WAE_SLOGI("Remove APP DEK. pkgId=%s, appType=%d, ret=%d", pPkgId, appType, ret); - return ret; + int ret = remove_app_dek(pPkgId, appType); + WAE_SLOGI("Remove APP DEK. pkgId=%s, appType=%d, ret=%d", pPkgId, appType, ret); + return ret; } diff --git a/tests/wae_tests.c b/tests/wae_tests.c index abaf4aa..c724d21 100644 --- a/tests/wae_tests.c +++ b/tests/wae_tests.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -37,193 +37,206 @@ static int tc_fail = 0; #define FPRINTF(format, args...) fprintf(stdout, format, ##args) -static int RUNTC(int (*tc_method)(), const char* tc_name) +static int RUNTC(int (*tc_method)(), const char *tc_name) { - int ret = WAE_ERROR_NONE; - FPRINTF("[%02d:%s]started...\n", tc_seq, tc_name); - ret = tc_method(); - if(ret == WAE_ERROR_NONE) { - FPRINTF("[%02d:%s]ended. SUCCESS\n\n", tc_seq, tc_name); - tc_succ++; - } else { - FPRINTF("[%02d:%s]ended. FAIL. error=%d\n\n", tc_seq, tc_name, ret); - tc_fail++; - } - tc_seq++; - return ret; + int ret = WAE_ERROR_NONE; + FPRINTF("[%02d:%s]started...\n", tc_seq, tc_name); + ret = tc_method(); + + if (ret == WAE_ERROR_NONE) { + FPRINTF("[%02d:%s]ended. SUCCESS\n\n", tc_seq, tc_name); + tc_succ++; + } else { + FPRINTF("[%02d:%s]ended. FAIL. error=%d\n\n", tc_seq, tc_name, ret); + tc_fail++; + } + + tc_seq++; + return ret; } static void PRINT_TC_SUMMARY() { - FPRINTF("\n"); - FPRINTF("===============================================\n"); - FPRINTF(" TOTAL = %d, SUCCESS = %d, FAIL = %d\n", tc_seq, tc_succ, tc_fail); - FPRINTF("===============================================\n"); + FPRINTF("\n"); + FPRINTF("===============================================\n"); + FPRINTF(" TOTAL = %d, SUCCESS = %d, FAIL = %d\n", tc_seq, tc_succ, tc_fail); + FPRINTF("===============================================\n"); } -void _print_binary_to_hex(const char* msg, unsigned char* bin, size_t len) +void _print_binary_to_hex(const char *msg, unsigned char *bin, size_t len) { - size_t i = 0; - FPRINTF("%s", msg); - for(i=0; i Date: Fri, 15 Jul 2016 15:01:54 +0900 Subject: [PATCH 09/16] Add test manifest for exec labeling Change-Id: Ib54e8558417b8f32782c7ada3d6bdda8999a5b0f Signed-off-by: Kyungwook Tak --- CMakeLists.txt | 8 ++++++-- ...appenc.manifest => libwebappenc-test.manifest.in} | 2 +- packaging/libwebappenc.manifest.in | 5 +++++ packaging/libwebappenc.spec | 20 ++++++++++++-------- resources/CMakeLists.txt | 2 +- srcs/key_handler.c | 9 ++++----- 6 files changed, 29 insertions(+), 17 deletions(-) rename packaging/{libwebappenc.manifest => libwebappenc-test.manifest.in} (54%) create mode 100644 packaging/libwebappenc.manifest.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c5a1bb..8d396a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,12 +55,17 @@ STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") 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") ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG") # ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") +CONFIGURE_FILE(packaging/lib${PROJECT_NAME}.manifest.in lib${PROJECT_NAME}.manifest @ONLY) +CONFIGURE_FILE(packaging/lib${PROJECT_NAME}-test.manifest.in lib${PROJECT_NAME}-test.manifest @ONLY) + ################# common configurations for srcs and test ###################### SET(DEPENDENTS "openssl dlog key-manager libtzplatform-config") PKG_CHECK_MODULES(WEB_APP_ENC_DEPS @@ -70,12 +75,11 @@ PKG_CHECK_MODULES(WEB_APP_ENC_DEPS ############################ For PC file setting ################################ -SET(PC_NAME ${PROJECT_NAME}) +SET(PC_NAME lib${PROJECT_NAME}) SET(PC_REQUIRED ${DEPENDENTS}) SET(PC_LDFLAGS -l${PROJECT_NAME}) #SET(PC_CFLAGS -I\${includedir}) - ############################ Target Setting ################################ SET(TARGET_WEBAPPENC ${PROJECT_NAME}) SET(TARGET_WAE_INITIALIZER wae_initializer) diff --git a/packaging/libwebappenc.manifest b/packaging/libwebappenc-test.manifest.in similarity index 54% rename from packaging/libwebappenc.manifest rename to packaging/libwebappenc-test.manifest.in index 226aaa0..13d4d92 100644 --- a/packaging/libwebappenc.manifest +++ b/packaging/libwebappenc-test.manifest.in @@ -3,6 +3,6 @@ - + diff --git a/packaging/libwebappenc.manifest.in b/packaging/libwebappenc.manifest.in new file mode 100644 index 0000000..86dbb26 --- /dev/null +++ b/packaging/libwebappenc.manifest.in @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index 342d1f3..a3e95b4 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -5,7 +5,6 @@ Release: 1 Group: Security/Libraries License: Apache-2.0 Source0: %{name}-%{version}.tar.gz -Source1001: %{name}.manifest Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -35,9 +34,12 @@ 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 + %prep %setup -q -cp %{SOURCE1001} . %build %{!?build_type:%define build_type "Release"} @@ -45,10 +47,11 @@ cp %{SOURCE1001} . -DEXEC_PREFIX=%{_exec_prefix} \ -DINCLUDEDIR=%{_includedir} \ -DLIBDIR=%{_libdir} \ - -DBINDIR=%TZ_SYS_BIN \ -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DCMAKE_BUILD_TYPE=%{build_type} \ - -DTZ_SYS_SHARE=%TZ_SYS_SHARE + -DRW_SHARE_DIR=%rw_share_dir \ + -DBINDIR=%bin_dir \ + -DINSTALLER_LABEL=%installer_label make %{?jobs:-j%jobs} @@ -82,9 +85,9 @@ fi %{_libdir}/%{name}.so.* %{_unitdir}/webappenc-initializer.service %{_unitdir}/multi-user.target.wants/webappenc-initializer.service -%{TZ_SYS_BIN}/wae_initializer -%{TZ_SYS_SHARE}/wae/app_dek/WAE_APPDEK_KEK_PrivateKey.pem -%{TZ_SYS_SHARE}/wae/app_dek/WAE_APPDEK_KEK_PublicKey.pem +%{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 %files devel %{_includedir}/* @@ -92,4 +95,5 @@ fi %{_libdir}/%{name}.so %files test -%{TZ_SYS_BIN}/wae_tests +%manifest %{name}-test.manifest +%{bin_dir}/wae_tests diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 4462cee..ae2bc8b 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -5,7 +5,7 @@ INSTALL(FILES ${PROJECT_SOURCE_DIR}/resources/WAE_APPDEK_KEK_PublicKey.pem ${PROJECT_SOURCE_DIR}/resources/WAE_APPDEK_KEK_PrivateKey.pem - DESTINATION ${TZ_SYS_SHARE}/wae/app_dek/ + DESTINATION ${RW_SHARE_DIR}/wae/app_dek/ PERMISSIONS OWNER_READ OWNER_WRITE ) diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 929d282..15dc96f 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -35,7 +35,6 @@ #include "crypto_service.h" #define RANDOM_FILE "/dev/urandom" -#define WRT_INSTALLER_LABEL "/User" #define APP_DEK_KEK_PRIKEY_PASSWORD "wae_appdek_kek_1q2w3e4r" #define APP_DEK_ALIAS_PFX "APP_DEK_" #define APP_DEK_LOADING_DONE_ALIAS "APP_DEKS_LOADING_FINISHED" @@ -168,8 +167,8 @@ void _get_alias(const char *pPkgId, wae_app_type_e appType, bool forSave, char * APP_DEK_ALIAS_PFX, pPkgId); } else { - snprintf(alias, buff_len, "%s%s%s%s", - WRT_INSTALLER_LABEL, + snprintf(alias, buff_len, "%c%s%s%s%s", + '/', INSTALLER_LABEL, ckmc_owner_id_separator, APP_DEK_ALIAS_PFX, pPkgId); @@ -400,13 +399,13 @@ int get_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDe ret = _to_wae_error(ckmc_get_data(alias, password, &pDekBuffer)); if (ret != WAE_ERROR_NONE) { - WAE_SLOGI("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", + WAE_SLOGE("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", pPkgId, alias, ret); goto error; } } - pDek = (unsigned char *) malloc(DEK_LEN); + pDek = (unsigned char *)malloc(DEK_LEN); if (pDek == NULL) { WAE_SLOGE("Fail to allocate a memory"); -- 2.7.4 From 25dec26957850ba42687ffff35fc226039405654 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Fri, 15 Jul 2016 19:42:35 +0900 Subject: [PATCH 10/16] Apply boost test framework run with sdb root on : wae_tests --run_test=SYSTEM run with sdb root off : wae_tests --run_test=USER Change-Id: I0792e1e649f5e36c6f8715047f5ba5fd9ec48ecf Signed-off-by: Kyungwook Tak --- CMakeLists.txt | 13 +- LICENSE.BSL-1.0 | 23 + packaging/libwebappenc.spec | 11 +- srcs/CMakeLists.txt | 56 ++- tests/CMakeLists.txt | 106 ++++- tests/colour_log_formatter.cpp | 268 ++++++++++++ tests/colour_log_formatter.h | 62 +++ tests/internals.cpp | 352 ++++++++++++++++ tests/main.cpp | 28 ++ tests/non-normals.cpp | 70 ++++ tests/normals.cpp | 50 +++ tests/test-common.cpp | 55 +++ tests/test-common.h | 51 +++ tests/test-helper.cpp | 178 ++++++++ tests/test-helper.h | 33 ++ tests/wae_tests.c | 923 ----------------------------------------- 16 files changed, 1297 insertions(+), 982 deletions(-) create mode 100644 LICENSE.BSL-1.0 create mode 100644 tests/colour_log_formatter.cpp create mode 100644 tests/colour_log_formatter.h create mode 100644 tests/internals.cpp create mode 100644 tests/main.cpp create mode 100644 tests/non-normals.cpp create mode 100644 tests/normals.cpp create mode 100644 tests/test-common.cpp create mode 100644 tests/test-common.h create mode 100644 tests/test-helper.cpp create mode 100644 tests/test-helper.h delete mode 100644 tests/wae_tests.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d396a8..84dd0d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,8 +59,8 @@ ADD_DEFINITIONS("-DBINDIR=\"${BINDIR}\"") ADD_DEFINITIONS("-DINSTALLER_LABEL=\"${INSTALLER_LABEL}\"") # IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") - ADD_DEFINITIONS("-DTIZEN_DEBUG_ENABLE") - ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG") + ADD_DEFINITIONS("-DTIZEN_DEBUG_ENABLE") + ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG") # ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") CONFIGURE_FILE(packaging/lib${PROJECT_NAME}.manifest.in lib${PROJECT_NAME}.manifest @ONLY) @@ -69,8 +69,8 @@ CONFIGURE_FILE(packaging/lib${PROJECT_NAME}-test.manifest.in lib${PROJECT_NAME}- ################# common configurations for srcs and test ###################### SET(DEPENDENTS "openssl dlog key-manager libtzplatform-config") PKG_CHECK_MODULES(WEB_APP_ENC_DEPS - REQUIRED - ${DEPENDENTS} + REQUIRED + ${DEPENDENTS} ) @@ -81,10 +81,11 @@ SET(PC_LDFLAGS -l${PROJECT_NAME}) #SET(PC_CFLAGS -I\${includedir}) ############################ Target Setting ################################ -SET(TARGET_WEBAPPENC ${PROJECT_NAME}) +SET(TARGET_WAE ${PROJECT_NAME}) SET(TARGET_WAE_INITIALIZER wae_initializer) SET(TARGET_WAE_ENCRYPTER wae_encrypter) -SET(TARGET_WEBAPPENC_TEST wae_tests) +SET(TARGET_WAE_TEST wae_tests) +SET(TARGET_WAE_TEST_COMMON wae_tests_common) ############################ Add Sub Directories ################################ ADD_SUBDIRECTORY(srcs) diff --git a/LICENSE.BSL-1.0 b/LICENSE.BSL-1.0 new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/LICENSE.BSL-1.0 @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/packaging/libwebappenc.spec b/packaging/libwebappenc.spec index a3e95b4..ed5434a 100644 --- a/packaging/libwebappenc.spec +++ b/packaging/libwebappenc.spec @@ -3,7 +3,7 @@ Summary: Web application encryption service Version: 0.1.0 Release: 1 Group: Security/Libraries -License: Apache-2.0 +License: Apache-2.0 and BSL-1.0 Source0: %{name}-%{version}.tar.gz Requires(post): /sbin/ldconfig @@ -20,6 +20,7 @@ Web application encryption and decryption service %package devel Summary: Web application encryption service (development files) +License: Apache-2.0 Group: Security/Development Requires: %{name} = %{version}-%{release} @@ -28,8 +29,10 @@ Web application encryption and decryption service (development files) %package test Summary: Web application encryption service (test) +License: Apache-2.0 and BSL-1.0 Group: Security/Development -Requires: %{name} = %{version}-%{release} +BuildRequires: boost-devel +Requires: %{name} = %{version}-%{release} %description test Web application encryption and decryption service (test) @@ -82,6 +85,7 @@ fi %files %manifest %{name}.manifest %license LICENSE +%license LICENSE.BSL-1.0 %{_libdir}/%{name}.so.* %{_unitdir}/webappenc-initializer.service %{_unitdir}/multi-user.target.wants/webappenc-initializer.service @@ -96,4 +100,7 @@ fi %files test %manifest %{name}-test.manifest +%license LICENSE +%license LICENSE.BSL-1.0 %{bin_dir}/wae_tests +%{_libdir}/libwae_tests_common.so* diff --git a/srcs/CMakeLists.txt b/srcs/CMakeLists.txt index 9eb766c..b95531b 100644 --- a/srcs/CMakeLists.txt +++ b/srcs/CMakeLists.txt @@ -3,34 +3,34 @@ ################################################################################ SET(WEB_APP_ENC_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/web_app_enc.c - ${CMAKE_CURRENT_SOURCE_DIR}/key_handler.c - ${CMAKE_CURRENT_SOURCE_DIR}/crypto_service.c + ${CMAKE_CURRENT_SOURCE_DIR}/web_app_enc.c + ${CMAKE_CURRENT_SOURCE_DIR}/key_handler.c + ${CMAKE_CURRENT_SOURCE_DIR}/crypto_service.c ) INCLUDE_DIRECTORIES( - ${PROJECT_SOURCE_DIR}/include - ${WEB_APP_ENC_DEPS_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/include + ${WEB_APP_ENC_DEPS_INCLUDE_DIRS} ) -ADD_LIBRARY(${TARGET_WEBAPPENC} SHARED ${WEB_APP_ENC_SOURCES}) +ADD_LIBRARY(${TARGET_WAE} SHARED ${WEB_APP_ENC_SOURCES}) -SET_TARGET_PROPERTIES(${TARGET_WEBAPPENC} PROPERTIES - SOVERSION ${SO_VERSION} - VERSION ${VERSION} - COMPILE_FLAGS "-D_GNU_SOURCE" +SET_TARGET_PROPERTIES(${TARGET_WAE} PROPERTIES + SOVERSION ${SO_VERSION} + VERSION ${VERSION} + COMPILE_FLAGS "-D_GNU_SOURCE" ) -TARGET_LINK_LIBRARIES(${TARGET_WEBAPPENC} - pthread - ${WEB_APP_ENC_DEPS_LIBRARIES} +TARGET_LINK_LIBRARIES(${TARGET_WAE} + pthread + ${WEB_APP_ENC_DEPS_LIBRARIES} ) -INSTALL(TARGETS ${TARGET_WEBAPPENC} - DESTINATION ${LIBDIR}) +INSTALL(TARGETS ${TARGET_WAE} + DESTINATION ${LIBDIR}) INSTALL(FILES ${PROJECT_SOURCE_DIR}/include/web_app_enc.h - DESTINATION ${INCLUDEDIR}) + DESTINATION ${INCLUDEDIR}) ################################################################################ @@ -39,30 +39,28 @@ INSTALL(FILES ${PROJECT_SOURCE_DIR}/include/web_app_enc.h SET(WAE_INITIALIZER_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/wae_initializer.c + ${CMAKE_CURRENT_SOURCE_DIR}/wae_initializer.c ) INCLUDE_DIRECTORIES( - ${PROJECT_SOURCE_DIR}/include - ${WEB_APP_ENC_DEPS_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/include + ${WEB_APP_ENC_DEPS_INCLUDE_DIRS} ) # -fPIE and -pie flag is added for ASLR SET_SOURCE_FILES_PROPERTIES( - ${WAE_INITIALIZER_SOURCES} - PROPERTIES - COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden -fPIE") + ${WAE_INITIALIZER_SOURCES} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden -fPIE") ADD_EXECUTABLE(${TARGET_WAE_INITIALIZER} ${WAE_INITIALIZER_SOURCES}) TARGET_LINK_LIBRARIES(${TARGET_WAE_INITIALIZER} - pthread - ${WEB_APP_ENC_DEPS_LIBRARIES} - ${TARGET_WEBAPPENC} - -pie + pthread + ${WEB_APP_ENC_DEPS_LIBRARIES} + ${TARGET_WAE} + -pie ) -INSTALL(TARGETS ${TARGET_WAE_INITIALIZER} - DESTINATION ${BINDIR}) - +INSTALL(TARGETS ${TARGET_WAE_INITIALIZER} DESTINATION ${BINDIR}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e1d0d6d..7c9e2c9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,37 +1,99 @@ -################################################################################ -# for wae_tests -################################################################################ +# 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 Kyungwook Tak (k.tak@samsung.com) +# @brief cmake for test program +# +ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK) +#### test common library #### +PKG_CHECK_MODULES(${TARGET_WAE_TEST_COMMON}_DEP + REQUIRED +) -SET(WEB_APP_ENC_TEST_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/wae_tests.c +SET(${TARGET_WAE_TEST_COMMON}_SRCS + colour_log_formatter.cpp + test-common.cpp ) INCLUDE_DIRECTORIES( - ${WEB_APP_ENC_DEPS_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR}/srcs + SYSTEM + ${${TARGET_WAE_TEST_COMMON}_DEP_INCLUDE_DIRS} ) -ADD_EXECUTABLE(${TARGET_WEBAPPENC_TEST} ${WEB_APP_ENC_TEST_SOURCES}) +INCLUDE_DIRECTORIES( + . +) +ADD_LIBRARY(${TARGET_WAE_TEST_COMMON} SHARED ${${TARGET_WAE_TEST_COMMON}_SRCS}) + +SET_TARGET_PROPERTIES(${TARGET_WAE_TEST_COMMON} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=default" +) -TARGET_LINK_LIBRARIES(${TARGET_WEBAPPENC_TEST} - ${WEB_APP_ENC_DEPS_LIBRARIES} - ${TARGET_WEBAPPENC} +TARGET_LINK_LIBRARIES(${TARGET_WAE_TEST_COMMON} + ${${TARGET_WAE_TEST_COMMON}_DEP_LIBRARIES} + -lboost_unit_test_framework ) +INSTALL(TARGETS ${TARGET_WAE_TEST_COMMON} DESTINATION ${LIBDIR}) -INSTALL(TARGETS ${TARGET_WEBAPPENC_TEST} - DESTINATION ${BINDIR} - PERMISSIONS OWNER_READ - OWNER_WRITE - OWNER_EXECUTE - GROUP_READ - GROUP_EXECUTE - WORLD_READ - WORLD_EXECUTE +#### main test program #### +PKG_CHECK_MODULES(${TARGET_WAE_TEST}_DEP + REQUIRED ) +SET(${TARGET_WAE_TEST}_SRCS + main.cpp + non-normals.cpp + normals.cpp + internals.cpp + test-helper.cpp +) + +INCLUDE_DIRECTORIES( + SYSTEM + ${${TARGET_WAE_TEST}_DEP_INCLUDE_DIRS} +) +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/srcs + . +) + +ADD_EXECUTABLE(${TARGET_WAE_TEST} ${${TARGET_WAE_TEST}_SRCS}) + +TARGET_LINK_LIBRARIES(${TARGET_WAE_TEST} + ${${TARGET_WAE_TEST}_DEP_LIBRARIES} + ${TARGET_WAE_TEST_COMMON} + ${TARGET_WAE} + -lboost_unit_test_framework + -ldl +) + + +INSTALL(TARGETS ${TARGET_WAE_TEST} + DESTINATION ${BINDIR} + PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE +) diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp new file mode 100644 index 0000000..50bd43c --- /dev/null +++ b/tests/colour_log_formatter.cpp @@ -0,0 +1,268 @@ +/* + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "colour_log_formatter.h" + +#include +#include + +#include +#include +#include +#include +#include + +// ************************************************************************** // +// ************** colour_log_formatter ************** // +// ************************************************************************** // + +using namespace boost::unit_test; +namespace Wae { +namespace Test { + +namespace { + +const char *GREEN_BEGIN = "\033[0;32m"; +const char *RED_BEGIN = "\033[0;31m"; +const char *CYAN_BEGIN = "\033[0;36m"; +const char *BOLD_YELLOW_BEGIN = "\033[1;33m"; +const char *COLOR_END = "\033[m"; + +const_string +test_phase_identifier() +{ + return framework::is_initialized() + ? const_string(framework::current_test_case().p_name.get()) + : BOOST_TEST_L("Test setup"); +} + +const_string +get_basename(const const_string &file_name) +{ + return basename(file_name.begin()); +} + +std::string +get_basename(const std::string &file_name) +{ + return basename(file_name.c_str()); +} + +} // local namespace + +//____________________________________________________________________________// + +void +colour_log_formatter::log_start( + std::ostream &output, + counter_t test_cases_amount) +{ + if (test_cases_amount > 0) + output << "Running " << test_cases_amount << " test " + << (test_cases_amount > 1 ? "cases" : "case") << "..." << std::endl; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_finish(std::ostream &ostr) +{ + ostr.flush(); +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_build_info(std::ostream &output) +{ + output << "Platform: " << BOOST_PLATFORM << std::endl + << "Compiler: " << BOOST_COMPILER << std::endl + << "STL : " << BOOST_STDLIB << std::endl + << "Boost : " << BOOST_VERSION / 100000 << "." + << BOOST_VERSION / 100 % 1000 << "." + << BOOST_VERSION % 100 << std::endl; +} + +//____________________________________________________________________________// + +void +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 << "\"" << + std::endl; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::test_unit_finish( + std::ostream &output, + 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 << "\"" << + std::endl; + return; + } + + std::string color = GREEN_BEGIN; + std::string status = "OK"; + + if (m_isTestCaseFailed) { + color = RED_BEGIN; + status = "FAIL"; + } + + output << "\t" << "[ " << color << status << COLOR_END << " ]"; + + output << ", " << CYAN_BEGIN << "time: "; + + if (elapsed > 0) { + if (elapsed % 1000 == 0) + output << elapsed / 1000 << "ms"; + else + output << elapsed << "mks"; + } else { + output << "N/A"; + } + + output << COLOR_END << std::endl; + m_isTestCaseFailed = false; +} + +//____________________________________________________________________________// + +void +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; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_exception( + 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_entry_start( + std::ostream &output, + log_entry_data const &entry_data, + log_entry_types let) +{ + switch (let) { + case BOOST_UTL_ET_INFO: + output << '\t' << entry_data.m_file_name << '(' << entry_data.m_line_num << + "), "; + output << "info: "; + break; + + case BOOST_UTL_ET_MESSAGE: + break; + + case BOOST_UTL_ET_WARNING: + output << '\t' << get_basename(entry_data.m_file_name) << '(' << + entry_data.m_line_num << "), "; + output << "warning in \"" << test_phase_identifier() << "\": "; + break; + + case BOOST_UTL_ET_ERROR: + output << '\t' << BOLD_YELLOW_BEGIN << get_basename(entry_data.m_file_name) + << '(' << entry_data.m_line_num << "), "; + output << "error in \"" << test_phase_identifier() << "\": "; + m_isTestCaseFailed = true; + break; + + case BOOST_UTL_ET_FATAL_ERROR: + output << '\t' << BOLD_YELLOW_BEGIN << get_basename(entry_data.m_file_name) + << '(' << entry_data.m_line_num << "), "; + output << " fatal error in \"" << test_phase_identifier() << "\": "; + m_isTestCaseFailed = true; + break; + } + + output << COLOR_END; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_entry_value( + std::ostream &output, + const_string value) +{ + output << value; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_entry_value( + std::ostream &output, + lazy_ostream const &value) +{ + output << value; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_entry_finish( + std::ostream &output) +{ + output << std::endl; +} + +//____________________________________________________________________________// + +//____________________________________________________________________________// +} // namespace Test +} // namespace Wae + +//____________________________________________________________________________// + diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h new file mode 100644 index 0000000..7c5dee3 --- /dev/null +++ b/tests/colour_log_formatter.h @@ -0,0 +1,62 @@ +/* + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include + +namespace Wae { +namespace Test { + +class colour_log_formatter : public boost::unit_test::unit_test_log_formatter { +public: + // Formatter interface + colour_log_formatter() : m_isTestCaseFailed(false) {} + void log_start( + std::ostream &, + boost::unit_test::counter_t test_cases_amount); + void log_finish(std::ostream &); + void log_build_info(std::ostream &); + + void test_unit_start( + std::ostream &, + boost::unit_test::test_unit const &tu); + void test_unit_finish( + std::ostream &, + boost::unit_test::test_unit const &tu, + unsigned long elapsed); + void test_unit_skipped( + std::ostream &, + boost::unit_test::test_unit const &tu); + + void log_exception( + std::ostream &, + boost::unit_test::log_checkpoint_data const &, + boost::execution_exception const &ex); + + void log_entry_start( + std::ostream &, + boost::unit_test::log_entry_data const &, + log_entry_types let); + void log_entry_value( + std::ostream &, + boost::unit_test::const_string value); + void log_entry_value( + std::ostream &, + boost::unit_test::lazy_ostream const &value); + void log_entry_finish(std::ostream &); + +private: + bool m_isTestCaseFailed; +}; + +} +} diff --git a/tests/internals.cpp b/tests/internals.cpp new file mode 100644 index 0000000..5d6ca2c --- /dev/null +++ b/tests/internals.cpp @@ -0,0 +1,352 @@ +/* + * 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 internals.cpp + * @author Dongsun Lee (ds73.lee@samsung.com) + * Kyungwook Tak (k.tak@samsung.com) + * @version 2.0 + * @brief internal functions test + */ +#include "web_app_enc.h" + +#include +#include + +#include + +#include "key_handler.h" +#include "crypto_service.h" + +#include "test-common.h" + +BOOST_AUTO_TEST_SUITE(SYSTEM) + +BOOST_AUTO_TEST_SUITE(INTERNALS) + +BOOST_AUTO_TEST_CASE(encrypt_decrypt_app_dek) +{ + const char *private_key = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEpgIBAAKCAQEA0kWtjpRO7Zh2KX2naVE/BDJdrfwK9xexfNA0MkY2VJ4J2AKM\n" + "YTj1D1jntceryupCEHOvP3rum+WsFvPXduz9+VKnSsSqj4jcTUubtpDUGA5G79Iq\n" + "LEPFuSBaqI8Uwkzd08pE+s30oaJDnNazMhSq8JkqBPoCCwtUs73ruE9VbtsBO/kT\n" + "lASIAfe8nXqcJLcDQgWYhizjJw0Pi6d74oCwS2OTvQDNvsXfFnA0ZJEEYw/rZLir\n" + "j7OHoOjz+Sh5N+1uA3Up6SPPEbHuP6L12YxqHdy7gnJXodLhvE/cR4SN9VW7+qmC\n" + "MBjmLkBejGrEX3STS9sLI7MZHu9Y26dwuYb4+wIDAQABAoIBAQCwxqV/vc2RUGDe\n" + "xuXM0+IvrAw37jJlw4SS0xNexMp+XxMViCbuwYy851h96azS/himbiuCKd6aL/96\n" + "mGunbtyiFEvSvv5Jh5z2Wr9BQAcfZjla+4w7BIsg9UNifE/OfgLsQBu34xhsHtfK\n" + "7nFehCOl/I5n+qtnD5KZPe0DWacQdwY4vEAj6YyXdb2bBg+MiwE9KVxGEIUDbklh\n" + "Is70JXczjLZCS+lIpOKh0/lbZmBZePoUbVTtS+GvtPTpQC/aTHRkwGoEtuPEWpbL\n" + "0Q1d6zO+vDJVLJlb5FF2haghs8IlqAxkkPjeUTNye+WktRrDQxmPu/blbxQrygfq\n" + "Au5tBnsxAoGBAOiVtcpg32puo3Yq2Y78oboe9PuHaQP0d3DhwP3/7J0BeNslpjW7\n" + "E1LWsVsCanxTE8XPUdFfAWgMk7lQqESN0wawGmSmWk+eQPZdjHanBaC8vh7aKjo6\n" + "q9FdT1DKjrRi23QyDco3f3E7hvM93IAAhw1ikNu8DT19JAxtdeMh5WAZAoGBAOdw\n" + "6neEvIFXh3RWEv2/GKVhVR8mxDqxmuFdXpOF+YWsK0Tg4uC8jm9kUGnwXgT2Mjke\n" + "oAwYAFcRbHQQGsxy/vkV16kv4aurTE2hMpjeXCAakwV0Pi2w1f9WnDokjgORkOmc\n" + "+QK9I8egdFPMVDfQjhLslhSUY0Eb4qcJ6q9WxfQzAoGBANSsAFybk+7oWAO3TtQW\n" + "YXOk1vIgcYAyS/0mEKixGZS/QdlxZbf/5b17nxTO8rvX416fIftG2ixgQ7vR6us0\n" + "m9+jq56ZFj9zP4eHJudf9h9yNo5TgwVXnMCGh/4iGbcMJgrrsfxUHu5VNiK5UCSj\n" + "VtqAZGDoZVryUMIkXQVhezIRAoGBAN7QUIqcGbcUA24257Wu4hVlrUN+WPCAyDEr\n" + "aL/x/ZV5eXaoYwQlw6LuGpTDOmDgfN2M5FyARuOL/LOIRaSLGXnIU4WoeUSCd8VM\n" + "6Z9Og7bMnrpjfPEUDBH02hcH1kkNPUwLOZgva2Dm0tdSIcpSWFVTu/E4Io4uQHi8\n" + "DVqc2ZsNAoGBAJT76ezXNSSv8hnrKqTpwgTicpqhRZ3eFQjyl4HRL26AJMKv++x8\n" + "4/IsVIwxaHzpbN3nnCjmAHV4gX9YpxVnvYcZflC9WZeDkwNMLmPYb3Zg27EzSMfQ\n" + "8yrfWJZo3qobipcHf1yohAt4fHk9kUKtPHEwp0xKe//rfhswLb3VCzvQ\n" + "-----END RSA PRIVATE KEY-----"; + + const char *public_key = + "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kWtjpRO7Zh2KX2naVE/\n" + "BDJdrfwK9xexfNA0MkY2VJ4J2AKMYTj1D1jntceryupCEHOvP3rum+WsFvPXduz9\n" + "+VKnSsSqj4jcTUubtpDUGA5G79IqLEPFuSBaqI8Uwkzd08pE+s30oaJDnNazMhSq\n" + "8JkqBPoCCwtUs73ruE9VbtsBO/kTlASIAfe8nXqcJLcDQgWYhizjJw0Pi6d74oCw\n" + "S2OTvQDNvsXfFnA0ZJEEYw/rZLirj7OHoOjz+Sh5N+1uA3Up6SPPEbHuP6L12Yxq\n" + "Hdy7gnJXodLhvE/cR4SN9VW7+qmCMBjmLkBejGrEX3STS9sLI7MZHu9Y26dwuYb4\n" + "+wIDAQAB\n" + "-----END PUBLIC KEY-----"; + + std::vector dek(32, 0); + + unsigned char *_encrypted = nullptr; + size_t _encrypted_len = 0; + int ret = encrypt_app_dek(reinterpret_cast(public_key), + strlen(public_key), dek.data(), dek.size(), &_encrypted, + &_encrypted_len); + auto encrypted = Wae::Test::bytearr_to_vec(_encrypted, _encrypted_len); + free(_encrypted); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to encrypt_app_dek. ec: " << ret); + + unsigned char *_decrypted = nullptr; + size_t _decrypted_len = 0; + ret = decrypt_app_dek(reinterpret_cast(private_key), + strlen(private_key), nullptr, encrypted.data(), encrypted.size(), + &_decrypted, &_decrypted_len); + auto decrypted = Wae::Test::bytearr_to_vec(_decrypted, _decrypted_len); + free(_decrypted); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to decrypt_app_dek. ec: " << ret); + + BOOST_REQUIRE_MESSAGE(dek == decrypted, + "encrypted/decrypted dek isn't valid. " + "dek(" << Wae::Test::bytes_to_hex(dek) << ") " + "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); +} + +BOOST_AUTO_TEST_CASE(encrypt_decrypt_aes_cbc) +{ + std::vector plaintext = { + 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', + 'o', 'q', '2', 'e', 'v', '0', '1', 'x' + }; + + size_t dek_len = 32; + std::vector dek(dek_len, 0); + + int ret = _get_random(dek.size(), dek.data()); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get random"); + + unsigned char *_encrypted = nullptr; + size_t _encrypted_len = 0; + ret = encrypt_aes_cbc(dek.data(), dek.size(), plaintext.data(), plaintext.size(), + &_encrypted, &_encrypted_len); + auto encrypted = Wae::Test::bytearr_to_vec(_encrypted, _encrypted_len); + free(_encrypted); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to encrypt_aes_cbc. ec: " << ret); + + unsigned char *_decrypted = nullptr; + size_t _decrypted_len = 0; + ret = decrypt_aes_cbc(dek.data(), dek.size(), encrypted.data(), encrypted.size(), + &_decrypted, &_decrypted_len); + auto decrypted = Wae::Test::bytearr_to_vec(_decrypted, _decrypted_len); + free(_decrypted); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to decrypt_aes_cbc. ec: " << ret); + BOOST_REQUIRE_MESSAGE(plaintext == decrypted, + "decrypted plaintext isn't valid. " + "plaintext(" << Wae::Test::bytes_to_hex(plaintext) << ") " + "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); +} + +BOOST_AUTO_TEST_CASE(cache) +{ + const char *pkg1 = "pkg1"; + const char *pkg2 = "pkg2"; + const char *pkg3 = "pkg3"; + const char *pkgDummy = "dummy"; + + std::vector dek1(32, 1); + std::vector dek2(32, 2); + std::vector dek3(32, 3); + + _initialize_cache(); + + _add_app_dek_to_cache(pkg1, dek1.data()); + _add_app_dek_to_cache(pkg2, dek2.data()); + _add_app_dek_to_cache(pkg3, dek3.data()); + + size_t dek_len = 32; + unsigned char *_cached = _get_app_dek_from_cache(pkg1); + auto cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + + BOOST_REQUIRE_MESSAGE(cached == dek1, + "cached dek isn't valid! " + "dek(" << Wae::Test::bytes_to_hex(dek1) << ") " + "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + + _cached = _get_app_dek_from_cache(pkg2); + cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + + BOOST_REQUIRE_MESSAGE(cached == dek2, + "cached dek isn't valid! " + "dek(" << Wae::Test::bytes_to_hex(dek2) << ") " + "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + + _cached = _get_app_dek_from_cache(pkg3); + cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + + BOOST_REQUIRE_MESSAGE(cached == dek3, + "cached dek isn't valid! " + "dek(" << Wae::Test::bytes_to_hex(dek3) << ") " + "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + + _cached = _get_app_dek_from_cache(pkgDummy); + if (_cached) { + cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + BOOST_REQUIRE_MESSAGE(false, + "wrong cached val is extracted by dummy pkg id. " + "val(" << Wae::Test::bytes_to_hex(cached) << ")"); + } + + _remove_app_dek_from_cache(pkg3); + + _cached = _get_app_dek_from_cache(pkg3); + if (_cached) { + cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + BOOST_REQUIRE_MESSAGE(false, + "app dek removed from cache but it's remained! " + "val(" << Wae::Test::bytes_to_hex(cached) << ")"); + } + + _initialize_cache(); + + _add_app_dek_to_cache(pkg1, dek1.data()); + + _cached = nullptr; + _cached = _get_app_dek_from_cache(pkg2); + if (_cached) { + cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + BOOST_REQUIRE_MESSAGE(false, + "cache is initialized but something is remained! " + "val(" << Wae::Test::bytes_to_hex(cached) << ")"); + } +} + +BOOST_AUTO_TEST_CASE(read_write_encrypted_app_dek) +{ + const char *pkg_id = "write_test_pkg"; + + std::vector dek(256, 0); + + int ret = _write_encrypted_app_dek_to_file(pkg_id, dek.data(), dek.size()); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to write_encrypted_app_dek_to_file. ec: " << ret); + + unsigned char *_readed = nullptr; + size_t _readed_len = 0; + ret = _read_encrypted_app_dek_from_file(pkg_id, &_readed, &_readed_len); + auto readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); + free(_readed); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to read_encrypted_app_dek_from_file. ec: " << ret); + + BOOST_REQUIRE_MESSAGE(dek == readed, + "dek isn't match after write/read file. " + "dek(" << Wae::Test::bytes_to_hex(dek) << ") " + "readed(" << Wae::Test::bytes_to_hex(readed) << ")"); +} + +BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1) +{ + const char *pkg_id = "TEST_PKG_ID_FOR_CREATE"; + + unsigned char *_readed = nullptr; + size_t _readed_len = 0; + int ret = get_preloaded_app_dek(pkg_id, &_readed, &_readed_len); + auto readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); + free(_readed); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NO_KEY, + "preloaded app dek to create is already exist. ec: " << ret); + + unsigned char *_dek = nullptr; + size_t _dek_len = 0; + ret = create_preloaded_app_dek(pkg_id, &_dek, &_dek_len); + auto dek = Wae::Test::bytearr_to_vec(_dek, _dek_len); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, + "Failed to create_preloaded_app_dek. ec: " << ret); + + _readed = nullptr; + ret = get_preloaded_app_dek(pkg_id, &_readed, &_readed_len); + readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); + free(_readed); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, + "Failed to get_preloaded_app_dek. ec: " << ret); + + BOOST_REQUIRE_MESSAGE(dek == readed, + "created/loaded dek is not matched! " + "created(" << Wae::Test::bytes_to_hex(dek) << ") " + "loaded(" << Wae::Test::bytes_to_hex(readed) << ")"); +} + +BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) +{ + 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_dek(pkg_id1, WAE_PRELOADED_APP); + remove_app_dek(pkg_id2, WAE_PRELOADED_APP); + unlink(path1); + unlink(path2); + + // create 2 deks for preloaded app + unsigned char *_dek1 = nullptr; + size_t _dek_len1 = 0; + int ret = create_preloaded_app_dek(pkg_id1, &_dek1, &_dek_len1); + auto dek1 = Wae::Test::bytearr_to_vec(_dek1, _dek_len1); + free(_dek1); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, + "Failed to create_preloaded_app_dek. ec: " << ret); + + unsigned char *_dek2 = nullptr; + size_t _dek_len2 = 0; + ret = create_preloaded_app_dek(pkg_id2, &_dek2, &_dek_len2); + auto dek2 = Wae::Test::bytearr_to_vec(_dek2, _dek_len2); + free(_dek2); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, + "Failed to create_preloaded_app_dek. ec: " << ret); + + ret = load_preloaded_app_deks(true); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, + "Failed to load_preloaded_app_deks. ec: " << ret); + + unsigned char *_readed1 = nullptr; + size_t _readed_len1 = 0; + ret = get_app_dek(pkg_id1, WAE_PRELOADED_APP, &_readed1, &_readed_len1); + auto readed1 = Wae::Test::bytearr_to_vec(_readed1, _readed_len1); + free(_readed1); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); + + unsigned char *_readed2 = nullptr; + size_t _readed_len2 = 0; + ret = get_app_dek(pkg_id2, WAE_PRELOADED_APP, &_readed2, &_readed_len2); + auto readed2 = Wae::Test::bytearr_to_vec(_readed2, _readed_len2); + free(_readed2); + + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); + + BOOST_REQUIRE_MESSAGE(dek1 == readed1, + "readed dek and original isn't matched! " + "original(" << Wae::Test::bytes_to_hex(dek1) << ") " + "readed(" << Wae::Test::bytes_to_hex(readed1) << ")"); + + BOOST_REQUIRE_MESSAGE(dek2 == readed2, + "readed dek and original isn't matched! " + "original(" << Wae::Test::bytes_to_hex(dek2) << ") " + "readed(" << Wae::Test::bytes_to_hex(readed2) << ")"); + + ret = remove_app_dek(pkg_id1, WAE_PRELOADED_APP); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, + "Failed remove app dek after used. ec: " << ret); + + ret = remove_app_dek(pkg_id2, WAE_PRELOADED_APP); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, + "Failed remove app dek after used. ec: " << ret); +} + +BOOST_AUTO_TEST_SUITE_END() // INTERNALS + +BOOST_AUTO_TEST_SUITE_END() // SYSTEM diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 0000000..2f52e03 --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,28 @@ +/* + * 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 main.cpp + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief test main used boost test framework + */ +#define BOOST_TEST_MODULE WAE_INTERNAL_TEST + +#include + +#include "test-common.h" + +BOOST_GLOBAL_FIXTURE(TestConfig); diff --git a/tests/non-normals.cpp b/tests/non-normals.cpp new file mode 100644 index 0000000..8667bfc --- /dev/null +++ b/tests/non-normals.cpp @@ -0,0 +1,70 @@ +/* + * 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 non-normals.cpp + * @author Dongsun Lee (ds73.lee@samsung.com) + * Kyungwook Tak (k.tak@samsung.com) + * @version 2.0 + * @brief API test for preloaded/global apps + */ +#include "web_app_enc.h" + +#include + +#include "test-helper.h" + +BOOST_AUTO_TEST_SUITE(SYSTEM) + +BOOST_AUTO_TEST_SUITE(GLOBAL_APP) + +BOOST_AUTO_TEST_CASE(add_get_remove_dek) +{ + Wae::Test::add_get_remove_dek(WAE_DOWNLOADED_GLOBAL_APP); +} + +BOOST_AUTO_TEST_CASE(create_app_dek) +{ + Wae::Test::create_app_dek(WAE_DOWNLOADED_GLOBAL_APP); +} + +BOOST_AUTO_TEST_CASE(encrypt_decrypt) +{ + Wae::Test::encrypt_decrypt_web_app(WAE_DOWNLOADED_GLOBAL_APP); +} + +BOOST_AUTO_TEST_SUITE_END() // GLOBAL_APP + + +BOOST_AUTO_TEST_SUITE(PRELOADED_APP) + +BOOST_AUTO_TEST_CASE(add_get_remove_dek) +{ + Wae::Test::add_get_remove_dek(WAE_PRELOADED_APP); +} + +BOOST_AUTO_TEST_CASE(create_app_dek) +{ + Wae::Test::create_app_dek(WAE_PRELOADED_APP); +} + +BOOST_AUTO_TEST_CASE(encrypt_decrypt) +{ + Wae::Test::encrypt_decrypt_web_app(WAE_PRELOADED_APP); +} + +BOOST_AUTO_TEST_SUITE_END() // PRELOADED_APP + +BOOST_AUTO_TEST_SUITE_END() // SYSTEM diff --git a/tests/normals.cpp b/tests/normals.cpp new file mode 100644 index 0000000..2ce272e --- /dev/null +++ b/tests/normals.cpp @@ -0,0 +1,50 @@ +/* + * 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 normals.cpp + * @author Dongsun Lee (ds73.lee@samsung.com) + * Kyungwook Tak (k.tak@samsung.com) + * @version 2.0 + * @brief test for normal downloaded app + */ +#include "web_app_enc.h" + +#include + +#include "test-helper.h" + +BOOST_AUTO_TEST_SUITE(USER) + +BOOST_AUTO_TEST_SUITE(DOWNLOADED_APP); + +BOOST_AUTO_TEST_CASE(add_get_remove_dek) +{ + Wae::Test::add_get_remove_dek(WAE_DOWNLOADED_NORMAL_APP); +} + +BOOST_AUTO_TEST_CASE(create_app_dek) +{ + Wae::Test::create_app_dek(WAE_DOWNLOADED_NORMAL_APP); +} + +BOOST_AUTO_TEST_CASE(encrypt_decrypt_normal_app) +{ + Wae::Test::encrypt_decrypt_web_app(WAE_DOWNLOADED_NORMAL_APP); +} + +BOOST_AUTO_TEST_SUITE_END() // DOWNLOADED_APP + +BOOST_AUTO_TEST_SUITE_END() // USER diff --git a/tests/test-common.cpp b/tests/test-common.cpp new file mode 100644 index 0000000..3e9e331 --- /dev/null +++ b/tests/test-common.cpp @@ -0,0 +1,55 @@ +/* + * 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 test-common.cpp + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + */ +#include "test-common.h" + +#include +#include +#include + +namespace Wae { +namespace Test { + +std::string bytes_to_hex(const std::vector &bytes) +{ + std::stringstream ss; + ss << std::hex; + + for (auto b : bytes) + ss << std::setw(2) << std::setfill('0') << static_cast(b); + + return ss.str(); +} + +std::vector bytearr_to_vec(const unsigned char *bytes, size_t len) +{ + if (bytes == nullptr || len == 0) + return std::vector(); + + std::vector vec; + + for (size_t i = 0; i < len; ++i) + vec.push_back(bytes[i]); + + return vec; +} + +} // namespace Test +} // namespace Wae diff --git a/tests/test-common.h b/tests/test-common.h new file mode 100644 index 0000000..2c4c54e --- /dev/null +++ b/tests/test-common.h @@ -0,0 +1,51 @@ +/* + * 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 test-common.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + */ +#pragma once + +#include + +#include +#include +#include + +#include "colour_log_formatter.h" + +/* fixtures should be declared on outside of namespace */ +struct TestConfig { + TestConfig() + { + boost::unit_test::unit_test_log.set_threshold_level(boost::unit_test::log_test_units); + boost::unit_test::results_reporter::set_level(boost::unit_test::SHORT_REPORT); + boost::unit_test::unit_test_log.set_formatter(new Wae::Test::colour_log_formatter); + + BOOST_TEST_MESSAGE("run test program with --run_test=SYSTEM on sdb root turned ON"); + BOOST_TEST_MESSAGE("run test program with --run_test=USER on sdb root turned OFF"); + } +}; + +namespace Wae { +namespace Test { + +std::string bytes_to_hex(const std::vector &bytes); +std::vector bytearr_to_vec(const unsigned char *bytes, size_t len); + +} // namespace Test +} // namespace Wae diff --git a/tests/test-helper.cpp b/tests/test-helper.cpp new file mode 100644 index 0000000..144299a --- /dev/null +++ b/tests/test-helper.cpp @@ -0,0 +1,178 @@ +/* + * 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 test-helper.cpp + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + */ +#include "test-helper.h" + +#include +#include + +#include "key_handler.h" +#include "crypto_service.h" + +#include "test-common.h" + +namespace Wae { +namespace Test { + +void add_get_remove_dek(wae_app_type_e app_type) +{ + const char *pkg_id = "TEST_PKG_ID"; + + std::vector dek(32, 0); + + BOOST_REQUIRE(_get_random(dek.size(), dek.data()) == WAE_ERROR_NONE); + + remove_app_dek(pkg_id, app_type); + + int tmp = _add_dek_to_key_manager(pkg_id, app_type, dek.data(), dek.size()); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, + "Failed to _add_dek_to_key_manager. ec: " << tmp); + + unsigned char *_stored_dek = nullptr; + size_t _stored_dek_len = 0; + tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, + "Failed to get_app_dek. ec: " << tmp); + + auto stored_dek = Wae::Test::bytearr_to_vec(_stored_dek, _stored_dek_len); + free(_stored_dek); + + BOOST_REQUIRE_MESSAGE(stored_dek == dek, "stored dek and dek isn't matched!"); + + tmp = remove_app_dek(pkg_id, app_type); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_dek. ec: " << tmp); + + _stored_dek = nullptr; + tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); + if (_stored_dek) + free(_stored_dek); + + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY, + "dek removed but it's remained still. ec: " << tmp); +} + +void create_app_dek(wae_app_type_e app_type) +{ + const char *pkg_id = "TEST_PKG_ID"; + + remove_app_dek(pkg_id, app_type); + + unsigned char *_dek = nullptr; + size_t _dek_len = 0; + + int tmp = create_app_dek(pkg_id, app_type, &_dek, &_dek_len); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, + "Failed to create_app_dek. ec: " << tmp); + + auto dek = Wae::Test::bytearr_to_vec(_dek, _dek_len); + free(_dek); + + unsigned char *_stored_dek = nullptr; + size_t _stored_dek_len = 0; + tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << tmp); + auto stored_dek = bytearr_to_vec(_stored_dek, _stored_dek_len); + free(_stored_dek); + + BOOST_REQUIRE_MESSAGE(stored_dek == dek, + "stored dek and dek isn't matched! " + "stored_dek(" << Wae::Test::bytes_to_hex(stored_dek) << ") " + "dek(" << Wae::Test::bytes_to_hex(dek) << ")"); + + remove_app_dek(pkg_id, app_type); +} + +void encrypt_decrypt_web_app(wae_app_type_e app_type) +{ + const char *pkg_id1 = "testpkg_for_normal"; + const char *pkg_id2 = "testpkg_for_global"; + const char *pkg_id3 = "testpkg_for_preloaded"; + + const char *pkg_id = nullptr; + switch (app_type) { + case WAE_DOWNLOADED_NORMAL_APP: + pkg_id = pkg_id1; + break; + + case WAE_DOWNLOADED_GLOBAL_APP: + pkg_id = pkg_id2; + break; + + case WAE_PRELOADED_APP: + default: + pkg_id = pkg_id3; + break; + } + + // remove old test data + wae_remove_app_dek(pkg_id, app_type); + + if (app_type == WAE_PRELOADED_APP) + _clear_app_deks_loaded(); + + std::vector plaintext = { + 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', + 'o', 'q', '2', 'e', 'v', '0', '1', 'x' + }; + + // 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); + 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); + 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_dek_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); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, + "Failed to wae_decrypt_web_application. ec: " << tmp); + + auto decrypted = bytearr_to_vec(_decrypted, _dec_len); + + BOOST_REQUIRE_MESSAGE(plaintext == decrypted, + "plaintext and decrypted isn't matched! " + "plaintext(" << Wae::Test::bytes_to_hex(plaintext) << ") " + "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); + + tmp = wae_remove_app_dek(pkg_id, app_type); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, + "Failed to wae_remove_app_dek. ec: " << tmp); +} + +} // namespace Test +} // namespace Wae diff --git a/tests/test-helper.h b/tests/test-helper.h new file mode 100644 index 0000000..132ceae --- /dev/null +++ b/tests/test-helper.h @@ -0,0 +1,33 @@ +/* + * 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 test-helper.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + */ +#pragma once + +#include "web_app_enc.h" + +namespace Wae { +namespace Test { + +void add_get_remove_dek(wae_app_type_e app_type); +void create_app_dek(wae_app_type_e app_type); +void encrypt_decrypt_web_app(wae_app_type_e app_type); + +} // namespace Test +} // namespace Wae diff --git a/tests/wae_tests.c b/tests/wae_tests.c deleted file mode 100644 index c724d21..0000000 --- a/tests/wae_tests.c +++ /dev/null @@ -1,923 +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 - * - * - * @file wae_tests.c - * @author Dongsun Lee (ds73.lee@samsung.com) - * @version 1.0 - * @brief internal test cases for libwebappenc. - */ - -#include -#include -#include -#include - -#include "web_app_enc.h" -#include "key_handler.h" -#include "crypto_service.h" - -#include - -static int tc_seq = 0; -static int tc_succ = 0; -static int tc_fail = 0; - -#define FPRINTF(format, args...) fprintf(stdout, format, ##args) - -static int RUNTC(int (*tc_method)(), const char *tc_name) -{ - int ret = WAE_ERROR_NONE; - FPRINTF("[%02d:%s]started...\n", tc_seq, tc_name); - ret = tc_method(); - - if (ret == WAE_ERROR_NONE) { - FPRINTF("[%02d:%s]ended. SUCCESS\n\n", tc_seq, tc_name); - tc_succ++; - } else { - FPRINTF("[%02d:%s]ended. FAIL. error=%d\n\n", tc_seq, tc_name, ret); - tc_fail++; - } - - tc_seq++; - return ret; -} - -static void PRINT_TC_SUMMARY() -{ - FPRINTF("\n"); - FPRINTF("===============================================\n"); - FPRINTF(" TOTAL = %d, SUCCESS = %d, FAIL = %d\n", tc_seq, tc_succ, tc_fail); - FPRINTF("===============================================\n"); -} - -void _print_binary_to_hex(const char *msg, unsigned char *bin, size_t len) -{ - size_t i = 0; - FPRINTF("%s", msg); - - for (i = 0; i < len; i++) { - FPRINTF("%02x", bin[i]); - } - - FPRINTF("\n"); -} - -int _compare_binary(const unsigned char *b1, size_t b1Len, const unsigned char *b2, size_t b2Len) -{ - size_t i = 0; - - if (b1Len != b2Len) - return b1Len - b2Len; - - for (i = 0; i < b1Len; i++) { - if (b1[i] != b2[i]) - return b1[i] - b2[i]; - } - - return 0; -} - -//================================================================================= -// tests for crypto_service.h -//================================================================================= -int wae_tc_encrypt_decrypt_app_dek() -{ - int ret = WAE_ERROR_NONE; - unsigned char dek[32]; - unsigned char *encryptedDek = NULL; - size_t encryptedDekLen = 0; - unsigned char *decryptedDek = NULL; - size_t decryptedDekLen = 0; - - const char *priKey = - "-----BEGIN RSA PRIVATE KEY-----\n" - "MIIEpgIBAAKCAQEA0kWtjpRO7Zh2KX2naVE/BDJdrfwK9xexfNA0MkY2VJ4J2AKM\n" - "YTj1D1jntceryupCEHOvP3rum+WsFvPXduz9+VKnSsSqj4jcTUubtpDUGA5G79Iq\n" - "LEPFuSBaqI8Uwkzd08pE+s30oaJDnNazMhSq8JkqBPoCCwtUs73ruE9VbtsBO/kT\n" - "lASIAfe8nXqcJLcDQgWYhizjJw0Pi6d74oCwS2OTvQDNvsXfFnA0ZJEEYw/rZLir\n" - "j7OHoOjz+Sh5N+1uA3Up6SPPEbHuP6L12YxqHdy7gnJXodLhvE/cR4SN9VW7+qmC\n" - "MBjmLkBejGrEX3STS9sLI7MZHu9Y26dwuYb4+wIDAQABAoIBAQCwxqV/vc2RUGDe\n" - "xuXM0+IvrAw37jJlw4SS0xNexMp+XxMViCbuwYy851h96azS/himbiuCKd6aL/96\n" - "mGunbtyiFEvSvv5Jh5z2Wr9BQAcfZjla+4w7BIsg9UNifE/OfgLsQBu34xhsHtfK\n" - "7nFehCOl/I5n+qtnD5KZPe0DWacQdwY4vEAj6YyXdb2bBg+MiwE9KVxGEIUDbklh\n" - "Is70JXczjLZCS+lIpOKh0/lbZmBZePoUbVTtS+GvtPTpQC/aTHRkwGoEtuPEWpbL\n" - "0Q1d6zO+vDJVLJlb5FF2haghs8IlqAxkkPjeUTNye+WktRrDQxmPu/blbxQrygfq\n" - "Au5tBnsxAoGBAOiVtcpg32puo3Yq2Y78oboe9PuHaQP0d3DhwP3/7J0BeNslpjW7\n" - "E1LWsVsCanxTE8XPUdFfAWgMk7lQqESN0wawGmSmWk+eQPZdjHanBaC8vh7aKjo6\n" - "q9FdT1DKjrRi23QyDco3f3E7hvM93IAAhw1ikNu8DT19JAxtdeMh5WAZAoGBAOdw\n" - "6neEvIFXh3RWEv2/GKVhVR8mxDqxmuFdXpOF+YWsK0Tg4uC8jm9kUGnwXgT2Mjke\n" - "oAwYAFcRbHQQGsxy/vkV16kv4aurTE2hMpjeXCAakwV0Pi2w1f9WnDokjgORkOmc\n" - "+QK9I8egdFPMVDfQjhLslhSUY0Eb4qcJ6q9WxfQzAoGBANSsAFybk+7oWAO3TtQW\n" - "YXOk1vIgcYAyS/0mEKixGZS/QdlxZbf/5b17nxTO8rvX416fIftG2ixgQ7vR6us0\n" - "m9+jq56ZFj9zP4eHJudf9h9yNo5TgwVXnMCGh/4iGbcMJgrrsfxUHu5VNiK5UCSj\n" - "VtqAZGDoZVryUMIkXQVhezIRAoGBAN7QUIqcGbcUA24257Wu4hVlrUN+WPCAyDEr\n" - "aL/x/ZV5eXaoYwQlw6LuGpTDOmDgfN2M5FyARuOL/LOIRaSLGXnIU4WoeUSCd8VM\n" - "6Z9Og7bMnrpjfPEUDBH02hcH1kkNPUwLOZgva2Dm0tdSIcpSWFVTu/E4Io4uQHi8\n" - "DVqc2ZsNAoGBAJT76ezXNSSv8hnrKqTpwgTicpqhRZ3eFQjyl4HRL26AJMKv++x8\n" - "4/IsVIwxaHzpbN3nnCjmAHV4gX9YpxVnvYcZflC9WZeDkwNMLmPYb3Zg27EzSMfQ\n" - "8yrfWJZo3qobipcHf1yohAt4fHk9kUKtPHEwp0xKe//rfhswLb3VCzvQ\n" - "-----END RSA PRIVATE KEY-----"; - const char *pubKey = - "-----BEGIN PUBLIC KEY-----\n" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kWtjpRO7Zh2KX2naVE/\n" - "BDJdrfwK9xexfNA0MkY2VJ4J2AKMYTj1D1jntceryupCEHOvP3rum+WsFvPXduz9\n" - "+VKnSsSqj4jcTUubtpDUGA5G79IqLEPFuSBaqI8Uwkzd08pE+s30oaJDnNazMhSq\n" - "8JkqBPoCCwtUs73ruE9VbtsBO/kTlASIAfe8nXqcJLcDQgWYhizjJw0Pi6d74oCw\n" - "S2OTvQDNvsXfFnA0ZJEEYw/rZLirj7OHoOjz+Sh5N+1uA3Up6SPPEbHuP6L12Yxq\n" - "Hdy7gnJXodLhvE/cR4SN9VW7+qmCMBjmLkBejGrEX3STS9sLI7MZHu9Y26dwuYb4\n" - "+wIDAQAB\n" - "-----END PUBLIC KEY-----"; - - ret = encrypt_app_dek((const unsigned char *) pubKey, strlen(pubKey), - dek, sizeof(dek), &encryptedDek, &encryptedDekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: encrypt_app_dek. ret=%d\n", ret); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - ret = decrypt_app_dek((const unsigned char *) priKey, strlen(priKey), NULL, - encryptedDek, encryptedDekLen, &decryptedDek, &decryptedDekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: decrypt_app_dek. ret=%d\n", ret); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - _print_binary_to_hex("...ORIG DEK= ", dek, sizeof(dek)); - _print_binary_to_hex("...ENC DEK= ", encryptedDek, encryptedDekLen); - _print_binary_to_hex("...DEC DEK= ", decryptedDek, decryptedDekLen); - - if (_compare_binary(dek, sizeof(dek), decryptedDek, decryptedDekLen) != 0) { - FPRINTF("...FAIL: ORIG DEK != decrypted DEK\n"); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - ret = WAE_ERROR_NONE; - -error: - if (encryptedDek != NULL) - free(encryptedDek); - - if (decryptedDek != NULL) - free(decryptedDek); - - return ret; -} - -int wae_tc_encrypt_decrypt_aes_cbc() -{ - int ret = WAE_ERROR_NONE; - - unsigned char dek[32] = {0, }; - size_t keyLen = 32; - const char *plaintext = "adbdfdfdfdfdererfdfdfererfdrerfdrer"; - size_t plaintextLen = strlen(plaintext); - unsigned char *encrypted = NULL; - size_t encLen = 0; - unsigned char *decrypted = NULL; - size_t decLen = 0; - char decrypted_str[1024] = {0, }; - - ret = _get_random(keyLen, dek); - - ret = encrypt_aes_cbc(dek, keyLen, (const unsigned char *)plaintext, plaintextLen, &encrypted, &encLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: encrypt_aes_cbc. ret=%d\n", ret); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - ret = decrypt_aes_cbc(dek, keyLen, encrypted, encLen, &decrypted, &decLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: decrypt_aes_cbc. ret=%d\n", ret); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - if (plaintextLen != decLen) { - FPRINTF("...FAIL: plaintextLen(%d) != decLen(%d)\n", (int) plaintextLen, (int) decLen); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - memcpy(decrypted_str, decrypted, decLen); - FPRINTF("...plaintext = %s\n", plaintext); - FPRINTF("...decrypted = %s\n", decrypted_str); - - if (strcmp(plaintext, decrypted_str) != 0) { - FPRINTF("...FAIL: plaintext(%s) != decrypted(%s)\n", plaintext, decrypted_str); - ret = WAE_ERROR_CRYPTO; - goto error; - } - -error: - if (encrypted != NULL) - free(encrypted); - - if (decrypted != NULL) - free(decrypted); - - return ret; -} - -//================================================================================= -// tests for key_handler.h -//================================================================================= -int wae_tc_cache() -{ - int ret = WAE_ERROR_NONE; - - const char *pkg1 = "pkg1"; - const char *pkg2 = "pkg2"; - const char *pkg3 = "pkg3"; - const char *pkgDummy = "dummy"; - - unsigned char dek1[32] = {1, }; - unsigned char dek2[32] = {2, }; - unsigned char dek3[32] = {3, }; - unsigned char *retDek = NULL; - - _initialize_cache(); - - _add_app_dek_to_cache(pkg1, dek1); - _add_app_dek_to_cache(pkg2, dek2); - _add_app_dek_to_cache(pkg3, dek3); - - retDek = NULL; - retDek = _get_app_dek_from_cache(pkg1); - - if (retDek == NULL || _compare_binary(dek1, 32, retDek, 32) != 0) { - FPRINTF("failed in cache. Diffent DEK1\n"); - ret = WAE_ERROR_UNKNOWN; - goto error; - } - - _print_binary_to_hex("...DEK1 : ", dek1, 32); - _print_binary_to_hex("...Returen DEK1 : ", retDek, 32); - - retDek = NULL; - retDek = _get_app_dek_from_cache(pkg2); - - if (retDek == NULL || _compare_binary(dek2, 32, retDek, 32) != 0) { - FPRINTF("failed in cache. Diffent DEK2\n"); - ret = WAE_ERROR_UNKNOWN; - goto error; - } - - _print_binary_to_hex("...DEK2 : ", dek2, 32); - _print_binary_to_hex("...Returen DEK1 : ", retDek, 32); - - retDek = NULL; - retDek = _get_app_dek_from_cache(pkg3); - - if (retDek == NULL || _compare_binary(dek3, 32, retDek, 32) != 0) { - FPRINTF("failed in cache. Diffent DEK3\n"); - ret = WAE_ERROR_UNKNOWN; - goto error; - } - - _print_binary_to_hex("...DEK3 : ", dek3, 32); - _print_binary_to_hex("...Returen DEK3 : ", retDek, 32); - - retDek = NULL; - retDek = _get_app_dek_from_cache(pkgDummy); - - if (retDek != NULL) { - FPRINTF("failed in cache. Wrong DEK_DUMMY1 returned\n"); - _print_binary_to_hex("retured wrong DEK : ", retDek, 32); - ret = WAE_ERROR_UNKNOWN; - goto error; - } - - _remove_app_dek_from_cache(pkg3); - retDek = NULL; - retDek = _get_app_dek_from_cache(pkg3); - - if (retDek != NULL) { - FPRINTF("fail to remove app dek from cache\n"); - ret = WAE_ERROR_UNKNOWN; - goto error; - } - - _initialize_cache(); - - _add_app_dek_to_cache(pkg1, dek1); - - retDek = NULL; - retDek = _get_app_dek_from_cache(pkg2); - - if (retDek != NULL) { - FPRINTF("failed in cache. Wrong DEK_DUMMY2 returned\n"); - _print_binary_to_hex("retured wrong DEK : ", retDek, 32); - ret = WAE_ERROR_UNKNOWN; - goto error; - } - - ret = WAE_ERROR_NONE; - -error: - return ret; -} - -int wae_tc_get_random() -{ - int ret = WAE_ERROR_NONE; - - size_t rand_len = 32; - unsigned char random[32] = {0, }; - - ret = _get_random(rand_len, random); - - _print_binary_to_hex("...RANDOM = ", random, sizeof(random)); - - return ret; -} - -int wae_tc_get_alias() -{ - int ret = WAE_ERROR_NONE; - - const char *pkgId = "TEST_PKG_ID"; - char alias[256] = {0, }; - - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, true, alias, sizeof(alias)); - FPRINTF("...pkgid=%s, alias for normal for save. app=%s\n", pkgId, alias); - - _get_alias(pkgId, WAE_DOWNLOADED_NORMAL_APP, false, alias, sizeof(alias)); - FPRINTF("...pkgid=%s, alias for normal for get. app=%s\n", pkgId, alias); - - _get_alias(pkgId, WAE_DOWNLOADED_GLOBAL_APP, true, alias, sizeof(alias)); - FPRINTF("...pkgid=%s, alias for global app=%s\n", pkgId, alias); - - _get_alias(pkgId, WAE_PRELOADED_APP, true, alias, sizeof(alias)); - FPRINTF("...pkgid=%s, alias for preloaded app=%s\n", pkgId, alias); - - return ret; -} - -int _wae_tc_add_get_remove_dek(wae_app_type_e appType) -{ - int ret = WAE_ERROR_NONE; - - const char *pkgId = "TEST_PKG_ID"; - - size_t dekLen = 32; - unsigned char dek[32] = {0, }; - size_t storedDekLen = 0; - unsigned char *storedDek = NULL; - - ret = _get_random(dekLen, dek); - - remove_app_dek(pkgId, appType); - - ret = _add_dek_to_key_manager(pkgId, appType, dek, dekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: _add_dek_to_key_manager. ret=%d\n", ret); - goto error; - } - - ret = get_app_dek(pkgId, appType, &storedDek, &storedDekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: get_app_dek. ret=%d\n", ret); - goto error; - } - - if (_compare_binary(dek, dekLen, storedDek, storedDekLen) != 0) { - ret = WAE_ERROR_KEY_MANAGER; - FPRINTF("...FAIL: DEK != STORED_DEK.\n"); - goto error; - } - - ret = remove_app_dek(pkgId, appType); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: remove_app_dek. ret=%d\n", ret); - goto error; - } - - ret = get_app_dek(pkgId, appType, &storedDek, &storedDekLen); - - if (ret == WAE_ERROR_NONE) { - ret = WAE_ERROR_UNKNOWN; - FPRINTF("...FAIL: APP DEK still exists in key_manager.\n"); - goto error; - } - - ret = WAE_ERROR_NONE; - -error: - if (storedDek != NULL) - free(storedDek); - - return ret; -} - -int wae_tc_add_get_remove_dek_for_normal_app() -{ - return _wae_tc_add_get_remove_dek(WAE_DOWNLOADED_NORMAL_APP); -} - -int wae_tc_add_get_remove_dek_for_global_app() -{ - return _wae_tc_add_get_remove_dek(WAE_DOWNLOADED_GLOBAL_APP); -} - -int wae_tc_add_get_remove_dek_for_preloaded_app() -{ - return _wae_tc_add_get_remove_dek(WAE_PRELOADED_APP); -} - -int wae_tc_get_preloaded_app_dek_file_path() -{ - int ret = WAE_ERROR_NONE; - - const char *pkgId = "test_pkg"; - const char *expectedPath = tzplatform_mkpath4(TZ_SYS_SHARE, - "wae", "app_dek", "WAE_APP_DEK_test_pkg.adek"); - char path[256]; - - FPRINTF("...expected path : %s\n", expectedPath); - ret = _get_preloaded_app_dek_file_path(pkgId, sizeof(path), path); - FPRINTF("...returned path : %s\n", path); - - if (ret != WAE_ERROR_NONE || strncmp(expectedPath, path, strlen(expectedPath)) != 0) { - ret = WAE_ERROR_UNKNOWN; - goto error; - } - -error: - return ret; -} - -int wae_tc_extract_pkg_id_from_file_name() -{ - int ret = WAE_ERROR_NONE; - const char *fileName = "WAE_APP_DEK_test_pkg.adek"; - const char *expectedPkgId = "test_pkg"; - char pkgId[100]; - - ret = _extract_pkg_id_from_file_name(fileName, pkgId); - FPRINTF("...expected pkgId: %s\n", expectedPkgId); - FPRINTF("...returned pkgId: %s\n", pkgId); - - if (ret != WAE_ERROR_NONE || strncmp(expectedPkgId, pkgId, strlen(expectedPkgId)) != 0) { - ret = WAE_ERROR_UNKNOWN; - goto error; - } - -error: - return ret; - -} - -int wae_tc_read_write_encrypted_app_dek() -{ - int ret = WAE_ERROR_NONE; - const char *pkgId = "write_test_pkg"; - unsigned char dek[256]; - unsigned char *readDek = NULL; - size_t readDekLen = 0; - - ret = _write_encrypted_app_dek_to_file(pkgId, dek, sizeof(dek)); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("Fail to _write_encrypted_app_dek_to_file. pkgId=%s\n", pkgId); - goto error; - } - - ret = _read_encrypted_app_dek_from_file(pkgId, &readDek, &readDekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("Fail to _read_encrypted_app_dek_from_file. pkgId=%s\n", pkgId); - goto error; - } - - _print_binary_to_hex("...ORIG DEK= ", dek, sizeof(dek)); - _print_binary_to_hex("...READ DEK= ", readDek, readDekLen); - - if (_compare_binary(dek, sizeof(dek), readDek, readDekLen) != 0) { - ret = WAE_ERROR_UNKNOWN; - FPRINTF("...FAIL: DEK != read_DEK.\n"); - goto error; - } - -error: - if (readDek != NULL) - free(readDek); - - return ret; -} - - -int _wae_tc_create_app_dek(wae_app_type_e appType) -{ - int ret = WAE_ERROR_NONE; - - const char *pkgId = "TEST_PKG_ID"; - unsigned char *dek = NULL; - size_t dekLen = 0; - - size_t storedDekLen = 0; - unsigned char *storedDek = NULL; - - remove_app_dek(pkgId, appType); - - ret = create_app_dek(pkgId, appType, &dek, &dekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: create_app_dek. ret=%d\n", ret); - goto error; - } - - ret = get_app_dek(pkgId, appType, &storedDek, &storedDekLen); - - if (ret != WAE_ERROR_NONE) { - ret = WAE_ERROR_KEY_MANAGER; - FPRINTF("...FAIL: get_app_dek. ret=%d\n", ret); - goto error; - } - - _print_binary_to_hex("...CREATED DEK = ", dek, dekLen); - _print_binary_to_hex("...STORED DEK = ", storedDek, storedDekLen); - - if (_compare_binary(dek, dekLen, storedDek, storedDekLen) != 0) { - ret = WAE_ERROR_FILE; - FPRINTF("...FAIL: DEK != STORED_DEK.\n"); - goto error; - } - - remove_app_dek(pkgId, appType); - - ret = WAE_ERROR_NONE; - -error: - if (dek != NULL) - free(dek); - - if (storedDek != NULL) - free(storedDek); - - return ret; -} - -int wae_tc_create_app_dek_for_normal_app() -{ - return _wae_tc_create_app_dek(WAE_DOWNLOADED_NORMAL_APP); -} - -int wae_tc_create_app_dek_for_global_app() -{ - return _wae_tc_create_app_dek(WAE_DOWNLOADED_GLOBAL_APP); -} - -int wae_tc_create_app_dek_for_preloaded_app() -{ - return _wae_tc_create_app_dek(WAE_PRELOADED_APP); -} - -int wae_tc_get_create_preloaded_app_dek() -{ - int ret = WAE_ERROR_NONE; - - const char *pkgId = "TEST_PKG_ID_FOR_CREATE"; - unsigned char *dek = NULL; - unsigned char *readDek = NULL; - size_t readDekLen = 0; - size_t dekLen = 0; - - ret = get_preloaded_app_dek(pkgId, &readDek, &readDekLen); - - if (ret != WAE_ERROR_NO_KEY) { - FPRINTF("...FAIL: There should be no APP DEK. get_preloaded_app_dek. ret=%d\n", ret); - ret = WAE_ERROR_FILE; - goto error; - } - - ret = create_preloaded_app_dek(pkgId, &dek, &dekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: create_preloaded_app_dek. ret=%d\n", ret); - goto error; - } - - ret = get_preloaded_app_dek(pkgId, &readDek, &readDekLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: get_preloaded_app_dek. ret=%d\n", ret); - goto error; - } - - _print_binary_to_hex("...CREATED DEK = ", dek, dekLen); - _print_binary_to_hex("...READ DEK = ", readDek, readDekLen); - - if (_compare_binary(dek, dekLen, readDek, readDekLen) != 0) { - ret = WAE_ERROR_FILE; - FPRINTF("...FAIL: DEK != READ_DEK.\n"); - goto error; - } - - ret = WAE_ERROR_NONE; - -error: - if (dek != NULL) - free(dek); - - if (readDek != NULL) - free(readDek); - - return ret; -} - -int wae_tc_load_preloaded_app_deks() -{ - int ret = WAE_ERROR_NONE; - - const char *pkgId1 = "TEST_PKGID_1"; - unsigned char *dek1 = NULL; - size_t dekLen1 = 0; - unsigned char *readDek1 = NULL; - size_t readDekLen1 = 0; - char path1[MAX_PATH_LEN] = {0, }; - - const char *pkgId2 = "TEST_PKGID_2"; - unsigned char *dek2 = NULL; - size_t dekLen2 = 0; - unsigned char *readDek2 = NULL; - size_t readDekLen2 = 0; - char path2[MAX_PATH_LEN] = {0, }; - - _get_preloaded_app_dek_file_path(pkgId1, sizeof(path1), path1); - _get_preloaded_app_dek_file_path(pkgId2, sizeof(path2), path2); - - // remove old test data - remove_app_dek(pkgId1, WAE_PRELOADED_APP); - remove_app_dek(pkgId2, WAE_PRELOADED_APP); - unlink(path1); - unlink(path2); - - // create 2 dek for preloaded app - ret = create_preloaded_app_dek(pkgId1, &dek1, &dekLen1); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: create_preloaded_app_dek. ret=%d\n", ret); - goto error; - } - - ret = create_preloaded_app_dek(pkgId2, &dek2, &dekLen2); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: create_preloaded_app_dek. ret=%d\n", ret); - goto error; - } - - // load_preloaded_app_deks - ret = load_preloaded_app_deks(true); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: load_preloaded_app_deks. ret=%d\n", ret); - goto error; - } - - // get_app_dek - ret = get_app_dek(pkgId1, WAE_PRELOADED_APP, &readDek1, &readDekLen1); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: get_app_dek. ret=%d\n", ret); - goto error; - } - - ret = get_app_dek(pkgId2, WAE_PRELOADED_APP, &readDek2, &readDekLen2); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: get_app_dek. ret=%d\n", ret); - goto error; - } - - _print_binary_to_hex("...CREATED DEK1 = ", dek1, dekLen1); - _print_binary_to_hex("...READ DEK1 = ", readDek1, readDekLen1); - - if (_compare_binary(dek1, dekLen1, readDek1, readDekLen1) != 0) { - ret = WAE_ERROR_FILE; - FPRINTF("...FAIL: DEK1 != READ_DEK1.\n"); - goto error; - } - - _print_binary_to_hex("...CREATED DEK2 = ", dek2, dekLen2); - _print_binary_to_hex("...READ DEK2 = ", readDek2, readDekLen2); - - if (_compare_binary(dek2, dekLen2, readDek2, readDekLen2) != 0) { - ret = WAE_ERROR_FILE; - FPRINTF("...FAIL: DEK2 != READ_DEK2.\n"); - goto error; - } - - // remove_app_dek - remove_app_dek(pkgId1, WAE_PRELOADED_APP); - remove_app_dek(pkgId2, WAE_PRELOADED_APP); - - ret = WAE_ERROR_NONE; - -error: - if (dek1 != NULL) - free(dek1); - - if (readDek1 != NULL) - free(readDek1); - - if (dek2 != NULL) - free(dek2); - - if (readDek2 != NULL) - free(readDek2); - - return ret; -} - -int _wae_tc_encrypt_decrypt_web_app(wae_app_type_e appType) -{ - int ret = WAE_ERROR_NONE; - - const char *pkgId1 = "testpkg_for_normal"; - const char *pkgId2 = "testpkg_for_global"; - const char *pkgId3 = "testpkg_for_preloaded"; - const char *pkgId = NULL; - const char *plaintext = "adbdfdfdfdfdererfdfdfererfdrerfdrer"; - size_t plaintextLen = strlen(plaintext); - unsigned char *encrypted = NULL; - size_t encLen = 0; - unsigned char *decrypted = NULL; - size_t decLen = 0; - char decrypted_str[1024] = {0, }; - - switch (appType) { - case WAE_DOWNLOADED_NORMAL_APP: - pkgId = pkgId1; - break; - - case WAE_DOWNLOADED_GLOBAL_APP: - pkgId = pkgId2; - break; - - case WAE_PRELOADED_APP: - pkgId = pkgId3; - break; - } - - // remove old test data - ret = wae_remove_app_dek(pkgId, appType); - - if (appType == WAE_PRELOADED_APP) { - _clear_app_deks_loaded(); - } - - // test for downloaded web application - ret = wae_encrypt_web_application(pkgId, appType, - (const unsigned char *)plaintext, plaintextLen, - &encrypted, &encLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: wae_encrypt_web_application. ret=%d\n", ret); - goto error; - } - - // encrypt test twice - ret = wae_encrypt_web_application(pkgId, appType, - (const unsigned char *)plaintext, plaintextLen, - &encrypted, &encLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: wae_encrypt_web_application. ret=%d\n", ret); - goto error; - } - - _remove_app_dek_from_cache(pkgId); - - if (appType == WAE_PRELOADED_APP) { - load_preloaded_app_deks(true); - } - - ret = wae_decrypt_web_application(pkgId, appType, encrypted, encLen, &decrypted, &decLen); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: wae_decrypt_web_application. ret=%d\n", ret); - goto error; - } - - if (plaintextLen != decLen) { - FPRINTF("...FAIL: plaintextLen(%d) != decLen(%d)\n", (int) plaintextLen, (int) decLen); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - memcpy(decrypted_str, decrypted, decLen); - FPRINTF("...plaintext(downloaded) = %s\n", plaintext); - FPRINTF("...decrypted(downloaded) = %s\n", decrypted_str); - - if (strcmp(plaintext, decrypted_str) != 0) { - FPRINTF("...FAIL: plaintext(%s) != decrypted(%s)\n", plaintext, decrypted_str); - ret = WAE_ERROR_CRYPTO; - goto error; - } - - ret = wae_remove_app_dek(pkgId, appType); - - if (ret != WAE_ERROR_NONE) { - FPRINTF("...FAIL: wae_remove_app_dek. ret=%d\n", ret); - goto error; - } - -error: - if (encrypted != NULL) - free(encrypted); - - if (decrypted != NULL) - free(decrypted); - - return ret; -} - -int wae_tc_encrypt_decrypt_normal_app() -{ - return _wae_tc_encrypt_decrypt_web_app(WAE_DOWNLOADED_NORMAL_APP); -} - -int wae_tc_encrypt_decrypt_global_app() -{ - return _wae_tc_encrypt_decrypt_web_app(WAE_DOWNLOADED_GLOBAL_APP); -} - -int wae_tc_encrypt_decrypt_preloaded_app() -{ - return _wae_tc_encrypt_decrypt_web_app(WAE_PRELOADED_APP); -} - - -int run_test_cases(char *test_mode) -{ - if (strcmp(test_mode, "system") == 0) { - RUNTC(wae_tc_encrypt_decrypt_app_dek, "wae_tc_encrypt_decrypt_app_dek"); - RUNTC(wae_tc_encrypt_decrypt_aes_cbc, "wae_tc_encrypt_decrypt_aes_cbc"); - RUNTC(wae_tc_cache, "wae_tc_cache"); - - RUNTC(wae_tc_get_random, "wae_tc_get_random"); - RUNTC(wae_tc_get_alias, "wae_tc_get_alias"); - - RUNTC(wae_tc_add_get_remove_dek_for_global_app, "wae_tc_add_get_remove_dek_for_global_app"); - RUNTC(wae_tc_add_get_remove_dek_for_preloaded_app, "wae_tc_add_get_remove_dek_for_preloaded_app"); - - RUNTC(wae_tc_get_preloaded_app_dek_file_path, "wae_tc_get_preloaded_app_dek_file_path"); - RUNTC(wae_tc_extract_pkg_id_from_file_name, "wae_tc_extract_pkg_id_from_file_name"); - RUNTC(wae_tc_read_write_encrypted_app_dek, "wae_tc_read_write_encrypted_app_dek"); - - RUNTC(wae_tc_create_app_dek_for_global_app, "wae_tc_create_app_dek_for_global_app"); - RUNTC(wae_tc_create_app_dek_for_preloaded_app, "wae_tc_create_app_dek_for_preloaded_app"); - - RUNTC(wae_tc_get_create_preloaded_app_dek, "wae_tc_get_create_preloaded_app_dek"); - RUNTC(wae_tc_load_preloaded_app_deks, "wae_tc_load_preloaded_app_deks"); - - RUNTC(wae_tc_encrypt_decrypt_global_app, "wae_tc_encrypt_decrypt_global_app"); - RUNTC(wae_tc_encrypt_decrypt_preloaded_app, "wae_tc_encrypt_decrypt_preloaded_app"); - } else { - RUNTC(wae_tc_add_get_remove_dek_for_normal_app, "wae_tc_add_get_remove_dek_for_normal_app"); - RUNTC(wae_tc_create_app_dek_for_normal_app, "wae_tc_create_app_dek_for_normal_app"); - RUNTC(wae_tc_encrypt_decrypt_normal_app, "wae_tc_encrypt_decrypt_normal_app"); - } - - PRINT_TC_SUMMARY(); - return 0; -} - -int main(int argc, char *argv[]) -{ - int ret = 0; - - if (argc != 2 || (strcmp(argv[1], "system") != 0 && strcmp(argv[1], "user"))) { - FPRINTF("invalid command formant. command format : %s system|user\n", argv[0]); - exit(1); - } - - ret = run_test_cases(argv[1]); - - return ret; -} -- 2.7.4 From f72179753846682e783bbc4dbe1a3a570e7fac23 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Mon, 18 Jul 2016 11:28:53 +0900 Subject: [PATCH 11/16] Fix C code naming rules & minor fixes - Remove some goto label which isn't needed - Change 'num' param of strncmp / strncpy with meaningful value (static buffer's size) - Add const to unsigned char array input param - Change param names (c string array and raw buffer array) const char *pPkgId -> pkgId unsigned char *pDek -> dek unsigned char **ppDek -> pDek - Change all camel naminges to underbar - Remove null checking before call free() free() does nothing if ptr is null pointer. (refer: http://linux.die.net/man/3/free) - Add missing closedir() after opendir() Change-Id: I7e5888ed3dc77e5355cfc441f10dc0d6d916921c Signed-off-by: Kyungwook Tak --- include/web_app_enc.h | 38 ++-- srcs/crypto_service.c | 122 ++++++------ srcs/crypto_service.h | 24 +-- srcs/key_handler.c | 504 +++++++++++++++++++++++-------------------------- srcs/key_handler.h | 32 ++-- srcs/wae_initializer.c | 10 +- srcs/web_app_enc.c | 210 +++++++-------------- tests/internals.cpp | 2 +- 8 files changed, 417 insertions(+), 525 deletions(-) diff --git a/include/web_app_enc.h b/include/web_app_enc.h index 7cadf7b..c876792 100644 --- a/include/web_app_enc.h +++ b/include/web_app_enc.h @@ -62,12 +62,12 @@ typedef enum { * @brief Encrypts web application data with internal key(APP DEK: Application Data Encryption Key). * * @since_tizen 3.0 - * @param[in] pPkgId The package id of an application. - * @param[in] appType The application type. - * @param[in] pData The data block to be encrypted. - * @param[in] dataLen The length of the data block. - * @param[out] ppEncryptedData The data block contaning encrypted data block. Memory allocated for ppEncryptedData. Has to be freed by free() function. - * @param[out] pEncDataLen The length of the encrypted data block. + * @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 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_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 @@ -79,18 +79,20 @@ typedef enum { * * @see wae_decrypt_web_application() */ -int wae_encrypt_web_application(const char *pPkgId, wae_app_type_e appType, const unsigned char *pData, size_t dataLen, unsigned char **ppEncryptedData, size_t *pEncDataLen); +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); /** * @brief Encrypts web application data with internal key. * * @since_tizen 3.0 - * @param[in] pPkgId The package id of an application. - * @param[in] appType The application type. - * @param[in] pData The data block to be decrypted. - * @param[in] dataLen The length of the data block. - * @param[out] ppDecryptedData Data block contaning decrypted data block. Memory allocated for ppEncryptedData. Has to be freed by free() function. - * @param[out] pDecDataLen The length of the decrypted data block. + * @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_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 @@ -102,14 +104,16 @@ int wae_encrypt_web_application(const char *pPkgId, wae_app_type_e appType, cons * * @see wae_encrypt_web_application() */ -int wae_decrypt_web_application(const char *pPkgId, wae_app_type_e appType, const unsigned char *pData, size_t dataLen, unsigned char **ppDecryptedData, size_t *pDecDataLen); +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); /** * @brief Remove a APP DEK(Application Data Encryption Key) used for encrytpion and decryption of a web application. * * @since_tizen 3.0 - * @param[in] pPkgId The package id of an application. - * @param[in] appType The application type. + * @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 @@ -119,7 +123,7 @@ int wae_decrypt_web_application(const char *pPkgId, wae_app_type_e appType, cons * @retval #WAE_ERROR_UNKNOWN Failed with unknown reason * */ -int wae_remove_app_dek(const char *pPkgId, wae_app_type_e appType); +int wae_remove_app_dek(const char *pkg_id, wae_app_type_e app_type); /** * @} diff --git a/srcs/crypto_service.c b/srcs/crypto_service.c index 7d90190..0991d42 100644 --- a/srcs/crypto_service.c +++ b/srcs/crypto_service.c @@ -52,36 +52,36 @@ void _initialize() } } -int encrypt_app_dek(const unsigned char *rsaPublicKey, size_t pubKeyLen, - const unsigned char *dek, size_t dekLen, - unsigned char **encryptedDek, size_t *encryptedDekLen) +int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, + const unsigned char *dek, size_t dek_len, + unsigned char **pencrypted_dek, size_t *pencrypted_dek_len) { int ret = WAE_ERROR_NONE; - EVP_PKEY *pKey = NULL; + EVP_PKEY *key = NULL; BIO *bio = NULL; EVP_PKEY_CTX *ctx = NULL; unsigned char *out = NULL; - size_t outLen = 0; + size_t out_len = 0; _initialize(); bio = BIO_new(BIO_s_mem()); - BIO_write(bio, rsaPublicKey, pubKeyLen); - pKey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + BIO_write(bio, pubkey, pubkey_len); + key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); - if (pKey == NULL) { + if (key == NULL) { BIO_reset(bio); - BIO_write(bio, rsaPublicKey, pubKeyLen); - pKey = d2i_PUBKEY_bio(bio, NULL); + BIO_write(bio, pubkey, pubkey_len); + key = d2i_PUBKEY_bio(bio, NULL); } - if (pKey == NULL) { + if (key == NULL) { ret = WAE_ERROR_FILE; WAE_SLOGE("Failt to convert to public key."); goto error; } - ctx = EVP_PKEY_CTX_new(pKey, NULL); + ctx = EVP_PKEY_CTX_new(key, NULL); if (ctx == NULL) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_CTX_new failed"); @@ -102,13 +102,13 @@ int encrypt_app_dek(const unsigned char *rsaPublicKey, size_t pubKeyLen, } /* Determine buffer length */ - if (EVP_PKEY_encrypt(ctx, NULL, &outLen, dek, dekLen) <= 0) { + if (EVP_PKEY_encrypt(ctx, NULL, &out_len, dek, dek_len) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - out = OPENSSL_malloc(outLen); + out = OPENSSL_malloc(out_len); if (out == NULL) { WAE_SLOGE("Encrypt APP DEK Failed. OPENSSL_malloc failed"); @@ -116,21 +116,21 @@ int encrypt_app_dek(const unsigned char *rsaPublicKey, size_t pubKeyLen, goto error; } - if (EVP_PKEY_encrypt(ctx, out, &outLen, dek, dekLen) <= 0) { + if (EVP_PKEY_encrypt(ctx, out, &out_len, dek, dek_len) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - *encryptedDek = out; - *encryptedDekLen = outLen; + *pencrypted_dek = out; + *pencrypted_dek_len = out_len; error: if (bio != NULL) BIO_free(bio); - if (pKey != NULL) - EVP_PKEY_free(pKey); + if (key != NULL) + EVP_PKEY_free(key); if (ctx != NULL) EVP_PKEY_CTX_free(ctx); @@ -141,37 +141,37 @@ error: return ret; } -int decrypt_app_dek(const unsigned char *rsaPrivateKey, size_t priKeyLen, - const char *priKeyPassword, - const unsigned char *encryptedDek, size_t dencryptedDekLen, - unsigned char **decryptedDek, size_t *decryptedDekLen) +int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, + const char *prikey_pass, + const unsigned char *encrypted_dek, size_t encrypted_dek_len, + unsigned char **pdecrypted_dek, size_t *pdecrypted_dek_len) { int ret = WAE_ERROR_NONE; - EVP_PKEY *pKey = NULL; + EVP_PKEY *key = NULL; BIO *bio = NULL; EVP_PKEY_CTX *ctx = NULL; unsigned char *out = NULL; - size_t outLen = 0; + size_t out_len = 0; _initialize(); bio = BIO_new(BIO_s_mem()); - BIO_write(bio, rsaPrivateKey, priKeyLen); - pKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)priKeyPassword); + BIO_write(bio, prikey, prikey_len); + key = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)prikey_pass); - if (pKey == NULL) { + if (key == NULL) { BIO_reset(bio); - BIO_write(bio, rsaPrivateKey, priKeyLen); - pKey = d2i_PrivateKey_bio(bio, NULL); + BIO_write(bio, prikey, prikey_len); + key = d2i_PrivateKey_bio(bio, NULL); } - if (pKey == NULL) { + if (key == NULL) { ret = WAE_ERROR_FILE; WAE_SLOGE("Failt to convert to public key."); goto error; } - ctx = EVP_PKEY_CTX_new(pKey, NULL); + ctx = EVP_PKEY_CTX_new(key, NULL); if (ctx == NULL) { WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_CTX_new failed"); @@ -192,13 +192,13 @@ int decrypt_app_dek(const unsigned char *rsaPrivateKey, size_t priKeyLen, } /* Determine buffer length */ - if (EVP_PKEY_decrypt(ctx, NULL, &outLen, encryptedDek, dencryptedDekLen) <= 0) { + if (EVP_PKEY_decrypt(ctx, NULL, &out_len, encrypted_dek, encrypted_dek_len) <= 0) { WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - out = OPENSSL_malloc(outLen); + out = OPENSSL_malloc(out_len); if (out == NULL) { WAE_SLOGE("Decrypt APP DEK Failed. OPENSSL_malloc failed"); @@ -206,21 +206,21 @@ int decrypt_app_dek(const unsigned char *rsaPrivateKey, size_t priKeyLen, goto error; } - if (EVP_PKEY_decrypt(ctx, out, &outLen, encryptedDek, dencryptedDekLen) <= 0) { + if (EVP_PKEY_decrypt(ctx, out, &out_len, encrypted_dek, encrypted_dek_len) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_decrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - *decryptedDek = out; - *decryptedDekLen = outLen; + *pdecrypted_dek = out; + *pdecrypted_dek_len = out_len; error: if (bio != NULL) BIO_free(bio); - if (pKey != NULL) - EVP_PKEY_free(pKey); + if (key != NULL) + EVP_PKEY_free(key); if (ctx != NULL) EVP_PKEY_CTX_free(ctx); @@ -232,9 +232,9 @@ error: } -int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, - const unsigned char *pData, size_t dataLen, - unsigned char **ppEncryptedData, size_t *pEncDataLen) +int encrypt_aes_cbc(const unsigned char *key, size_t key_len, + const unsigned char *data, size_t data_len, + unsigned char **pencrypted_data, size_t *pencrypted_data_len) { EVP_CIPHER_CTX *ctx; int len; @@ -245,16 +245,16 @@ int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, _initialize(); - WAE_SLOGI("Encryption Started. size=%d", dataLen); + WAE_SLOGI("Encryption Started. size=%d", data_len); /* check input paramter */ - if (keyLen != 32) { - WAE_SLOGE("Encryption Failed. Invalid Key Length. keyLen=%d", keyLen); + if (key_len != 32) { + WAE_SLOGE("Encryption Failed. Invalid Key Length. key_len=%d", key_len); return WAE_ERROR_INVALID_PARAMETER; } // assing a enough memory for decryption. - ciphertext = (unsigned char *) malloc(dataLen + 32); + ciphertext = (unsigned char *) malloc(data_len + 32); /* Create and initialise the context */ if (!(ctx = EVP_CIPHER_CTX_new())) { @@ -268,7 +268,7 @@ int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, * In this example we are using 256 bit AES (i.e. a 256 bit key). The * IV size for *most* modes is the same as the block size. For AES this * is 128 bits */ - if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) { + if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { WAE_SLOGE("Encryption Failed. EVP_EncryptInit_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -277,7 +277,7 @@ int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, /* Provide the message to be encrypted, and obtain the encrypted output. * EVP_EncryptUpdate can be called multiple times if necessary */ - if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, pData, dataLen)) { + if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, data, data_len)) { WAE_SLOGE("Encryption Failed. EVP_EncryptUpdate failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -296,8 +296,8 @@ int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, ciphertext_len += len; - *ppEncryptedData = ciphertext; - *pEncDataLen = ciphertext_len; + *pencrypted_data = ciphertext; + *pencrypted_data_len = ciphertext_len; ret = WAE_ERROR_NONE; WAE_SLOGI("Encryption Ended Successfully. encrypted_len", ciphertext_len); @@ -312,9 +312,9 @@ error: return ret; } -int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, - const unsigned char *pData, size_t dataLen, - unsigned char **ppDecryptedData, size_t *pDecDataLen) +int decrypt_aes_cbc(const unsigned char *key, size_t key_len, + const unsigned char *data, size_t data_len, + unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) { EVP_CIPHER_CTX *ctx; int len; @@ -325,16 +325,16 @@ int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, _initialize(); - WAE_SLOGI("Decryption Started. size=%d", dataLen); + WAE_SLOGI("Decryption Started. size=%d", data_len); /* check input paramter */ - if (keyLen != 32) { - WAE_SLOGE("Decryption Failed. Invalid Key Length. keyLen=%d", keyLen); + if (key_len != 32) { + WAE_SLOGE("Decryption Failed. Invalid Key Length. key_len=%d", key_len); return WAE_ERROR_INVALID_PARAMETER; } // assing a enough memory for decryption. - plaintext = (unsigned char *) malloc(dataLen); + plaintext = (unsigned char *) malloc(data_len); /* Create and initialise the context */ if (!(ctx = EVP_CIPHER_CTX_new())) { @@ -348,7 +348,7 @@ int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, * In this example we are using 256 bit AES (i.e. a 256 bit key). The * IV size for *most* modes is the same as the block size. For AES this * is 128 bits */ - if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, pKey, iv)) { + if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { WAE_SLOGE("Decryption Failed. EVP_DecryptInit_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -357,7 +357,7 @@ int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, /* Provide the message to be decrypted, and obtain the plaintext output. * EVP_DecryptUpdate can be called multiple times if necessary */ - if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, pData, dataLen)) { + if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, data, data_len)) { WAE_SLOGE("Decryption Failed. EVP_DecryptUpdate failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -376,8 +376,8 @@ int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, plaintext_len += len; - *ppDecryptedData = plaintext; - *pDecDataLen = plaintext_len; + *pdecrypted_data = plaintext; + *pdecrypted_data_len = plaintext_len; ret = WAE_ERROR_NONE; WAE_SLOGI("Decryption Ended Successfully. decrypted_len", plaintext_len); diff --git a/srcs/crypto_service.h b/srcs/crypto_service.h index 61f4d0b..8a64d6d 100644 --- a/srcs/crypto_service.h +++ b/srcs/crypto_service.h @@ -28,23 +28,23 @@ extern "C" { #include -int encrypt_app_dek(const unsigned char *rsaPublicKey, size_t pubKeyLen, - const unsigned char *dek, size_t dekLen, +int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, + const unsigned char *dek, size_t dek_len, unsigned char **encryptedDek, size_t *encryptedDekLen); -int decrypt_app_dek(const unsigned char *rsaPrivateKey, size_t priKeyLen, - const char *priKeyPassword, - const unsigned char *encryptedDek, size_t dencryptedDekLen, - unsigned char **decryptedDek, size_t *decryptedDekLen); +int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, + const char *prikey_pass, + const unsigned char *encrypted_dek, size_t encrypted_dek_len, + unsigned char **pdecrypted_dek, size_t *pdecrypted_dek_len); -int encrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, - const unsigned char *pData, size_t dataLen, - unsigned char **ppEncryptedData, size_t *pEncDataLen); +int encrypt_aes_cbc(const unsigned char *key, size_t key_len, + const unsigned char *data, size_t data_len, + unsigned char **pencrypted_data, size_t *pencrypted_data_len); -int decrypt_aes_cbc(const unsigned char *pKey, size_t keyLen, - const unsigned char *pData, size_t dataLen, - unsigned char **ppDecryptedData, size_t *pDecDataLen); +int decrypt_aes_cbc(const unsigned char *key, size_t key_len, + const unsigned char *data, size_t data_len, + unsigned char **pdecrypted_data, size_t *pdecrypted_data_len); #ifdef __cplusplus } diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 15dc96f..0cb2776 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -47,7 +47,7 @@ #define MAX_CACHE_SIZE 100 typedef struct _dek_cache_element { - char pkgId[MAX_PKGID_LEN]; + char pkg_id[MAX_PKGID_LEN]; unsigned char dek[DEK_LEN]; } dek_cache_element; @@ -57,55 +57,51 @@ int NEXT_CACHE_IDX = -1; void _initialize_cache() { NEXT_CACHE_IDX = 0; - memset(APP_DEK_CACHE, 0, sizeof(dek_cache_element)*MAX_CACHE_SIZE); + memset(APP_DEK_CACHE, 0, sizeof(dek_cache_element) * MAX_CACHE_SIZE); } -unsigned char *_get_app_dek_from_cache(const char *pkgId) +const unsigned char *_get_app_dek_from_cache(const char *pkg_id) { if (NEXT_CACHE_IDX < 0) _initialize_cache(); - for (int i = 0; i < MAX_CACHE_SIZE; i++) { - //WAE_SLOGI("CACHED APP_DEK[%d]=%s", i, APP_DEK_CACHE[i].pkgId); - if (strlen(APP_DEK_CACHE[i].pkgId) == strlen(pkgId) && - strncmp(pkgId, APP_DEK_CACHE[i].pkgId, strlen(pkgId)) == 0) { + for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { + //WAE_SLOGI("CACHED APP_DEK[%d]=%s", i, APP_DEK_CACHE[i].pkg_id); + if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) return APP_DEK_CACHE[i].dek; - } } return NULL; } -void _add_app_dek_to_cache(const char *pkgId, unsigned char *dek) +void _add_app_dek_to_cache(const char *pkg_id, const unsigned char *dek) { if (NEXT_CACHE_IDX < 0) _initialize_cache(); // if existing one has the same pkgid - for (int i = 0; i < MAX_CACHE_SIZE; i++) { - if (strlen(APP_DEK_CACHE[i].pkgId) == strlen(pkgId) && - strncmp(pkgId, APP_DEK_CACHE[i].pkgId, strlen(pkgId)) == 0) { + for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { + if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) { memcpy(APP_DEK_CACHE[i].dek, dek, DEK_LEN); return; } } // for new pkgid - strncpy(APP_DEK_CACHE[NEXT_CACHE_IDX].pkgId, pkgId, strlen(pkgId)); + strncpy(APP_DEK_CACHE[NEXT_CACHE_IDX].pkg_id, pkg_id, MAX_PKGID_LEN - 1); memcpy(APP_DEK_CACHE[NEXT_CACHE_IDX].dek, dek, DEK_LEN); - NEXT_CACHE_IDX++; + ++NEXT_CACHE_IDX; if (NEXT_CACHE_IDX >= MAX_CACHE_SIZE) NEXT_CACHE_IDX = 0; } -void _remove_app_dek_from_cache(const char *pkgId) +void _remove_app_dek_from_cache(const char *pkg_id) { - for (int i = 0; i < MAX_CACHE_SIZE; i++) { - if (strlen(APP_DEK_CACHE[i].pkgId) == strlen(pkgId) && - strncmp(pkgId, APP_DEK_CACHE[i].pkgId, strlen(pkgId)) == 0) { - memset(APP_DEK_CACHE[i].pkgId, 0, sizeof(APP_DEK_CACHE[i].pkgId)); + for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { + if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) { + memset(APP_DEK_CACHE[i].pkg_id, 0, MAX_PKGID_LEN); return; } } @@ -137,48 +133,43 @@ int _to_wae_error(int key_manager_error) int _get_random(size_t length, unsigned char *random) { - FILE *f = NULL; - size_t i = 0; - int ch = 0; + FILE *f = fopen(RANDOM_FILE, "r"); - //read random file - if ((f = fopen(RANDOM_FILE, "r")) != NULL) { - while (i < length) { - if ((ch = fgetc(f)) == EOF) { - break; - } - - random[i] = (unsigned char) ch; - i++; - } + if (f == NULL) { + WAE_SLOGE("Failed to open random file source: %s", RANDOM_FILE); + return WAE_ERROR_FILE; } - if (f != NULL) - fclose(f); + size_t i = 0; + int ch = 0; + while (i < length && (ch = fgetc(f) != EOF)) + random[i++] = (unsigned char)ch; + + fclose(f); return WAE_ERROR_NONE; } -void _get_alias(const char *pPkgId, wae_app_type_e appType, bool forSave, char *alias, size_t buff_len) +void _get_alias(const char *pkg_id, wae_app_type_e app_type, bool forSave, char *alias, size_t buff_len) { - if (appType == WAE_DOWNLOADED_NORMAL_APP) { + if (app_type == WAE_DOWNLOADED_NORMAL_APP) { if (forSave) { snprintf(alias, buff_len, "%s%s", APP_DEK_ALIAS_PFX, - pPkgId); + pkg_id); } else { snprintf(alias, buff_len, "%c%s%s%s%s", '/', INSTALLER_LABEL, ckmc_owner_id_separator, APP_DEK_ALIAS_PFX, - pPkgId); + 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, - pPkgId); + pkg_id); } } @@ -213,49 +204,46 @@ const char *_get_dek_store_path() return tzplatform_mkpath3(TZ_SYS_SHARE, "wae", "app_dek"); } -int _add_dek_to_key_manager(const char *pPkgId, wae_app_type_e appType, const unsigned char *pDek, size_t len) +int _add_dek_to_key_manager(const char *pkg_id, wae_app_type_e app_type, const unsigned char *dek, size_t dek_len) { int ret = WAE_ERROR_NONE; - char alias[MAX_ALIAS_LEN] = {0,}; + char alias[MAX_ALIAS_LEN] = {0, }; ckmc_raw_buffer_s buff; ckmc_policy_s policy; - buff.data = (unsigned char *)pDek; - buff.size = len; + buff.data = (unsigned char *)dek; + buff.size = dek_len; policy.password = NULL; policy.extractable = true; - // save app_dek in key_manager - _get_alias(pPkgId, appType, true, alias, sizeof(alias)); + _get_alias(pkg_id, app_type, true, alias, sizeof(alias)); // even if it fails to remove, ignore it. - ret = _to_wae_error(ckmc_remove_alias(alias)); + ckmc_remove_alias(alias); ret = _to_wae_error(ckmc_save_data(alias, buff, policy)); - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to add APP_DEK to key-manager. pkgId=%s, alias=%s, ret=%d", pPkgId, alias, ret); + WAE_SLOGE("WAE: Fail to add APP_DEK to key-manager. pkg_id=%s, alias=%s, ret=%d", pkg_id, alias, ret); return ret; } // share app_dek for web app laucher to use app_dek - ret = _to_wae_error(ckmc_set_permission(alias, pPkgId, CKMC_PERMISSION_READ)); - + ret = _to_wae_error(ckmc_set_permission(alias, pkg_id, CKMC_PERMISSION_READ)); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to set_permission to APP_DEK. pkgId=%s, ret=%d", pPkgId, ret); + WAE_SLOGE("WAE: Fail to set_permission to APP_DEK. pkg_id=%s, ret=%d", pkg_id, ret); return ret; } - WAE_SLOGI("WAE: Success to add APP_DEK to key-manager. pkgId=%s, alias=%s", pPkgId, alias); + WAE_SLOGI("WAE: Success to add APP_DEK to key-manager. pkg_id=%s, alias=%s", pkg_id, alias); return ret; } -int _get_preloaded_app_dek_file_path(const char *pPkgId, size_t size, char *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, pPkgId); + _get_dek_store_path(), APP_DEK_FILE_PFX, pkg_id); if (ret < 0) return WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ @@ -263,47 +251,46 @@ int _get_preloaded_app_dek_file_path(const char *pPkgId, size_t size, char *path return WAE_ERROR_NONE; } -int _extract_pkg_id_from_file_name(const char *fileName, char *pkgId) +int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) { - char *start = strstr(fileName, APP_DEK_FILE_PFX); + char *start = strstr(file_name, APP_DEK_FILE_PFX); if (start == NULL) { - WAE_SLOGE("WAE: Fail to extract pkgid from APP_DEK file. fileName=%s", fileName); + WAE_SLOGE("WAE: Fail to extract pkgid from APP_DEK file. file_name=%s", file_name); return WAE_ERROR_FILE; } start = start + strlen(APP_DEK_FILE_PFX) + 1; - char *end = strstr(fileName, ".adek"); + char *end = strstr(file_name, ".adek"); if (start == NULL) { - WAE_SLOGE("WAE: Fail to extract pkgid from APP_DEK file. fileName=%s", fileName); + WAE_SLOGE("WAE: Fail to extract pkgid from APP_DEK file. file_name=%s", file_name); return WAE_ERROR_FILE; } - strncpy(pkgId, start, end - start); - pkgId[end - start] = 0; //terminate string + strncpy(pkg_id, start, end - start); + pkg_id[end - start] = 0; //terminate string return WAE_ERROR_NONE; } -int _read_encrypted_app_dek_from_file(const char *pPkgId, unsigned char **encrypted_app_dek, size_t *len) +int _read_encrypted_app_dek_from_file(const char *pkg_id, unsigned char **pencrypted_app_dek, size_t *pencrypted_app_dek_len) { char path[MAX_PATH_LEN] = {0,}; - _get_preloaded_app_dek_file_path(pPkgId, sizeof(path), path); - return _read_from_file(path, encrypted_app_dek, len); + _get_preloaded_app_dek_file_path(pkg_id, sizeof(path), path); + return _read_from_file(path, pencrypted_app_dek, pencrypted_app_dek_len); } -int _write_encrypted_app_dek_to_file(const char *pPkgId, const unsigned char *encrypted_app_dek, size_t len) +int _write_encrypted_app_dek_to_file(const char *pkg_id, const unsigned char *encrypted_app_dek, size_t encrypted_app_dek_len) { char path[MAX_PATH_LEN] = {0,}; - _get_preloaded_app_dek_file_path(pPkgId, sizeof(path), path); - return _write_to_file(path, encrypted_app_dek, len); + _get_preloaded_app_dek_file_path(pkg_id, sizeof(path), path); + return _write_to_file(path, encrypted_app_dek, encrypted_app_dek_len); } -int _read_from_file(const char *path, unsigned char **data, size_t *len) +int _read_from_file(const char *path, unsigned char **pdata, size_t *pdata_len) { int ret = WAE_ERROR_NONE; - int file_len = -1; unsigned char *file_contents = NULL; int ch = 0; int i = 0; @@ -316,7 +303,7 @@ int _read_from_file(const char *path, unsigned char **data, size_t *len) } fseek(f, 0, SEEK_END); // move to the end of a file - file_len = ftell(f); + int file_len = ftell(f); if (file_len <= 0) { WAE_SLOGE("WAE: Failed to get file size by ftell. ret: %d", file_len); @@ -326,7 +313,7 @@ int _read_from_file(const char *path, unsigned char **data, size_t *len) fseek(f, 0, SEEK_SET); // move to the start of a file - file_contents = (unsigned char *) malloc(file_len); + file_contents = (unsigned char *)malloc(file_len); if (file_contents == NULL) { WAE_SLOGE("WAE: Fail to allocate memory for encrypted_app_dek"); @@ -336,29 +323,23 @@ int _read_from_file(const char *path, unsigned char **data, size_t *len) memset(file_contents, 0x00, file_len); - while ((ch = fgetc(f)) != EOF) { + while ((ch = fgetc(f)) != EOF) file_contents[i++] = (char)ch; - } - *data = file_contents; - *len = file_len; + *pdata = file_contents; + *pdata_len = file_len; error: - if (f != NULL) - fclose(f); + fclose(f); - if (ret != WAE_ERROR_NONE && file_contents != NULL) + if (ret != WAE_ERROR_NONE) free(file_contents); return ret; } -int _write_to_file(const char *path, const unsigned char *data, size_t len) +int _write_to_file(const char *path, const unsigned char *data, size_t data_len) { - int ret = WAE_ERROR_NONE; - - int write_len = -1; - FILE *f = fopen(path, "w"); if (f == NULL) { @@ -366,72 +347,80 @@ int _write_to_file(const char *path, const unsigned char *data, size_t len) return WAE_ERROR_FILE; } - write_len = fwrite(data, 1, len, f); + int write_len = fwrite(data, 1, data_len, f); + + fclose(f); - if (write_len != (int) len) { + if (write_len != (int)data_len) { WAE_SLOGE("WAE: Fail to write a file. file=%s", path); - ret = WAE_ERROR_FILE; - goto error; + return WAE_ERROR_FILE; } -error: - if (f != NULL) - fclose(f); - - return ret; + return WAE_ERROR_NONE; } -int get_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen) +int get_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len) { int ret = WAE_ERROR_NONE; - char *password = NULL; - ckmc_raw_buffer_s *pDekBuffer = NULL; - char alias[MAX_ALIAS_LEN] = {0,}; - unsigned char *pDek = NULL; + ckmc_raw_buffer_s *dek_buffer = NULL; + char alias[MAX_ALIAS_LEN] = {0, }; - unsigned char *cached_dek = _get_app_dek_from_cache(pPkgId); + const unsigned char *cached_dek = _get_app_dek_from_cache(pkg_id); if (cached_dek == NULL) { // get APP_DEK from system database - _get_alias(pPkgId, appType, false, alias, sizeof(alias)); + _get_alias(pkg_id, app_type, false, alias, sizeof(alias)); - ret = _to_wae_error(ckmc_get_data(alias, password, &pDekBuffer)); + ret = _to_wae_error(ckmc_get_data(alias, NULL, &dek_buffer)); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", - pPkgId, alias, ret); + WAE_SLOGE("Failed to get APP_DEK from key-manager. pkg_id=%s, alias=%s, ret=%d", + pkg_id, alias, ret); + goto error; + } else if (dek_buffer == NULL || dek_buffer->data == NULL) { + WAE_SLOGE("key-manager success but buffer is null for getting dek of pkg_id=%s", + pkg_id); + ret = WAE_ERROR_KEY_MANAGER; + goto error; + } else if (dek_buffer->size != DEK_LEN) { + WAE_SLOGE("DEK's length which has been saved in key-manager is not valid!"); + ret = WAE_ERROR_KEY_MANAGER; goto error; } + + WAE_SLOGD("Successfully get dek from key-manager for pkgid=%s", pkg_id); + cached_dek = dek_buffer->data; } - pDek = (unsigned char *)malloc(DEK_LEN); + unsigned char *dek = (unsigned char *)malloc(DEK_LEN); - if (pDek == NULL) { + if (dek == NULL) { WAE_SLOGE("Fail to allocate a memory"); ret = WAE_ERROR_MEMORY; goto error; } - memcpy(pDek, (cached_dek != NULL) ? cached_dek : pDekBuffer->data, DEK_LEN); + memcpy(dek, cached_dek, DEK_LEN); + + *pdek = dek; + *pdek_len = DEK_LEN; - *ppDek = pDek; - *dekLen = DEK_LEN; - WAE_SLOGI("WAE: Success to get APP_DEK from key-manager. pkgId=%s, alias=%s", pPkgId, alias); + WAE_SLOGI("WAE: Success to get APP_DEK from key-manager. pkg_id=%s, alias=%s", + pkg_id, alias); error: - if (pDekBuffer != NULL) - ckmc_buffer_free(pDekBuffer); + ckmc_buffer_free(dek_buffer); - if (ret != WAE_ERROR_NONE && pDek != NULL) - free(pDek); + if (ret != WAE_ERROR_NONE) + free(dek); return ret; } -int create_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen) +int create_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len) { - unsigned char *dek = (unsigned char *) malloc(DEK_LEN); + unsigned char *dek = (unsigned char *)malloc(DEK_LEN); if (dek == NULL) return WAE_ERROR_MEMORY; @@ -439,69 +428,63 @@ int create_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **p int ret = _get_random(DEK_LEN, dek); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to get random for APP_DEK. pkgId=%s, ret=%d", pPkgId, ret); + WAE_SLOGE("WAE: Fail to get random for APP_DEK. pkg_id=%s, ret=%d", pkg_id, ret); goto error; } // save app_dek in key_manager - ret = _add_dek_to_key_manager(pPkgId, appType, dek, DEK_LEN); + ret = _add_dek_to_key_manager(pkg_id, app_type, dek, DEK_LEN); if (ret != WAE_ERROR_NONE) { goto error; } // store APP_DEK in cache - _add_app_dek_to_cache(pPkgId, dek); + _add_app_dek_to_cache(pkg_id, dek); - *ppDek = dek; - *dekLen = DEK_LEN; + *pdek = dek; + *pdek_len = DEK_LEN; - WAE_SLOGI("WAE: Success to create APP_DEK and store it in key-manager. pkgId=%s", pPkgId); + WAE_SLOGI("WAE: Success to create APP_DEK and store it in key-manager. pkg_id=%s", pkg_id); + + return WAE_ERROR_NONE; error: - if (ret != WAE_ERROR_NONE && dek != NULL) - free(dek); + free(dek); return ret; } -int get_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen) +int get_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len) { - int ret = WAE_ERROR_NONE; - - unsigned char *cached_dek = _get_app_dek_from_cache(pPkgId); + const unsigned char *cached_dek = _get_app_dek_from_cache(pkg_id); if (cached_dek == NULL) { WAE_SLOGE("WAE: Fail to get APP_DEK from cache for preloaded app"); return WAE_ERROR_NO_KEY; } - unsigned char *dek = (unsigned char *) malloc(DEK_LEN); + unsigned char *dek = (unsigned char *)malloc(DEK_LEN); if (dek == NULL) { WAE_SLOGE("WAE: Fail to allocate memory for preloaded app dek"); - ret = WAE_ERROR_MEMORY; - goto error; + return WAE_ERROR_MEMORY; } memcpy(dek, cached_dek, DEK_LEN); - *ppDek = dek; - *dekLen = DEK_LEN; - -error: - if (ret != WAE_ERROR_NONE && dek != NULL) - free(dek); + *pdek = dek; + *pdek_len = DEK_LEN; - return ret; + return WAE_ERROR_NONE; } -int create_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen) +int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len) { unsigned char *encrypted_app_dek = NULL; size_t encrypted_app_dek_len = 0; - unsigned char *pubKey = NULL; - size_t pubKeyLen = 0; + unsigned char *pubkey = NULL; + size_t pubkey_len = 0; // create APP_DEK unsigned char *dek = (unsigned char *)malloc(DEK_LEN); @@ -515,14 +498,14 @@ int create_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t * goto error; // encrypt APP_DEK with APP_DEK_KEK - ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubKey, &pubKeyLen); + ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubkey, &pubkey_len); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Public Key"); goto error; } - ret = encrypt_app_dek(pubKey, pubKeyLen, dek, DEK_LEN, &encrypted_app_dek, &encrypted_app_dek_len); + ret = encrypt_app_dek(pubkey, pubkey_len, dek, DEK_LEN, &encrypted_app_dek, &encrypted_app_dek_len); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("WAE: Fail to encrypt APP_DEK with APP_DEK_KEK"); @@ -530,73 +513,70 @@ int create_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t * } // write APP_DEK in a file - ret = _write_encrypted_app_dek_to_file(pPkgId, encrypted_app_dek, encrypted_app_dek_len); + ret = _write_encrypted_app_dek_to_file(pkg_id, encrypted_app_dek, encrypted_app_dek_len); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to write encrypted APP_DEK. pkgId=%s", pPkgId); + WAE_SLOGE("WAE: Fail to write encrypted APP_DEK. pkg_id=%s", pkg_id); goto error; } // store APP_DEK in cache - _add_app_dek_to_cache(pPkgId, dek); + _add_app_dek_to_cache(pkg_id, dek); - *ppDek = dek; - *dekLen = DEK_LEN; - WAE_SLOGI("WAE: Success to create preleaded APP_DEK and write it in initail value file. pkgId=%s", pPkgId); + *pdek = dek; + *pdek_len = DEK_LEN; + WAE_SLOGI("WAE: Success to create preleaded APP_DEK and write it in initail value file. pkg_id=%s", pkg_id); error: - if (pubKey != NULL) - free(pubKey); + free(pubkey); + free(encrypted_app_dek); - if (encrypted_app_dek != NULL) - free(encrypted_app_dek); - - if (ret != WAE_ERROR_NONE && dek != NULL) + if (ret != WAE_ERROR_NONE) free(dek); return ret; } -int _get_app_dek_kek(unsigned char **ppDekKek, size_t *kekLen) +int _get_app_dek_kek(unsigned char **pdek_kek, size_t *pdek_kek_len) { - int ret = _read_from_file(_get_dek_kek_pri_key_path(), ppDekKek, kekLen); + int ret = _read_from_file(_get_dek_kek_pri_key_path(), pdek_kek, pdek_kek_len); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Private Key"); return ret; } - /* - char* password = NULL; - ckmc_raw_buffer_s *pKekBuffer = NULL; - unsigned char* pKek = NULL; - - char dek_kek_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_kek_alias(dek_kek_alias, sizeof(dek_kek_alias)); - - ret = _to_wae_error(ckmc_get_data(dek_kek_alias, password, &pKekBuffer)); - if(ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to get APP_DEK_KEK from key-manager. alias=%s, ret=%d", APP_DEK_KEK_ALIAS, ret); - goto error; - } - - pKek = (unsigned char*) malloc(pKekBuffer->size); - if(pKek == NULL) { - WAE_SLOGE("Fail to allocate a memory"); - ret = WAE_ERROR_MEMORY; - goto error; - } - memcpy(pKek, pKekBuffer->data, pKekBuffer->size); - - *ppDekKek = pKek; - *kekLen = pKekBuffer->size; - WAE_SLOGI("Success to get APP_DEK_KEK from key-manager."); - error: - if(pKekBuffer != NULL) - ckmc_buffer_free(pKekBuffer); - if(ret != WAE_ERROR_NONE && pKek != NULL) - free(pKek); - */ +#if 0 + ckmc_raw_buffer_s *kek_buffer = NULL; + unsigned char* kek = NULL; + + char dek_kek_alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_kek_alias(dek_kek_alias, sizeof(dek_kek_alias)); + + ret = _to_wae_error(ckmc_get_data(dek_kek_alias, NULL, &kek_buffer)); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Fail to get APP_DEK_KEK from key-manager. alias=%s, ret=%d", + APP_DEK_KEK_ALIAS, ret); + goto error; + } + + kek = (unsigned char *)malloc(kek_buffer->size); + if(kek == NULL) { + WAE_SLOGE("Fail to allocate a memory"); + ret = WAE_ERROR_MEMORY; + goto error; + } + memcpy(kek, kek_buffer->data, kek_buffer->size); + + *pdek_kek = kek; + *pdek_kek_len = kek_buffer->size; + WAE_SLOGI("Success to get APP_DEK_KEK from key-manager."); + +error: + ckmc_buffer_free(kek_buffer); + free(kek); +#endif + return ret; } @@ -605,8 +585,8 @@ int _get_app_deks_loaded() char loading_done_alias[MAX_ALIAS_LEN] = {0, }; _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - ckmc_raw_buffer_s *pBuffer = NULL; - int ret = _to_wae_error(ckmc_get_data(loading_done_alias, NULL, &pBuffer)); + ckmc_raw_buffer_s *buffer = NULL; + int ret = _to_wae_error(ckmc_get_data(loading_done_alias, NULL, &buffer)); if (ret == WAE_ERROR_NO_KEY) WAE_SLOGI("WAE: APP_DEK_LOADING was not done"); @@ -615,8 +595,7 @@ int _get_app_deks_loaded() else WAE_SLOGE("WAE: Fail to get information from key-manager about APP_DEK_LOADING_DONE_ALIAS. ret=%d", ret); - if (pBuffer != NULL) - ckmc_buffer_free(pBuffer); + ckmc_buffer_free(buffer); return ret; } @@ -625,10 +604,10 @@ int _set_app_deks_loaded() { ckmc_raw_buffer_s buff; ckmc_policy_s policy; - unsigned char dummyData[1] = {0}; + unsigned char dummy_data[1] = {0}; - buff.data = dummyData; - buff.size = sizeof(dummyData); + buff.data = dummy_data; + buff.size = sizeof(dummy_data); policy.password = NULL; policy.extractable = true; @@ -673,19 +652,15 @@ int load_preloaded_app_deks(bool reload) { int ret = WAE_ERROR_NONE; - char pkgId[MAX_PKGID_LEN] = {0, }; + char pkg_id[MAX_PKGID_LEN] = {0, }; - DIR *dir = NULL; - struct dirent entry; - struct dirent *result; - int error; char file_path_buff[MAX_PATH_LEN]; unsigned char *encrypted_app_dek = NULL; size_t encrypted_app_dek_len = 0; unsigned char *app_dek = NULL; size_t app_dek_len = 0; - unsigned char *priKey = NULL; - size_t priKeyLen = 0; + unsigned char *prikey = NULL; + size_t prikey_len = 0; int error_during_loading = 0; @@ -697,23 +672,25 @@ int load_preloaded_app_deks(bool reload) return ret; } - ret = _get_app_dek_kek(&priKey, &priKeyLen); + ret = _get_app_dek_kek(&prikey, &prikey_len); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); return ret; } - dir = opendir(_get_dek_store_path()); + DIR *dir = opendir(_get_dek_store_path()); if (dir == NULL) { WAE_SLOGE("Fail to open dir. dir=%s", _get_dek_store_path()); - ret = WAE_ERROR_FILE; - goto error; + return WAE_ERROR_FILE; } + struct dirent entry; + struct dirent *result = NULL; + while (true) { - error = readdir_r(dir, &entry, &result); + int error = readdir_r(dir, &entry, &result); if (error != 0) { ret = WAE_ERROR_FILE; @@ -726,58 +703,57 @@ int load_preloaded_app_deks(bool reload) 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) { - memset(file_path_buff, 0, sizeof(file_path_buff)); - ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", - _get_dek_store_path(), entry.d_name); - - if (ret < 0) { - WAE_SLOGE("Failed to make file path by snprintf."); - ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ - goto error; - } - - ret = _extract_pkg_id_from_file_name(entry.d_name, pkgId); - - if (ret != WAE_ERROR_NONE) { - WAE_SLOGW("Fail to extract pkgid from file. It will be ignored. file=%s", file_path_buff); - continue; - } - - ret = _read_from_file(file_path_buff, &encrypted_app_dek, &encrypted_app_dek_len); - - if (ret != WAE_ERROR_NONE || encrypted_app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to read file. It will be ignored. file=%s", file_path_buff); - continue; - } - - ret = decrypt_app_dek(priKey, priKeyLen, APP_DEK_KEK_PRIKEY_PASSWORD, - encrypted_app_dek, encrypted_app_dek_len, - &app_dek, &app_dek_len); - - if (ret != WAE_ERROR_NONE || app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to decrypt APP DEK. It will be ignored. file=%s", file_path_buff); - continue; - } - - // save app_dek in key_manager - ret = _add_dek_to_key_manager(pkgId, WAE_PRELOADED_APP, app_dek, app_dek_len); - // free temp objects - free(app_dek); - free(encrypted_app_dek); - app_dek = NULL; - encrypted_app_dek = NULL; - - if (ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("Key Manager already has APP_DEK. It will be ignored. file=%s", file_path_buff); - continue; - } else if (ret != WAE_ERROR_NONE) { - error_during_loading++; - WAE_SLOGW("Fail to add APP DEK to key-manager. file=%s", file_path_buff); - continue; - } + if (entry.d_type != DT_REG || strstr(entry.d_name, APP_DEK_FILE_PFX) == NULL) + continue; + + memset(file_path_buff, 0, sizeof(file_path_buff)); + ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", + _get_dek_store_path(), entry.d_name); + + if (ret < 0) { + WAE_SLOGE("Failed to make file path by snprintf."); + ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */ + goto error; + } + + ret = _extract_pkg_id_from_file_name(entry.d_name, pkg_id); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGW("Fail to extract pkgid from file. It will be ignored. file=%s", file_path_buff); + continue; + } + + ret = _read_from_file(file_path_buff, &encrypted_app_dek, &encrypted_app_dek_len); + + if (ret != WAE_ERROR_NONE || encrypted_app_dek == NULL) { + error_during_loading++; + WAE_SLOGW("Fail to read file. It will be ignored. file=%s", file_path_buff); + continue; + } + + ret = decrypt_app_dek(prikey, prikey_len, APP_DEK_KEK_PRIKEY_PASSWORD, + encrypted_app_dek, encrypted_app_dek_len, + &app_dek, &app_dek_len); + + if (ret != WAE_ERROR_NONE || app_dek == NULL) { + error_during_loading++; + WAE_SLOGW("Fail to decrypt APP DEK. It will be ignored. file=%s", file_path_buff); + continue; + } + + // save app_dek in key_manager + ret = _add_dek_to_key_manager(pkg_id, WAE_PRELOADED_APP, app_dek, app_dek_len); + // free temp objects + free(app_dek); + free(encrypted_app_dek); + app_dek = NULL; + encrypted_app_dek = NULL; + + if (ret == WAE_ERROR_KEY_EXISTS) { + WAE_SLOGI("Key Manager already has APP_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); } } @@ -791,27 +767,27 @@ int load_preloaded_app_deks(bool reload) } error: - if (priKey != NULL) - free(priKey); + free(prikey); + closedir(dir); return ret; } -int remove_app_dek(const char *pPkgId, wae_app_type_e appType) +int remove_app_dek(const char *pkg_id, wae_app_type_e app_type) { char alias[MAX_ALIAS_LEN] = {0,}; - _get_alias(pPkgId, appType, true, alias, sizeof(alias)); + _get_alias(pkg_id, app_type, true, alias, sizeof(alias)); int ret = _to_wae_error(ckmc_remove_alias(alias)); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to remove APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d", pPkgId, alias, ret); + WAE_SLOGE("Fail to remove APP_DEK from key-manager. pkg_id=%s, alias=%s, ret=%d", pkg_id, alias, ret); return ret; } - _remove_app_dek_from_cache(pPkgId); - WAE_SLOGI("Success to remove APP_DEK from key-manager. pkgId=%s", pPkgId); + _remove_app_dek_from_cache(pkg_id); + WAE_SLOGI("Success to remove APP_DEK from key-manager. pkg_id=%s", pkg_id); return WAE_ERROR_NONE; } diff --git a/srcs/key_handler.h b/srcs/key_handler.h index e1ad727..c2e65a7 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -34,34 +34,34 @@ extern "C" { /* functions with "_" prefix are internal static functions but declared here for testing */ void _initialize_cache(); -unsigned char *_get_app_dek_from_cache(const char *pkgId); -void _add_app_dek_to_cache(const char *pkgId, unsigned char *dek); -void _remove_app_dek_from_cache(const char *pkgId); +const unsigned char *_get_app_dek_from_cache(const char *pkg_id); +void _add_app_dek_to_cache(const char *pkg_id, const unsigned char *dek); +void _remove_app_dek_from_cache(const char *pkg_id); int _get_random(size_t length, unsigned char *random); -void _get_alias(const char *pPkgId, wae_app_type_e appType, bool forSave, char *alias, size_t buff_len); +void _get_alias(const char *pkg_id, wae_app_type_e app_type, bool forSave, char *alias, size_t buff_len); void _get_dek_kek_alias(char *alias, size_t buff_len); void _get_dek_loading_done_alias(char *alias, size_t buff_len); const char *_get_dek_kek_pub_key_path(); const char *_get_dek_kek_pri_key_path(); const char *_get_dek_store_path(); -int _add_dek_to_key_manager(const char *pPkgId, wae_app_type_e appType, const unsigned char *pDek, size_t len); -int _get_preloaded_app_dek_file_path(const char *pPkgId, size_t size, char *path); -int _extract_pkg_id_from_file_name(const char *fileName, char *pkgId); -int _read_encrypted_app_dek_from_file(const char *pPkgId, unsigned char **encrypted_app_dek, size_t *len); -int _write_encrypted_app_dek_to_file(const char *pPkgId, const unsigned char *encrypted_app_dek, size_t len); -int _read_from_file(const char *path, unsigned char **data, size_t *len); -int _write_to_file(const char *path, const unsigned char *data, size_t len); +int _add_dek_to_key_manager(const char *pkg_id, wae_app_type_e app_type, const unsigned char *dek, size_t dek_len); +int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path); +int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id); +int _read_encrypted_app_dek_from_file(const char *pkg_id, unsigned char **pencrypted_app_dek, size_t *pencrypted_app_dek_len); +int _write_encrypted_app_dek_to_file(const char *pkg_id, const unsigned char *encrypted_app_dek, size_t encrypted_app_dek_len); +int _read_from_file(const char *path, unsigned char **pdata, size_t *pdata_len); +int _write_to_file(const char *path, const unsigned char *data, size_t data_len); int _get_app_deks_loaded(); int _set_app_deks_loaded(); int _clear_app_deks_loaded(); /* functions for interface */ -int get_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen); -int create_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen); -int get_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen); -int create_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen); +int get_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len); +int create_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len); +int get_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len); +int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len); int load_preloaded_app_deks(bool reload); -int remove_app_dek(const char *pPkgId, wae_app_type_e appType); +int remove_app_dek(const char *pkg_id, wae_app_type_e app_type); #ifdef __cplusplus } diff --git a/srcs/wae_initializer.c b/srcs/wae_initializer.c index b9d7ce8..956b04d 100644 --- a/srcs/wae_initializer.c +++ b/srcs/wae_initializer.c @@ -23,25 +23,19 @@ #include "web_app_enc.h" #include "wae_log.h" -#include - int main(int argc, char *argv[]) { - int ret = WAE_ERROR_NONE; bool reload = false; - if (argc == 2 && strcmp(argv[1], "--reload") == 0) { + if (argc == 2 && strcmp(argv[1], "--reload") == 0) reload = true; - } - ret = load_preloaded_app_deks(reload); + int ret = load_preloaded_app_deks(reload); if (ret == WAE_ERROR_NONE) { - printf("WAE INITIALIZER was finished successfully.\n"); WAE_SLOGI("WAE INITIALIZER was finished successfully."); return 0; } else { - printf("WAE INITIALIZER was finished with error. ret=%d\n", ret); WAE_SLOGE("WAE INITIALIZER was finished with error. ret=%d", ret); return -1; } diff --git a/srcs/web_app_enc.c b/srcs/web_app_enc.c index 0e31c30..dd133d9 100644 --- a/srcs/web_app_enc.c +++ b/srcs/web_app_enc.c @@ -22,210 +22,128 @@ #include "web_app_enc.h" #include -#include #include "key_handler.h" #include "crypto_service.h" #include "wae_log.h" -int _wae_encrypt_downloaded_web_application(const char *pPkgId, wae_app_type_e appType, - const unsigned char *pData, size_t dataLen, - unsigned char **ppEncryptedData, size_t *pEncDataLen) +int _wae_encrypt_downloaded_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 ret = WAE_ERROR_NONE; - unsigned char *pDek = NULL; - size_t dekLen = -1; - - if (pPkgId == NULL) { - WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - if (pData == NULL || dataLen <= 0) { - WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - if (ppEncryptedData == NULL || pEncDataLen == NULL) { - WAE_SLOGE("Invalid Parameter. ppEncryptedData or pEncDataLen is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } + if (pkg_id == NULL || data == NULL || data_len == 0 || pencrypted_data == NULL || + pencrypted_data_len == NULL) + return WAE_ERROR_INVALID_PARAMETER; // get APP_DEK. // if not exists, create APP_DEK - ret = get_app_dek(pPkgId, appType, &pDek, &dekLen); + unsigned char *dek = NULL; + size_t dek_len = -1; + int ret = get_app_dek(pkg_id, app_type, &dek, &dek_len); - if (ret == WAE_ERROR_NO_KEY) { - ret = create_app_dek(pPkgId, appType, &pDek, &dekLen); - } + if (ret == WAE_ERROR_NO_KEY) + ret = create_app_dek(pkg_id, app_type, &dek, &dek_len); - if (ret != WAE_ERROR_NONE) { + if (ret != WAE_ERROR_NONE) goto error; - } // encrypt - ret = encrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppEncryptedData, pEncDataLen); - - if (ret != WAE_ERROR_NONE) { - goto error; - } + ret = encrypt_aes_cbc(dek, dek_len, data, data_len, pencrypted_data, pencrypted_data_len); error: - if (pDek != NULL) - free(pDek); + free(dek); return ret; } -int _wae_decrypt_downloaded_web_application(const char *pPkgId, wae_app_type_e appType, - const unsigned char *pData, size_t dataLen, - unsigned char **ppDecryptedData, size_t *pDecDataLen) +int _wae_decrypt_downloaded_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 ret = WAE_ERROR_NONE; - unsigned char *pDek = NULL; - size_t dekLen = -1; - if (pPkgId == NULL) { - WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - if (pData == NULL || dataLen <= 0) { - WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - if (ppDecryptedData == NULL || pDecDataLen == NULL) { - WAE_SLOGE("Invalid Parameter. ppDecryptedData or pDecDataLen is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } + if (pkg_id == NULL || data == NULL || data_len == 0 || pdecrypted_data == NULL || + pdecrypted_data_len == NULL) + return WAE_ERROR_INVALID_PARAMETER; - ret = get_app_dek(pPkgId, appType, &pDek, &dekLen); + unsigned char *dek = NULL; + size_t dek_len = -1; + int ret = get_app_dek(pkg_id, app_type, &dek, &dek_len); - if (ret != WAE_ERROR_NONE) { + if (ret != WAE_ERROR_NONE) goto error; - } // decrypt - ret = decrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppDecryptedData, pDecDataLen); - - if (ret != WAE_ERROR_NONE) { - goto error; - } + ret = decrypt_aes_cbc(dek, dek_len, data, data_len, pdecrypted_data, pdecrypted_data_len); error: - if (pDek != NULL) - free(pDek); + free(dek); return ret; } -int _wae_encrypt_preloaded_web_application(const char *pPkgId, - const unsigned char *pData, size_t dataLen, - unsigned char **ppEncryptedData, size_t *pEncDataLen) +int _wae_encrypt_preloaded_web_application(const char *pkg_id, + const unsigned char *data, size_t data_len, + unsigned char **pencrypted_data, size_t *pencrypted_data_len) { + if (pkg_id == NULL || data == NULL || data_len == 0 || pencrypted_data == NULL || + pencrypted_data_len == NULL) + return WAE_ERROR_INVALID_PARAMETER; - int ret = WAE_ERROR_NONE; - unsigned char *pDek = NULL; - size_t dekLen = -1; + unsigned char *dek = NULL; + size_t dek_len = -1; + int ret = get_preloaded_app_dek(pkg_id, &dek, &dek_len); - if (pPkgId == NULL) { - WAE_SLOGE("Invalid Parameter. pPkgId is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } + if (ret == WAE_ERROR_NO_KEY) + ret = create_preloaded_app_dek(pkg_id, &dek, &dek_len); - if (pData == NULL || dataLen <= 0) { - WAE_SLOGE("Invalid Parameter. pData is NULL or invalid dataLen(%d)", dataLen); - ret = WAE_ERROR_INVALID_PARAMETER; + if (ret != WAE_ERROR_NONE) goto error; - } - - if (ppEncryptedData == NULL || pEncDataLen == NULL) { - WAE_SLOGE("Invalid Parameter. ppEncryptedData or pEncDataLen is NULL"); - ret = WAE_ERROR_INVALID_PARAMETER; - goto error; - } - - ret = get_preloaded_app_dek(pPkgId, &pDek, &dekLen); - - if (ret == WAE_ERROR_NO_KEY) { - ret = create_preloaded_app_dek(pPkgId, &pDek, &dekLen); - } - - if (ret != WAE_ERROR_NONE) { - goto error; - } // encrypt - ret = encrypt_aes_cbc(pDek, dekLen, pData, dataLen, ppEncryptedData, pEncDataLen); - - if (ret != WAE_ERROR_NONE) { - goto error; - } + ret = encrypt_aes_cbc(dek, dek_len, data, data_len, pencrypted_data, pencrypted_data_len); error: - if (pDek != NULL) - free(pDek); + free(dek); return ret; } -int _wae_decrypt_preloaded_web_application(const char *pPkgId, wae_app_type_e appType, - const unsigned char *pData, size_t dataLen, - unsigned char **ppDecryptedData, size_t *pDecDataLen) +int _wae_decrypt_preloaded_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) { // same with the decryption of downloaded web application - return _wae_decrypt_downloaded_web_application(pPkgId, appType, - pData, dataLen, ppDecryptedData, pDecDataLen); + return _wae_decrypt_downloaded_web_application(pkg_id, app_type, + data, data_len, pdecrypted_data, pdecrypted_data_len); } -int wae_encrypt_web_application(const char *pPkgId, wae_app_type_e appType, - const unsigned char *pData, size_t dataLen, - unsigned char **ppEncryptedData, size_t *pEncDataLen) +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 ret = WAE_ERROR_NONE; - - if (appType == WAE_PRELOADED_APP) - ret = _wae_encrypt_preloaded_web_application(pPkgId, - pData, dataLen, ppEncryptedData, pEncDataLen); + if (app_type == WAE_PRELOADED_APP) + return _wae_encrypt_preloaded_web_application(pkg_id, + data, data_len, pencrypted_data, pencrypted_data_len); else - ret = _wae_encrypt_downloaded_web_application(pPkgId, appType, - pData, dataLen, ppEncryptedData, pEncDataLen); - - WAE_SLOGI("Encrypt Web App. pkgId=%s, appType=%d, dataLen=%d, ret=%d", - pPkgId, appType, dataLen, ret); - return ret; + return _wae_encrypt_downloaded_web_application(pkg_id, app_type, + data, data_len, pencrypted_data, pencrypted_data_len); } -int wae_decrypt_web_application(const char *pPkgId, wae_app_type_e appType, - const unsigned char *pData, size_t dataLen, - unsigned char **ppDecryptedData, size_t *pDecDataLen) +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 ret = WAE_ERROR_NONE; - - if (appType == WAE_PRELOADED_APP) - ret = _wae_decrypt_preloaded_web_application(pPkgId, appType, - pData, dataLen, ppDecryptedData, pDecDataLen); + if (app_type == WAE_PRELOADED_APP) + return _wae_decrypt_preloaded_web_application(pkg_id, app_type, + data, data_len, pdecrypted_data, pdecrypted_data_len); else - ret = _wae_decrypt_downloaded_web_application(pPkgId, appType, - pData, dataLen, ppDecryptedData, pDecDataLen); - - WAE_SLOGI("Decrypt Web App. pkgId=%s, appType=%d, dataLen=%d, ret=%d", - pPkgId, appType, dataLen, ret); - return ret; + return _wae_decrypt_downloaded_web_application(pkg_id, app_type, + data, data_len, pdecrypted_data, pdecrypted_data_len); } -int wae_remove_app_dek(const char *pPkgId, wae_app_type_e appType) +int wae_remove_app_dek(const char *pkg_id, wae_app_type_e app_type) { - int ret = remove_app_dek(pPkgId, appType); - WAE_SLOGI("Remove APP DEK. pkgId=%s, appType=%d, ret=%d", pPkgId, appType, ret); - return ret; + return remove_app_dek(pkg_id, app_type); } diff --git a/tests/internals.cpp b/tests/internals.cpp index 5d6ca2c..257447b 100644 --- a/tests/internals.cpp +++ b/tests/internals.cpp @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(cache) _add_app_dek_to_cache(pkg3, dek3.data()); size_t dek_len = 32; - unsigned char *_cached = _get_app_dek_from_cache(pkg1); + const unsigned char *_cached = _get_app_dek_from_cache(pkg1); auto cached = Wae::Test::bytearr_to_vec(_cached, dek_len); BOOST_REQUIRE_MESSAGE(cached == dek1, -- 2.7.4 From 99ad3b114bce6ba5743f74c39079d524781134cd Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Mon, 18 Jul 2016 12:54:40 +0900 Subject: [PATCH 12/16] Support platform upgrade case secure-storage is removed since Tizen platform version 3.0. downloaded web apps encryption works based on different key from lower than 3.0. secure-storage used DUK(device unique key with seed(pkgid)) as DEK. If downloaded app cannot find DEK when decrypt, it's considered as encrypted lower than 3.0 case. So webappenc creates DEK and uses algorithm which had been used lower than 3.0 in secure-storage. For now it's hard to save newly created old key in key-manager because migrated web app is considered as global app and the case would be found in decryption time (by web app launcher) who don't have permission to save in system db of key-manager with "/System" label. Permission policy of system db of key-manager should be changed OR migrated app should not be global app (it should be downloaded normal app) to save created key in key-manager. Change-Id: I9b8516184cce9f43b328e290c15127151e5c861e Signed-off-by: Kyungwook Tak --- srcs/CMakeLists.txt | 27 ++++++- srcs/decrypt_migrated_wgt.c | 185 ++++++++++++++++++++++++++++++++++++++++++++ srcs/decrypt_migrated_wgt.h | 31 ++++++++ srcs/web_app_enc.c | 13 +++- 4 files changed, 251 insertions(+), 5 deletions(-) create mode 100644 srcs/decrypt_migrated_wgt.c create mode 100644 srcs/decrypt_migrated_wgt.h diff --git a/srcs/CMakeLists.txt b/srcs/CMakeLists.txt index b95531b..3de6d18 100644 --- a/srcs/CMakeLists.txt +++ b/srcs/CMakeLists.txt @@ -1,11 +1,30 @@ +# 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 +# @brief +# + ################################################################################ # for libwebappenc.so ################################################################################ - SET(WEB_APP_ENC_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/web_app_enc.c - ${CMAKE_CURRENT_SOURCE_DIR}/key_handler.c - ${CMAKE_CURRENT_SOURCE_DIR}/crypto_service.c + web_app_enc.c + key_handler.c + crypto_service.c + decrypt_migrated_wgt.c ) INCLUDE_DIRECTORIES( diff --git a/srcs/decrypt_migrated_wgt.c b/srcs/decrypt_migrated_wgt.c new file mode 100644 index 0000000..d240fa4 --- /dev/null +++ b/srcs/decrypt_migrated_wgt.c @@ -0,0 +1,185 @@ +/* + * 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 decrypt_migrated_wgt.c + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Restore old encryption key for removed secure-storage + */ +#include "decrypt_migrated_wgt.h" + +#include +#include + +#include +#include +#include +#include + +#include "wae_log.h" +#include "web_app_enc.h" + +#define DUK_LEN 16 + +static int _get_old_duk(const char *pkg_id, unsigned char **pduk, size_t *pduk_len) +{ + unsigned char salt[32]; + + memset(salt, 0xFF, sizeof(salt)); + + unsigned char *duk = (unsigned char *)malloc(sizeof(unsigned char) * ((DUK_LEN * 2) + 1)); + if (duk == NULL) { + WAE_SLOGE("Failed to allocate memory for old duk."); + return WAE_ERROR_MEMORY; + } + + PKCS5_PBKDF2_HMAC_SHA1(pkg_id, strlen(pkg_id), salt, sizeof(salt), 1, (DUK_LEN * 2), duk); + duk[DUK_LEN * 2] = '\0'; + + *pduk = duk; + *pduk_len = DUK_LEN; + + WAE_SLOGD("get old duk of length: %d", *pduk_len); + + return WAE_ERROR_NONE; +} + +static int _get_old_iv(const unsigned char *src, size_t src_len, unsigned char **piv, size_t *piv_len) +{ + unsigned char iv_buf[SHA_DIGEST_LENGTH] = {0, }; + unsigned int iv_len = 0; + + if (EVP_Digest(src, src_len, iv_buf, &iv_len, EVP_sha1(), NULL) != 1) { + WAE_SLOGE("Failed to EVP_Digest for getting old iv"); + return WAE_ERROR_CRYPTO; + } + + unsigned char *iv = (unsigned char *)malloc(sizeof(unsigned char) * sizeof(iv_buf)); + if (iv == NULL) + return WAE_ERROR_MEMORY; + + memcpy(iv, iv_buf, sizeof(iv_buf)); + + *piv = iv; + *piv_len = iv_len; + + WAE_SLOGD("get old iv of length: %d", *piv_len); + + return WAE_ERROR_NONE; +} + +static int _decrypt(const unsigned char *key, size_t key_len, + const unsigned char *iv, size_t iv_len, + const unsigned char *data, size_t data_len, + unsigned char **pdecrypted, size_t *pdecrypted_len) +{ + if (key == NULL || iv == NULL || data == NULL || pdecrypted == NULL || + pdecrypted_len == 0) + return WAE_ERROR_INVALID_PARAMETER; + + if (key_len != 16 || iv_len < 16) { + WAE_SLOGE("Invalid key or iv size for decrypt by aes_128_cbc algorithm. " + "key should be 16 bytes and iv should be bigger than 16 bytes"); + return WAE_ERROR_INVALID_PARAMETER; + } + + const struct evp_cipher_st *algo = EVP_aes_128_cbc(); + + EVP_CIPHER_CTX ctx; + + size_t tmp_len = (data_len / algo->block_size + 1) * algo->block_size; + int decrypted_len = 0; + int final_len = 0; + + unsigned char *decrypted = (unsigned char *)calloc(tmp_len, 1); + + if (decrypted == NULL) + return WAE_ERROR_MEMORY; + + EVP_CIPHER_CTX_init(&ctx); + + int ret = EVP_CipherInit(&ctx, algo, key, iv, 0); + + if (ret != 1) { + ret = WAE_ERROR_CRYPTO; + goto error; + } + + ret = EVP_CIPHER_CTX_set_padding(&ctx, 1); + + if (ret != 1) { + ret = WAE_ERROR_CRYPTO; + goto error; + } + + ret = EVP_CipherUpdate(&ctx, decrypted, &decrypted_len, data, data_len); + + if (ret != 1) { + ret = WAE_ERROR_CRYPTO; + goto error; + } else if (decrypted_len <= 0) { + ret = WAE_ERROR_CRYPTO; + goto error; + } + + ret = EVP_CipherFinal(&ctx, decrypted + decrypted_len, &final_len); + + if (ret != 1) { + ret = WAE_ERROR_CRYPTO; + goto error; + } else if (final_len <= 0) { + ret = WAE_ERROR_CRYPTO; + goto error; + } + + *pdecrypted = decrypted; + *pdecrypted_len = decrypted_len + final_len; + + ret = WAE_ERROR_NONE; + +error: + EVP_CIPHER_CTX_cleanup(&ctx); + + return ret; +} + +int decrypt_by_old_ss_algo(const char *pkg_id, const unsigned char *encrypted, size_t encrypted_len, + unsigned char **pdecrypted, size_t *pdecrypted_len) +{ + unsigned char *duk = NULL; + size_t duk_len = 0; + int ret = _get_old_duk(pkg_id, &duk, &duk_len); + + if (ret != WAE_ERROR_NONE) + return ret; + + unsigned char *iv = NULL; + size_t iv_len = 0; + ret = _get_old_iv(duk, duk_len, &iv, &iv_len); + + if (ret != WAE_ERROR_NONE) + goto error; + + ret = _decrypt(duk, duk_len, iv, iv_len, encrypted, encrypted_len, pdecrypted, pdecrypted_len); + + WAE_SLOGI("decrypt with old ss algo success of pkg: %s", pkg_id); + +error: + free(duk); + free(iv); + + return WAE_ERROR_NONE; +} diff --git a/srcs/decrypt_migrated_wgt.h b/srcs/decrypt_migrated_wgt.h new file mode 100644 index 0000000..95f481e --- /dev/null +++ b/srcs/decrypt_migrated_wgt.h @@ -0,0 +1,31 @@ +/* + * 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 decrypt_migrated_wgt.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Restore old encryption key for removed secure-storage + */ +#ifndef __WAE_SS_KEY_GENERATOR_H +#define __WAE_SS_KEY_GENERATOR_H + +#include + +int decrypt_by_old_ss_algo(const char *pkg_id, + const unsigned char *encrypted, size_t encrypted_len, + unsigned char **pdecrypted, size_t *pdecrypted_len); + +#endif /* __WAE_SS_KEY_GENERATOR_H */ diff --git a/srcs/web_app_enc.c b/srcs/web_app_enc.c index dd133d9..a5224ea 100644 --- a/srcs/web_app_enc.c +++ b/srcs/web_app_enc.c @@ -23,6 +23,7 @@ #include +#include "decrypt_migrated_wgt.h" #include "key_handler.h" #include "crypto_service.h" #include "wae_log.h" @@ -70,8 +71,18 @@ int _wae_decrypt_downloaded_web_application(const char *pkg_id, wae_app_type_e a size_t dek_len = -1; int ret = get_app_dek(pkg_id, app_type, &dek, &dek_len); - if (ret != WAE_ERROR_NONE) + if (app_type == WAE_DOWNLOADED_GLOBAL_APP && ret == WAE_ERROR_NO_KEY) { + WAE_SLOGI("app dek for decrypt downloaded app(%s) doesn't exist. This case would be " + "needed secure-storage data migration.", pkg_id); + + ret = decrypt_by_old_ss_algo(pkg_id, data, data_len, pdecrypted_data, pdecrypted_data_len); + if (ret != WAE_ERROR_NONE) + goto error; + else + return WAE_ERROR_NONE; + } else if (ret != WAE_ERROR_NONE) { goto error; + } // decrypt ret = decrypt_aes_cbc(dek, dek_len, data, data_len, pdecrypted_data, pdecrypted_data_len); -- 2.7.4 From f0718c7aa95e51b41e1ee71747a01d75b3aaa9e6 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Tue, 19 Jul 2016 16:16:10 +0900 Subject: [PATCH 13/16] Logging openssl log on crypto error cases Change-Id: I60d574d8813637077fa1e278a3d72dbfed07333c Signed-off-by: Kyungwook Tak --- srcs/decrypt_migrated_wgt.c | 73 +++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/srcs/decrypt_migrated_wgt.c b/srcs/decrypt_migrated_wgt.c index d240fa4..dfaf28a 100644 --- a/srcs/decrypt_migrated_wgt.c +++ b/srcs/decrypt_migrated_wgt.c @@ -28,12 +28,23 @@ #include #include #include +#include #include "wae_log.h" #include "web_app_enc.h" #define DUK_LEN 16 +static void _logging_openssl_err() +{ + unsigned long e = ERR_get_error(); + char buf[512] = {0, }; + + ERR_error_string_n(e, buf, 511); + + WAE_SLOGE("Openssl err: %s", buf); +} + static int _get_old_duk(const char *pkg_id, unsigned char **pduk, size_t *pduk_len) { unsigned char salt[32]; @@ -46,7 +57,12 @@ static int _get_old_duk(const char *pkg_id, unsigned char **pduk, size_t *pduk_l return WAE_ERROR_MEMORY; } - PKCS5_PBKDF2_HMAC_SHA1(pkg_id, strlen(pkg_id), salt, sizeof(salt), 1, (DUK_LEN * 2), duk); + if (PKCS5_PBKDF2_HMAC_SHA1(pkg_id, strlen(pkg_id), salt, sizeof(salt), 1, + (DUK_LEN * 2), duk) != 1) { + free(duk); + return WAE_ERROR_CRYPTO; + } + duk[DUK_LEN * 2] = '\0'; *pduk = duk; @@ -59,19 +75,15 @@ static int _get_old_duk(const char *pkg_id, unsigned char **pduk, size_t *pduk_l static int _get_old_iv(const unsigned char *src, size_t src_len, unsigned char **piv, size_t *piv_len) { - unsigned char iv_buf[SHA_DIGEST_LENGTH] = {0, }; - unsigned int iv_len = 0; - - if (EVP_Digest(src, src_len, iv_buf, &iv_len, EVP_sha1(), NULL) != 1) { - WAE_SLOGE("Failed to EVP_Digest for getting old iv"); - return WAE_ERROR_CRYPTO; - } - - unsigned char *iv = (unsigned char *)malloc(sizeof(unsigned char) * sizeof(iv_buf)); + unsigned int iv_len = SHA_DIGEST_LENGTH; + unsigned char *iv = (unsigned char *)malloc(sizeof(unsigned char) * iv_len); if (iv == NULL) return WAE_ERROR_MEMORY; - memcpy(iv, iv_buf, sizeof(iv_buf)); + if (EVP_Digest(src, src_len, iv, &iv_len, EVP_sha1(), NULL) != 1) { + free(iv); + return WAE_ERROR_CRYPTO; + } *piv = iv; *piv_len = iv_len; @@ -111,48 +123,47 @@ static int _decrypt(const unsigned char *key, size_t key_len, EVP_CIPHER_CTX_init(&ctx); - int ret = EVP_CipherInit(&ctx, algo, key, iv, 0); + int ret = WAE_ERROR_NONE; - if (ret != 1) { + if (EVP_CipherInit(&ctx, algo, key, iv, 0) != 1) { ret = WAE_ERROR_CRYPTO; goto error; } - ret = EVP_CIPHER_CTX_set_padding(&ctx, 1); - - if (ret != 1) { + if (EVP_CIPHER_CTX_set_padding(&ctx, 1) != 1) { ret = WAE_ERROR_CRYPTO; goto error; } - ret = EVP_CipherUpdate(&ctx, decrypted, &decrypted_len, data, data_len); - - if (ret != 1) { + if (EVP_CipherUpdate(&ctx, decrypted, &decrypted_len, data, data_len) != 1) { ret = WAE_ERROR_CRYPTO; goto error; } else if (decrypted_len <= 0) { - ret = WAE_ERROR_CRYPTO; + WAE_SLOGE("EVP_CipherUpdate success but returned decrypted_len(%d) <= 0", + decrypted_len); + ret = WAE_ERROR_UNKNOWN; goto error; } - ret = EVP_CipherFinal(&ctx, decrypted + decrypted_len, &final_len); - - if (ret != 1) { + if (EVP_CipherFinal(&ctx, decrypted + decrypted_len, &final_len) != 1) { ret = WAE_ERROR_CRYPTO; goto error; } else if (final_len <= 0) { - ret = WAE_ERROR_CRYPTO; + WAE_SLOGE("EVP_CipherFinal success but returned final_len(%d) <= 0", + final_len); + ret = WAE_ERROR_UNKNOWN; goto error; } *pdecrypted = decrypted; *pdecrypted_len = decrypted_len + final_len; - ret = WAE_ERROR_NONE; - error: EVP_CIPHER_CTX_cleanup(&ctx); + if (ret != WAE_ERROR_NONE) + free(decrypted); + return ret; } @@ -161,13 +172,14 @@ int decrypt_by_old_ss_algo(const char *pkg_id, const unsigned char *encrypted, s { unsigned char *duk = NULL; size_t duk_len = 0; + unsigned char *iv = NULL; + size_t iv_len = 0; + int ret = _get_old_duk(pkg_id, &duk, &duk_len); if (ret != WAE_ERROR_NONE) - return ret; + goto error; - unsigned char *iv = NULL; - size_t iv_len = 0; ret = _get_old_iv(duk, duk_len, &iv, &iv_len); if (ret != WAE_ERROR_NONE) @@ -178,6 +190,9 @@ int decrypt_by_old_ss_algo(const char *pkg_id, const unsigned char *encrypted, s WAE_SLOGI("decrypt with old ss algo success of pkg: %s", pkg_id); error: + if (ret == WAE_ERROR_CRYPTO) + _logging_openssl_err(); + free(duk); free(iv); -- 2.7.4 From 1aebf02f77796380a570ea41732db0c706213ed1 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Tue, 19 Jul 2016 16:21:51 +0900 Subject: [PATCH 14/16] Fix memory leak on decrypt migrated wgt Change-Id: I300a887e7e633af858e102797c500d1266566355 Signed-off-by: Kyungwook Tak --- srcs/web_app_enc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/srcs/web_app_enc.c b/srcs/web_app_enc.c index a5224ea..083addf 100644 --- a/srcs/web_app_enc.c +++ b/srcs/web_app_enc.c @@ -76,10 +76,7 @@ int _wae_decrypt_downloaded_web_application(const char *pkg_id, wae_app_type_e a "needed secure-storage data migration.", pkg_id); ret = decrypt_by_old_ss_algo(pkg_id, data, data_len, pdecrypted_data, pdecrypted_data_len); - if (ret != WAE_ERROR_NONE) - goto error; - else - return WAE_ERROR_NONE; + goto error; // always go to error to skip decyprt_aes_cbc } else if (ret != WAE_ERROR_NONE) { goto error; } -- 2.7.4 From 6818b8559b7d4d45adaeb1937d708a154dc00fd7 Mon Sep 17 00:00:00 2001 From: Yunjin Lee Date: Wed, 20 Jul 2016 19:24:34 +0900 Subject: [PATCH 15/16] Set SmackProcessLabel to System Change-Id: I685a98780fde45ad0975a0a80dcabd68760f9244 Signed-off-by: Yunjin Lee --- systemd/webappenc-initializer.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/systemd/webappenc-initializer.service.in b/systemd/webappenc-initializer.service.in index e9441d8..976a877 100644 --- a/systemd/webappenc-initializer.service.in +++ b/systemd/webappenc-initializer.service.in @@ -7,6 +7,7 @@ After=central-key-manager.service [Service] Type=oneshot ExecStart=/usr/bin/wae_initializer +SmackProcessLabel=System [Install] WantedBy=multi-user.target -- 2.7.4 From d6da3e3d9bc29e22103b094bee5ca68f5d8f0f61 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Thu, 21 Jul 2016 16:46:00 +0900 Subject: [PATCH 16/16] Add data structures For migrated web app, we need to more fields in cache e.g., IV and is_migrated flag to handle it separately. Because cipher algorithm, iv and key size could be different between old secure storage, it depends on product implementation. So this architecture needs more flexibility. A lot of code changed because of the principle data structure is added from the bottom. Change-Id: Id6a10b9f707f4da25016dd928ab4049be619a610 Signed-off-by: Kyungwook Tak --- srcs/CMakeLists.txt | 2 + srcs/crypto_service.c | 187 ++++++------ srcs/crypto_service.h | 25 +- srcs/decrypt_migrated_wgt.c | 141 +++++---- srcs/decrypt_migrated_wgt.h | 16 +- srcs/key_handler.c | 710 ++++++++++++++++---------------------------- srcs/key_handler.h | 38 +-- srcs/key_manager.c | 393 ++++++++++++++++++++++++ srcs/key_manager.h | 46 +++ srcs/types.c | 255 ++++++++++++++++ srcs/types.h | 65 ++++ srcs/web_app_enc.c | 98 +++--- tests/internals.cpp | 325 ++++++++++---------- tests/non-normals.cpp | 8 +- tests/normals.cpp | 4 +- tests/test-common.cpp | 35 ++- tests/test-common.h | 7 +- tests/test-helper.cpp | 100 +++---- tests/test-helper.h | 4 +- 19 files changed, 1530 insertions(+), 929 deletions(-) create mode 100644 srcs/key_manager.c create mode 100644 srcs/key_manager.h create mode 100644 srcs/types.c create mode 100644 srcs/types.h diff --git a/srcs/CMakeLists.txt b/srcs/CMakeLists.txt index 3de6d18..0b44fdd 100644 --- a/srcs/CMakeLists.txt +++ b/srcs/CMakeLists.txt @@ -25,6 +25,8 @@ SET(WEB_APP_ENC_SOURCES key_handler.c crypto_service.c decrypt_migrated_wgt.c + types.c + key_manager.c ) INCLUDE_DIRECTORIES( diff --git a/srcs/crypto_service.c b/srcs/crypto_service.c index 0991d42..bd83eba 100644 --- a/srcs/crypto_service.c +++ b/srcs/crypto_service.c @@ -36,11 +36,6 @@ #define AES_256_KEY_SIZE 32 -static unsigned char AES_CBC_IV[16] = { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - static bool __initialized = false; void _initialize() @@ -52,26 +47,27 @@ void _initialize() } } -int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, - const unsigned char *dek, size_t dek_len, - unsigned char **pencrypted_dek, size_t *pencrypted_dek_len) +int encrypt_app_dek(const raw_buffer_s *pubkey, const raw_buffer_s *dek, + raw_buffer_s **pencrypted_dek) { + if (!is_buffer_valid(pubkey) || !is_buffer_valid(dek) || pencrypted_dek == NULL) + return WAE_ERROR_INVALID_PARAMETER; + int ret = WAE_ERROR_NONE; EVP_PKEY *key = NULL; - BIO *bio = NULL; EVP_PKEY_CTX *ctx = NULL; - unsigned char *out = NULL; - size_t out_len = 0; + raw_buffer_s *encrypted_dek = NULL; + size_t len = 0; _initialize(); - bio = BIO_new(BIO_s_mem()); - BIO_write(bio, pubkey, pubkey_len); + BIO *bio = BIO_new(BIO_s_mem()); + BIO_write(bio, pubkey->buf, pubkey->size); key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); if (key == NULL) { BIO_reset(bio); - BIO_write(bio, pubkey, pubkey_len); + BIO_write(bio, pubkey->buf, pubkey->size); key = d2i_PUBKEY_bio(bio, NULL); } @@ -102,28 +98,26 @@ int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, } /* Determine buffer length */ - if (EVP_PKEY_encrypt(ctx, NULL, &out_len, dek, dek_len) <= 0) { + if (EVP_PKEY_encrypt(ctx, NULL, &len, dek->buf, dek->size) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - out = OPENSSL_malloc(out_len); - - if (out == NULL) { + if ((encrypted_dek = buffer_create(len)) == NULL) { WAE_SLOGE("Encrypt APP DEK Failed. OPENSSL_malloc failed"); ret = WAE_ERROR_MEMORY; goto error; } - if (EVP_PKEY_encrypt(ctx, out, &out_len, dek, dek_len) <= 0) { + if (EVP_PKEY_encrypt(ctx, encrypted_dek->buf, &encrypted_dek->size, dek->buf, + dek->size) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - *pencrypted_dek = out; - *pencrypted_dek_len = out_len; + *pencrypted_dek = encrypted_dek; error: if (bio != NULL) @@ -135,39 +129,41 @@ error: if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && out != NULL) - OPENSSL_free(out); + if (ret != WAE_ERROR_NONE) + buffer_destroy(encrypted_dek); return ret; } -int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, - const char *prikey_pass, - const unsigned char *encrypted_dek, size_t encrypted_dek_len, - unsigned char **pdecrypted_dek, size_t *pdecrypted_dek_len) +int decrypt_app_dek(const raw_buffer_s *prikey, const char *prikey_pass, + const raw_buffer_s *encrypted_dek, raw_buffer_s **pdek) { + if (!is_buffer_valid(prikey) || !is_buffer_valid(encrypted_dek) || pdek == NULL) + return WAE_ERROR_INVALID_PARAMETER; + int ret = WAE_ERROR_NONE; - EVP_PKEY *key = NULL; - BIO *bio = NULL; EVP_PKEY_CTX *ctx = NULL; - unsigned char *out = NULL; - size_t out_len = 0; + raw_buffer_s *dek = NULL; + size_t len = 0; _initialize(); - bio = BIO_new(BIO_s_mem()); - BIO_write(bio, prikey, prikey_len); - key = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)prikey_pass); + BIO *bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + return WAE_ERROR_MEMORY; + + BIO_write(bio, prikey->buf, prikey->size); + EVP_PKEY *key = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)prikey_pass); if (key == NULL) { BIO_reset(bio); - BIO_write(bio, prikey, prikey_len); + BIO_write(bio, prikey->buf, prikey->size); key = d2i_PrivateKey_bio(bio, NULL); } if (key == NULL) { ret = WAE_ERROR_FILE; - WAE_SLOGE("Failt to convert to public key."); + WAE_SLOGE("Failed to convert to public key."); goto error; } @@ -192,28 +188,27 @@ int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, } /* Determine buffer length */ - if (EVP_PKEY_decrypt(ctx, NULL, &out_len, encrypted_dek, encrypted_dek_len) <= 0) { + if (EVP_PKEY_decrypt(ctx, NULL, &len, encrypted_dek->buf, encrypted_dek->size) <= 0) { WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - out = OPENSSL_malloc(out_len); - - if (out == NULL) { + dek = buffer_create(len); + if (dek == NULL) { WAE_SLOGE("Decrypt APP DEK Failed. OPENSSL_malloc failed"); ret = WAE_ERROR_MEMORY; goto error; } - if (EVP_PKEY_decrypt(ctx, out, &out_len, encrypted_dek, encrypted_dek_len) <= 0) { + if (EVP_PKEY_decrypt(ctx, dek->buf, &dek->size, encrypted_dek->buf, + encrypted_dek->size) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_decrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - *pdecrypted_dek = out; - *pdecrypted_dek_len = out_len; + *pdek = dek; error: if (bio != NULL) @@ -225,36 +220,40 @@ error: if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && out != NULL) - OPENSSL_free(out); + if (ret != WAE_ERROR_NONE) + buffer_destroy(dek); return ret; } -int encrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pencrypted_data, size_t *pencrypted_data_len) +int encrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *data, + raw_buffer_s **pencrypted_data) { - EVP_CIPHER_CTX *ctx; - int len; - unsigned char *ciphertext = NULL; - size_t ciphertext_len; - unsigned char *iv = AES_CBC_IV; + if (!is_crypto_element_valid(ce) || !is_buffer_valid(data) || pencrypted_data == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + EVP_CIPHER_CTX *ctx = NULL; + int len = 0; + raw_buffer_s *encrypted_data = NULL; int ret = WAE_ERROR_NONE; _initialize(); - WAE_SLOGI("Encryption Started. size=%d", data_len); + WAE_SLOGI("Encryption Started. size=%d", data->size); /* check input paramter */ - if (key_len != 32) { - WAE_SLOGE("Encryption Failed. Invalid Key Length. key_len=%d", key_len); + if (ce->dek->size != 32) { + WAE_SLOGE("Encryption Failed. Invalid Key Length. key_len=%d", ce->dek->size); return WAE_ERROR_INVALID_PARAMETER; } // assing a enough memory for decryption. - ciphertext = (unsigned char *) malloc(data_len + 32); + encrypted_data = buffer_create(data->size + 32); + if (encrypted_data == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } /* Create and initialise the context */ if (!(ctx = EVP_CIPHER_CTX_new())) { @@ -268,7 +267,7 @@ int encrypt_aes_cbc(const unsigned char *key, size_t key_len, * In this example we are using 256 bit AES (i.e. a 256 bit key). The * IV size for *most* modes is the same as the block size. For AES this * is 128 bits */ - if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { + if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, ce->dek->buf, ce->iv->buf) != 1) { WAE_SLOGE("Encryption Failed. EVP_EncryptInit_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -277,64 +276,68 @@ int encrypt_aes_cbc(const unsigned char *key, size_t key_len, /* Provide the message to be encrypted, and obtain the encrypted output. * EVP_EncryptUpdate can be called multiple times if necessary */ - if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, data, data_len)) { + len = encrypted_data->size; + if (EVP_EncryptUpdate(ctx, encrypted_data->buf, &len, data->buf, + data->size) != 1) { WAE_SLOGE("Encryption Failed. EVP_EncryptUpdate failed"); ret = WAE_ERROR_CRYPTO; goto error; } - ciphertext_len = len; + encrypted_data->size = len; - /* Finalise the encryption. Further ciphertext bytes may be written at + /* Finalise the encryption. Further encrypted data bytes may be written at * this stage. */ - if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { + if (EVP_EncryptFinal_ex(ctx, encrypted_data->buf + encrypted_data->size, &len) != 1) { WAE_SLOGE("Encryption Failed. EVP_EncryptFinal_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; } - ciphertext_len += len; + encrypted_data->size += len; - *pencrypted_data = ciphertext; - *pencrypted_data_len = ciphertext_len; + *pencrypted_data = encrypted_data; - ret = WAE_ERROR_NONE; - WAE_SLOGI("Encryption Ended Successfully. encrypted_len", ciphertext_len); + WAE_SLOGI("Encryption Ended Successfully. encrypted_len: %d", encrypted_data->size); error: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && ciphertext != NULL) - free(ciphertext); + if (ret != WAE_ERROR_NONE) + buffer_destroy(encrypted_data); return ret; } -int decrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) +int decrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *encrypted_data, + raw_buffer_s **pdata) { - EVP_CIPHER_CTX *ctx; - int len; - unsigned char *plaintext = NULL; - size_t plaintext_len; - unsigned char *iv = AES_CBC_IV; + if (!is_crypto_element_valid(ce) || !is_buffer_valid(encrypted_data) || pdata == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + EVP_CIPHER_CTX *ctx = NULL; + int len = 0; + raw_buffer_s *data = NULL; int ret = WAE_ERROR_NONE; _initialize(); - WAE_SLOGI("Decryption Started. size=%d", data_len); + WAE_SLOGI("Decryption Started. size=%d", encrypted_data->size); /* check input paramter */ - if (key_len != 32) { - WAE_SLOGE("Decryption Failed. Invalid Key Length. key_len=%d", key_len); + if (ce->dek->size != 32) { + WAE_SLOGE("Decryption Failed. Invalid Key Length. key_len=%d", ce->dek->size); return WAE_ERROR_INVALID_PARAMETER; } // assing a enough memory for decryption. - plaintext = (unsigned char *) malloc(data_len); + data = buffer_create(encrypted_data->size); + if (data == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } /* Create and initialise the context */ if (!(ctx = EVP_CIPHER_CTX_new())) { @@ -348,7 +351,7 @@ int decrypt_aes_cbc(const unsigned char *key, size_t key_len, * In this example we are using 256 bit AES (i.e. a 256 bit key). The * IV size for *most* modes is the same as the block size. For AES this * is 128 bits */ - if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { + if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, ce->dek->buf, ce->iv->buf) != 1) { WAE_SLOGE("Decryption Failed. EVP_DecryptInit_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -357,37 +360,37 @@ int decrypt_aes_cbc(const unsigned char *key, size_t key_len, /* Provide the message to be decrypted, and obtain the plaintext output. * EVP_DecryptUpdate can be called multiple times if necessary */ - if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, data, data_len)) { + len = data->size; + if (EVP_DecryptUpdate(ctx, data->buf, &len, encrypted_data->buf, + encrypted_data->size) != 1) { WAE_SLOGE("Decryption Failed. EVP_DecryptUpdate failed"); ret = WAE_ERROR_CRYPTO; goto error; } - plaintext_len = len; + data->size = len; /* Finalise the decryption. Further plaintext bytes may be written at * this stage. */ - if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) { + if (EVP_DecryptFinal_ex(ctx, data->buf + data->size, &len) != 1) { WAE_SLOGE("Decryption Failed. EVP_DecryptFinal_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; } - plaintext_len += len; + data->size += len; - *pdecrypted_data = plaintext; - *pdecrypted_data_len = plaintext_len; + *pdata = data; - ret = WAE_ERROR_NONE; - WAE_SLOGI("Decryption Ended Successfully. decrypted_len", plaintext_len); + WAE_SLOGI("Decryption Ended Successfully. decrypted_len: %d", data->size); error: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && plaintext != NULL) - free(plaintext); + if (ret != WAE_ERROR_NONE) + buffer_destroy(data); return ret; } diff --git a/srcs/crypto_service.h b/srcs/crypto_service.h index 8a64d6d..c6340ae 100644 --- a/srcs/crypto_service.h +++ b/srcs/crypto_service.h @@ -26,25 +26,18 @@ extern "C" { #endif -#include +#include "types.h" -int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, - const unsigned char *dek, size_t dek_len, - unsigned char **encryptedDek, size_t *encryptedDekLen); +int encrypt_app_dek(const raw_buffer_s *pubkey, const raw_buffer_s *dek, + raw_buffer_s **pencrypted_dek); +int decrypt_app_dek(const raw_buffer_s *prikey, const char *prikey_pass, + const raw_buffer_s *encrypted_dek, raw_buffer_s **pdek); -int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, - const char *prikey_pass, - const unsigned char *encrypted_dek, size_t encrypted_dek_len, - unsigned char **pdecrypted_dek, size_t *pdecrypted_dek_len); - -int encrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pencrypted_data, size_t *pencrypted_data_len); - -int decrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pdecrypted_data, size_t *pdecrypted_data_len); +int encrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *data, + raw_buffer_s **pencrypted_data); +int decrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *encrypted_data, + raw_buffer_s **pdata); #ifdef __cplusplus } diff --git a/srcs/decrypt_migrated_wgt.c b/srcs/decrypt_migrated_wgt.c index dfaf28a..1012a35 100644 --- a/srcs/decrypt_migrated_wgt.c +++ b/srcs/decrypt_migrated_wgt.c @@ -33,7 +33,7 @@ #include "wae_log.h" #include "web_app_enc.h" -#define DUK_LEN 16 +#define DUK_SIZE 16 static void _logging_openssl_err() { @@ -45,64 +45,62 @@ static void _logging_openssl_err() WAE_SLOGE("Openssl err: %s", buf); } -static int _get_old_duk(const char *pkg_id, unsigned char **pduk, size_t *pduk_len) +static int _get_old_duk(const char *pkg_id, raw_buffer_s **pduk) { + if (pkg_id == NULL || pduk == NULL) + return WAE_ERROR_INVALID_PARAMETER; + unsigned char salt[32]; memset(salt, 0xFF, sizeof(salt)); - unsigned char *duk = (unsigned char *)malloc(sizeof(unsigned char) * ((DUK_LEN * 2) + 1)); - if (duk == NULL) { - WAE_SLOGE("Failed to allocate memory for old duk."); + raw_buffer_s *duk = buffer_create(DUK_SIZE * 2); + if (duk == NULL) return WAE_ERROR_MEMORY; - } if (PKCS5_PBKDF2_HMAC_SHA1(pkg_id, strlen(pkg_id), salt, sizeof(salt), 1, - (DUK_LEN * 2), duk) != 1) { - free(duk); + duk->size, duk->buf) != 1) { + buffer_destroy(duk); return WAE_ERROR_CRYPTO; } - duk[DUK_LEN * 2] = '\0'; + duk->size = DUK_SIZE; *pduk = duk; - *pduk_len = DUK_LEN; - WAE_SLOGD("get old duk of length: %d", *pduk_len); + WAE_SLOGD("get old duk of length: %d", duk->size); return WAE_ERROR_NONE; } -static int _get_old_iv(const unsigned char *src, size_t src_len, unsigned char **piv, size_t *piv_len) +static int _get_old_iv(const raw_buffer_s *src, raw_buffer_s **piv) { - unsigned int iv_len = SHA_DIGEST_LENGTH; - unsigned char *iv = (unsigned char *)malloc(sizeof(unsigned char) * iv_len); + if (!is_buffer_valid(src) || piv == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + raw_buffer_s *iv = buffer_create(SHA_DIGEST_LENGTH); if (iv == NULL) return WAE_ERROR_MEMORY; - if (EVP_Digest(src, src_len, iv, &iv_len, EVP_sha1(), NULL) != 1) { - free(iv); + if (EVP_Digest(src->buf, src->size, iv->buf, &iv->size, EVP_sha1(), NULL) != 1) { + buffer_destroy(iv); return WAE_ERROR_CRYPTO; } *piv = iv; - *piv_len = iv_len; - WAE_SLOGD("get old iv of length: %d", *piv_len); + WAE_SLOGD("get old iv of length: %d", iv->size); return WAE_ERROR_NONE; } -static int _decrypt(const unsigned char *key, size_t key_len, - const unsigned char *iv, size_t iv_len, - const unsigned char *data, size_t data_len, - unsigned char **pdecrypted, size_t *pdecrypted_len) +static int _decrypt(const crypto_element_s *ce, const raw_buffer_s *data, + raw_buffer_s **pdecrypted) { - if (key == NULL || iv == NULL || data == NULL || pdecrypted == NULL || - pdecrypted_len == 0) + if (!is_crypto_element_valid(ce) || !is_buffer_valid(data) || pdecrypted == NULL) return WAE_ERROR_INVALID_PARAMETER; - if (key_len != 16 || iv_len < 16) { + if (ce->dek->size != DUK_SIZE || ce->iv->size < DUK_SIZE) { WAE_SLOGE("Invalid key or iv size for decrypt by aes_128_cbc algorithm. " "key should be 16 bytes and iv should be bigger than 16 bytes"); return WAE_ERROR_INVALID_PARAMETER; @@ -110,22 +108,22 @@ static int _decrypt(const unsigned char *key, size_t key_len, const struct evp_cipher_st *algo = EVP_aes_128_cbc(); - EVP_CIPHER_CTX ctx; - - size_t tmp_len = (data_len / algo->block_size + 1) * algo->block_size; - int decrypted_len = 0; + int in_len = data->size; + int out_len = 0; int final_len = 0; - unsigned char *decrypted = (unsigned char *)calloc(tmp_len, 1); + raw_buffer_s *decrypted = buffer_create( + (in_len / algo->block_size + 1) * algo->block_size); if (decrypted == NULL) return WAE_ERROR_MEMORY; + EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); int ret = WAE_ERROR_NONE; - if (EVP_CipherInit(&ctx, algo, key, iv, 0) != 1) { + if (EVP_CipherInit(&ctx, algo, ce->dek->buf, ce->iv->buf, 0) != 1) { ret = WAE_ERROR_CRYPTO; goto error; } @@ -135,66 +133,85 @@ static int _decrypt(const unsigned char *key, size_t key_len, goto error; } - if (EVP_CipherUpdate(&ctx, decrypted, &decrypted_len, data, data_len) != 1) { + if (EVP_CipherUpdate(&ctx, decrypted->buf, &out_len, data->buf, in_len) != 1) { ret = WAE_ERROR_CRYPTO; goto error; - } else if (decrypted_len <= 0) { - WAE_SLOGE("EVP_CipherUpdate success but returned decrypted_len(%d) <= 0", - decrypted_len); - ret = WAE_ERROR_UNKNOWN; - goto error; } - if (EVP_CipherFinal(&ctx, decrypted + decrypted_len, &final_len) != 1) { + if (EVP_CipherFinal(&ctx, decrypted->buf + out_len, &final_len) != 1) { ret = WAE_ERROR_CRYPTO; goto error; - } else if (final_len <= 0) { - WAE_SLOGE("EVP_CipherFinal success but returned final_len(%d) <= 0", - final_len); - ret = WAE_ERROR_UNKNOWN; - goto error; } + decrypted->size = out_len + final_len; + *pdecrypted = decrypted; - *pdecrypted_len = decrypted_len + final_len; error: EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WAE_ERROR_NONE) - free(decrypted); + buffer_destroy(decrypted); return ret; } -int decrypt_by_old_ss_algo(const char *pkg_id, const unsigned char *encrypted, size_t encrypted_len, - unsigned char **pdecrypted, size_t *pdecrypted_len) +int get_old_ss_crypto_element(const char *pkg_id, crypto_element_s **pce) { - unsigned char *duk = NULL; - size_t duk_len = 0; - unsigned char *iv = NULL; - size_t iv_len = 0; + if (pkg_id == NULL || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; - int ret = _get_old_duk(pkg_id, &duk, &duk_len); + raw_buffer_s *duk = NULL; + raw_buffer_s *iv = NULL; + crypto_element_s *ce = NULL; + int ret = _get_old_duk(pkg_id, &duk); if (ret != WAE_ERROR_NONE) - goto error; - - ret = _get_old_iv(duk, duk_len, &iv, &iv_len); + return ret; + ret = _get_old_iv(duk, &iv); if (ret != WAE_ERROR_NONE) goto error; - ret = _decrypt(duk, duk_len, iv, iv_len, encrypted, encrypted_len, pdecrypted, pdecrypted_len); + ce = crypto_element_create(duk, iv); + if (ce == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } - WAE_SLOGI("decrypt with old ss algo success of pkg: %s", pkg_id); + ce->is_migrated_app = true; + + *pce = ce; + + return WAE_ERROR_NONE; error: - if (ret == WAE_ERROR_CRYPTO) - _logging_openssl_err(); + buffer_destroy(duk); + buffer_destroy(iv); - free(duk); - free(iv); + return ret; +} - return WAE_ERROR_NONE; +int decrypt_by_old_ss_algo(const crypto_element_s *ce, const raw_buffer_s *encrypted, + raw_buffer_s **pdecrypted) +{ + if (!is_crypto_element_valid(ce) || !is_buffer_valid(encrypted) || pdecrypted == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + int ret = _decrypt(ce, encrypted, pdecrypted); + + switch (ret) { + case WAE_ERROR_CRYPTO: + WAE_SLOGE("decrypt with old ss algo failed with crypto error below."); + _logging_openssl_err(); + break; + case WAE_ERROR_NONE: + WAE_SLOGI("decrypt with old ss algo success!"); + break; + default: + WAE_SLOGE("decrypt with old ss algo failed! ret(%d)", ret); + break; + } + + return ret; } diff --git a/srcs/decrypt_migrated_wgt.h b/srcs/decrypt_migrated_wgt.h index 95f481e..42f99ad 100644 --- a/srcs/decrypt_migrated_wgt.h +++ b/srcs/decrypt_migrated_wgt.h @@ -22,10 +22,18 @@ #ifndef __WAE_SS_KEY_GENERATOR_H #define __WAE_SS_KEY_GENERATOR_H -#include +#ifdef __cplusplus +extern "C" { +#endif -int decrypt_by_old_ss_algo(const char *pkg_id, - const unsigned char *encrypted, size_t encrypted_len, - unsigned char **pdecrypted, size_t *pdecrypted_len); +#include "types.h" + +int get_old_ss_crypto_element(const char *pkg_id, crypto_element_s **pce); +int decrypt_by_old_ss_algo(const crypto_element_s *ce, const raw_buffer_s *encrypted, + raw_buffer_s **pdecrypted); + +#ifdef __cplusplus +} +#endif #endif /* __WAE_SS_KEY_GENERATOR_H */ diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 0cb2776..af7280b 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -27,112 +27,55 @@ #include #include -#include #include #include "wae_log.h" -#include "web_app_enc.h" #include "crypto_service.h" +#include "key_manager.h" +#include "decrypt_migrated_wgt.h" #define RANDOM_FILE "/dev/urandom" #define APP_DEK_KEK_PRIKEY_PASSWORD "wae_appdek_kek_1q2w3e4r" -#define APP_DEK_ALIAS_PFX "APP_DEK_" -#define APP_DEK_LOADING_DONE_ALIAS "APP_DEKS_LOADING_FINISHED" #define APP_DEK_FILE_PFX "WAE_APP_DEK" -#define APP_DEK_KEK_ALIAS "WAE_APP_DEK_KEK" #define DEK_LEN 32 -#define MAX_ALIAS_LEN 256 +#define IV_LEN 16 #define MAX_PKGID_LEN 256 #define MAX_CACHE_SIZE 100 -typedef struct _dek_cache_element { - char pkg_id[MAX_PKGID_LEN]; - unsigned char dek[DEK_LEN]; -} dek_cache_element; +static unsigned char AES_CBC_IV[IV_LEN] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; -dek_cache_element APP_DEK_CACHE[MAX_CACHE_SIZE]; -int NEXT_CACHE_IDX = -1; +static crypto_element_map_s *_map; -void _initialize_cache() +static void deinit_lib(void) __attribute__((destructor)); +static void deinit_lib(void) { - NEXT_CACHE_IDX = 0; - memset(APP_DEK_CACHE, 0, sizeof(dek_cache_element) * MAX_CACHE_SIZE); + crypto_element_map_destroy(_map); } -const unsigned char *_get_app_dek_from_cache(const char *pkg_id) +static const crypto_element_s *_get_app_ce_from_cache(const char *pkg_id) { - if (NEXT_CACHE_IDX < 0) - _initialize_cache(); - - for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { - //WAE_SLOGI("CACHED APP_DEK[%d]=%s", i, APP_DEK_CACHE[i].pkg_id); - if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) - return APP_DEK_CACHE[i].dek; - } - - return NULL; + return crypto_element_map_get(_map, pkg_id); } -void _add_app_dek_to_cache(const char *pkg_id, const unsigned char *dek) +static int _add_app_ce_to_cache(const char *pkg_id, crypto_element_s *ce) { - if (NEXT_CACHE_IDX < 0) - _initialize_cache(); - - // if existing one has the same pkgid - for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { - if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) { - memcpy(APP_DEK_CACHE[i].dek, dek, DEK_LEN); - return; - } - } - - // for new pkgid - strncpy(APP_DEK_CACHE[NEXT_CACHE_IDX].pkg_id, pkg_id, MAX_PKGID_LEN - 1); - memcpy(APP_DEK_CACHE[NEXT_CACHE_IDX].dek, dek, DEK_LEN); - - ++NEXT_CACHE_IDX; - - if (NEXT_CACHE_IDX >= MAX_CACHE_SIZE) - NEXT_CACHE_IDX = 0; + return crypto_element_map_add(&_map, pkg_id, ce); } -void _remove_app_dek_from_cache(const char *pkg_id) +void _remove_app_ce_from_cache(const char *pkg_id) { - for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { - if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) { - memset(APP_DEK_CACHE[i].pkg_id, 0, MAX_PKGID_LEN); - return; - } - } - + crypto_element_map_remove(&_map, pkg_id); } -int _to_wae_error(int key_manager_error) +int _get_random(raw_buffer_s *rb) { - switch (key_manager_error) { - case CKMC_ERROR_NONE: - return WAE_ERROR_NONE; - - case CKMC_ERROR_INVALID_PARAMETER: + if (!is_buffer_valid(rb)) return WAE_ERROR_INVALID_PARAMETER; - case CKMC_ERROR_PERMISSION_DENIED: - return WAE_ERROR_PERMISSION_DENIED; - - case CKMC_ERROR_DB_ALIAS_UNKNOWN: - return WAE_ERROR_NO_KEY; - - case CKMC_ERROR_DB_ALIAS_EXISTS: - return WAE_ERROR_KEY_EXISTS; - - default: - return WAE_ERROR_KEY_MANAGER; - } -} - -int _get_random(size_t length, unsigned char *random) -{ FILE *f = fopen(RANDOM_FILE, "r"); if (f == NULL) { @@ -142,100 +85,95 @@ int _get_random(size_t length, unsigned char *random) size_t i = 0; int ch = 0; - while (i < length && (ch = fgetc(f) != EOF)) - random[i++] = (unsigned char)ch; + while (i < rb->size && (ch = fgetc(f) != EOF)) + rb->buf[i++] = (unsigned char)ch; fclose(f); return WAE_ERROR_NONE; } -void _get_alias(const char *pkg_id, wae_app_type_e app_type, bool forSave, char *alias, size_t buff_len) +static const char *_get_dek_kek_pub_key_path() { - if (app_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); - } + return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PublicKey.pem"); } -void _get_dek_kek_alias(char *alias, size_t buff_len) +static const char *_get_dek_kek_pri_key_path() { - snprintf(alias, buff_len, "%s%s%s", - ckmc_owner_id_system, - ckmc_owner_id_separator, - APP_DEK_KEK_ALIAS); + return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PrivateKey.pem"); } -void _get_dek_loading_done_alias(char *alias, size_t buff_len) +static const char *_get_dek_store_path() { - snprintf(alias, buff_len, "%s%s%s", - ckmc_owner_id_system, - ckmc_owner_id_separator, - APP_DEK_LOADING_DONE_ALIAS); + return tzplatform_mkpath3(TZ_SYS_SHARE, "wae", "app_dek"); } -const char *_get_dek_kek_pub_key_path() +static int _write_to_file(const char *path, const raw_buffer_s *data) { - return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PublicKey.pem"); -} + if (path == NULL || data == NULL || data->buf == NULL || data->size == 0) + return WAE_ERROR_INVALID_PARAMETER; -const char *_get_dek_kek_pri_key_path() -{ - return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PrivateKey.pem"); -} + FILE *f = fopen(path, "w"); -const char *_get_dek_store_path() -{ - return tzplatform_mkpath3(TZ_SYS_SHARE, "wae", "app_dek"); + if (f == NULL) { + WAE_SLOGE("WAE: Fail to open a file. file=%s", path); + return WAE_ERROR_FILE; + } + + int write_len = fwrite(data->buf, 1, data->size, f); + + fclose(f); + + if (write_len != (int)data->size) { + WAE_SLOGE("WAE: Fail to write a file. file=%s", path); + return WAE_ERROR_FILE; + } + + return WAE_ERROR_NONE; } -int _add_dek_to_key_manager(const char *pkg_id, wae_app_type_e app_type, const unsigned char *dek, size_t dek_len) +static int _read_from_file(const char *path, raw_buffer_s **pdata) { int ret = WAE_ERROR_NONE; - char alias[MAX_ALIAS_LEN] = {0, }; - ckmc_raw_buffer_s buff; - ckmc_policy_s policy; - - buff.data = (unsigned char *)dek; - buff.size = dek_len; + raw_buffer_s *data = NULL; + int ch = 0; + int i = 0; - policy.password = NULL; - policy.extractable = true; + FILE *f = fopen(path, "r"); - _get_alias(pkg_id, app_type, true, alias, sizeof(alias)); + if (f == NULL) { + WAE_SLOGE("Failed to open a file. file=%s", path); + return WAE_ERROR_FILE; + } - // even if it fails to remove, ignore it. - ckmc_remove_alias(alias); + fseek(f, 0, SEEK_END); // move to the end of a file + int file_len = ftell(f); - ret = _to_wae_error(ckmc_save_data(alias, buff, policy)); - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to add APP_DEK to key-manager. pkg_id=%s, alias=%s, ret=%d", pkg_id, alias, ret); - return ret; + if (file_len <= 0) { + WAE_SLOGE("Failed to get file size by ftell. ret: %d", file_len); + ret = WAE_ERROR_FILE; + goto error; } - // share app_dek for web app laucher to use app_dek - ret = _to_wae_error(ckmc_set_permission(alias, pkg_id, CKMC_PERMISSION_READ)); - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to set_permission to APP_DEK. pkg_id=%s, ret=%d", pkg_id, ret); - return ret; + fseek(f, 0, SEEK_SET); // move to the start of a file + + data = buffer_create(file_len); + if (data == NULL) { + WAE_SLOGE("Failed to allocate memory for encrypted_dek"); + ret = WAE_ERROR_MEMORY; + goto error; } - WAE_SLOGI("WAE: Success to add APP_DEK to key-manager. pkg_id=%s, alias=%s", pkg_id, alias); + while ((ch = fgetc(f)) != EOF) + data->buf[i++] = (char)ch; + + *pdata = data; + +error: + fclose(f); + + if (ret != WAE_ERROR_NONE) + buffer_destroy(data); return ret; } @@ -251,7 +189,7 @@ int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path return WAE_ERROR_NONE; } -int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) +static int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) { char *start = strstr(file_name, APP_DEK_FILE_PFX); @@ -274,238 +212,172 @@ int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) return WAE_ERROR_NONE; } -int _read_encrypted_app_dek_from_file(const char *pkg_id, unsigned char **pencrypted_app_dek, size_t *pencrypted_app_dek_len) +int _read_encrypted_app_dek_from_file(const char *pkg_id, raw_buffer_s **pencrypted) { char path[MAX_PATH_LEN] = {0,}; _get_preloaded_app_dek_file_path(pkg_id, sizeof(path), path); - return _read_from_file(path, pencrypted_app_dek, pencrypted_app_dek_len); + return _read_from_file(path, pencrypted); } -int _write_encrypted_app_dek_to_file(const char *pkg_id, const unsigned char *encrypted_app_dek, size_t encrypted_app_dek_len) +int _write_encrypted_app_dek_to_file(const char *pkg_id, const raw_buffer_s *encrypted) { char path[MAX_PATH_LEN] = {0,}; _get_preloaded_app_dek_file_path(pkg_id, sizeof(path), path); - return _write_to_file(path, encrypted_app_dek, encrypted_app_dek_len); + return _write_to_file(path, encrypted); } -int _read_from_file(const char *path, unsigned char **pdata, size_t *pdata_len) +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 ret = WAE_ERROR_NONE; - unsigned char *file_contents = NULL; - int ch = 0; - int i = 0; - - FILE *f = fopen(path, "r"); + if (pkg_id == NULL || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; - if (f == NULL) { - WAE_SLOGE("WAE: Fail to open a file. file=%s", path); - return WAE_ERROR_FILE; + const crypto_element_s *cached_ce = _get_app_ce_from_cache(pkg_id); + if (cached_ce != NULL) { + WAE_SLOGD("cache hit of app ce for pkg_id(%s)", pkg_id); + *pce = cached_ce; + return WAE_ERROR_NONE; } - fseek(f, 0, SEEK_END); // move to the end of a file - int file_len = ftell(f); + WAE_SLOGD("cache miss of app ce for pkg_id(%s)", pkg_id); - if (file_len <= 0) { - WAE_SLOGE("WAE: Failed to get file size by ftell. ret: %d", file_len); - ret = WAE_ERROR_FILE; - goto error; - } + crypto_element_s *ce = NULL; + int ret = get_from_key_manager(pkg_id, app_type, &ce); - fseek(f, 0, SEEK_SET); // move to the start of a file + 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); - file_contents = (unsigned char *)malloc(file_len); + if ((ret = get_old_ss_crypto_element(pkg_id, &ce)) != WAE_ERROR_NONE) + goto error; - if (file_contents == NULL) { - WAE_SLOGE("WAE: Fail to allocate memory for encrypted_app_dek"); - ret = WAE_ERROR_MEMORY; + // (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); + //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; } - memset(file_contents, 0x00, file_len); + 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; + } - while ((ch = fgetc(f)) != EOF) - file_contents[i++] = (char)ch; + *pce = ce; - *pdata = file_contents; - *pdata_len = file_len; + WAE_SLOGD("Successfully get ce! pkgid(%s)", pkg_id); -error: - fclose(f); + return WAE_ERROR_NONE; - if (ret != WAE_ERROR_NONE) - free(file_contents); +error: + crypto_element_destroy(ce); return ret; } -int _write_to_file(const char *path, const unsigned char *data, size_t data_len) +int create_app_ce(const char *pkg_id, wae_app_type_e app_type, const crypto_element_s **pce) { - FILE *f = fopen(path, "w"); + 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); - if (f == NULL) { - WAE_SLOGE("WAE: Fail to open a file. file=%s", path); - return WAE_ERROR_FILE; - } - - int write_len = fwrite(data, 1, data_len, f); - - fclose(f); - - if (write_len != (int)data_len) { - WAE_SLOGE("WAE: Fail to write a file. file=%s", path); - return WAE_ERROR_FILE; - } - - return WAE_ERROR_NONE; -} - -int get_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len) -{ int ret = WAE_ERROR_NONE; - ckmc_raw_buffer_s *dek_buffer = NULL; - char alias[MAX_ALIAS_LEN] = {0, }; - - const unsigned char *cached_dek = _get_app_dek_from_cache(pkg_id); - - if (cached_dek == NULL) { - // get APP_DEK from system database - _get_alias(pkg_id, app_type, false, alias, sizeof(alias)); - - ret = _to_wae_error(ckmc_get_data(alias, NULL, &dek_buffer)); - - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to get APP_DEK from key-manager. pkg_id=%s, alias=%s, ret=%d", - pkg_id, alias, ret); - goto error; - } else if (dek_buffer == NULL || dek_buffer->data == NULL) { - WAE_SLOGE("key-manager success but buffer is null for getting dek of pkg_id=%s", - pkg_id); - ret = WAE_ERROR_KEY_MANAGER; - goto error; - } else if (dek_buffer->size != DEK_LEN) { - WAE_SLOGE("DEK's length which has been saved in key-manager is not valid!"); - ret = WAE_ERROR_KEY_MANAGER; - goto error; - } - - WAE_SLOGD("Successfully get dek from key-manager for pkgid=%s", pkg_id); - cached_dek = dek_buffer->data; - } - - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); - - if (dek == NULL) { - WAE_SLOGE("Fail to allocate a memory"); + if (ce == NULL) { ret = WAE_ERROR_MEMORY; goto error; } - memcpy(dek, cached_dek, DEK_LEN); - - *pdek = dek; - *pdek_len = DEK_LEN; - - WAE_SLOGI("WAE: Success to get APP_DEK from key-manager. pkg_id=%s, alias=%s", - pkg_id, alias); - -error: - ckmc_buffer_free(dek_buffer); - - if (ret != WAE_ERROR_NONE) - free(dek); - - return ret; -} - -int create_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len) -{ - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); - - if (dek == NULL) - return WAE_ERROR_MEMORY; - - int ret = _get_random(DEK_LEN, dek); + memcpy(ce->iv->buf, AES_CBC_IV, ce->iv->size); + ret = _get_random(dek); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to get random for APP_DEK. pkg_id=%s, ret=%d", pkg_id, ret); + WAE_SLOGE("Failed to get random for dek. pkg_id(%s) ret(%d)", pkg_id, ret); goto error; } - // save app_dek in key_manager - ret = _add_dek_to_key_manager(pkg_id, app_type, dek, DEK_LEN); - + ret = save_to_key_manager(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); goto error; } - // store APP_DEK in cache - _add_app_dek_to_cache(pkg_id, dek); + 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; + } - *pdek = dek; - *pdek_len = DEK_LEN; + *pce = ce; - WAE_SLOGI("WAE: Success to create APP_DEK and store it in key-manager. pkg_id=%s", pkg_id); + WAE_SLOGI("Success to create dek/iv and store it in key-manager. pkg_id(%s)", pkg_id); return WAE_ERROR_NONE; error: - free(dek); + if (ce == NULL) { + buffer_destroy(dek); + buffer_destroy(iv); + } else { + crypto_element_destroy(ce); + } return ret; } -int get_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len) +int get_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce) { - const unsigned char *cached_dek = _get_app_dek_from_cache(pkg_id); + const crypto_element_s *cached_ce = _get_app_ce_from_cache(pkg_id); - if (cached_dek == NULL) { + if (cached_ce == NULL) { WAE_SLOGE("WAE: Fail to get APP_DEK from cache for preloaded app"); return WAE_ERROR_NO_KEY; } - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); - - if (dek == NULL) { - WAE_SLOGE("WAE: Fail to allocate memory for preloaded app dek"); - return WAE_ERROR_MEMORY; - } - - memcpy(dek, cached_dek, DEK_LEN); - - *pdek = dek; - *pdek_len = DEK_LEN; + *pce = cached_ce; return WAE_ERROR_NONE; } -int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len) +int create_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce) { - unsigned char *encrypted_app_dek = NULL; - size_t encrypted_app_dek_len = 0; - unsigned char *pubkey = NULL; - size_t pubkey_len = 0; + raw_buffer_s *encrypted_app_dek = NULL; + raw_buffer_s *pubkey = NULL; + raw_buffer_s *dek = buffer_create(DEK_LEN); + raw_buffer_s *iv = buffer_create(sizeof(AES_CBC_IV)); + crypto_element_s *ce = crypto_element_create(dek, iv); - // create APP_DEK - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); + int ret = WAE_ERROR_NONE; - if (dek == NULL) - return WAE_ERROR_MEMORY; + if (dek == NULL || iv == NULL || ce == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } - int ret = _get_random(DEK_LEN, dek); + ret = _get_random(dek); if (ret != WAE_ERROR_NONE) goto error; - // encrypt APP_DEK with APP_DEK_KEK - ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubkey, &pubkey_len); + // copy default iv for preloaded app + memcpy(iv->buf, AES_CBC_IV, sizeof(AES_CBC_IV)); + + ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubkey); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Public Key"); goto error; } - ret = encrypt_app_dek(pubkey, pubkey_len, dek, DEK_LEN, &encrypted_app_dek, &encrypted_app_dek_len); + ret = encrypt_app_dek(pubkey, dek, &encrypted_app_dek); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("WAE: Fail to encrypt APP_DEK with APP_DEK_KEK"); @@ -513,139 +385,48 @@ int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *p } // write APP_DEK in a file - ret = _write_encrypted_app_dek_to_file(pkg_id, encrypted_app_dek, encrypted_app_dek_len); + ret = _write_encrypted_app_dek_to_file(pkg_id, encrypted_app_dek); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to write encrypted APP_DEK. pkg_id=%s", pkg_id); + WAE_SLOGE("Failed to write encrypted dek to file. pkg_id(%s)", pkg_id); goto error; } // store APP_DEK in cache - _add_app_dek_to_cache(pkg_id, dek); - - *pdek = dek; - *pdek_len = DEK_LEN; - WAE_SLOGI("WAE: Success to create preleaded APP_DEK and write it in initail value file. pkg_id=%s", pkg_id); - -error: - free(pubkey); - free(encrypted_app_dek); - - if (ret != WAE_ERROR_NONE) - free(dek); - - return ret; -} - -int _get_app_dek_kek(unsigned char **pdek_kek, size_t *pdek_kek_len) -{ - int ret = _read_from_file(_get_dek_kek_pri_key_path(), pdek_kek, pdek_kek_len); - - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Private Key"); - return ret; - } - -#if 0 - ckmc_raw_buffer_s *kek_buffer = NULL; - unsigned char* kek = NULL; - - char dek_kek_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_kek_alias(dek_kek_alias, sizeof(dek_kek_alias)); - - ret = _to_wae_error(ckmc_get_data(dek_kek_alias, NULL, &kek_buffer)); + _add_app_ce_to_cache(pkg_id, ce); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to get APP_DEK_KEK from key-manager. alias=%s, ret=%d", - APP_DEK_KEK_ALIAS, ret); - goto error; + WAE_SLOGE("Failed to add ce to cache for pkg_id(%s) ret(%d)", pkg_id, ret); + goto error; } - kek = (unsigned char *)malloc(kek_buffer->size); - if(kek == NULL) { - WAE_SLOGE("Fail to allocate a memory"); - ret = WAE_ERROR_MEMORY; - goto error; - } - memcpy(kek, kek_buffer->data, kek_buffer->size); + *pce = ce; - *pdek_kek = kek; - *pdek_kek_len = kek_buffer->size; - WAE_SLOGI("Success to get APP_DEK_KEK from key-manager."); + WAE_SLOGI("Success to create preleaded dek and write it in initial value file. " + "pkg_id(%s)", pkg_id); error: - ckmc_buffer_free(kek_buffer); - free(kek); -#endif - - return ret; -} - -int _get_app_deks_loaded() -{ - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - ckmc_raw_buffer_s *buffer = NULL; - int ret = _to_wae_error(ckmc_get_data(loading_done_alias, NULL, &buffer)); - - if (ret == WAE_ERROR_NO_KEY) - WAE_SLOGI("WAE: APP_DEK_LOADING was not done"); - else if (ret == WAE_ERROR_NONE) - WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); - else - WAE_SLOGE("WAE: Fail to get information from key-manager about APP_DEK_LOADING_DONE_ALIAS. ret=%d", ret); - - ckmc_buffer_free(buffer); + buffer_destroy(encrypted_app_dek); + buffer_destroy(pubkey); - return ret; -} - -int _set_app_deks_loaded() -{ - ckmc_raw_buffer_s buff; - ckmc_policy_s policy; - unsigned char dummy_data[1] = {0}; - - buff.data = dummy_data; - buff.size = sizeof(dummy_data); - - policy.password = NULL; - policy.extractable = true; - - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - int ret = _to_wae_error(ckmc_save_data(loading_done_alias, buff, policy)); - - if (ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); - ret = WAE_ERROR_NONE; - } else if (ret == WAE_ERROR_NONE) { - WAE_SLOGI("Success to set APP_DEK_LOADING_DONE_ALIAS to key-manager."); - } else { - WAE_SLOGE("WAE: Fail to set APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); + if (ret != WAE_ERROR_NONE) { + if (ce) { + crypto_element_destroy(ce); + } else { + buffer_destroy(dek); + buffer_destroy(iv); + } } return ret; } -int _clear_app_deks_loaded() +int _get_app_dek_kek(raw_buffer_s **pdek_kek) { - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - int ret = _to_wae_error(ckmc_remove_alias(loading_done_alias)); - - if (ret == WAE_ERROR_NO_KEY) { - WAE_SLOGI("APP_DEK_LOADING_DONE_ALIAS was not set to key-manager before."); - ret = WAE_ERROR_NONE; - } else if (ret == WAE_ERROR_NONE) { - WAE_SLOGI("Success to clear app deks loaded"); - } else { - WAE_SLOGE("Fail to clear APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); - } - - return ret; +#if 0 + return get_dek_kek_from_key_manager(pdek_kek); +#else + return _read_from_file(_get_dek_kek_pri_key_path(), pdek_kek); +#endif } int load_preloaded_app_deks(bool reload) @@ -655,24 +436,23 @@ int load_preloaded_app_deks(bool reload) char pkg_id[MAX_PKGID_LEN] = {0, }; char file_path_buff[MAX_PATH_LEN]; - unsigned char *encrypted_app_dek = NULL; - size_t encrypted_app_dek_len = 0; - unsigned char *app_dek = NULL; - size_t app_dek_len = 0; - unsigned char *prikey = NULL; - size_t prikey_len = 0; + 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. - ret = _get_app_deks_loaded(); + ret = is_app_deks_loaded_in_key_manager(); if (ret == WAE_ERROR_NONE) return ret; } - ret = _get_app_dek_kek(&prikey, &prikey_len); + ret = _get_app_dek_kek(&prikey); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); @@ -706,7 +486,6 @@ int load_preloaded_app_deks(bool reload) if (entry.d_type != DT_REG || strstr(entry.d_name, APP_DEK_FILE_PFX) == NULL) continue; - memset(file_path_buff, 0, sizeof(file_path_buff)); ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", _get_dek_store_path(), entry.d_name); @@ -719,75 +498,92 @@ int load_preloaded_app_deks(bool reload) ret = _extract_pkg_id_from_file_name(entry.d_name, pkg_id); if (ret != WAE_ERROR_NONE) { - WAE_SLOGW("Fail to extract pkgid from file. It will be ignored. file=%s", file_path_buff); + WAE_SLOGW("Failed to extract pkgid from file. It will be ignored. file=%s", + file_path_buff); continue; } - ret = _read_from_file(file_path_buff, &encrypted_app_dek, &encrypted_app_dek_len); + ret = _read_from_file(file_path_buff, &encrypted_dek); - if (ret != WAE_ERROR_NONE || encrypted_app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to read file. It will be ignored. file=%s", file_path_buff); + 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, prikey_len, APP_DEK_KEK_PRIKEY_PASSWORD, - encrypted_app_dek, encrypted_app_dek_len, - &app_dek, &app_dek_len); + ret = decrypt_app_dek(prikey, APP_DEK_KEK_PRIKEY_PASSWORD, encrypted_dek, &dek); - if (ret != WAE_ERROR_NONE || app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to decrypt APP DEK. It will be ignored. file=%s", file_path_buff); + 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); - // save app_dek in key_manager - ret = _add_dek_to_key_manager(pkg_id, WAE_PRELOADED_APP, app_dek, app_dek_len); - // free temp objects - free(app_dek); - free(encrypted_app_dek); - app_dek = NULL; - encrypted_app_dek = NULL; + 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, WAE_PRELOADED_APP, ce); if (ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("Key Manager already has APP_DEK. It will be ignored. file=%s", file_path_buff); + 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++; + ++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(); + ret = set_app_deks_loaded_to_key_manager(); - if (ret == WAE_ERROR_NONE) { - WAE_SLOGI("Success to load_preloaded_app_deks"); - ret = WAE_ERROR_NONE; - } else { - WAE_SLOGW("Fail to _set_app_deks_loaded to key-manager. ret=%d", ret); +error: + if (ret != WAE_ERROR_NONE) { + if (ce) { + crypto_element_destroy(ce); + } else { + buffer_destroy(dek); + buffer_destroy(iv); + } } -error: - free(prikey); + buffer_destroy(prikey); closedir(dir); return ret; } -int remove_app_dek(const char *pkg_id, wae_app_type_e app_type) +int remove_app_ce(const char *pkg_id, wae_app_type_e app_type) { - char alias[MAX_ALIAS_LEN] = {0,}; - - _get_alias(pkg_id, app_type, true, alias, sizeof(alias)); - - int ret = _to_wae_error(ckmc_remove_alias(alias)); + int ret = remove_from_key_manager(pkg_id, app_type); - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to remove APP_DEK from key-manager. pkg_id=%s, alias=%s, ret=%d", pkg_id, alias, ret); - return ret; - } + if (ret != WAE_ERROR_NONE) + WAE_SLOGE("Failed to remove app ce for pkg_id(%s) ret(%d)", pkg_id, ret); + else + WAE_SLOGI("Success to remove app ce for pkg_id(%s)", pkg_id); - _remove_app_dek_from_cache(pkg_id); - WAE_SLOGI("Success to remove APP_DEK from key-manager. pkg_id=%s", pkg_id); + _remove_app_ce_from_cache(pkg_id); - return WAE_ERROR_NONE; + return ret; } diff --git a/srcs/key_handler.h b/srcs/key_handler.h index c2e65a7..e64d81c 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -28,40 +28,28 @@ extern "C" { #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 _initialize_cache(); -const unsigned char *_get_app_dek_from_cache(const char *pkg_id); -void _add_app_dek_to_cache(const char *pkg_id, const unsigned char *dek); -void _remove_app_dek_from_cache(const char *pkg_id); -int _get_random(size_t length, unsigned char *random); -void _get_alias(const char *pkg_id, wae_app_type_e app_type, bool forSave, char *alias, size_t buff_len); -void _get_dek_kek_alias(char *alias, size_t buff_len); -void _get_dek_loading_done_alias(char *alias, size_t buff_len); -const char *_get_dek_kek_pub_key_path(); -const char *_get_dek_kek_pri_key_path(); -const char *_get_dek_store_path(); -int _add_dek_to_key_manager(const char *pkg_id, wae_app_type_e app_type, const unsigned char *dek, size_t dek_len); +void _remove_app_ce_from_cache(const char *pkg_id); +int _get_random(raw_buffer_s *rb); int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path); -int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id); -int _read_encrypted_app_dek_from_file(const char *pkg_id, unsigned char **pencrypted_app_dek, size_t *pencrypted_app_dek_len); -int _write_encrypted_app_dek_to_file(const char *pkg_id, const unsigned char *encrypted_app_dek, size_t encrypted_app_dek_len); -int _read_from_file(const char *path, unsigned char **pdata, size_t *pdata_len); -int _write_to_file(const char *path, const unsigned char *data, size_t data_len); -int _get_app_deks_loaded(); -int _set_app_deks_loaded(); -int _clear_app_deks_loaded(); +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_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len); -int create_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len); -int get_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len); -int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len); +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, + const crypto_element_s **pce); +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_dek(const char *pkg_id, wae_app_type_e app_type); +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 new file mode 100644 index 0000000..4ef5b8a --- /dev/null +++ b/srcs/key_manager.c @@ -0,0 +1,393 @@ +/* + * 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 key_manager.c + * @author Kyungwook Tak + * @version 1.0 + * @brief Serialize/deserialize crypto element and save/get to key-manager + */ +#include "key_manager.h" + +#include +#include +#include + +#include + +#include "wae_log.h" + +#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) +{ + switch (key_manager_error) { + case CKMC_ERROR_NONE: + return WAE_ERROR_NONE; + + case CKMC_ERROR_INVALID_PARAMETER: + return WAE_ERROR_INVALID_PARAMETER; + + case CKMC_ERROR_PERMISSION_DENIED: + return WAE_ERROR_PERMISSION_DENIED; + + case CKMC_ERROR_DB_ALIAS_UNKNOWN: + return WAE_ERROR_NO_KEY; + + case CKMC_ERROR_DB_ALIAS_EXISTS: + return WAE_ERROR_KEY_EXISTS; + + case CKMC_ERROR_OUT_OF_MEMORY: + return WAE_ERROR_MEMORY; + + default: + return WAE_ERROR_KEY_MANAGER; + } +} + +static int _serialize(const crypto_element_s *ce, ckmc_raw_buffer_s **pbuf) +{ + if (!is_crypto_element_valid(ce) || pbuf == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + size_t total_len = sizeof(size_t) * 3 + ce->dek->size + ce->iv->size + sizeof(bool); + + WAE_SLOGD("(serialization) total(%d) dek(%d) iv(%d) is_migrated(%d)", + total_len, ce->dek->size, ce->iv->size, ce->is_migrated_app); + + unsigned char *_buf = (unsigned char *)malloc(total_len); + if (_buf == NULL) + return WAE_ERROR_MEMORY; + + ckmc_raw_buffer_s *buf = NULL; + int ret = _to_wae_error(ckmc_buffer_new(_buf, total_len, &buf)); + + free(_buf); + + if (ret != WAE_ERROR_NONE) + return ret; + + size_t pos = 0; + memcpy(buf->data, &total_len, sizeof(size_t)); + pos += sizeof(size_t); + memcpy(buf->data + pos, &ce->dek->size, sizeof(size_t)); + pos += sizeof(size_t); + memcpy(buf->data + pos, ce->dek->buf, ce->dek->size); + pos += ce->dek->size; + memcpy(buf->data + pos, &ce->iv->size, sizeof(size_t)); + pos += sizeof(size_t); + memcpy(buf->data + pos, ce->iv->buf, ce->iv->size); + pos += ce->iv->size; + memcpy(buf->data + pos, &ce->is_migrated_app, sizeof(bool)); + pos += sizeof(bool); + + if (total_len != pos) { + WAE_SLOGE("(serialization) total len(%d) and actualy written byte(%d) " + "isn't matched!", total_len, pos); + ckmc_buffer_free(buf); + return WAE_ERROR_UNKNOWN; + } + + *pbuf = buf; + + WAE_SLOGD("(serialization) success!"); + + return WAE_ERROR_NONE; +} + +static int _deserialize(const ckmc_raw_buffer_s *buf, crypto_element_s **pce) +{ + if (buf == NULL || buf->data == NULL || buf->size == 0 || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + size_t dek_size = 0; + size_t iv_size = 0; + bool is_migrated_app = false; + size_t pos = 0; + size_t total_len = 0; + crypto_element_s *ce = NULL; + + memcpy(&total_len, buf->data, sizeof(size_t)); + pos += sizeof(size_t); + + if (buf->size != total_len) { + WAE_SLOGE("(deserialization) total len(%d) and actualy written byte(%d) " + "isn't matched!", total_len, buf->size); + return WAE_ERROR_UNKNOWN; + } + + // deserialize dek size + memcpy(&dek_size, buf->data + pos, sizeof(size_t)); + pos += sizeof(size_t); + + raw_buffer_s *dek = buffer_create(dek_size); + if (dek == NULL) + return WAE_ERROR_MEMORY; + + // deserialize dek + memcpy(dek->buf, buf->data + pos, dek->size); + pos += dek->size; + + // deserialize iv size + memcpy(&iv_size, buf->data + pos, sizeof(size_t)); + pos += sizeof(size_t); + + raw_buffer_s *iv = buffer_create(iv_size); + int ret = WAE_ERROR_NONE; + if (iv == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } + + // deserialize iv + memcpy(iv->buf, buf->data + pos, iv->size); + pos += iv->size; + + // deserialize is_migrated_app + memcpy(&is_migrated_app, buf->data + pos, sizeof(bool)); + pos += sizeof(bool); + + WAE_SLOGD("(deserialization) total(%d) dek(%d) iv(%d) is_migrated(%d)", + total_len, dek_size, iv_size, is_migrated_app); + + if (pos != buf->size) { + WAE_SLOGE("(deserialization) raw buffer remained after deserializatation done!"); + ret = WAE_ERROR_UNKNOWN; + goto error; + } + + ce = crypto_element_create(dek, iv); + if (ce == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } + + ce->is_migrated_app = is_migrated_app; + + *pce = ce; + + WAE_SLOGD("(deserialization) success!"); + + return WAE_ERROR_NONE; + +error: + buffer_destroy(dek); + buffer_destroy(iv); + + return ret; +} + +static void _get_alias(const char *pkg_id, wae_app_type_e type, 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); + } +} + +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 *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)); + + 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); + return ret; + } + + ckmc_policy_s policy; + policy.password = NULL; + policy.extractable = true; + + ret = _to_wae_error(ckmc_save_data(alias, *buf, policy)); + + 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); + return ret; + } + + ret = _to_wae_error(ckmc_set_permission(alias, pkg_id, CKMC_PERMISSION_READ)); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to set perm of crypto element: pkg_id(%s) alias(%s) ret(%d)", + pkg_id, alias, ret); + + ckmc_remove_alias(alias); // rollback + return ret; + } + + WAE_SLOGI("Success to save crypto element to key-manager. pkg_id(%s)", pkg_id); + + return WAE_ERROR_NONE; +} + +int get_from_key_manager(const char *pkg_id, wae_app_type_e type, crypto_element_s **pce) +{ + if (pkg_id == NULL || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + char alias[MAX_ALIAS_LEN] = {0, }; + + _get_alias(pkg_id, type, false, alias, sizeof(alias)); + + ckmc_raw_buffer_s *buf = NULL; + int ret = _to_wae_error(ckmc_get_data(alias, NULL, &buf)); + if (ret != WAE_ERROR_NONE) + return ret; + + ret = _deserialize(buf, pce); + + ckmc_buffer_free(buf); + + return ret; +} + +int remove_from_key_manager(const char *pkg_id, wae_app_type_e type) +{ + char alias[MAX_ALIAS_LEN] = {0, }; + + _get_alias(pkg_id, type, true, alias, sizeof(alias)); + + return _to_wae_error(ckmc_remove_alias(alias)); +} + +static void _get_dek_kek_alias(char *alias, size_t buff_len) +{ + snprintf(alias, buff_len, "%s%s%s", + ckmc_owner_id_system, + ckmc_owner_id_separator, + APP_DEK_KEK_ALIAS); +} + +int get_dek_kek_from_key_manager(raw_buffer_s **pdek_kek) +{ + if (pdek_kek == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + ckmc_raw_buffer_s *buf = NULL; + + char alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_kek_alias(alias, sizeof(alias)); + + int ret = _to_wae_error(ckmc_get_data(alias, NULL, &buf)); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to get dek kek from key-manager. alias(%s) ret(%d)", + alias, ret); + return ret; + } + + raw_buffer_s *dek_kek = buffer_create(buf->size); + if (dek_kek == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } + memcpy(dek_kek->buf, buf->data, dek_kek->size); + + *pdek_kek = dek_kek; + + WAE_SLOGI("Success to get dek kek from key-manager."); + +error: + ckmc_buffer_free(buf); + + if (ret != WAE_ERROR_NONE) + buffer_destroy(dek_kek); + + return ret; +} diff --git a/srcs/key_manager.h b/srcs/key_manager.h new file mode 100644 index 0000000..ec84561 --- /dev/null +++ b/srcs/key_manager.h @@ -0,0 +1,46 @@ +/* + * 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 key_manager.h + * @author Kyungwook Tak + * @version 1.0 + * @brief Serialize/deserialize crypto element and save/get to key-manager + */ +#ifndef __WAE_KEY_MANAGER_H +#define __WAE_KEY_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#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); + +bool is_app_deks_loaded_in_key_manager(); +int set_app_deks_loaded_to_key_manager(); +int clear_app_deks_loaded_from_key_manager(); + +#ifdef __cplusplus +} +#endif + +#endif /* __WAE_KEY_MANAGER_H */ diff --git a/srcs/types.c b/srcs/types.c new file mode 100644 index 0000000..fc76c33 --- /dev/null +++ b/srcs/types.c @@ -0,0 +1,255 @@ +/* + * 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 types.c + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Type definitions + */ +#include "types.h" + +#include +#include + +#include "wae_log.h" +#include "web_app_enc.h" + +const size_t MAX_MAP_ELEMENT_SIZE = 20; + +raw_buffer_s *buffer_create(size_t size) +{ + raw_buffer_s *rb = (raw_buffer_s *)malloc(sizeof(raw_buffer_s)); + if (rb == NULL) + return NULL; + + rb->buf = (unsigned char *)malloc(sizeof(unsigned char) * size); + if (rb->buf == NULL) { + free(rb); + return NULL; + } + + memset(rb->buf, 0x00, size); + + rb->size = size; + + return rb; +} + +raw_buffer_s *buffer_create_managed(unsigned char *buf, size_t size) +{ + if (buf == NULL || size == 0) + return NULL; + + raw_buffer_s *rb = (raw_buffer_s *)malloc(sizeof(raw_buffer_s)); + if (rb == NULL) + return NULL; + + rb->buf = buf; + rb->size = size; + + return rb; +} + +void buffer_destroy(raw_buffer_s *rb) +{ + if (rb == NULL) + return; + + free(rb->buf); + free(rb); +} + +bool is_buffer_valid(const raw_buffer_s *rb) +{ + return rb != NULL && rb->buf != NULL && rb->size != 0; +} + +crypto_element_s *crypto_element_create(raw_buffer_s *dek, raw_buffer_s *iv) +{ + if (dek == NULL || iv == NULL) + return NULL; + + crypto_element_s *ce = (crypto_element_s *)malloc(sizeof(crypto_element_s)); + if (ce == NULL) + return NULL; + + ce->dek = dek; + ce->iv = iv; + ce->is_migrated_app = false; + + return ce; +} + +void crypto_element_destroy(crypto_element_s *ce) +{ + if (ce == NULL) + return; + + buffer_destroy(ce->dek); + buffer_destroy(ce->iv); + free(ce); +} + +bool is_crypto_element_valid(const crypto_element_s *ce) +{ + return ce != NULL && is_buffer_valid(ce->dek) && is_buffer_valid(ce->iv); +} + +struct _crypto_element_map_s { + char *key; + crypto_element_s *value; + crypto_element_map_s *next; +}; + +static crypto_element_map_s *crypto_element_map_create() +{ + crypto_element_map_s *cem = (crypto_element_map_s *)malloc(sizeof(crypto_element_map_s)); + if (cem == NULL) + return NULL; + + cem->key = NULL; + cem->value = NULL; + cem->next = NULL; + + return cem; +} + +void crypto_element_map_destroy(crypto_element_map_s *cem) +{ + if (cem == NULL) + return; + + crypto_element_map_s *current = cem; + while (current) { + WAE_SLOGD("Destroy crypto element of key(%s)", current->key); + crypto_element_map_s *tmp = current->next; + + free(current->key); + crypto_element_destroy(current->value); + free(current); + + current = tmp; + } +} + +int crypto_element_map_add(crypto_element_map_s **map, + const char *key, crypto_element_s *value) +{ + if (map == NULL || key == NULL || !is_crypto_element_valid(value)) + return WAE_ERROR_INVALID_PARAMETER; + + crypto_element_map_s *last = *map; + size_t count = 0; + for (crypto_element_map_s *current = *map; current != NULL; current = current->next) { + if (strcmp(current->key, key) == 0) { + WAE_SLOGD("Update value to map on existing key(%s)", key); + crypto_element_destroy(current->value); + current->value = value; + return WAE_ERROR_NONE; + } + + ++count; + last = current; + } + + WAE_SLOGD("Add value to map on new key(%s)", key); + crypto_element_map_s *e = crypto_element_map_create(); + if (e == NULL) + return WAE_ERROR_MEMORY; + + e->key = strdup(key); + if (e->key == NULL) { + free(e); + return WAE_ERROR_MEMORY; + } + + e->value = value; + e->next = NULL; + + if (last == NULL) + *map = e; + else + last->next = e; + + if (count == MAX_MAP_ELEMENT_SIZE) { + WAE_SLOGD("Map size touched max! Remove one element from the front(%s)", + (*map)->key); + + crypto_element_map_s *next = (*map)->next; + + crypto_element_destroy((*map)->value); + free((*map)->key); + free(*map); + + *map = next; + } + + return WAE_ERROR_NONE; +} + +void crypto_element_map_remove(crypto_element_map_s **map, const char *key) +{ + if (map == NULL || key == NULL) + return; + + if (*map == NULL) { + WAE_SLOGD("Map is empty so remove operation ignored for key(%s)", key); + return; + } + + crypto_element_map_s *before = NULL; + crypto_element_map_s *current = *map; + while (current) { + if (strcmp(key, current->key) != 0) { + before = current; + current = current->next; + continue; + } + + WAE_SLOGD("Removing value mapped by key(%s)", key); + + crypto_element_map_s *next = current->next; + + free(current->key); + crypto_element_destroy(current->value); + free(current); + + if (before == NULL) + *map = next; + else + before->next = next; + + break; + } +} + +crypto_element_s *crypto_element_map_get(crypto_element_map_s *map, const char *key) +{ + if (map == NULL || key == NULL) { + WAE_SLOGD("Map is empty so nothing to get."); + return NULL; + } + + for (crypto_element_map_s *current = map; current != NULL; current = current->next) { + if (strcmp(key, current->key) == 0) { + WAE_SLOGD("Getting value mapped by key(%s)", key); + return current->value; + } + } + + WAE_SLOGD("Cannot get value mapped by key(%s). No mapped value!", key); + return NULL; +} diff --git a/srcs/types.h b/srcs/types.h new file mode 100644 index 0000000..7e27aeb --- /dev/null +++ b/srcs/types.h @@ -0,0 +1,65 @@ +/* + * 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 types.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Type definitions + */ +#ifndef __WAE_TYPES_H +#define __WAE_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct _raw_buffer_s { + unsigned char *buf; + size_t size; +} raw_buffer_s; + +typedef struct _crypto_element_s { + raw_buffer_s *dek; + raw_buffer_s *iv; + bool is_migrated_app; +} crypto_element_s; + +typedef struct _crypto_element_map_s crypto_element_map_s; + +raw_buffer_s *buffer_create(size_t size); +raw_buffer_s *buffer_create_managed(unsigned char *buf, size_t size); +void buffer_destroy(raw_buffer_s *); +bool is_buffer_valid(const raw_buffer_s *); + +crypto_element_s *crypto_element_create(raw_buffer_s *dek, raw_buffer_s *iv); +void crypto_element_destroy(crypto_element_s *c); +bool is_crypto_element_valid(const crypto_element_s *); + +extern const size_t MAX_MAP_ELEMENT_SIZE; + +void crypto_element_map_destroy(crypto_element_map_s *); +int crypto_element_map_add(crypto_element_map_s **map, const char *key, crypto_element_s *value); +void crypto_element_map_remove(crypto_element_map_s **map, const char *key); +crypto_element_s *crypto_element_map_get(crypto_element_map_s *map, const char *key); + +#ifdef __cplusplus +} +#endif + +#endif /* __WAE_TYPES_H */ diff --git a/srcs/web_app_enc.c b/srcs/web_app_enc.c index 083addf..22da420 100644 --- a/srcs/web_app_enc.c +++ b/srcs/web_app_enc.c @@ -26,6 +26,7 @@ #include "decrypt_migrated_wgt.h" #include "key_handler.h" #include "crypto_service.h" +#include "types.h" #include "wae_log.h" int _wae_encrypt_downloaded_web_application( @@ -37,57 +38,65 @@ int _wae_encrypt_downloaded_web_application( pencrypted_data_len == NULL) return WAE_ERROR_INVALID_PARAMETER; - // get APP_DEK. - // if not exists, create APP_DEK - unsigned char *dek = NULL; - size_t dek_len = -1; - int ret = get_app_dek(pkg_id, app_type, &dek, &dek_len); + const crypto_element_s *e = NULL; + int ret = get_app_ce(pkg_id, app_type, false, &e); if (ret == WAE_ERROR_NO_KEY) - ret = create_app_dek(pkg_id, app_type, &dek, &dek_len); + ret = create_app_ce(pkg_id, app_type, &e); if (ret != WAE_ERROR_NONE) - goto error; + return ret; - // encrypt - ret = encrypt_aes_cbc(dek, dek_len, data, data_len, pencrypted_data, pencrypted_data_len); + raw_buffer_s _data; + _data.buf = (unsigned char *)data; + _data.size = data_len; -error: - free(dek); + raw_buffer_s *_encrypted_data = NULL; + ret = encrypt_aes_cbc(e, &_data, &_encrypted_data); + if (ret != WAE_ERROR_NONE) + return ret; + + *pencrypted_data = _encrypted_data->buf; + *pencrypted_data_len = _encrypted_data->size; - return ret; + free(_encrypted_data); + + return WAE_ERROR_NONE; } int _wae_decrypt_downloaded_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) { - if (pkg_id == NULL || data == NULL || data_len == 0 || pdecrypted_data == NULL || pdecrypted_data_len == NULL) return WAE_ERROR_INVALID_PARAMETER; - unsigned char *dek = NULL; - size_t dek_len = -1; - int ret = get_app_dek(pkg_id, app_type, &dek, &dek_len); + raw_buffer_s _data; + _data.buf = (unsigned char *)data; + _data.size = data_len; + + const crypto_element_s *ce = NULL; + int ret = get_app_ce(pkg_id, app_type, true, &ce); + + if (ret != WAE_ERROR_NONE) + return ret; - if (app_type == WAE_DOWNLOADED_GLOBAL_APP && ret == WAE_ERROR_NO_KEY) { - WAE_SLOGI("app dek for decrypt downloaded app(%s) doesn't exist. This case would be " - "needed secure-storage data migration.", pkg_id); + raw_buffer_s *_decrypted_data = NULL; + if (ce->is_migrated_app) + ret = decrypt_by_old_ss_algo(ce, &_data, &_decrypted_data); + else + ret = decrypt_aes_cbc(ce, &_data, &_decrypted_data); - ret = decrypt_by_old_ss_algo(pkg_id, data, data_len, pdecrypted_data, pdecrypted_data_len); - goto error; // always go to error to skip decyprt_aes_cbc - } else if (ret != WAE_ERROR_NONE) { - goto error; - } + if (ret != WAE_ERROR_NONE) + return ret; - // decrypt - ret = decrypt_aes_cbc(dek, dek_len, data, data_len, pdecrypted_data, pdecrypted_data_len); + *pdecrypted_data = _decrypted_data->buf; + *pdecrypted_data_len = _decrypted_data->size; -error: - free(dek); + free(_decrypted_data); - return ret; + return WAE_ERROR_NONE; } int _wae_encrypt_preloaded_web_application(const char *pkg_id, @@ -98,23 +107,31 @@ int _wae_encrypt_preloaded_web_application(const char *pkg_id, pencrypted_data_len == NULL) return WAE_ERROR_INVALID_PARAMETER; - unsigned char *dek = NULL; - size_t dek_len = -1; - int ret = get_preloaded_app_dek(pkg_id, &dek, &dek_len); + const crypto_element_s *e = NULL; + int ret = get_preloaded_app_ce(pkg_id, &e); if (ret == WAE_ERROR_NO_KEY) - ret = create_preloaded_app_dek(pkg_id, &dek, &dek_len); + ret = create_preloaded_app_ce(pkg_id, &e); if (ret != WAE_ERROR_NONE) - goto error; + return ret; - // encrypt - ret = encrypt_aes_cbc(dek, dek_len, data, data_len, pencrypted_data, pencrypted_data_len); + raw_buffer_s _data; + _data.buf = (unsigned char *)data; + _data.size = data_len; -error: - free(dek); + raw_buffer_s *_encrypted_data = NULL; + ret = encrypt_aes_cbc(e, &_data, &_encrypted_data); + + if (ret != WAE_ERROR_NONE) + return ret; - return ret; + *pencrypted_data = _encrypted_data->buf; + *pencrypted_data_len = _encrypted_data->size; + + free(_encrypted_data); + + return WAE_ERROR_NONE; } int _wae_decrypt_preloaded_web_application(const char *pkg_id, wae_app_type_e app_type, @@ -150,8 +167,7 @@ int wae_decrypt_web_application(const char *pkg_id, wae_app_type_e app_type, data, data_len, pdecrypted_data, pdecrypted_data_len); } - int wae_remove_app_dek(const char *pkg_id, wae_app_type_e app_type) { - return remove_app_dek(pkg_id, app_type); + return remove_app_ce(pkg_id, app_type); } diff --git a/tests/internals.cpp b/tests/internals.cpp index 257447b..b5c106d 100644 --- a/tests/internals.cpp +++ b/tests/internals.cpp @@ -22,6 +22,7 @@ */ #include "web_app_enc.h" +#include #include #include @@ -32,6 +33,51 @@ #include "test-common.h" +namespace { + +using rb_raii = std::unique_ptr; +using ce_raii = std::unique_ptr; +using map_raii = std::unique_ptr; + +inline rb_raii _safe(raw_buffer_s *ptr) +{ + return rb_raii(ptr, buffer_destroy); +} + +inline ce_raii _safe(crypto_element_s *ptr) +{ + return ce_raii(ptr, crypto_element_destroy); +} + +inline map_raii _safe(crypto_element_map_s *ptr) +{ + return map_raii(ptr, crypto_element_map_destroy); +} + +crypto_element_s *_create_ce(void) +{ + raw_buffer_s *dek = buffer_create(32); + raw_buffer_s *iv = buffer_create(16); + crypto_element_s *ce = crypto_element_create(dek, iv); + + if (ce == nullptr) { + buffer_destroy(dek); + buffer_destroy(iv); + } else if (_get_random(ce->dek) != WAE_ERROR_NONE) { + crypto_element_destroy(ce); + ce = nullptr; + } else if (_get_random(ce->iv) != WAE_ERROR_NONE) { + crypto_element_destroy(ce); + ce = nullptr; + } + + BOOST_REQUIRE(ce != nullptr); + + return ce; +} + +} + BOOST_AUTO_TEST_SUITE(SYSTEM) BOOST_AUTO_TEST_SUITE(INTERNALS) @@ -78,29 +124,37 @@ BOOST_AUTO_TEST_CASE(encrypt_decrypt_app_dek) "+wIDAQAB\n" "-----END PUBLIC KEY-----"; - std::vector dek(32, 0); + raw_buffer_s *dek = buffer_create(32); + + auto _raii1 = _safe(dek); + + BOOST_REQUIRE_MESSAGE(dek != nullptr && dek->size == 32, "Failed to create buffer"); + BOOST_REQUIRE_MESSAGE(_get_random(dek) == WAE_ERROR_NONE, "Failed to get random"); + + raw_buffer_s pubkey; + + pubkey.buf = (unsigned char *)public_key; + pubkey.size = strlen(public_key); + + raw_buffer_s *encrypted = nullptr; + int ret = encrypt_app_dek(&pubkey, dek, &encrypted); - unsigned char *_encrypted = nullptr; - size_t _encrypted_len = 0; - int ret = encrypt_app_dek(reinterpret_cast(public_key), - strlen(public_key), dek.data(), dek.size(), &_encrypted, - &_encrypted_len); - auto encrypted = Wae::Test::bytearr_to_vec(_encrypted, _encrypted_len); - free(_encrypted); + auto _raii2 = _safe(encrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to encrypt_app_dek. ec: " << ret); - unsigned char *_decrypted = nullptr; - size_t _decrypted_len = 0; - ret = decrypt_app_dek(reinterpret_cast(private_key), - strlen(private_key), nullptr, encrypted.data(), encrypted.size(), - &_decrypted, &_decrypted_len); - auto decrypted = Wae::Test::bytearr_to_vec(_decrypted, _decrypted_len); - free(_decrypted); + raw_buffer_s prikey; + prikey.buf = (unsigned char *)private_key; + prikey.size = strlen(private_key); + + raw_buffer_s *decrypted = nullptr; + ret = decrypt_app_dek(&prikey, nullptr, encrypted, &decrypted); + + auto _raii3 = _safe(decrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to decrypt_app_dek. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek == decrypted, + BOOST_REQUIRE_MESSAGE(Wae::Test::bytes_to_hex(dek) == Wae::Test::bytes_to_hex(decrypted), "encrypted/decrypted dek isn't valid. " "dek(" << Wae::Test::bytes_to_hex(dek) << ") " "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); @@ -108,37 +162,32 @@ BOOST_AUTO_TEST_CASE(encrypt_decrypt_app_dek) BOOST_AUTO_TEST_CASE(encrypt_decrypt_aes_cbc) { - std::vector plaintext = { - 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', - 'o', 'q', '2', 'e', 'v', '0', '1', 'x' - }; + raw_buffer_s *data = buffer_create(16); + + auto _raii1 = _safe(data); - size_t dek_len = 32; - std::vector dek(dek_len, 0); + BOOST_REQUIRE_MESSAGE(data != nullptr && data->size == 16, "Failed to create buffer"); - int ret = _get_random(dek.size(), dek.data()); - BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get random"); + crypto_element_s *ce = _create_ce(); - unsigned char *_encrypted = nullptr; - size_t _encrypted_len = 0; - ret = encrypt_aes_cbc(dek.data(), dek.size(), plaintext.data(), plaintext.size(), - &_encrypted, &_encrypted_len); - auto encrypted = Wae::Test::bytearr_to_vec(_encrypted, _encrypted_len); - free(_encrypted); + auto _raii2 = _safe(ce); + + raw_buffer_s *encrypted = nullptr; + int ret = encrypt_aes_cbc(ce, data, &encrypted); + + auto _raii3 = _safe(encrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to encrypt_aes_cbc. ec: " << ret); - unsigned char *_decrypted = nullptr; - size_t _decrypted_len = 0; - ret = decrypt_aes_cbc(dek.data(), dek.size(), encrypted.data(), encrypted.size(), - &_decrypted, &_decrypted_len); - auto decrypted = Wae::Test::bytearr_to_vec(_decrypted, _decrypted_len); - free(_decrypted); + raw_buffer_s *decrypted = nullptr; + ret = decrypt_aes_cbc(ce, encrypted, &decrypted); + + auto _raii4 = _safe(decrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to decrypt_aes_cbc. ec: " << ret); - BOOST_REQUIRE_MESSAGE(plaintext == decrypted, + BOOST_REQUIRE_MESSAGE(Wae::Test::bytes_to_hex(data) == Wae::Test::bytes_to_hex(decrypted), "decrypted plaintext isn't valid. " - "plaintext(" << Wae::Test::bytes_to_hex(plaintext) << ") " + "plaintext(" << Wae::Test::bytes_to_hex(data) << ") " "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); } @@ -149,90 +198,79 @@ BOOST_AUTO_TEST_CASE(cache) const char *pkg3 = "pkg3"; const char *pkgDummy = "dummy"; - std::vector dek1(32, 1); - std::vector dek2(32, 2); - std::vector dek3(32, 3); + auto ce1 = _create_ce(); + auto ce2 = _create_ce(); + auto ce3 = _create_ce(); - _initialize_cache(); + crypto_element_map_s *map = nullptr; - _add_app_dek_to_cache(pkg1, dek1.data()); - _add_app_dek_to_cache(pkg2, dek2.data()); - _add_app_dek_to_cache(pkg3, dek3.data()); + int tmp = crypto_element_map_add(&map, pkg1, ce1); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to add ce to map. ret: " << tmp); - size_t dek_len = 32; - const unsigned char *_cached = _get_app_dek_from_cache(pkg1); - auto cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + tmp = crypto_element_map_add(&map, pkg2, ce2); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to add ce to map. ret: " << tmp); - BOOST_REQUIRE_MESSAGE(cached == dek1, - "cached dek isn't valid! " - "dek(" << Wae::Test::bytes_to_hex(dek1) << ") " - "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + tmp = crypto_element_map_add(&map, pkg3, ce3); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to add ce to map. ret: " << tmp); - _cached = _get_app_dek_from_cache(pkg2); - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg1) == ce1, + "cached ce has different address with actual."); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg2) == ce2, + "cached ce has different address with actual."); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg3) == ce3, + "cached ce has different address with actual."); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkgDummy) == nullptr, + "something returned with pkg dummy from map which should be null."); - BOOST_REQUIRE_MESSAGE(cached == dek2, - "cached dek isn't valid! " - "dek(" << Wae::Test::bytes_to_hex(dek2) << ") " - "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + crypto_element_map_remove(&map, pkg3); - _cached = _get_app_dek_from_cache(pkg3); - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg3) == nullptr, + "removed pkg(" << pkg3 << ") is returned from map which should be null."); - BOOST_REQUIRE_MESSAGE(cached == dek3, - "cached dek isn't valid! " - "dek(" << Wae::Test::bytes_to_hex(dek3) << ") " - "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + auto ce4 = _create_ce(); + tmp = crypto_element_map_add(&map, pkg1, ce4); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to update ce to map. ret: " << tmp); - _cached = _get_app_dek_from_cache(pkgDummy); - if (_cached) { - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); - BOOST_REQUIRE_MESSAGE(false, - "wrong cached val is extracted by dummy pkg id. " - "val(" << Wae::Test::bytes_to_hex(cached) << ")"); - } + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg1) == ce4, + "cached ce has different address with actual."); - _remove_app_dek_from_cache(pkg3); + crypto_element_map_destroy(map); +} - _cached = _get_app_dek_from_cache(pkg3); - if (_cached) { - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); - BOOST_REQUIRE_MESSAGE(false, - "app dek removed from cache but it's remained! " - "val(" << Wae::Test::bytes_to_hex(cached) << ")"); - } +BOOST_AUTO_TEST_CASE(cache_max) +{ + crypto_element_map_s *map = nullptr; - _initialize_cache(); + for (size_t i = 0; i < MAX_MAP_ELEMENT_SIZE + 1; ++i) { + BOOST_REQUIRE(crypto_element_map_add(&map, std::to_string(i).c_str(), _create_ce()) == WAE_ERROR_NONE); + } - _add_app_dek_to_cache(pkg1, dek1.data()); + BOOST_REQUIRE(crypto_element_map_get(map, "0") == nullptr); - _cached = nullptr; - _cached = _get_app_dek_from_cache(pkg2); - if (_cached) { - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); - BOOST_REQUIRE_MESSAGE(false, - "cache is initialized but something is remained! " - "val(" << Wae::Test::bytes_to_hex(cached) << ")"); - } + crypto_element_map_destroy(map); } BOOST_AUTO_TEST_CASE(read_write_encrypted_app_dek) { const char *pkg_id = "write_test_pkg"; - std::vector dek(256, 0); + raw_buffer_s *dek = buffer_create(256); - int ret = _write_encrypted_app_dek_to_file(pkg_id, dek.data(), dek.size()); + auto raii1 = _safe(dek); + + BOOST_REQUIRE(dek != nullptr); + BOOST_REQUIRE(_get_random(dek) == WAE_ERROR_NONE); + + 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); - unsigned char *_readed = nullptr; - size_t _readed_len = 0; - ret = _read_encrypted_app_dek_from_file(pkg_id, &_readed, &_readed_len); - auto readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); - free(_readed); + raw_buffer_s *readed = nullptr; + ret = _read_encrypted_app_dek_from_file(pkg_id, &readed); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to read_encrypted_app_dek_from_file. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek == readed, + auto raii2 = _safe(readed); + + BOOST_REQUIRE_MESSAGE(Wae::Test::bytes_to_hex(dek) == Wae::Test::bytes_to_hex(readed), "dek isn't match after write/read file. " "dek(" << Wae::Test::bytes_to_hex(dek) << ") " "readed(" << Wae::Test::bytes_to_hex(readed) << ")"); @@ -242,35 +280,23 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1) { const char *pkg_id = "TEST_PKG_ID_FOR_CREATE"; - unsigned char *_readed = nullptr; - size_t _readed_len = 0; - int ret = get_preloaded_app_dek(pkg_id, &_readed, &_readed_len); - auto readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); - free(_readed); + const crypto_element_s *readed = nullptr; + int ret = get_preloaded_app_ce(pkg_id, &readed); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NO_KEY, - "preloaded app dek to create is already exist. ec: " << ret); + "preloaded app ce to create is already exist. ec: " << ret); - unsigned char *_dek = nullptr; - size_t _dek_len = 0; - ret = create_preloaded_app_dek(pkg_id, &_dek, &_dek_len); - auto dek = Wae::Test::bytearr_to_vec(_dek, _dek_len); + const crypto_element_s *ce = nullptr; + ret = create_preloaded_app_ce(pkg_id, &ce); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to create_preloaded_app_dek. ec: " << ret); - - _readed = nullptr; - ret = get_preloaded_app_dek(pkg_id, &_readed, &_readed_len); - readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); - free(_readed); + "Failed to create_preloaded_app_ce. ec: " << ret); + ret = get_preloaded_app_ce(pkg_id, &readed); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to get_preloaded_app_dek. ec: " << ret); + "Failed to get_preloaded_app_ce. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek == readed, - "created/loaded dek is not matched! " - "created(" << Wae::Test::bytes_to_hex(dek) << ") " - "loaded(" << Wae::Test::bytes_to_hex(readed) << ")"); + BOOST_REQUIRE_MESSAGE(readed == ce, "cached ce address and actual is different!"); } BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) @@ -284,67 +310,42 @@ 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_dek(pkg_id1, WAE_PRELOADED_APP); - remove_app_dek(pkg_id2, WAE_PRELOADED_APP); + remove_app_ce(pkg_id1, WAE_PRELOADED_APP); + remove_app_ce(pkg_id2, WAE_PRELOADED_APP); unlink(path1); unlink(path2); - // create 2 deks for preloaded app - unsigned char *_dek1 = nullptr; - size_t _dek_len1 = 0; - int ret = create_preloaded_app_dek(pkg_id1, &_dek1, &_dek_len1); - auto dek1 = Wae::Test::bytearr_to_vec(_dek1, _dek_len1); - free(_dek1); - + // create 2 ces for preloaded app + const crypto_element_s *ce1 = nullptr; + int ret = create_preloaded_app_ce(pkg_id1, &ce1); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to create_preloaded_app_dek. ec: " << ret); - - unsigned char *_dek2 = nullptr; - size_t _dek_len2 = 0; - ret = create_preloaded_app_dek(pkg_id2, &_dek2, &_dek_len2); - auto dek2 = Wae::Test::bytearr_to_vec(_dek2, _dek_len2); - free(_dek2); + "Failed to create_preloaded_app_ce. ec: " << ret); + const crypto_element_s *ce2 = nullptr; + ret = create_preloaded_app_ce(pkg_id2, &ce2); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to create_preloaded_app_dek. ec: " << ret); + "Failed to create_preloaded_app_ce. ec: " << ret); ret = load_preloaded_app_deks(true); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to load_preloaded_app_deks. ec: " << ret); - unsigned char *_readed1 = nullptr; - size_t _readed_len1 = 0; - ret = get_app_dek(pkg_id1, WAE_PRELOADED_APP, &_readed1, &_readed_len1); - auto readed1 = Wae::Test::bytearr_to_vec(_readed1, _readed_len1); - free(_readed1); - + const crypto_element_s *readed1 = nullptr; + ret = get_app_ce(pkg_id1, WAE_PRELOADED_APP, false, &readed1); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); - unsigned char *_readed2 = nullptr; - size_t _readed_len2 = 0; - ret = get_app_dek(pkg_id2, WAE_PRELOADED_APP, &_readed2, &_readed_len2); - auto readed2 = Wae::Test::bytearr_to_vec(_readed2, _readed_len2); - free(_readed2); - + const crypto_element_s *readed2 = nullptr; + ret = get_app_ce(pkg_id2, WAE_PRELOADED_APP, false, &readed2); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek1 == readed1, - "readed dek and original isn't matched! " - "original(" << Wae::Test::bytes_to_hex(dek1) << ") " - "readed(" << Wae::Test::bytes_to_hex(readed1) << ")"); + BOOST_REQUIRE_MESSAGE(readed1 == ce1, "cached ce and actual address is different!"); + BOOST_REQUIRE_MESSAGE(readed2 == ce2, "cached ce and actual address is different!"); - BOOST_REQUIRE_MESSAGE(dek2 == readed2, - "readed dek and original isn't matched! " - "original(" << Wae::Test::bytes_to_hex(dek2) << ") " - "readed(" << Wae::Test::bytes_to_hex(readed2) << ")"); + ret = remove_app_ce(pkg_id1, WAE_PRELOADED_APP); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret); - ret = remove_app_dek(pkg_id1, WAE_PRELOADED_APP); - BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed remove app dek after used. ec: " << ret); - - ret = remove_app_dek(pkg_id2, WAE_PRELOADED_APP); - BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed remove app dek after used. ec: " << ret); + ret = remove_app_ce(pkg_id2, WAE_PRELOADED_APP); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret); } BOOST_AUTO_TEST_SUITE_END() // INTERNALS diff --git a/tests/non-normals.cpp b/tests/non-normals.cpp index 8667bfc..81c0173 100644 --- a/tests/non-normals.cpp +++ b/tests/non-normals.cpp @@ -32,12 +32,12 @@ BOOST_AUTO_TEST_SUITE(GLOBAL_APP) BOOST_AUTO_TEST_CASE(add_get_remove_dek) { - Wae::Test::add_get_remove_dek(WAE_DOWNLOADED_GLOBAL_APP); + Wae::Test::add_get_remove_ce(WAE_DOWNLOADED_GLOBAL_APP); } BOOST_AUTO_TEST_CASE(create_app_dek) { - Wae::Test::create_app_dek(WAE_DOWNLOADED_GLOBAL_APP); + Wae::Test::create_app_ce(WAE_DOWNLOADED_GLOBAL_APP); } BOOST_AUTO_TEST_CASE(encrypt_decrypt) @@ -52,12 +52,12 @@ BOOST_AUTO_TEST_SUITE(PRELOADED_APP) BOOST_AUTO_TEST_CASE(add_get_remove_dek) { - Wae::Test::add_get_remove_dek(WAE_PRELOADED_APP); + Wae::Test::add_get_remove_ce(WAE_PRELOADED_APP); } BOOST_AUTO_TEST_CASE(create_app_dek) { - Wae::Test::create_app_dek(WAE_PRELOADED_APP); + Wae::Test::create_app_ce(WAE_PRELOADED_APP); } BOOST_AUTO_TEST_CASE(encrypt_decrypt) diff --git a/tests/normals.cpp b/tests/normals.cpp index 2ce272e..5d67910 100644 --- a/tests/normals.cpp +++ b/tests/normals.cpp @@ -32,12 +32,12 @@ BOOST_AUTO_TEST_SUITE(DOWNLOADED_APP); BOOST_AUTO_TEST_CASE(add_get_remove_dek) { - Wae::Test::add_get_remove_dek(WAE_DOWNLOADED_NORMAL_APP); + Wae::Test::add_get_remove_ce(WAE_DOWNLOADED_NORMAL_APP); } BOOST_AUTO_TEST_CASE(create_app_dek) { - Wae::Test::create_app_dek(WAE_DOWNLOADED_NORMAL_APP); + Wae::Test::create_app_ce(WAE_DOWNLOADED_NORMAL_APP); } BOOST_AUTO_TEST_CASE(encrypt_decrypt_normal_app) diff --git a/tests/test-common.cpp b/tests/test-common.cpp index 3e9e331..3157ca6 100644 --- a/tests/test-common.cpp +++ b/tests/test-common.cpp @@ -38,15 +38,42 @@ std::string bytes_to_hex(const std::vector &bytes) return ss.str(); } -std::vector bytearr_to_vec(const unsigned char *bytes, size_t len) +std::string bytes_to_hex(const raw_buffer_s *rb) { - if (bytes == nullptr || len == 0) + if (!is_buffer_valid(rb)) + return std::string(); + + return bytes_to_hex(rb->buf, rb->size); +} + +std::string bytes_to_hex(const unsigned char *ptr, size_t len) +{ + std::stringstream ss; + ss << std::hex; + + for (size_t i = 0; i < len; ++i) + ss << std::setw(2) << std::setfill('0') << static_cast(ptr[i]); + + return ss.str(); +} + +std::vector bytearr_to_vec(const raw_buffer_s *rb) +{ + if (!is_buffer_valid(rb)) + return std::vector(); + + return bytearr_to_vec(rb->buf, rb->size); +} + +std::vector bytearr_to_vec(const unsigned char *ptr, size_t len) +{ + if (ptr == nullptr || len == 0) return std::vector(); - std::vector vec; + std::vector vec(len); for (size_t i = 0; i < len; ++i) - vec.push_back(bytes[i]); + vec[i] = ptr[i]; return vec; } diff --git a/tests/test-common.h b/tests/test-common.h index 2c4c54e..57bf83b 100644 --- a/tests/test-common.h +++ b/tests/test-common.h @@ -28,6 +28,8 @@ #include "colour_log_formatter.h" +#include "types.h" + /* fixtures should be declared on outside of namespace */ struct TestConfig { TestConfig() @@ -45,7 +47,10 @@ namespace Wae { namespace Test { std::string bytes_to_hex(const std::vector &bytes); -std::vector bytearr_to_vec(const unsigned char *bytes, size_t len); +std::string bytes_to_hex(const unsigned char *ptr, size_t len); +std::string bytes_to_hex(const raw_buffer_s *rb); +std::vector bytearr_to_vec(const unsigned char *ptr, size_t len); +std::vector bytearr_to_vec(const raw_buffer_s *); } // namespace Test } // namespace Wae diff --git a/tests/test-helper.cpp b/tests/test-helper.cpp index 144299a..f303b75 100644 --- a/tests/test-helper.cpp +++ b/tests/test-helper.cpp @@ -25,78 +25,64 @@ #include "key_handler.h" #include "crypto_service.h" +#include "types.h" +#include "key_manager.h" #include "test-common.h" namespace Wae { namespace Test { -void add_get_remove_dek(wae_app_type_e app_type) +void add_get_remove_ce(wae_app_type_e app_type) { const char *pkg_id = "TEST_PKG_ID"; - std::vector dek(32, 0); - - BOOST_REQUIRE(_get_random(dek.size(), dek.data()) == WAE_ERROR_NONE); - - remove_app_dek(pkg_id, app_type); - - int tmp = _add_dek_to_key_manager(pkg_id, app_type, dek.data(), dek.size()); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, - "Failed to _add_dek_to_key_manager. ec: " << tmp); - - unsigned char *_stored_dek = nullptr; - size_t _stored_dek_len = 0; - tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, - "Failed to get_app_dek. ec: " << tmp); - - auto stored_dek = Wae::Test::bytearr_to_vec(_stored_dek, _stored_dek_len); - free(_stored_dek); - - BOOST_REQUIRE_MESSAGE(stored_dek == dek, "stored dek and dek isn't matched!"); - - tmp = remove_app_dek(pkg_id, app_type); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_dek. ec: " << tmp); - - _stored_dek = nullptr; - tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); - if (_stored_dek) - free(_stored_dek); - - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY, - "dek removed but it's remained still. ec: " << tmp); + const crypto_element_s *ce = nullptr; + int tmp = create_app_ce(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); + 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); + 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); + 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); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY, + "removed app ce is still remaining. ret(" << tmp << ")"); + } } -void create_app_dek(wae_app_type_e app_type) +void create_app_ce(wae_app_type_e app_type) { const char *pkg_id = "TEST_PKG_ID"; - remove_app_dek(pkg_id, app_type); - - unsigned char *_dek = nullptr; - size_t _dek_len = 0; + remove_app_ce(pkg_id, app_type); - int tmp = create_app_dek(pkg_id, app_type, &_dek, &_dek_len); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, - "Failed to create_app_dek. ec: " << tmp); + const crypto_element_s *ce = nullptr; - auto dek = Wae::Test::bytearr_to_vec(_dek, _dek_len); - free(_dek); + int tmp = create_app_ce(pkg_id, app_type, &ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp); - unsigned char *_stored_dek = nullptr; - size_t _stored_dek_len = 0; - tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << tmp); - auto stored_dek = bytearr_to_vec(_stored_dek, _stored_dek_len); - free(_stored_dek); + const crypto_element_s *stored_ce = nullptr; + tmp = get_app_ce(pkg_id, app_type, false, &stored_ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp); - BOOST_REQUIRE_MESSAGE(stored_dek == dek, - "stored dek and dek isn't matched! " - "stored_dek(" << Wae::Test::bytes_to_hex(stored_dek) << ") " - "dek(" << Wae::Test::bytes_to_hex(dek) << ")"); + BOOST_REQUIRE_MESSAGE(ce == stored_ce, + "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!"); - remove_app_dek(pkg_id, app_type); + tmp = remove_app_ce(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) @@ -125,7 +111,7 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) wae_remove_app_dek(pkg_id, app_type); if (app_type == WAE_PRELOADED_APP) - _clear_app_deks_loaded(); + clear_app_deks_loaded_from_key_manager(); std::vector plaintext = { 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', @@ -150,7 +136,7 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) auto encrypted = bytearr_to_vec(_encrypted, _enc_len); free(_encrypted); - _remove_app_dek_from_cache(pkg_id); + _remove_app_ce_from_cache(pkg_id); if (app_type == WAE_PRELOADED_APP) load_preloaded_app_deks(true); @@ -166,8 +152,8 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) BOOST_REQUIRE_MESSAGE(plaintext == decrypted, "plaintext and decrypted isn't matched! " - "plaintext(" << Wae::Test::bytes_to_hex(plaintext) << ") " - "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); + "plaintext(" << bytes_to_hex(plaintext) << ") " + "decrypted(" << bytes_to_hex(decrypted) << ")"); tmp = wae_remove_app_dek(pkg_id, app_type); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, diff --git a/tests/test-helper.h b/tests/test-helper.h index 132ceae..c0c77f6 100644 --- a/tests/test-helper.h +++ b/tests/test-helper.h @@ -25,8 +25,8 @@ namespace Wae { namespace Test { -void add_get_remove_dek(wae_app_type_e app_type); -void create_app_dek(wae_app_type_e app_type); +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); } // namespace Test -- 2.7.4