diff options
46 files changed, 4147 insertions, 0 deletions
@@ -0,0 +1 @@ +Kidong Kim <kd0228.kim@samsung.com> diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..71cd20b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,75 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(secure-storage C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +SET(VERSION_MAJOR 1) +SET(VERSION ${VERSION_MAJOR}.0.0) + +#Verbose +#SET(CMAKE_VERBOSE_MAKEFILE ON) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED openssl dlog) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(ss_dir "./") +SET(ss_include_dir "./include") +SET(ss_client_dir "./client/src") +SET(ss_client_include_dir "./client/include") +SET(ss_server_dir "./server/src") +SET(ss_server_include_dir "./server/include") +SET(ss_test_dir "./testcases") + +## About debug +#SET(debug_type "") # for debug - use no debugging +#SET(debug_type "-DSS_CONSOLE_USE") # for debug - use console window +SET(debug_type "-DSS_DLOG_USE") # for debug - use dlog +#SET(debug_type "") # for debug - DO NOT use +SET(use_key "-DUSE_KEY_FILE") # for private key - use key file +#SET(use_key "-DUSE_NOT") # for private key - use no private key, key will be fixed + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +################################################################################################### +## for libss-client.so (library) +SET(libss-client_SOURCES ${ss_client_dir}/ss_client_intf.c ${ss_client_dir}/ss_client_ipc.c ${ss_client_dir}/ss_manager.c) +SET(libss-client_LDFLAGS " -module -avoid-version ${OPENSSL_LIBS}") +SET(libss-client_CFLAGS " ${CFLAGS} -fPIC -I${ss_client_include_dir} -I${ss_include_dir} ${OPENSSL_CFLAGS} ${debug_type} ") +#SET(libss-client_LIBADD " ${OPENSSL_LIBS} ") + +ADD_LIBRARY(ss-client SHARED ${libss-client_SOURCES}) +TARGET_LINK_LIBRARIES(ss-client ${pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(ss-client PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(ss-client PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES(ss-client PROPERTIES COMPILE_FLAGS "${libss-client_CFLAGS}") +################################################################################################### + +################################################################################################### +## for ss-server (binary) +SET(ss-server_SOURCES ${ss_server_dir}/ss_server_ipc.c ${ss_server_dir}/ss_server_main.c) +SET(ss-server_CFLAGS " -I. -I${ss_include_dir} -I${ss_server_include_dir} ${debug_type} ${use_key} ${OPENSSL_CFLAGS} -D_GNU_SOURCE ") +SET(ss-server_LDFLAGS ${pkgs_LDFLAGS}) + +ADD_EXECUTABLE(ss-server ${ss-server_SOURCES}) +TARGET_LINK_LIBRARIES(ss-server ${pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(ss-server PROPERTIES COMPILE_FLAGS "${ss-server_CFLAGS}") +#################################################################################################### + +CONFIGURE_FILE(secure-storage.pc.in secure-storage.pc @ONLY) +CONFIGURE_FILE(config.in config @ONLY) + +INSTALL(TARGETS ss-client DESTINATION lib) +INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/ss-server DESTINATION bin) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/secure-storage.pc DESTINATION lib/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config DESTINATION share/secure-storage/) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/ss_manager.h DESTINATION include) +INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/ss-serverd DESTINATION /etc/rc.d/init.d) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..9f19478 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2012 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. + @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/TC/build.sh b/TC/build.sh new file mode 100755 index 0000000..91656c9 --- /dev/null +++ b/TC/build.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +export TET_INSTALL_PATH=$HOME/work/TETware # local tetware path +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH +export TET_ROOT=$TET_TARGET_PATH + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -c -p ./ +tcc -b -j $JOURNAL_RESULT -p ./ +grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/execute.sh b/TC/execute.sh new file mode 100755 index 0000000..e2c742e --- /dev/null +++ b/TC/execute.sh @@ -0,0 +1,19 @@ +#!/bin/sh +export TET_INSTALL_PATH=/mnt/nfs/TETware +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH + +export TET_ROOT=$TET_TARGET_PATH + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -e -j $JOURNAL_RESULT -p ./ +grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/scenario1/Makefile b/TC/scenario1/Makefile new file mode 100755 index 0000000..454fc3e --- /dev/null +++ b/TC/scenario1/Makefile @@ -0,0 +1,27 @@ +CC ?= gcc + +TARGETS = \ + utc_SecurityFW_ssm_write_file_func \ + utc_SecurityFW_ssm_write_buffer_func \ + utc_SecurityFW_ssm_read_func \ + utc_SecurityFW_ssm_getinfo_func \ + utc_SecurityFW_ssm_delete_file_func + +PKGS = secure-storage + +LDFLAGS = `pkg-config --libs $(PKGS)` +LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s + +CFLAGS = -I. `pkg-config --cflags $(PKGS)` +CFLAGS += -I$(TET_ROOT)/inc/tet3 +CFLAGS += -Wall + +all: $(TARGETS) + +$(TARGETS): %: %.c + $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS) + +clean: + rm -f $(TARGETS) *~ diff --git a/TC/scenario1/tslist b/TC/scenario1/tslist new file mode 100755 index 0000000..c04c3f0 --- /dev/null +++ b/TC/scenario1/tslist @@ -0,0 +1,5 @@ +/scenario1/utc_SecurityFW_ssm_write_file_func +/scenario1/utc_SecurityFW_ssm_write_buffer_func +/scenario1/utc_SecurityFW_ssm_read_func +/scenario1/utc_SecurityFW_ssm_getinfo_func +/scenario1/utc_SecurityFW_ssm_delete_file_func diff --git a/TC/scenario1/utc_SecurityFW_ssm_delete_file_func.c b/TC/scenario1/utc_SecurityFW_ssm_delete_file_func.c new file mode 100755 index 0000000..88f782c --- /dev/null +++ b/TC/scenario1/utc_SecurityFW_ssm_delete_file_func.c @@ -0,0 +1,137 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ss_manager.h> +#include <tet_api.h> + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SecurityFW_ssm_delete_file_func_01(void); +static void utc_SecurityFW_ssm_delete_file_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SecurityFW_ssm_delete_file_func_01, POSITIVE_TC_IDX }, + { utc_SecurityFW_ssm_delete_file_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 } +}; + +static void startup(void) +{ + printf("Make temporary directory - /opt/secure-storage/test/\n"); + system("mkdir -p /opt/secure-storage/test"); + printf("Make temporary file\n"); + system("touch /opt/secure-storage/test/input.txt"); + system("echo \"abcdefghij\" > /opt/secure-storage/test/input.txt"); + system("cp /opt/secure-storage/test/input.txt /opt/secure-storage/test/input2.txt"); +} + +static void cleanup(void) +{ + printf("Remove tamporary file and directory\n"); + system("rm -rf /opt/secure-storage/test"); +} + +/** + * @brief Positive test case of ssm_delete_file() + */ +static void utc_SecurityFW_ssm_delete_file_func_01(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_delete_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + + /* write file to secure-storage */ + ret = ssm_write_file(filepath, flag, group_id); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto error; + } + + /* delete file */ + ret = ssm_delete_file(filepath, flag, group_id); + if(ret == 0) + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} + +/** + * @brief Negative test case of ssm_delete_file() + */ +static void utc_SecurityFW_ssm_delete_file_func_02(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_delete_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input2.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + + printf("[%s] checkpoint1\n", __func__); + + /* write file to secure-storage */ + ret = ssm_write_file(filepath, flag, group_id); + printf("[%s] checkpoint2 [%d]\n", __func__, ret); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto error; + } + + /* delete file */ + ret = ssm_delete_file(NULL, flag, group_id); + printf("[%s] checkpoint3 [%d]\n", __func__, ret); + if(ret != 0) + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + + /* delete encrypted file */ + ret = ssm_delete_file(filepath, flag, group_id); + printf("[%s] checkpoint4 [%d]\n", __func__, ret); + if(ret != 0) + tetResult = TET_UNINITIATED; + +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} diff --git a/TC/scenario1/utc_SecurityFW_ssm_getinfo_func.c b/TC/scenario1/utc_SecurityFW_ssm_getinfo_func.c new file mode 100755 index 0000000..fb6064f --- /dev/null +++ b/TC/scenario1/utc_SecurityFW_ssm_getinfo_func.c @@ -0,0 +1,144 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ss_manager.h> +#include <tet_api.h> + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SecurityFW_ssm_getinfo_func_01(void); +static void utc_SecurityFW_ssm_getinfo_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SecurityFW_ssm_getinfo_func_01, POSITIVE_TC_IDX }, + { utc_SecurityFW_ssm_getinfo_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 } +}; + +static void startup(void) +{ + printf("Make temporary directory - /opt/secure-storage/test/\n"); + system("mkdir -p /opt/secure-storage/test"); + printf("Make temporary file\n"); + system("touch /opt/secure-storage/test/input.txt"); + system("echo \"abcdefghij\" > /opt/secure-storage/test/input.txt"); + system("cp /opt/secure-storage/test/input.txt /opt/secure-storage/test/input2.txt"); +} + +static void cleanup(void) +{ + printf("Remove tamporary file and directory\n"); + system("rm -rf /opt/secure-storage/test"); +} + +/** + * @brief Positive test case of ssm_getinfo() + */ +static void utc_SecurityFW_ssm_getinfo_func_01(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + ssm_file_info_t sfi; + + /* write file to secure-storage */ + ret = ssm_write_file(filepath, flag, group_id); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto error; + } + + /* get information */ + ret = ssm_getinfo(filepath, &sfi, flag, group_id); + if(ret == 0) // success + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + + /* delete encrypted file */ + ret = ssm_delete_file(filepath, flag, group_id); + if(ret != 0) + tetResult = TET_UNINITIATED; + +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} + +/** + * @brief Negative test case of ssm_getinfo() + */ +static void utc_SecurityFW_ssm_getinfo_func_02(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input2.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + ssm_file_info_t sfi; + + printf("[%s] checkpoint1\n", __func__); + + /* write file to secure-storage */ + ret = ssm_write_file(filepath, flag, group_id); + printf("[%s] checkpoint2 [%d]\n", __func__, ret); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto error; + } + + /* get information */ + ret = ssm_getinfo(NULL, &sfi, flag, group_id); + printf("[%s] checkpoint3 [%d]\n", __func__, ret); + if(ret == 0) // success + tetResult = TET_FAIL; + else + tetResult = TET_PASS; + + /* delete encrypted file */ + ret = ssm_delete_file(filepath, flag, group_id); + printf("[%s] checkpoint4 [%d]\n", __func__, ret); + if(ret != 0) + tetResult = TET_UNINITIATED; + +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} diff --git a/TC/scenario1/utc_SecurityFW_ssm_read_func.c b/TC/scenario1/utc_SecurityFW_ssm_read_func.c new file mode 100755 index 0000000..e976f06 --- /dev/null +++ b/TC/scenario1/utc_SecurityFW_ssm_read_func.c @@ -0,0 +1,187 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ss_manager.h> +#include <tet_api.h> + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SecurityFW_ssm_read_func_01(void); +static void utc_SecurityFW_ssm_read_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SecurityFW_ssm_read_func_01, POSITIVE_TC_IDX }, + { utc_SecurityFW_ssm_read_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 } +}; + +static void startup(void) +{ + printf("Make temporary directory - /opt/secure-storage/test/\n"); + system("mkdir -p /opt/secure-storage/test"); + printf("Make temporary file\n"); + system("touch /opt/secure-storage/test/input.txt"); + system("echo \"abcdefghij\" > /opt/secure-storage/test/input.txt"); + system("cp /opt/secure-storage/test/input.txt /opt/secure-storage/test/input2.txt"); +} + +static void cleanup(void) +{ + printf("Remove tamporary file and directory\n"); + system("rm -rf /opt/secure-storage/test"); +} + +/** + * @brief Positive test case of ssm_read() + */ +static void utc_SecurityFW_ssm_read_func_01(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + + /* variables for ssm_read */ + FILE* fp_original = NULL; + char buf[20]; + char* retbuf = NULL; + int readlen = 0; + ssm_file_info_t sfi; + + /* get original file content. after encrypting, original file will be deleted */ + memset(buf, 0x00, 20); + fp_original = fopen(filepath, "r"); + fgets(buf, 20, fp_original); + fclose(fp_original); + + /* write file to secure-storage */ + ret = ssm_write_file(filepath, flag, group_id); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto error; + } + + /* read and compare */ + ssm_getinfo(filepath, &sfi, flag, group_id); + retbuf = (char*)malloc(sizeof(char) * (sfi.originSize + 1)); + memset(retbuf, 0x00, (sfi.originSize + 1)); + ret = ssm_read(filepath, retbuf, sfi.originSize, &readlen, flag, group_id); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto free_error; + } + + if(tetResult != TET_UNINITIATED) + { + if(!memcmp(buf, retbuf, strlen(retbuf))) // if same + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + } + + /* delete encrypted file */ + ret = ssm_delete_file(filepath, flag, group_id); + if(ret != 0) + tetResult = TET_UNINITIATED; + +free_error: + free(retbuf); +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} + +/** + * @brief Negative test case of ssm_read() + */ +static void utc_SecurityFW_ssm_read_func_02(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input2.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + + /* variables for ssm_read */ + FILE* fp_original = NULL; + char buf[20]; + char* retbuf = NULL; + int readlen = 0; + ssm_file_info_t sfi; + + /* get original file content. after encrypting, original file will be deleted */ + memset(buf, 0x00, 20); + fp_original = fopen(filepath, "r"); + fgets(buf, 20, fp_original); + fclose(fp_original); + + printf("[%s] checkpoint1\n", __func__); + + /* write file to secure-storage */ + ret = ssm_write_file(filepath, flag, group_id); + printf("[%s] checkpoint2 [%d]\n", __func__, ret); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto error; + } + + /* read and compare */ + ret = ssm_getinfo(filepath, &sfi, flag, group_id); + printf("[%s] checkpoint3 [%d]\n", __func__, ret); + retbuf = (char*)malloc(sizeof(char) * (sfi.originSize + 1)); + memset(retbuf, 0x00, (sfi.originSize + 1)); + ret = ssm_read(NULL, retbuf, sfi.originSize, &readlen, flag, group_id); + printf("[%s] checkpoint4 [%d]\n", __func__, ret); + if(ret != 0) // if fail, + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + + /* delete encrypted file */ + ret = ssm_delete_file(filepath, flag, group_id); + printf("[%s] checkpoint5 [%d]\n", __func__, ret); + if(ret != 0) + tetResult = TET_UNINITIATED; + + free(retbuf); +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} diff --git a/TC/scenario1/utc_SecurityFW_ssm_write_buffer_func.c b/TC/scenario1/utc_SecurityFW_ssm_write_buffer_func.c new file mode 100755 index 0000000..50faf2c --- /dev/null +++ b/TC/scenario1/utc_SecurityFW_ssm_write_buffer_func.c @@ -0,0 +1,155 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ss_manager.h> +#include <tet_api.h> + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SecurityFW_ssm_write_buffer_func_01(void); +static void utc_SecurityFW_ssm_write_buffer_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SecurityFW_ssm_write_buffer_func_01, POSITIVE_TC_IDX }, + { utc_SecurityFW_ssm_write_buffer_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 } +}; + +static void startup(void) +{ + printf("Make temporary directory - /opt/secure-storage/test/\n"); + system("mkdir -p /opt/secure-storage/test"); + printf("Make temporary file\n"); + system("touch /opt/secure-storage/test/input.txt"); + system("echo \"abcdefghij\" > /opt/secure-storage/test/input.txt"); +} + +static void cleanup(void) +{ + printf("Remove tamporary file and directory\n"); + system("rm -rf /opt/secure-storage/test"); +} + +/** + * @brief Positive test case of ssm_write_buffer() + */ +static void utc_SecurityFW_ssm_write_buffer_func_01(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_buffer */ + int ret = -1; + char oribuf[20]; + ssm_flag flag = SSM_FLAG_SECRET_OPERATION; + char* group_id = NULL; + char* filename = "write_buffer.txt"; + int buflen = 0; + + /* variables for ssm_read */ + char buf[20]; + char* retbuf = NULL; + int readlen = 0; + ssm_file_info_t sfi; + + /* set contents in buffers */ + memset(oribuf, 0x00, 20); + memset(buf, 0x00, 20); + strncpy(oribuf, "abcdefghij", 10); // original buffer + strncpy(buf, "abcdefghij", 10); // encrypting + + buflen = strlen(buf); + + /* write file to secure-storage */ + ret = ssm_write_buffer(buf, buflen, filename, flag, group_id); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto error; + } + + /* read and compare */ + ssm_getinfo(filename, &sfi, flag, group_id); + retbuf = (char*)malloc(sizeof(char) * (sfi.originSize + 1)); + memset(retbuf, 0x00, (sfi.originSize + 1)); + + ret = ssm_read(filename, retbuf, sfi.originSize, &readlen, flag, group_id); + if(ret != 0) // if fail, + { + tetResult = TET_UNINITIATED; + goto free_error; + } + + if(tetResult != TET_UNINITIATED) + { + if(!memcmp(oribuf, retbuf, strlen(retbuf))) // if same + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + } + + /* delete encrypted file */ + ret = ssm_delete_file(filename, flag, group_id); + if(ret != 0) + tetResult = TET_UNINITIATED; + +free_error: + free(retbuf); +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} + +/** + * @brief Negative test case of ssm_write_buffer() + */ +static void utc_SecurityFW_ssm_write_buffer_func_02(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_buffer */ + int ret = -1; + char* filename = "write_buffer.txt"; + ssm_flag flag = SSM_FLAG_SECRET_OPERATION; + char buf[20]; + int buflen = 0; + char* group_id = NULL; + + /* write file to secure-storage */ + ret = ssm_write_buffer(NULL, buflen, filename, flag, group_id); + if(ret != 0) // if fail, + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} diff --git a/TC/scenario1/utc_SecurityFW_ssm_write_file_func.c b/TC/scenario1/utc_SecurityFW_ssm_write_file_func.c new file mode 100755 index 0000000..a502992 --- /dev/null +++ b/TC/scenario1/utc_SecurityFW_ssm_write_file_func.c @@ -0,0 +1,147 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ss_manager.h> +#include <tet_api.h> + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SecurityFW_ssm_write_file_func_01(void); +static void utc_SecurityFW_ssm_write_file_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SecurityFW_ssm_write_file_func_01, POSITIVE_TC_IDX }, + { utc_SecurityFW_ssm_write_file_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 } +}; + +static void startup(void) +{ + printf("Make temporary directory - /opt/secure-storage/test/\n"); + system("mkdir -p /opt/secure-storage/test"); + printf("Make temporary file\n"); + system("touch /opt/secure-storage/test/input.txt"); + system("echo \"abcdefghij\" > /opt/secure-storage/test/input.txt"); +} + +static void cleanup(void) +{ + printf("Remove tamporary file and directory\n"); + system("rm -rf /opt/secure-storage/test"); +} + +/** + * @brief Positive test case of ssm_write_file() + */ +static void utc_SecurityFW_ssm_write_file_func_01(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + + /* variables for ssm_read */ + FILE* fp_original = NULL; + char buf[20]; + char* retbuf = NULL; + int readlen = 0; + ssm_file_info_t sfi; + + /* get original file content. after encrypting, original file will be deleted */ + memset(buf, 0x00, 20); + fp_original = fopen(filepath, "r"); + fgets(buf, 20, fp_original); + fclose(fp_original); + + /* write file to secure-storage */ + ret = ssm_write_file(filepath, flag, group_id); + if(ret != 0) { // if fail, + tetResult = TET_UNINITIATED; + goto error; + } + + /* read and compare */ + ssm_getinfo(filepath, &sfi, flag, group_id); + retbuf = (char*)malloc(sizeof(char) * (sfi.originSize + 1)); + memset(retbuf, 0x00, (sfi.originSize + 1)); + ret = ssm_read(filepath, retbuf, sfi.originSize, &readlen, flag, group_id); + if(ret != 0) { // if fail, + tetResult = TET_UNINITIATED; + goto free_error; + } + + if(tetResult != TET_UNINITIATED) + { + if(!memcmp(buf, retbuf, strlen(retbuf))) // if same + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + } + + /* delete encrypted file */ + ret = ssm_delete_file(filepath, flag, group_id); + if(ret != 0) + tetResult = TET_UNINITIATED; + +free_error: + free(retbuf); +error: + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} + +/** + * @brief Negative test case of ssm_write_file() + */ +static void utc_SecurityFW_ssm_write_file_func_02(void) +{ + int tetResult = TET_FAIL; + /* variables for ssm_write_file */ + int ret = -1; + char* filepath = "/opt/secure-storage/test/input.txt"; + ssm_flag flag = SSM_FLAG_DATA; + char* group_id = NULL; + + /* write file to secure-storage */ + ret = ssm_write_file(NULL, flag, group_id); + if(ret != 0) // if fail, + tetResult = TET_PASS; + else + tetResult = TET_FAIL; + + printf("[%d] [%s]\n", tetResult, __FILE__); + tet_result(tetResult); +} diff --git a/TC/tet_code b/TC/tet_code new file mode 100755 index 0000000..a2cf6c1 --- /dev/null +++ b/TC/tet_code @@ -0,0 +1,12 @@ +# TET reserved codes +0 "PASS" +1 "FAIL" +2 "UNRESOLVED" +3 "NOTINUSE" +4 "UNSUPPORTED" +5 "UNTESTED" +6 "UNINITIATED" +7 "NORESULT" + +# Test suite additional codes +33 "INSPECT" diff --git a/TC/tet_scen b/TC/tet_scen new file mode 100755 index 0000000..c63a380 --- /dev/null +++ b/TC/tet_scen @@ -0,0 +1,7 @@ +all + ^TEST +##### Scenarios for TEST ##### + +# Test scenario +TEST + :include:/scenario1/tslist diff --git a/TC/tetbuild.cfg b/TC/tetbuild.cfg new file mode 100755 index 0000000..1f80874 --- /dev/null +++ b/TC/tetbuild.cfg @@ -0,0 +1,4 @@ +TET_OUTPUT_CAPTURE=False +TET_BUILD_TOOL=make +TET_PASS_TC_NAME=True +TET_API_COMPLIANT=True diff --git a/TC/tetclean.cfg b/TC/tetclean.cfg new file mode 100755 index 0000000..55ef6b5 --- /dev/null +++ b/TC/tetclean.cfg @@ -0,0 +1,3 @@ +TET_OUTPUT_CAPTURE=False +TET_CLEAN_TOOL=make clean +TET_API_COMPLIANT=True diff --git a/TC/tetexec.cfg b/TC/tetexec.cfg new file mode 100755 index 0000000..eb4f0d3 --- /dev/null +++ b/TC/tetexec.cfg @@ -0,0 +1,3 @@ +TET_OUTPUT_CAPTURE=True +TET_API_COMPLIANT=True +TET_PASS_TC_NAME=True diff --git a/client/include/ss_client_intf.h b/client/include/ss_client_intf.h new file mode 100644 index 0000000..49255ea --- /dev/null +++ b/client/include/ss_client_intf.h @@ -0,0 +1,68 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#ifndef __SS_MANAGER__ +#include "ss_manager.h" +#endif + +/* + * Declare new function + * + * @name: SsClientDataStore + * @parameter + * - filepath: [in] + * - flag: [in] + * @return type: int + * - 1: success + * - <1: error + */ +int SsClientDataStoreFromFile(const char* filepath, ssm_flag flag, const char* group_id); +int SsClientDataStoreFromBuffer(char* writebuffer, size_t bufLen, const char* filename, ssm_flag flag, const char* group_id); + +/* + * Declare new function + * + * @name: SsClientDataRead + * @parameter + * - filepath: [in] + * - pRetBuf: [out] + * - bufLen: [in] + * - readLen: [out] + * @return type: int + * - 1: success + * - <1: error + */ +int SsClientDataRead(const char* filepath, char* pRetBuf, size_t bufLen, size_t *readLen, ssm_flag flag, const char* group_id); + +/* + * Declare new function + * + * @name: SsClientGetInfo + * @parameter + * - filepath: [in] + * - sfi: [out] + * @return type: int + * - 1: success + * - <1: error + */ +int SsClientGetInfo(const char* filepath, ssm_file_info_t* sfi, ssm_flag flag, const char* group_id); + +int SsClientDeleteFile(const char* pFilePath, ssm_flag flag, const char* group_id); diff --git a/client/include/ss_client_ipc.h b/client/include/ss_client_ipc.h new file mode 100644 index 0000000..036d49b --- /dev/null +++ b/client/include/ss_client_ipc.h @@ -0,0 +1,32 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +/* + * Declare new function + * + * @name: SsClientComm + * @parameter: client_data + * @return type: RspData_t + */ + +#include "secure_storage.h" + +RspData_t SsClientComm(ReqData_t* client_data); diff --git a/client/src/ss_client_intf.c b/client/src/ss_client_intf.c new file mode 100644 index 0000000..577f8b7 --- /dev/null +++ b/client/src/ss_client_intf.c @@ -0,0 +1,415 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "secure_storage.h" +#include "ss_client_intf.h" +#include "ss_client_ipc.h" +#include "ss_manager.h" + +int SsClientDataStoreFromFile(const char* filepath, ssm_flag flag, const char* group_id) +{ + ReqData_t* send_data = NULL; + RspData_t recv_data; + int temp_len = 0; + int cookie_size = 20; + +// cookie_size = security_server_get_cookie_size(); + char cookie_content[20] = {0, }; + +// if(security_server_request_cookie(cookie_content, cookie_size) < 0) // error while getting cookie +// { +// SLOGE("Fail to get cookie\n"); +// recv_data.rsp_type = SS_SECURE_STORAGE_ERROR; +// goto Error; +// } + + if(!filepath) + { + SLOGE("Parameter error in SsClientDataStoreFromFile..\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Error; + } + + send_data = (ReqData_t*)malloc(sizeof(ReqData_t)); + + if(!send_data) + { + SLOGE("Memory allocation fail in SsClientDataStoreFromFile..\n"); + recv_data.rsp_type = SS_MEMORY_ERROR; + goto Error; + } + + send_data->req_type = 1; // file store + send_data->enc_type = 1; // initial type + send_data->count = 0; + send_data->flag = flag; // flag + temp_len = strlen(filepath); + if(temp_len < MAX_FILENAME_LEN) + { + strncpy(send_data->data_infilepath, filepath, MAX_FILENAME_LEN - 1); + send_data->data_infilepath[temp_len] = '\0'; + } + else + { + SLOGE("filepath is too long.\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Free_and_Error; + } + memset(send_data->cookie, 0x00, MAX_COOKIE_LEN); + memset(send_data->group_id, 0x00, MAX_GROUP_ID_LEN); + memcpy(send_data->cookie, cookie_content, cookie_size); + if(group_id) + strncpy(send_data->group_id, group_id, MAX_GROUP_ID_LEN - 1); + else + strncpy(send_data->group_id, "NOTUSED", MAX_GROUP_ID_LEN - 1); + + memset(send_data->buffer, 0x00, MAX_SEND_DATA_LEN + 1); + recv_data = SsClientComm(send_data); + +Free_and_Error: + free(send_data); +Error: + return recv_data.rsp_type; +} + +int SsClientDataStoreFromBuffer(char* writebuffer, size_t bufLen, const char* filename, ssm_flag flag, const char* group_id) +{ + ReqData_t* send_data = NULL; + RspData_t recv_data; + int temp_len = 0; + int cookie_size = 20; + +// cookie_size = security_server_get_cookie_size(); + char cookie_content[20] = {0, }; + +// if(security_server_request_cookie(cookie_content, cookie_size) < 0) // error while getting cookie +// { +// SLOGE("Fail to get cookie\n"); +// recv_data.rsp_type = SS_SECURE_STORAGE_ERROR; +// goto Error; +// } + + if(!writebuffer || !filename) + { + SLOGE("Parameter error in SsClientDataStoreFromBuffer..\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Error; + } + + send_data = (ReqData_t*)malloc(sizeof(ReqData_t)); + if(!send_data) + { + SLOGE("Memory allocation fail in SsClientDataStoreFromBuffer..\n"); + recv_data.rsp_type = SS_MEMORY_ERROR; + goto Error; + } + + send_data->req_type = 2; // buffer store + send_data->enc_type = 1; + send_data->count = bufLen; + send_data->flag = flag; + temp_len = strlen(filename); + if(temp_len < MAX_FILENAME_LEN) + { + strncpy(send_data->data_infilepath, filename, MAX_FILENAME_LEN - 1); + send_data->data_infilepath[temp_len] = '\0'; + } + else + { + SLOGE("filepath is too long.\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Free_and_Error; + } + memset(send_data->cookie, 0x00, MAX_COOKIE_LEN); + memset(send_data->group_id, 0x00, MAX_GROUP_ID_LEN); + memcpy(send_data->cookie, cookie_content, cookie_size); + if(group_id) + strncpy(send_data->group_id, group_id, MAX_GROUP_ID_LEN - 1); + else + strncpy(send_data->group_id, "NOTUSED", MAX_GROUP_ID_LEN - 1); + + memcpy(send_data->buffer, writebuffer, bufLen); + recv_data = SsClientComm(send_data); + +Free_and_Error: + free(send_data); +Error: + return recv_data.rsp_type; +} + +int SsClientDataRead(const char* filepath, char* pRetBuf, size_t bufLen, size_t *readLen, ssm_flag flag, const char* group_id) +{ + unsigned int count = (unsigned int)(bufLen / MAX_RECV_DATA_LEN + 1); + unsigned int rest = (unsigned int)(bufLen % MAX_RECV_DATA_LEN); + char* buffer; + ReqData_t* send_data = NULL; + RspData_t recv_data; + int temp_len = 0; + int cookie_size = 20; + +// cookie_size = security_server_get_cookie_size(); + char cookie_content[20] = {0, }; + +// if(security_server_request_cookie(cookie_content, cookie_size) < 0) // error while getting cookie +// { +// SLOGE("Fail to get cookie\n"); +// recv_data.rsp_type = SS_SECURE_STORAGE_ERROR; +// goto Error; +// } + + if(!filepath) + { + SLOGE("filepath Parameter error in SsClientDataRead..\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Error; + } + if(!readLen) + { + SLOGE("readLen Parameter error in SsClientDataRead..\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Error; + } + + *readLen = 0; + buffer = pRetBuf; + + send_data = (ReqData_t*)malloc(sizeof(ReqData_t)); + + if(!send_data) + { + SLOGE("Memory allocation fail in SsClientDataRead..\n"); + recv_data.rsp_type = SS_MEMORY_ERROR; + goto Error; + } + + // fill send_data + send_data->req_type = 3; // read data from storage + send_data->enc_type = 1; // initial type + send_data->count = 0; + send_data->flag = flag & 0x000000ff; //flag; + temp_len = strlen(filepath); + if(temp_len < MAX_FILENAME_LEN) + { + strncpy(send_data->data_infilepath, filepath, MAX_FILENAME_LEN - 1); + send_data->data_infilepath[temp_len] = '\0'; + } + else + { + SLOGE("filepath is too long.\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Free_and_Error; + } + memset(send_data->cookie, 0x00, MAX_COOKIE_LEN); + memset(send_data->group_id, 0x00, MAX_GROUP_ID_LEN); + memcpy(send_data->cookie, cookie_content, MAX_COOKIE_LEN); + if(group_id) + strncpy(send_data->group_id, group_id, MAX_GROUP_ID_LEN - 1); + else + strncpy(send_data->group_id, "NOTUSED", MAX_GROUP_ID_LEN - 1); + memset(send_data->buffer, 0x00, MAX_SEND_DATA_LEN+1); + + // Call Server per 4KB data (count from 0 to ~) + for ( ; send_data->count < count; send_data->count++) + { + //receive data from server + recv_data = SsClientComm(send_data); + + // check response type + if(recv_data.rsp_type != 1) + { + SLOGE("data read error from server...\n"); + goto Free_and_Error; + } + // copy the last data (last count) + if(send_data->count == (count - 1)) + { + memcpy(buffer, recv_data.buffer, rest); + *readLen += (size_t)rest; + goto Last; + //break; + } + + memcpy(buffer, recv_data.buffer, MAX_RECV_DATA_LEN); + *readLen += (size_t)recv_data.readLen; + buffer += recv_data.readLen; + } +Last : + if(bufLen != *readLen) + { + SLOGE("Decrypted abnormally\n"); + recv_data.rsp_type = SS_DECRYPTION_ERROR; + goto Free_and_Error; + } + + SLOGE("Decrypted file name : %s\n", recv_data.data_filepath); +Free_and_Error: + free(send_data); +Error: + return recv_data.rsp_type; +} + +int SsClientGetInfo(const char* filepath, ssm_file_info_t* sfi, ssm_flag flag, const char* group_id) +{ + + ReqData_t* send_data = NULL; + RspData_t recv_data; + ssm_file_info_convert_t sfic; + int temp_len = 0; + int cookie_size = 20; + +// cookie_size = security_server_get_cookie_size(); + char cookie_content[20] = {0, }; + +// if(security_server_request_cookie(cookie_content, cookie_size) < 0) // error while getting cookie +// { +// SLOGE("Fail to get cookie\n"); +// recv_data.rsp_type = SS_SECURE_STORAGE_ERROR; +// goto Error; +// } + + if(!filepath || !sfi) + { + SLOGE("Parameter error in SsClientGetInfo..\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Error; + } + + send_data = (ReqData_t*)malloc(sizeof(ReqData_t)); + + if(!send_data) + { + SLOGE("Memory allocation fail in SsClientGetInfo..\n"); + recv_data.rsp_type = SS_MEMORY_ERROR; + goto Error; + } + + // fill send_data + send_data->req_type = 4; // get info type + send_data->enc_type = 1; // initial type + send_data->count = 0; + send_data->flag = flag & 0x000000ff; //flag; + temp_len = strlen(filepath); + if(temp_len < MAX_FILENAME_LEN) + { + strncpy(send_data->data_infilepath, filepath, MAX_FILENAME_LEN - 1); + send_data->data_infilepath[temp_len] = '\0'; + } + else + { + SLOGE("filepath is too long.\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Free_and_Error; + } + memset(send_data->cookie, 0x00, MAX_COOKIE_LEN); + memset(send_data->group_id, 0x00, MAX_GROUP_ID_LEN); + memcpy(send_data->cookie, cookie_content, cookie_size); + if(group_id) + strncpy(send_data->group_id, group_id, MAX_GROUP_ID_LEN - 1); + else + strncpy(send_data->group_id, "NOTUSED", MAX_GROUP_ID_LEN - 1); + memset(send_data->buffer, 0x00, MAX_SEND_DATA_LEN + 1); + + recv_data = SsClientComm(send_data); + + memcpy(sfic.fInfoArray, recv_data.buffer, sizeof(ssm_file_info_t)); + sfi->originSize = sfic.fInfoStruct.originSize; + sfi->storedSize = sfic.fInfoStruct.storedSize; + memcpy(sfi->reserved, sfic.fInfoStruct.reserved, 8); + +Free_and_Error: + free(send_data); +Error: + return recv_data.rsp_type; +} + +int SsClientDeleteFile(const char *pFilePath, ssm_flag flag, const char* group_id) +{ + ReqData_t* send_data = NULL; + RspData_t recv_data; + int temp_len = 0; + int cookie_size = 20; + +// cookie_size = security_server_get_cookie_size(); + char cookie_content[20] = {0, }; + +// if(security_server_request_cookie(cookie_content, cookie_size) < 0) // error while getting cookie +// { +// SLOGE("Fail to get cookie\n"); +// recv_data.rsp_type = SS_SECURE_STORAGE_ERROR; +// goto Error; +// } + + if(!pFilePath) + { + SLOGE("Parameter error in SsClientDeleteFile..\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Error; + } + + send_data = (ReqData_t*)malloc(sizeof(ReqData_t)); + + if(!send_data) + { + SLOGE("Memory allocation fail in SsClientDeleteFile..\n"); + recv_data.rsp_type = SS_MEMORY_ERROR; + goto Error; + } + + send_data->req_type = 10; // delete file + send_data->enc_type = 1; // initial type + send_data->count = 0; + send_data->flag = flag; // flag + temp_len = strlen(pFilePath); + if(temp_len < MAX_FILENAME_LEN) + { + strncpy(send_data->data_infilepath, pFilePath, MAX_FILENAME_LEN - 1); + send_data->data_infilepath[temp_len] = '\0'; + } + else + { + SLOGE("filepath is too long.\n"); + recv_data.rsp_type = SS_PARAM_ERROR; + goto Free_and_Error; + } + memset(send_data->cookie, 0x00, MAX_COOKIE_LEN); + memset(send_data->group_id, 0x00, MAX_GROUP_ID_LEN); + memcpy(send_data->cookie, cookie_content, cookie_size); + if(group_id) + strncpy(send_data->group_id, group_id, MAX_GROUP_ID_LEN - 1); + else + strncpy(send_data->group_id, "NOTUSED", MAX_GROUP_ID_LEN - 1); + memset(send_data->buffer, 0x00, MAX_SEND_DATA_LEN+1); + + recv_data = SsClientComm(send_data); + +Free_and_Error: + free(send_data); + + SLOGE("Deleted file name: %s\n", recv_data.data_filepath); + +Error: + return recv_data.rsp_type; +} diff --git a/client/src/ss_client_ipc.c b/client/src/ss_client_ipc.c new file mode 100644 index 0000000..ec18c7d --- /dev/null +++ b/client/src/ss_client_ipc.c @@ -0,0 +1,103 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/un.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> + +#include "ss_client_ipc.h" +#include "secure_storage.h" + +RspData_t SsClientComm(ReqData_t* client_data) +{ + int sockfd = 0; + int client_len = 0; + struct sockaddr_un clientaddr; + ReqData_t send_data = {0, }; + RspData_t recv_data = {0, }; + int temp_len_in = 0; + int temp_len_sock = 0; + int cookie_size = 20; + + send_data.req_type = client_data->req_type; + send_data.enc_type = client_data->enc_type; + send_data.count = client_data->count; + send_data.flag = client_data->flag; + + temp_len_in = strlen(client_data->data_infilepath); + + strncpy(send_data.data_infilepath, client_data->data_infilepath, MAX_FILENAME_LEN - 1); + send_data.data_infilepath[temp_len_in] = '\0'; + +// cookie_size = security_server_get_cookie_size(); + memcpy(send_data.cookie, client_data->cookie, cookie_size); + strncpy(send_data.group_id, client_data->group_id, MAX_GROUP_ID_LEN - 1); + + memcpy(send_data.buffer, client_data->buffer, MAX_SEND_DATA_LEN); + + if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + SLOGE("Error in function socket()..\n"); + recv_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_exit; + } + + temp_len_sock = strlen(SS_SOCK_PATH); + + bzero(&clientaddr, sizeof(clientaddr)); + clientaddr.sun_family = AF_UNIX; + strncpy(clientaddr.sun_path, SS_SOCK_PATH, temp_len_sock); + clientaddr.sun_path[temp_len_sock] = '\0'; + client_len = sizeof(clientaddr); + + if(connect(sockfd, (struct sockaddr*)&clientaddr, client_len) < 0) + { + SLOGE("Error in function connect()..\n"); + recv_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_close_exit; + } + + if(write(sockfd, (char*)&send_data, sizeof(send_data)) < 0) + { + SLOGE("Error in function write()..\n"); + recv_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_close_exit; + } + + if(read(sockfd, (char*)&recv_data, sizeof(recv_data)) < 0) + { + SLOGE("Error in function read()..\n"); + recv_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_close_exit; + } + +Error_close_exit: + close(sockfd); + +Error_exit: + return recv_data; +} diff --git a/client/src/ss_manager.c b/client/src/ss_manager.c new file mode 100644 index 0000000..a94357e --- /dev/null +++ b/client/src/ss_manager.c @@ -0,0 +1,214 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "secure_storage.h" +#include "ss_client_intf.h" + +#ifndef SS_API +#define SS_API __attribute__((visibility("default"))) +#endif + +/***************************************************************************** + * Internal Functions + *****************************************************************************/ +SS_API +int ssm_getinfo(const char* pFilePath, ssm_file_info_t *sfi, ssm_flag flag, const char* group_id) +{ + int ret = 0; + + if(!pFilePath || !sfi) + { + SLOGE("Parameter error in ssm_getinfo()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + + ret = SsClientGetInfo(pFilePath, sfi, flag, group_id); + + if(ret == 1) + { + SLOGI("Getinfo Success.\n"); + ret = 0; // return true + } + else + SLOGE("Getinfo Fail.\n"); + +Error: + return -(ret); +} + +/***************************************************************************** + * Manager APIs + *****************************************************************************/ +SS_API +int ssm_write_file(const char* pFilePath, ssm_flag flag, const char* group_id) +{ + int ret = 0; + + if(!pFilePath) + { + SLOGE("Parameter error in ssm_write_file()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + + if(flag <= SSM_FLAG_NONE || flag >= SSM_FLAG_MAX) + { + SLOGE("Parameter error in ssm_write_file()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + + ret = SsClientDataStoreFromFile(pFilePath, flag, group_id); + if(ret == 1) + { + if(unlink(pFilePath) != 0) // if fail + { + SLOGE("unlink fail. [%s]\n", pFilePath); + return -1; // return false + } + SLOGI("Write file Success.\n"); + return 0; // return true + } + else + SLOGE("Write file Fail.\n"); + +Error: + return -(ret); +} + +SS_API +int ssm_write_buffer(char* pWriteBuffer, size_t bufLen, const char* pFileName, ssm_flag flag, const char* group_id) +{ + int ret = 0; + + if(!pWriteBuffer || !pFileName || (pFileName[0] == '/')) + { + SLOGE("Parameter error in ssm_write_buffer()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + if(bufLen <= 0 || bufLen > 4096) + { + SLOGE("Parameter error in ssm_write_buffer()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + if(flag <= SSM_FLAG_NONE || flag >= SSM_FLAG_MAX) + { + SLOGE("Parameter error in ssm_write_buffer()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + + ret = SsClientDataStoreFromBuffer(pWriteBuffer, bufLen, pFileName, flag, group_id); + if(ret == 1) + { + SLOGI("Write buffer Success.\n"); + return 0; // return true + } + else + SLOGE("Write buffer Fail.\n"); + +Error: + return -(ret); +} + +SS_API +int ssm_read(const char* pFilePath, char* pRetBuf, size_t bufLen, size_t *readLen, ssm_flag flag, const char* group_id) +{ + int ret = 0; + ssm_file_info_t sfi; + + if(!pFilePath || !pRetBuf) + { + SLOGE("Parameter error in ssm_read()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + if(!readLen) + { + SLOGE("Parameter error in ssm_read()...\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + + // get info + ret = ssm_getinfo(pFilePath, &sfi, flag, group_id); + if(ret != 0) // ret != true? + { + SLOGE("getinfo error in ssm_read()..\n"); + goto Error; + } + // in case of flag mismatch... + // check flag... + // To do : + if((bufLen > sfi.originSize) || (sfi.reserved[0] != (flag & 0x000000ff))) + { + SLOGE("Flag mismatch or buffer length error in ssm_read()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + + ret = SsClientDataRead(pFilePath, pRetBuf, sfi.originSize, readLen, flag, group_id); + + if(ret == 1) + { + SLOGI("Read Success.\n"); + return 0; // return true + } + else + SLOGE("Read Fail.\n"); + +Error: + return -(ret); +} + +SS_API +int ssm_delete_file(const char *pFilePath, ssm_flag flag, const char* group_id) +{ + int ret = 0; + + if(!pFilePath) + { + SLOGE("Parameter error in ssm_delete_file()..\n"); + ret = SS_PARAM_ERROR; + goto Error; + } + + ret = SsClientDeleteFile(pFilePath, flag, group_id); + + if(ret == 1) // success + { + SLOGI("Delete file Success.\n"); + return 0; + } + else // fail + SLOGE("Delete file Fail.\n"); + +Error: + return -(ret); +} diff --git a/config.in b/config.in new file mode 100644 index 0000000..8005cca --- /dev/null +++ b/config.in @@ -0,0 +1,2 @@ +PRESERVE_DIR : /csa/ +MASTER_KEY_PATH : /csa/.seckey diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..c802bf1 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,7 @@ +secure-storage (0.12.7-18) unstable; urgency=low + + * randomize initial vector of AES_cbc cryptographic algorithm + * Git: framework/security/secure-storage + * Tag: secure-storage_0.12.7-18 + + -- Kidong Kim <kd0228.kim@samsung.com> Mon, 14 May 2012 12:00:40 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..b66dfd1 --- /dev/null +++ b/debian/control @@ -0,0 +1,30 @@ +Source: secure-storage +Priority: extra +Maintainer: Kidong Kim <kd0228.kim@samsung.com> +Build-Depends: debhelper (>= 5), autotools-dev, libssl-dev, openssl, dlog-dev +Standards-Version: 3.7.2 +Section: base + +Package: libss-client-dev +Section: libs +Architecture: any +Depends: ${misc:Depends}, libssl-dev, libss-client-0 (= ${Source-Version}), dlog-dev +Description: secure storage client library develpoment package + +Package: libss-client-0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: secure storage client library package + +Package: ss-server +Section: base +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libss-client-0 (= ${Source-Version}), libdlog-0 +Description: secure storage server + +Package: ss-server-dbg +Section: debug +Architecture: any +Depends: ss-server (= ${Source-Version}) +Description: debug package of secure storage source package diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/docs diff --git a/debian/libss-client-0.install.in b/debian/libss-client-0.install.in new file mode 100644 index 0000000..8db61c4 --- /dev/null +++ b/debian/libss-client-0.install.in @@ -0,0 +1 @@ +usr/lib/libss-client.so* diff --git a/debian/libss-client-0.postinst b/debian/libss-client-0.postinst new file mode 100755 index 0000000..8fb2afe --- /dev/null +++ b/debian/libss-client-0.postinst @@ -0,0 +1,8 @@ +#!/bin/sh + +#if [ ${USER} == "root" ] +#then +# chown root:root /usr/lib/libss-client.so +#fi + +#chmod 644 /usr/lib/libss-client.so diff --git a/debian/libss-client-dev.install.in b/debian/libss-client-dev.install.in new file mode 100644 index 0000000..7e38b28 --- /dev/null +++ b/debian/libss-client-dev.install.in @@ -0,0 +1,2 @@ +usr/include/ss_manager.h +usr/lib/pkgconfig/secure-storage.pc diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..67da1e8 --- /dev/null +++ b/debian/rules @@ -0,0 +1,128 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +CFLAGS ?= -Wall -g +CXXFLAGS ?= -Wall -g +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 + CXXFLAGS += -O0 +else + CFLAGS += -O2 + CXXFLAGS += -O2 +endif + +LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX) + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #docbook-to-man debian/wavplayer.sgml > wavplayer.1 + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) clean + rm -rf CMakeCache.txt + rm -rf CMakeFiles + rm -rf cmake_install.cmake + rm -rf Makefile + rm -rf install_manifest.txt + rm -rf *.so + rm -rf *.pc + rm -rf config + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/wavplayer. + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/ + mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/ + ln -s ../init.d/ss-serverd $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S26ss-server + ln -s ../init.d/ss-serverd $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/S26ss-server + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link +# dh_strip +# dh_strip --dbg-package=secure-storage-dbg + dh_strip --dbg-package=ss-server-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/debian/ss-server.install.in b/debian/ss-server.install.in new file mode 100644 index 0000000..8a02822 --- /dev/null +++ b/debian/ss-server.install.in @@ -0,0 +1,5 @@ +usr/share/secure-storage/config +usr/bin/ss-server +etc/rc.d/rc3.d/S26ss-server +etc/rc.d/rc5.d/S26ss-server +etc/rc.d/init.d/ss-serverd diff --git a/debian/ss-server.postinst b/debian/ss-server.postinst new file mode 100755 index 0000000..673fd19 --- /dev/null +++ b/debian/ss-server.postinst @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ ${USER} = "root" ] +then +# chown root:root /usr/bin/ss-server + chown root:root /etc/rc.d/init.d/ss-serverd +fi + +#chmod 700 /usr/bin/ss-server +chmod 755 /etc/rc.d/init.d/ss-serverd diff --git a/include/secure_storage.h b/include/secure_storage.h new file mode 100644 index 0000000..67ff3d0 --- /dev/null +++ b/include/secure_storage.h @@ -0,0 +1,90 @@ +/*
+ * secure storage
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Kidong Kim <kd0228.kim@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __SECURE_STORAGE__
+#define __SECURE_STORAGE__
+
+#include "ss_manager.h"
+
+#define SS_SOCK_PATH "/tmp/SsSocket"
+
+#define MAX_FILENAME_LEN 256 // for absolute path
+//#define MAX_RECV_DATA_LEN 16384 // internal buffer = 4KB
+#define MAX_RECV_DATA_LEN 4096 // internal buffer = 4KB
+//#define MAX_SEND_DATA_LEN 16384 // internal buffer = 4KB
+#define MAX_SEND_DATA_LEN 4096 // internal buffer = 4KB
+#define MAX_GROUP_ID_LEN 32
+#define MAX_COOKIE_LEN 20
+
+#define SS_STORAGE_DEFAULT_PATH "/opt/share/secure-storage/"
+
+/* using dlog */
+#ifdef SS_DLOG_USE
+
+#define LOG_TAG "SECURE_STORAGE"
+#include <dlog.h>
+
+#elif SS_CONSOLE_USE // debug msg will be printed in console
+
+#define SLOGD(FMT, ARG ...) fprintf(stderr, FMT, ##ARG)
+#define SLOGV(FMT, ARG ...) fprintf(stderr, FMT, ##ARG)
+#define SLOGI(FMT, ARG ...) fprintf(stderr, FMT, ##ARG)
+#define SLOGW(FMT, ARG ...) fprintf(stderr, FMT, ##ARG)
+#define SLOGE(FMT, ARG ...) fprintf(stderr, FMT, ##ARG)
+#define SLOGF(FMT, ARG ...) fprintf(stderr, FMT, ##ARG)
+
+#else // don't use logging
+
+#define SLOGD(FMT, ARG ...) {}
+#define SLOGV(FMT, ARG ...) {}
+#define SLOGI(FMT, ARG ...) {}
+#define SLOGW(FMT, ARG ...) {}
+#define SLOGE(FMT, ARG ...) {}
+#define SLOGF(FMT, ARG ...) {}
+
+#endif
+
+#define SS_FILE_POSTFIX ".e"
+
+typedef union {
+ ssm_file_info_t fInfoStruct;
+ char fInfoArray[16];
+} ssm_file_info_convert_t;
+
+typedef struct {
+ int req_type;
+ int enc_type;
+ unsigned int count; // 1 count = 4KB
+ unsigned int flag;
+ char data_infilepath[MAX_FILENAME_LEN];
+ char buffer[MAX_SEND_DATA_LEN+1];
+ char group_id[MAX_GROUP_ID_LEN];
+ char cookie[MAX_COOKIE_LEN];
+} ReqData_t;
+
+typedef struct {
+ int rsp_type;
+ unsigned int readLen;
+ char data_filepath[MAX_FILENAME_LEN];
+ char buffer[MAX_RECV_DATA_LEN+1];
+} RspData_t;
+
+#endif
diff --git a/include/ss_manager.h b/include/ss_manager.h new file mode 100644 index 0000000..942a1a1 --- /dev/null +++ b/include/ss_manager.h @@ -0,0 +1,402 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#ifndef __SS_MANAGER__ +#define __SS_MANAGER__ + +/** + * @{ + */ + +/** + * @defgroup SECURE_STORAGE secure storage + * @ingroup SecurityFW + * @{ + */ + +#define SSM_STORAGE_DEFAULT_PATH "/opt/share/secure-storage/" + +#define DEPRECATED __attribute__((deprecated)) + +/** + * \name Enumeration + */ +typedef enum { + SSM_FLAG_NONE = 0x00, + SSM_FLAG_DATA, // normal data for user (ex> picture, video, memo, etc.) + SSM_FLAG_SECRET_PRESERVE, // for preserved operation + SSM_FLAG_SECRET_OPERATION, // for oma drm , wifi addr, divx and bt addr + SSM_FLAG_WIDGET, // for wiget encryption/decryption + SSM_FLAG_MAX +} ssm_flag; + +/** + * \name Type definition + */ +typedef struct { + unsigned int originSize; + unsigned int storedSize; + char reserved[8]; +}ssm_file_info_t; + +/** + * \name Error codes + */ +#define SS_PARAM_ERROR 0x00000002 // 2 +#define SS_FILE_TYPE_ERROR 0x00000003 // 3 +#define SS_FILE_OPEN_ERROR 0x00000004 // 4 +#define SS_FILE_READ_ERROR 0x00000005 // 5 +// +#define SS_FILE_WRITE_ERROR 0x00000006 // 6 +#define SS_MEMORY_ERROR 0x00000007 // 7 +#define SS_SOCKET_ERROR 0x00000008 // 8 +#define SS_ENCRYPTION_ERROR 0x00000009 // 9 +#define SS_DECRYPTION_ERROR 0x0000000a // 10 +// +#define SS_SIZE_ERROR 0x0000000b // 11 +#define SS_SECURE_STORAGE_ERROR 0x0000000c // 12 +#define SS_PERMISSION_DENIED 0x0000000d // 13 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Functions + */ +/** + * \par Description: + * Store encrypted file to secure-storage. + * + * \par Purpose: + * Encrypt file in order not to expose the contents of that file. The encrypted file is stored in specific directory and that file only be read by secure-storage server daemon. + * + * \par Typical use case: + * When user wants to store some file securely, he(or she) can use this API. + * + * \par Method of function operation: + * First, encrypt the given file. Then make new file path which will be stored in secure storage. Then store new encrypted file and remove older one. + * + * \par Important Notes: + * - After encryption, original file will be deleted.\n + * + * \param[in] pFilePath Absolute file path of original file + * \param[in] flag Type of stored data (data or secret) + * \param[in] group_id Sharing group id(string). (NULL if not used) + * + * \return Return Type (integer) \n + * - 0 - Success \n + * - <0 - Fail \n + * + * \par Related functions: + * None + * + * \par Known issues/bugs: + * None + * + * \pre None + * \post None + * \see None + * \remark None + * + * \par Sample code: + * \code + * #include <ss_manager.h> + * + * ... + * + * int ret = -1; + * char* infilepath = "/opt/test/test.txt"; + * ssm_flag flag = SSM_FLAG_DATA; + * + * ret = ssm_write_file(infilepath, flag, NULL); + * + * return ret; // in case of success, return 0. Or fail, return corresponding error code. + * + * ... + * \endcode + * + */ +/*================================================================================================*/ +int ssm_write_file(const char* pFilePath, ssm_flag flag, const char* group_id); + +/** + * \par Description: + * Store encrypted file to secure-storage (Original data is in memory buffer). + * + * \par Purpose: + * Encrypt buffer in order not to expose the contents of that buffer. The encrypted file is stored in specific directory and that file only be read by secure-storage server daemon. + * + * \par Typical use case: + * When user wants to store some buffer contents securely, he(or she) can use this API. + * + * \par Method of function operation: + * First, encrypt the given buffer contents. Then make new file path which will be stored in secure storage. Then store new encrypted file. + * + * \par Important Notes: + * None + * + * \param[in] pWriteBuffer Data buffer to be stored in secure storage + * \param[in] bufLen Data size of buffer + * \param[in] pFileName File name be used when stored. Only file name, not a path + * \param[in] flag Type of stored data (data or secret) + * \param[in] group_id Sharing group id(string). (NULL if not used) + * + * \return Return Type (integer) \n + * - 0 - Success \n + * - <0 - Fail \n + * + * \par Related functions: + * None + * + * \par Known issues/bugs: + * None + * + * \pre None + * \post None + * \see None + * \remark None + * + * \par Sample code: + * \code + * #include <ss_manager.h> + * + * ... + * + * int ret = -1; + * char buf[27] = "abcdefghijklmnopqrstuvwxyz"; + * int buflen = strlen(buf); + * char* filename = write_buf.txt; + * ssm_flag flag = SSM_FLAG_SECRET_OPERATION; + * + * ret = ssm_write_buffer(buf, buflen, filename, flag, NULL); + * + * return ret; // in case of success, return 0. Or fail, return corresponding error code. + * + * ... + * \endcode + * + */ +/*================================================================================================*/ +int ssm_write_buffer(char* pWriteBuffer, size_t bufLen, const char* pFileName, ssm_flag flag, const char* group_id); + +/** + * \par Description: + * Decrypt encrypted file into memory buffer. + * + * \par Purpose: + * Read encrypted file which be stored in secure storage. Decrypted contents are only existed in the form of memory buffer, not file. + * + * \par Typical use case: + * When user wants to know the contents which be stored in secure storage, he(or she) can use this API. + * + * \par Method of function operation: + * First, read the file which be in secure storage. Then decrypt that file and store to memory buffer. Then return that buffer. + * + * \par Important Notes: + * - flag must be same with the one of stored data.\n + * - pFilePath can be either absolute path or file name.\n + * - pRetBuf is JUST pointer. User allocates memory buffer and passes a pointer.\n + * - not uses sting function, but uses memory function (not strcpy, strlen, ... use memcpy, memset, ...).\n + * + * \param[in] pFilePath File name or path to be read in secure storage + * \param[in] bufLen Length of data to be read + * \param[in] flag Type of stored data (data or secret) + * \param[out] readLen Length of data that this function read + * \param[out] pRetBuf Buffer for decrypted data + * \param[in] group_id Sharing group id(string). (NULL if not used) + * + * \return Return Type (integer) \n + * - 0 - Success \n + * - <0 - Fail \n + * + * \par Related functions: + * ssm_get_info() - use in order to know file size + * + * \par Known issues/bugs: + * None + * + * \pre None + * \post None + * \see None + * \remark None + * + * \par Sample code: + * \code + * #include <ss_manager.h> + * + * ... + * + * int ret = -1; + * char *filepath = "/opt/test/input.txt"; + * int buflen = 128; + * ssm_flag flag = SSM_FLAG_DATA; + * char* retbuf = NULL; + * int readlen = 0; + * ssm_file_info_t sfi; + * + * ssm_getinfo(filepath, &sfi, SSM_FLAG_DATA); + * retbuf = (char*)malloc(sizeof(char) * (sfi.originSize + 1)); + * memset(retbuf, 0x00, (sfi.originSize + 1)); + * + * ret = ssm_read(filepath, retbuf, sfi.originSize, &readlen, SSM_FLAG_DATA, NULL); + * free(retbuf); + * + * return ret; // in case of success, return 0. Or fail, return corresponding error code. + * + * ... + * \endcode + * + */ +/*================================================================================================*/ +int ssm_read(const char* pFilePath, char* pRetBuf, size_t bufLen, size_t *readLen, ssm_flag flag, const char* group_id); + +/** + * \par Description: + * Get information of data which will be read. + * + * \par Purpose: + * Use in order to know file statistic information of encrypted file, original file size and encrypted file size. + * + * \par Typical use case: + * When using ssm_read API, user should know the size of original size of encrypted file. In that case, he(or she) can use this API. + * + * \par Method of function operation: + * When encrypting some file, information regarding size of file are saved with encrypted file. In this API, returns that information. + * + * \par Important Notes: + * None + * + * \param[in] pFilePath File name or path of file + * \param[in] flag Type of stored data (data or secret) + * \param[out] sfi Structure of file information + * \param[in] group_id Sharing group id(string). (NULL if not used) + * + * \return Return Type (integer) \n + * - 0 - Success \n + * - <0 - Fail \n + * + * \par Related functions: + * ssm_read() + * + * \par Known issues/bugs: + * None + * + * \pre None + * \post None + * \see None + * \remark None + * + * \par Sample code: + * \code + * #include <ss_manager.h> + * + * ... + * + * int ret = -1; + * char *filepath = "/opt/secure-storage/test/input.txt"; + * ssm_flag flag = SSM_FLAG_DATA; + * ssm_file_info_t sfi; + * + * ret = ssm_getinfo(filepath, &sfi, flag, NULL); + * + * printf(" ** original size: [%d]\n", sfi.originSize); + * printf(" ** stored size: [%d]\n", sfi.storedSize); + * printf(" ** reserved: [%s]\n", sfi.reserved); + * + * return ret; // in case of success, return 0. Or fail, return corresponding error code. + * + * ... + * \endcode + * + */ +/*================================================================================================*/ +int ssm_getinfo(const char* pFilePath, ssm_file_info_t* sfi, ssm_flag flag, const char* group_id); + +/** + * \par Description: + * Delete encrypted file in Secure-storage. + * + * \par Purpose: + * The Secure-storage is the special place, which only ss-server daemon can access. Therefore, in order to delete file, process requests to ss-server. + * + * \par Typical use case: + * When user wants to delete specific file, he(or she) can use this API. + * + * \par Method of function operation: + * All files in secure-storage have unique name. Process will request to delete some file, then ss-server deletes that. + * + * \par Important Notes: + * None + * + * \param[in] pFilePath File path + * \param[in] flag Type of stored data (data or secret) + * \param[in] group_id Sharing group id(string). (NULL if not used) + * + * \return Return Type (integer) \n + * - 0 - Success \n + * - <0 - Fail \n + * + * \par Related functions: + * None + * + * \par Known issues/bugs: + * None + * + * \pre None + * \post None + * \see None + * \remark None + * + * \par Sample code: + * \code + * #include <ss_manager.h> + * + * ... + * + * int ret = -1; + * char *infilepath = "res_write_buf.txt"; + * ssm_flag flag = SSM_FLAG_SECRET_OPERATION; + * + * ret = ssm_delete_file(infilepath, flag, NULL); + * + * return ret; // in case of success, return 0. Or fail, return corresponding error code. + * + * ... + * \endcode + * + */ +/*================================================================================================*/ +int ssm_delete_file(const char* pFilePath, ssm_flag flag, const char* group_id); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +/** + * @} + */ + +#endif diff --git a/libss-client.manifest b/libss-client.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/libss-client.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_"/> + </request> +</manifest> diff --git a/packaging/secure-storage.service b/packaging/secure-storage.service new file mode 100644 index 0000000..d46ceee --- /dev/null +++ b/packaging/secure-storage.service @@ -0,0 +1,10 @@ + +[Unit] +Description=Start the Secure Storage server + +[Service] +ExecStartPre=-/bin/mkdir -p /csa +ExecStart=/usr/bin/ss-server + +[Install] +WantedBy=multi-user.target diff --git a/packaging/secure-storage.spec b/packaging/secure-storage.spec new file mode 100644 index 0000000..a4cd34b --- /dev/null +++ b/packaging/secure-storage.spec @@ -0,0 +1,115 @@ +Name: secure-storage +Summary: Secure storage +Version: 0.12.9 +Release: 3 +Group: System/Security +License: Apache 2.0 +Source0: secure-storage-%{version}.tar.gz +Source1: secure-storage.service +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(dlog) +#BuildRequires: pkgconfig(libsystemd-daemon) +BuildRequires: cmake + +%description +Secure storage package + +%package -n libss-client +Summary: Secure storage (client) +Group: Development/Libraries +Provides: libss-client.so +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libss-client +Secure storage package (client) + +%package -n libss-client-devel +Summary: Secure storage (client-devel) +Group: Development/Libraries +Requires: libss-client = %{version}-%{release} + +%description -n libss-client-devel +Secure storage package (client-devel) + +%package -n ss-server +Summary: Secure storage (ss-server) +Group: Development/Libraries +Requires(preun): /usr/bin/systemctl +Requires(post): /usr/bin/systemctl +Requires(postun): /usr/bin/systemctl +Requires: systemd +Requires: libss-client = %{version}-%{release} + +%description -n ss-server +Secure storage package (ss-server) + +%prep +%setup -q + + +%build +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants +install -m 0644 %{SOURCE1} %{buildroot}%{_libdir}/systemd/system/secure-storage.service +ln -s ../secure-storage.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/secure-storage.service + +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d +ln -s ../init.d/ss-serverd %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S40ss-server +ln -s ../init.d/ss-serverd %{buildroot}%{_sysconfdir}/rc.d/rc5.d/S40ss-server + +mkdir -p %{buildroot}/usr/share/license +cp LICENSE.APLv2 %{buildroot}/usr/share/license/ss-server +cp LICENSE.APLv2 %{buildroot}/usr/share/license/libss-client + +%preun -n ss-server +if [ $1 == 0 ]; then + systemctl stop secure-storage.service +fi + +%post -n ss-server +systemctl daemon-reload +if [ $1 == 1 ]; then + systemctl restart secure-storage.service +fi + +%postun -n ss-server +systemctl daemon-reload + +%post -n libss-client -p /sbin/ldconfig + +%postun -n libss-client -p /sbin/ldconfig + +%files -n ss-server +%manifest ss-server.manifest +%defattr(-,root,root,-) +%attr(0755,root,root) %{_sysconfdir}/rc.d/init.d/ss-serverd +%{_sysconfdir}/rc.d/rc3.d/S40ss-server +%{_sysconfdir}/rc.d/rc5.d/S40ss-server +%{_bindir}/ss-server +%{_libdir}/systemd/system/secure-storage.service +%{_libdir}/systemd/system/multi-user.target.wants/secure-storage.service +%{_datadir}/secure-storage/config +/usr/share/license/ss-server + +%files -n libss-client +%manifest libss-client.manifest +%defattr(-,root,root) +%{_libdir}/libss-client.so.* +/usr/share/license/libss-client + +%files -n libss-client-devel +%defattr(-,root,root,-) +%{_includedir}/ss_manager.h +%{_libdir}/pkgconfig/secure-storage.pc +%{_libdir}/libss-client.so + diff --git a/secure-storage.pc.in b/secure-storage.pc.in new file mode 100644 index 0000000..ae27633 --- /dev/null +++ b/secure-storage.pc.in @@ -0,0 +1,11 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: secure-storage +Description: Secure Storage Package +Version: @VERSION@ +Requires: openssl +Libs: -L${libdir} -lss-client +Cflags: -I${includedir}/secure-storage diff --git a/server/include/ss_server_ipc.h b/server/include/ss_server_ipc.h new file mode 100644 index 0000000..641c075 --- /dev/null +++ b/server/include/ss_server_ipc.h @@ -0,0 +1,30 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +/* + * Declare new function + * + * @name: SsServerComm + * @parameter: void + * @return type: void + */ +void SsServerComm(void); +char* get_key_file_path(void); diff --git a/server/include/ss_server_main.h b/server/include/ss_server_main.h new file mode 100644 index 0000000..2d84c41 --- /dev/null +++ b/server/include/ss_server_main.h @@ -0,0 +1,61 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include "ss_manager.h" + +/* + * Declare new function + * + * @name: SsServerDataStore + * @parameter + * - sender_pid + * - filepath + * @return type: int + */ +int SsServerDataStoreFromFile(int sender_pid, const char* filepath, ssm_flag flag, const char* cookie, const char* group_id); +int SsServerDataStoreFromBuffer(int sender_pid, char* writebuffer, size_t bufLen, const char* filename, ssm_flag flag, const char* cookie, const char* group_id); + +/* + * Declare new function + * + * @name: SsServerDataRead + * @parameter + * - sender_pid + * - filepath + * - pRetBuf + * - count + * - redLen + * @return type: int + */ +int SsServerDataRead(int sender_pid, const char* filepath, char* pRetBuf, unsigned int count, unsigned int* readLen, ssm_flag flag, const char* cookie, const char* group_id); + +/* + * Declare new function + * + * @name: SsServerGetInfo + * @parameter + * - sender_pid + * - filepath + * - file_info + * @return type: int + */ +int SsServerGetInfo(int sender_pid, const char* filepath, char* file_info, ssm_flag flag, const char* cookie, const char* group_id); +int SsServerDeleteFile(int sender_pid, const char* filepath, ssm_flag flag, const char* cookie, const char* group_id); diff --git a/server/src/ss_server_ipc.c b/server/src/ss_server_ipc.c new file mode 100644 index 0000000..bba503e --- /dev/null +++ b/server/src/ss_server_ipc.c @@ -0,0 +1,408 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <sys/un.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <errno.h> +#include <dirent.h> +#include <sys/ioctl.h> +#include <fcntl.h> + +#include "secure_storage.h" +#include "ss_server_ipc.h" +#include "ss_server_main.h" + +#ifdef USE_KEY_FILE +#define CONF_FILE_PATH "/usr/share/secure-storage/config" +#endif // USE_KEY_FILE + +char* get_key_file_path() +{ + FILE* fp_conf = NULL; + char buf[128]; + char* retbuf = NULL; + char seps[] = " :\n\r\t"; + char* token = NULL; + + retbuf = (char*)malloc(sizeof(char) * 128); + if(!retbuf) + { + SLOGE("fail to allocate memory.\n"); + return NULL; + } + memset(buf, 0x00, 128); + memset(retbuf, 0x00, 128); + + if(!(fp_conf = fopen(CONF_FILE_PATH, "r"))) + { + SLOGE("Configuration file is not exist\n"); + free(retbuf); + return NULL; + } + + while(fgets(buf, 128, fp_conf)) + { + token = strtok(buf, seps); + if(!strncmp(token, "MASTER_KEY_PATH", 15)) // master key path + { + token = strtok(NULL, seps); // real path + break; + } + + token = NULL; + } + fclose(fp_conf); + + if(token) + strncpy(retbuf, token, 128); + else { + if(retbuf != NULL) + free(retbuf); + return NULL; + } + + return retbuf; +} + +int check_key_file() +{ + FILE* fp_key = NULL; + char* key_path = NULL; + + key_path = get_key_file_path(); + if(key_path == NULL) + { + SLOGE("Configuration file is not exist\n"); + return 0; + } + + if(!(fp_key = fopen(key_path, "r"))) + { + SLOGE("Secret key file is not exist, [%s]\n", key_path); + free(key_path); + return 0; + } + + free(key_path); + fclose(fp_key); + return 1; +} + +int make_key_file() +{ + FILE* fp_key = NULL; + int random_dev = -1; + int i = 0; + char tmp_key[1]; + char key[33]; + char* key_path = NULL; + + memset(key, 0x00, 33); + + key_path = get_key_file_path(); + if(key_path == NULL) + { + SLOGE("Configuration file is not exist\n"); + return 0; + } + + if((random_dev = open("/dev/urandom", O_RDONLY)) < 0) + { + SLOGE("Random device Open error\n"); + free(key_path); + return 0; + } + + while(i < 32) + { + read(random_dev, tmp_key, 1); + + if((tmp_key[0] >= '!') && (tmp_key[0] <= '~')) { + key[i] = tmp_key[0]; + i++; + } + } + + if(!(fp_key = fopen(key_path, "w"))) + { + SLOGE("Secret key file Open error, [%s]\n", key_path); + free(key_path); + close(random_dev); + return 0; + } + + fprintf(fp_key, "%s", key); + chmod(key_path, 0600); + + free(key_path); + fclose(fp_key); + close(random_dev); + return 1; +} + +/* for executing coverage tool (2009-04-03) */ +void SigHandler(int signo) +{ + SLOGI("Got Signal %d\n", signo); + exit(1); +} +/* end */ + +void SsServerComm(void) +{ + int server_sockfd, client_sockfd; + int client_len; + struct sockaddr_un clientaddr, serveraddr; + + struct ucred cr; // for test client pid. 2009-03-24 + int cl = sizeof(cr); // + int temp_len_sock = 0; + int temp_len_in = 0; + + ReqData_t recv_data = {0, }; + RspData_t send_data = {0, }; + + client_len = sizeof(clientaddr); + + server_sockfd = client_sockfd = -1; + + if((server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + SLOGE("Error in function socket()..\n"); + send_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_exit; + } + + temp_len_sock = strlen(SS_SOCK_PATH); + + bzero(&serveraddr, sizeof(serveraddr)); + serveraddr.sun_family = AF_UNIX; + strncpy(serveraddr.sun_path, SS_SOCK_PATH, temp_len_sock); + serveraddr.sun_path[temp_len_sock] = '\0'; + + if((bind(server_sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr))) < 0) + { + unlink("/tmp/SsSocket"); + if((bind(server_sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr))) < 0) + { + SLOGE("Error in function bind()..\n"); + send_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_close_exit; + } + } + + if(chmod(SS_SOCK_PATH, S_IRWXU | S_IRWXG | S_IRWXO) != 0) + { + send_data.rsp_type = SS_SOCKET_ERROR; + goto Error_close_exit; + } + + if((listen(server_sockfd, 5)) < 0) + { + SLOGE("Error in function listen()..\n"); + send_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_close_exit; + } + + signal(SIGINT, (void*)SigHandler); + + while(1) + { + errno = 0; + + if((client_sockfd = accept(server_sockfd, (struct sockaddr*)&clientaddr, (socklen_t*)&client_len)) < 0) + { + SLOGE("Error in function accept()..[%d, %d]\n", client_sockfd, errno); + send_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_close_exit; + } + + // for test client pid. 2009-03-24 + if(getsockopt(client_sockfd, SOL_SOCKET, SO_PEERCRED, &cr, (socklen_t*)&cl) != 0) + { + SLOGE("getsockopt() fail\n"); + } + // end + + if(read(client_sockfd, (char*)&recv_data, sizeof(recv_data)) < 0) + { + SLOGE("Error in function read()..\n"); + send_data.rsp_type = SS_SOCKET_ERROR; // ipc error + goto Error_close_exit; + } + + temp_len_in = strlen(recv_data.data_infilepath); + + switch(recv_data.req_type) + { + case 1: + send_data.rsp_type = SsServerDataStoreFromFile(cr.pid, recv_data.data_infilepath, recv_data.flag, recv_data.cookie, recv_data.group_id); + + if(send_data.rsp_type == 1) + { + strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_LEN - 1); + send_data.data_filepath[temp_len_in] = '\0'; + } + else + { + strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_LEN - 1); + send_data.data_filepath[15] = '\0'; + } + + write(client_sockfd, (char*)&send_data, sizeof(send_data)); + break; + case 2: + send_data.rsp_type = SsServerDataStoreFromBuffer(cr.pid, recv_data.buffer, recv_data.count, recv_data.data_infilepath, recv_data.flag, recv_data.cookie, recv_data.group_id); + + if(send_data.rsp_type == 1) + { + strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_LEN - 1); + send_data.data_filepath[temp_len_in] = '\0'; + } + else + { + strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_LEN - 1); + send_data.data_filepath[15] = '\0'; + } + + write(client_sockfd, (char*)&send_data, sizeof(send_data)); + break; + case 3: + send_data.rsp_type = SsServerDataRead(cr.pid, recv_data.data_infilepath, send_data.buffer, recv_data.count, &(send_data.readLen), recv_data.flag, recv_data.cookie, recv_data.group_id); + + if(send_data.rsp_type == 1) + { + strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_LEN - 1); + send_data.data_filepath[temp_len_in] = '\0'; + } + else + { + strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_LEN - 1); + send_data.data_filepath[15] = '\0'; + } + + write(client_sockfd, (char*)&send_data, sizeof(send_data)); + break; + case 4: + send_data.rsp_type = SsServerGetInfo(cr.pid, recv_data.data_infilepath, send_data.buffer, recv_data.flag, recv_data.cookie, recv_data.group_id); + + if(send_data.rsp_type == 1) + { + strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_LEN - 1); + send_data.data_filepath[temp_len_in] = '\0'; + } + else + { + strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_LEN - 1); + send_data.data_filepath[15] = '\0'; + } + + write(client_sockfd, (char*)&send_data, sizeof(send_data)); + break; + case 10: + send_data.rsp_type = SsServerDeleteFile(cr.pid, recv_data.data_infilepath, recv_data.flag, recv_data.cookie, recv_data.group_id); + + if(send_data.rsp_type == 1) + { + strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_LEN - 1); + send_data.data_filepath[temp_len_in] = '\0'; + } + else + { + strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_LEN - 1); + send_data.data_filepath[15] = '\0'; + } + + write(client_sockfd, (char*)&send_data, sizeof(send_data)); + break; + + default: + SLOGE("Input error..Please check request type\n"); + break; + } + close(client_sockfd); + } + +Error_close_exit: + close(server_sockfd); + +Error_exit: + strncpy(send_data.data_filepath, "error", MAX_FILENAME_LEN - 1); + send_data.data_filepath[5] = '\0'; + + if(client_sockfd >= 0) + { + write(client_sockfd, (char*)&send_data, sizeof(send_data)); + close(client_sockfd); + } + else + SLOGE("cannot connect to client socket.\n"); +} + +int main(void) +{ + SLOGI("Secure Storage Server Start..\n"); + +#ifdef USE_KEY_FILE + int exist_ret = -1; + int make_ret = -1; +#endif // USE_KEY_FILE + DIR* dp = NULL; // make default directory(if not exist) + + if((dp = opendir(SS_STORAGE_DEFAULT_PATH)) == NULL) + { + SLOGI("directory [%s] is not exist, making now.\n", SS_STORAGE_DEFAULT_PATH); + if(mkdir(SS_STORAGE_DEFAULT_PATH, 0700) < 0) + { + int err_tmp = errno; + SLOGE("Failed while making [%s] directory. Errno: %s\n", SS_STORAGE_DEFAULT_PATH, strerror(err_tmp)); + return 0; + } + } + else + closedir(dp); + +#ifdef USE_KEY_FILE + exist_ret = check_key_file(); // if 0, there is not key file. Or 1, exist. + + if(exist_ret == 0) + { + make_ret = make_key_file(); + + if(make_ret == 0) + { + SLOGE("Making key file fail. ss-server will be terminated..\n"); + return 0; + } + } +#endif // USE_KEY_FILE + + SsServerComm(); + + return 0; +} diff --git a/server/src/ss_server_main.c b/server/src/ss_server_main.c new file mode 100644 index 0000000..e9682bc --- /dev/null +++ b/server/src/ss_server_main.c @@ -0,0 +1,819 @@ +/* + * secure storage + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Kidong Kim <kd0228.kim@samsung.com> + * + * 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. + * + */ + +/* encrypted file format + * + * total file size = metadata (8 bytes) + realdata (...) + * ----------------------------------------------------------- + * | metadata | realdata | + * ----------------------------------------------------------- + * 0 16 EOF + * metadata -> ssm_file_info_t + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/time.h> +#include <unistd.h> +#include <dirent.h> +#include <errno.h> + +#include <openssl/aes.h> +#include <openssl/sha.h> + +#include "secure_storage.h" +#include "ss_server_main.h" +#include "ss_server_ipc.h" + +#ifdef USE_KEY_FILE +#define CONF_FILE_PATH "/usr/share/secure-storage/config" +#endif // USE_KEY_FILE + +#define ENCRYPT_SIZE 1024 + +/* skey : need to help from hardware */ +char skey[16+1] = "thisisasecretkey"; + +/*************************************************************************** + * Internal functions + **************************************************************************/ + +char* get_preserved_dir() +{ + FILE* fp_conf = NULL; + char buf[128]; + char* retbuf = NULL; + char seps[] = " :\n\r\t"; + char* token = NULL; + + retbuf = (char*)malloc(sizeof(char) * 128); + if(retbuf == NULL) + { + SLOGE("malloc return NULL\n"); + return NULL; + } + memset(buf, 0x00, 128); + memset(retbuf, 0x00, 128); + + if(!(fp_conf = fopen(CONF_FILE_PATH, "r"))) + { + SLOGE("Configuration file is not exist\n"); + free(retbuf); + return NULL; + } + + while(fgets(buf, 128, fp_conf)) + { + token = strtok(buf, seps); + if(!strncmp(token, "PRESERVE_DIR", 12)) // preserve directory? + { + token = strtok(NULL, seps); // real path + break; + } + + token = NULL; + } + fclose(fp_conf); + + if(token) + strncpy(retbuf, token, 127); + else { + free(retbuf); + return NULL; + } + + return retbuf; +} + +/* get key from hardware( ex. OMAP e-fuse random key ) */ +void GetKey(char* key, unsigned char* iv) +{ +#ifdef USE_KEY_FILE + FILE* fp_key = NULL; + char buf[33]; + char* key_path = NULL; + + memset(buf, 0x00, 33); + + key_path = get_key_file_path(); + if(key_path == NULL) + { + SLOGE("Configuration file is not exist\n"); + memcpy(buf, skey, 16); + } + else + { + if(!(fp_key = fopen(key_path, "r"))) + { + SLOGE("Secret key file opening error\n"); + memcpy(buf, skey, 16); + } + else + { + if(!fgets(buf, 33, fp_key)) + { + SLOGE("Secret key file reading error\n"); + memcpy(buf, skey, 16); // if fail to get key, set to default value. + } + } + } + + if(key) + strncpy(key, buf, 16); + if(iv) + strncpy(iv, buf+16, 16); + + if(key_path) + free(key_path); + if(fp_key) + fclose(fp_key); + +#else + if(key) + memcpy(key, skey, 16); + if(iv) + memcpy(iv, 0x00, 16); +#endif // USE_KEY_FILE +} + +unsigned short GetHashCode(const unsigned char* pString) +{ + unsigned short hash = 5381; + int len = SHA_DIGEST_LENGTH; + int i; + + for(i = 0; i < len; i++) + { + hash = ((hash << 5) + hash) + (unsigned short)pString[i]; // hash * 33 + ch + } + + return hash; +} + +int IsDirExist(char* dirpath) +{ + DIR* dp = NULL; + + if((dp = opendir(dirpath)) == NULL) // dir is not exist + { + SLOGE("directory [%s] is not exist.\n", dirpath); + return 0; // return value '0' represents dir is not exist + } + else + { + closedir(dp); + return 1; + } + + return -1; +} + +int check_privilege(const char* cookie, const char* group_id) +{ +// int ret = -1; // if success, return 0 +// int gid = -1; + +// if(!strncmp(group_id, "NOTUSED", 7)) // group_id is NULL +// return 0; +// else +// { +// gid = security_server_get_gid(group_id); +// ret = security_server_check_privilege(cookie, gid); +// } + +// return ret; + return 0; // success always +} + +/* convert normal file path to secure storage file path */ +int ConvertFileName(int sender_pid, char* dest, const char* src, ssm_flag flag, const char* group_id) +{ + char* if_pointer = NULL; + unsigned short h_code = 0; + unsigned short h_code2 = 0; + unsigned char path_hash[SHA_DIGEST_LENGTH + 1]; + char s[33+1]; + const char* dir = NULL; + char tmp_cmd[32] = {0, }; + char tmp_buf[10] = {0, }; + const unsigned char exe_path[256] = {0, }; + FILE* fp_proc = NULL; + char* preserved_dir = NULL; + int is_dir_exist = -1; + + if(!dest || !src) + { + SLOGE("Parameter error in ConvertFileName()...\n"); + return SS_FILE_OPEN_ERROR; // file related error + } + + memset(tmp_cmd, 0x00, 32); + snprintf(tmp_cmd, 32, "/proc/%d/cmdline", sender_pid); + + if(!(fp_proc = fopen(tmp_cmd, "r"))) + { + SLOGE("file open error: [%s]", tmp_cmd); + return SS_FILE_OPEN_ERROR; + } + + fgets((char*)exe_path, 256, fp_proc); + fclose(fp_proc); + + if(!strncmp(group_id, "NOTUSED", 7)) // don't share + { + h_code2 = GetHashCode(exe_path); + memset(tmp_buf, 0x00, 10); + snprintf(tmp_buf, 10, "%u", h_code2); + dir = tmp_buf; + } + else // share + dir = group_id; + + if_pointer = strrchr(src, '/'); + + if(flag == SSM_FLAG_DATA) // /opt/share/secure-storage/* + { + // check whether directory is exist or not + is_dir_exist = IsDirExist(SS_STORAGE_DEFAULT_PATH); + + if (is_dir_exist == 0) // SS_STORAGE_FILE_PATH is not exist + { + SLOGI("directory [%s] is making now.\n", SS_STORAGE_DEFAULT_PATH); + if(mkdir(SS_STORAGE_DEFAULT_PATH, 0700) < 0) // fail to make directory + { + SLOGE("[%s] cannot be made\n", SS_STORAGE_DEFAULT_PATH); + return SS_FILE_OPEN_ERROR; + } + } + else if (is_dir_exist == -1) // Unknown error + { + SLOGE("Unknown error in the function IsDirExist().\n"); + return SS_PARAM_ERROR; + } + + // TBD + strncpy(dest, SS_STORAGE_DEFAULT_PATH, MAX_FILENAME_LEN - 1); + strncat(dest, dir, (strlen(dest) - 1)); + strncat(dest, "/", 1); + + // make directory + dest[strlen(SS_STORAGE_DEFAULT_PATH) + strlen(dir) + 2] = '\0'; + is_dir_exist = IsDirExist(dest); + + if(is_dir_exist == 0) // not exist + { + SLOGI("%s is making now.\n", dest); + if(mkdir(dest, 0700) < 0) // fail to make directory + { + SLOGE("[%s] cannot be made\n", dest); + return SS_FILE_OPEN_ERROR; + } + } + + strncat(dest, if_pointer + 1, strlen(if_pointer) + 1); + strncat(dest, "_", 1); + + SHA1((unsigned char*)src, (size_t)strlen(src), path_hash); + h_code = GetHashCode(path_hash); + memset(s, 0x00, 34); + snprintf(s, 34, "%u", h_code); + strncat(dest, s, strlen(s)); + strncat(dest, SS_FILE_POSTFIX, strlen(SS_FILE_POSTFIX)); + + dest[strlen(SS_STORAGE_DEFAULT_PATH) + strlen(dir) + strlen(if_pointer) + strlen(s) + strlen(SS_FILE_POSTFIX) + 4] = '\0'; + } + else if(flag == SSM_FLAG_SECRET_PRESERVE) // /tmp/csa/ + { + preserved_dir = get_preserved_dir(); + if(preserved_dir == NULL) // fail to get preserved directory + { + SLOGE("fail to get preserved dir\n"); + return SS_FILE_OPEN_ERROR; + } + + if(strncmp(src, preserved_dir, strlen(preserved_dir)) == 0) //src[0] == '/') + { + strncpy(dest, src, MAX_FILENAME_LEN - 1); + strncat(dest, SS_FILE_POSTFIX, strlen(SS_FILE_POSTFIX)); + + dest[strlen(src) + strlen(SS_FILE_POSTFIX)] = '\0'; + } + else if(if_pointer != NULL) // absolute path == file + { + strncpy(dest, preserved_dir, MAX_FILENAME_LEN - 1); + strncat(dest, if_pointer + 1, strlen(if_pointer) + 1); + strncat(dest, SS_FILE_POSTFIX, strlen(SS_FILE_POSTFIX)); + dest[strlen(preserved_dir) + strlen(if_pointer) + strlen(SS_FILE_POSTFIX) + 1] = '\0'; + } + else // relative path == buffer + { + strncpy(dest, preserved_dir, MAX_FILENAME_LEN - 1); + strncat(dest, src, strlen(src)); + strncat(dest, SS_FILE_POSTFIX, strlen(SS_FILE_POSTFIX)); + dest[strlen(preserved_dir) + strlen(src) + strlen(SS_FILE_POSTFIX)] = '\0'; + } + + free(preserved_dir); + + } + else if(flag == SSM_FLAG_SECRET_OPERATION) // /opt/share/secure-storage/ + { + if(if_pointer != NULL) // absolute path == input is a file + { + // check whether directory is exist or not + is_dir_exist = IsDirExist(SS_STORAGE_DEFAULT_PATH); + + if (is_dir_exist == 0) // SS_STORAGE_FILE_PATH is not exist + { + SLOGI("%s is making now.\n", SS_STORAGE_DEFAULT_PATH); + if(mkdir(SS_STORAGE_DEFAULT_PATH, 0700) < 0) // fail to make directory + { + SLOGE("[%s] cannnot be made\n", SS_STORAGE_DEFAULT_PATH); + return SS_FILE_OPEN_ERROR; + } + } + else if (is_dir_exist == -1) // Unknown error + { + SLOGE("Unknown error in the function IsDirExist().\n"); + return SS_PARAM_ERROR; + } + + strncpy(dest, SS_STORAGE_DEFAULT_PATH, MAX_FILENAME_LEN - 1); + strncat(dest, dir, strlen(dir)); + strncat(dest, "/", 1); + + // make directory + dest[strlen(SS_STORAGE_DEFAULT_PATH) + strlen(dir) + 2] = '\0'; + is_dir_exist = IsDirExist(dest); + + if(is_dir_exist == 0) // not exist + { + SLOGI("%s is making now.\n", dest); + if(mkdir(dest, 0700) < 0) + { + SLOGE("[%s] cannot be made\n", dest); + return SS_FILE_OPEN_ERROR; + } + } + + strncat(dest, if_pointer + 1, strlen(if_pointer) + 1); + strncat(dest, "_", 1); + SHA1((unsigned char*)src, (size_t)strlen(src), path_hash); + h_code = GetHashCode(path_hash); + memset(s, 0x00, 34); + snprintf(s, 34, "%u", h_code); + strncat(dest, s, strlen(s)); + strncat(dest, SS_FILE_POSTFIX, strlen(SS_FILE_POSTFIX)); + + dest[strlen(SS_STORAGE_DEFAULT_PATH) + strlen(dir) + strlen(if_pointer) + strlen(s) + strlen(SS_FILE_POSTFIX) + 4] = '\0'; + } + else // relative path == input is a buffer + { + // check whether directory is exist or not + is_dir_exist = IsDirExist(SS_STORAGE_DEFAULT_PATH); + + if (is_dir_exist == 0) // SS_STORAGE_BUFFER_PATH is not exist + { + SLOGI("%s is making now.\n", SS_STORAGE_DEFAULT_PATH); + if(mkdir(SS_STORAGE_DEFAULT_PATH, 0700) < 0) + { + SLOGE("[%s] cannot be made\n", SS_STORAGE_DEFAULT_PATH); + return SS_FILE_OPEN_ERROR; + } + } + else if (is_dir_exist == -1) // Unknown error + { + SLOGE("Unknown error in the function IsDirExist().\n"); + return SS_PARAM_ERROR; + } + + strncpy(dest, SS_STORAGE_DEFAULT_PATH, MAX_FILENAME_LEN - 1); + strncat(dest, dir, strlen(dir)); + strncat(dest, "/", 1); + + // make directory + dest[strlen(SS_STORAGE_DEFAULT_PATH) + strlen(dir) + 2] = '\0'; + is_dir_exist = IsDirExist(dest); + + if(is_dir_exist == 0) // not exist + { + SLOGI("%s is making now.\n", dest); + if(mkdir(dest, 0700) < 0) + { + SLOGE("[%s] cannot be made\n", dest); + return SS_FILE_OPEN_ERROR; + } + } + + strncat(dest, src, strlen(src)); + strncat(dest, SS_FILE_POSTFIX, strlen(SS_FILE_POSTFIX)); + + dest[strlen(SS_STORAGE_DEFAULT_PATH) + strlen(dir) + strlen(src) + strlen(SS_FILE_POSTFIX) + 2] = '\0'; + } + } + else + { + SLOGE("flag mispatch. cannot convert file name.\n"); + return SS_PARAM_ERROR; + } + + return 1; +} + +/* aes crypto function wrapper - p_text : plain text, c_text : cipher text, aes_key : from GetKey, mode : ENCRYPT/DECRYPT, size : data size */ +unsigned char* AES_Crypto(unsigned char* p_text, unsigned char* c_text, char* aes_key, unsigned char* iv, int mode, unsigned long size) +{ + AES_KEY e_key, d_key; + + AES_set_encrypt_key((unsigned char*)aes_key, 128, &e_key); + AES_set_decrypt_key((unsigned char*)aes_key, 128, &d_key); + + if(mode == 1) + { + AES_cbc_encrypt(p_text, c_text, size, &e_key, iv, AES_ENCRYPT); + return c_text; + } + else + { + AES_cbc_encrypt(c_text, p_text, size, &d_key, iv, AES_DECRYPT); + return p_text; + } +} + + +/*************************************************************************** + * Function Definition + **************************************************************************/ + +int SsServerDataStoreFromFile(int sender_pid, const char* data_filepath, ssm_flag flag, const char* cookie, const char* group_id) +{ + char key[16] = {0, }; + unsigned char iv[16] = {0, }; + const char* in_filepath = data_filepath; + char out_filepath[MAX_FILENAME_LEN] = {0, }; + FILE* fd_in = NULL; + FILE* fd_out = NULL; + struct stat file_info; + ssm_file_info_convert_t sfic; + int res = -1; + + unsigned char p_text[ENCRYPT_SIZE]= {0, }; + unsigned char e_text[ENCRYPT_SIZE]= {0, }; + + size_t read = 0, rest = 0; + + //0. privilege check and get directory name + if(check_privilege(cookie, group_id) != 0) + { + SLOGE("[%s] permission denied\n", group_id); + return SS_PERMISSION_DENIED; + } + + // 1. create out file name + ConvertFileName(sender_pid, out_filepath, in_filepath, flag, group_id); + + // 2. file open + if(!(fd_in = fopen(in_filepath, "rb"))) + { + SLOGE("File open error:(in_filepath) %s\n", in_filepath); + return SS_FILE_OPEN_ERROR; // file related error + } + + if(!(fd_out = fopen(out_filepath, "wb"))) + { + SLOGE("File open error:(out_filepath) %s\n", out_filepath); + fclose(fd_in); + return SS_FILE_OPEN_ERROR; // file related error + } + if(chmod(out_filepath, 0600) < 0) + { + int err_tmp = errno; + SLOGE("chmod error: %s\n", strerror(err_tmp)); + fclose(fd_in); + fclose(fd_out); + return SS_FILE_OPEN_ERROR; // file related error + } + + // 3. write metadata + if(!stat(in_filepath, &file_info)) + { + sfic.fInfoStruct.originSize = (unsigned int)file_info.st_size; + sfic.fInfoStruct.storedSize = (unsigned int)(sfic.fInfoStruct.originSize/AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE; + sfic.fInfoStruct.reserved[0] = flag & 0x000000ff; + } + else + { + SLOGE("the function stat() fail.\n"); + fclose(fd_in); + fclose(fd_out); + return SS_FILE_READ_ERROR; + } + + fwrite(sfic.fInfoArray, 1, sizeof(ssm_file_info_t), fd_out); + + // 4. encrypt real data + read = fread(p_text, 1, ENCRYPT_SIZE, fd_in); + GetKey(key, iv); + + while(read == ENCRYPT_SIZE) + { + AES_Crypto(p_text, e_text, key, iv, 1, ENCRYPT_SIZE); + + fwrite(e_text, 1, ENCRYPT_SIZE, fd_out); + + memset(e_text, 0x00, ENCRYPT_SIZE); + memset(p_text, 0x00, ENCRYPT_SIZE); + read = fread( p_text, 1, ENCRYPT_SIZE, fd_in ); + } + + rest = AES_BLOCK_SIZE - (read % AES_BLOCK_SIZE); + AES_Crypto(p_text, e_text, key, iv, 1, read+rest); + fwrite(e_text, 1, read + rest, fd_out); + + if((res = fflush(fd_out)) != 0) { + SLOGE("fail to execute fflush().\n"); + fclose(fd_in); + fclose(fd_out); + return SS_FILE_WRITE_ERROR; + } + else { + SLOGI("success to execute fflush().\n"); + if((res = fsync(fd_out->_fileno)) == -1) { + SLOGE("fail to execute fsync().\n"); + fclose(fd_in); + fclose(fd_out); + return SS_FILE_WRITE_ERROR; + } + else + SLOGI("success to execute fsync(). read=[%d], rest=[%d]\n", read, rest); + } + + fclose(fd_in); + fclose(fd_out); + + return 1; +} + +int SsServerDataStoreFromBuffer(int sender_pid, char* writebuffer, size_t bufLen, const char* filename, ssm_flag flag, const char* cookie, const char* group_id) +{ + char key[16] = {0, }; + unsigned char iv[16] = {0, }; + char out_filepath[MAX_FILENAME_LEN+1]; + char *buffer = NULL; + unsigned int writeLen = 0, loop, rest, count; + FILE *fd_out = NULL; + ssm_file_info_convert_t sfic; + unsigned char p_text[ENCRYPT_SIZE]= {0, }; + unsigned char e_text[ENCRYPT_SIZE]= {0, }; + int res = -1; + + writeLen = (unsigned int)(bufLen / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE; + buffer = (char*)malloc(writeLen + 1); + if(!buffer) + { + SLOGE("Memory Allocation Fail in SsServerDataStoreFromBuffer()..\n"); + return SS_MEMORY_ERROR; + } + memset(buffer, 0x00, writeLen); + memcpy(buffer, writebuffer, bufLen); + + //0. privilege check and get directory name + if(check_privilege(cookie, group_id) != 0) + { + SLOGE("permission denied\n"); + free(buffer); + return SS_PERMISSION_DENIED; + } + + // create file path from filename + ConvertFileName(sender_pid, out_filepath, filename, flag, group_id); + + // open a file with write mode + if(!(fd_out = fopen(out_filepath, "wb"))) + { + SLOGE("File open error:(out_filepath) %s\n", out_filepath); + free(buffer); + return SS_FILE_OPEN_ERROR; // file related error + } + if(chmod(out_filepath, 0600) < 0) + { + int err_tmp = errno; + SLOGE("chmod error: %s\n", strerror(err_tmp)); + free(buffer); + fclose(fd_out); + return SS_FILE_OPEN_ERROR; // file related error + } + + // write metadata + sfic.fInfoStruct.originSize = (unsigned int)bufLen; + sfic.fInfoStruct.storedSize = writeLen; + sfic.fInfoStruct.reserved[0] = flag & 0x000000ff; + + fwrite(sfic.fInfoArray, 1, sizeof(ssm_file_info_t), fd_out); + + // encrypt buffer + loop = writeLen / ENCRYPT_SIZE; + rest = writeLen % ENCRYPT_SIZE; + GetKey(key, iv); + + for(count = 0; count < loop; count++) + { + memcpy(p_text, buffer+count*ENCRYPT_SIZE, ENCRYPT_SIZE); + AES_Crypto( p_text, e_text, key, iv, 1, ENCRYPT_SIZE); + fwrite(e_text, 1, ENCRYPT_SIZE, fd_out); + memset(e_text, 0x00, ENCRYPT_SIZE); + memset(p_text, 0x00, ENCRYPT_SIZE); + } + + memcpy(p_text, buffer + loop*ENCRYPT_SIZE, rest); + AES_Crypto(p_text, e_text, key, iv, 1, rest); + fwrite(e_text, 1, rest, fd_out); + + if((res = fflush(fd_out)) != 0) { + SLOGE("fail to execute fflush().\n"); + fclose(fd_out); + free(buffer); + return SS_FILE_WRITE_ERROR; + } + else { + SLOGI("success to execute fflush().\n"); + if((res = fsync(fd_out->_fileno)) == -1) { + SLOGE("fail to execute fsync().\n"); + fclose(fd_out); + free(buffer); + return SS_FILE_WRITE_ERROR; + } + else + SLOGI("success to execute fsync(). loop=[%d], rest=[%d]\n", loop, rest); + } + + fclose(fd_out); + free(buffer); + + return 1; +} + +int SsServerDataRead(int sender_pid, const char* data_filepath, char* pRetBuf, unsigned int count, unsigned int* readLen, ssm_flag flag, const char* cookie, const char* group_id) +{ + unsigned int offset = count * MAX_RECV_DATA_LEN; + char key[16] = {0, }; + unsigned char iv[16] = {0, }; + char in_filepath[MAX_FILENAME_LEN] = {0, }; + FILE* fd_in = NULL; + char *out_data = pRetBuf; + unsigned char p_text[ENCRYPT_SIZE]= {0, }; + unsigned char e_text[ENCRYPT_SIZE]= {0, }; + size_t read = 0; + + *readLen = 0; + + //0. privilege check and get directory name + if(check_privilege(cookie, group_id) != 0) + { + SLOGE("permission denied\n"); + return SS_PERMISSION_DENIED; + } + + // 1. create in file name : convert file name in order to access secure storage + if(flag == SSM_FLAG_WIDGET) + strncpy(in_filepath, data_filepath, MAX_FILENAME_LEN - 1); + else + ConvertFileName(sender_pid, in_filepath, data_filepath, flag, group_id); + + // 2. open file + if(!(fd_in = fopen(in_filepath, "rb"))) + { + SLOGE("File open error:(in_filepath) %s\n", in_filepath); + return SS_FILE_OPEN_ERROR; // file related error + } + + // 3. skip to offset + if(fseek(fd_in, (long)offset + sizeof(ssm_file_info_t), SEEK_SET) < 0) + { + int err_tmp = errno; + SLOGE("Fseek error: %s in %s\n", strerror(err_tmp), in_filepath); + fclose(fd_in); + return SS_FILE_OPEN_ERROR; // file related error + } + + // 4. decrypt data + GetKey(key, iv); + + read = fread(e_text, 1, ENCRYPT_SIZE, fd_in); + + while((read == ENCRYPT_SIZE)) + { + AES_Crypto(p_text, e_text, key, iv, 0, ENCRYPT_SIZE) ; + + memcpy(out_data, p_text, ENCRYPT_SIZE); + out_data += ENCRYPT_SIZE; + *readLen += ENCRYPT_SIZE; + + if(*readLen == MAX_RECV_DATA_LEN) + goto Last; + + memset(p_text, 0x00, ENCRYPT_SIZE); + memset(e_text, 0x00, ENCRYPT_SIZE); + + read = fread(e_text, 1, ENCRYPT_SIZE, fd_in); + } + + AES_Crypto(p_text, e_text, key, iv, 0, read) ; + + memcpy(out_data, p_text, read); + out_data += read; + *readLen += read; +Last: + *out_data = '\0'; + + fclose(fd_in); + + return 1; +} + +int SsServerDeleteFile(int sender_pid, const char* data_filepath, ssm_flag flag, const char* cookie, const char* group_id) +{ + const char* in_filepath = data_filepath; + char out_filepath[MAX_FILENAME_LEN] = {0, }; + + //0. privilege check and get directory name + if(check_privilege(cookie, group_id) != 0) + { + SLOGE("permission denied\n"); + return SS_PERMISSION_DENIED; + } + + // 1. create out file name + ConvertFileName(sender_pid, out_filepath, in_filepath, flag, group_id); + + // 2. delete designated file + if(unlink(out_filepath) != 0) // unlink fail? + { + SLOGE("error occured while deleting file\n"); + return SS_FILE_WRITE_ERROR; + } + + return 1; +} + +int SsServerGetInfo(int sender_pid, const char* data_filepath, char* file_info, ssm_flag flag, const char* cookie, const char* group_id) +{ + size_t read = 0; + FILE *fd_in = NULL; + char in_filepath[MAX_FILENAME_LEN] = {0, }; + + //0. privilege check and get directory name + if(check_privilege(cookie, group_id) != 0) + { + SLOGE("permission denied, [%s]\n", group_id); + return SS_PERMISSION_DENIED; + } + + // 1. create in file name : convert file name in order to access secure storage + if(flag == SSM_FLAG_WIDGET) + strncpy(in_filepath, data_filepath, MAX_FILENAME_LEN - 1); + else + ConvertFileName(sender_pid, in_filepath, data_filepath, flag, group_id); + + // 1. open file + if(!(fd_in = fopen( in_filepath, "rb"))) + { + SLOGE("File open error:(in_filepath) [%s], [%s]\n", data_filepath, in_filepath ); + return SS_FILE_OPEN_ERROR; // file related error + } + + // 2. read metadata field - first 8 bytes + read = fread(file_info, 1, sizeof(ssm_file_info_t), fd_in); + + if(read != sizeof(ssm_file_info_t)) + { + fclose(fd_in); + return SS_FILE_READ_ERROR; + } + + fclose(fd_in); + return 1; +} diff --git a/ss-server.manifest b/ss-server.manifest new file mode 100644 index 0000000..f4da9b9 --- /dev/null +++ b/ss-server.manifest @@ -0,0 +1,13 @@ +<manifest> + <define> + <domain name="secure-storage"/> + </define> + <request> + <domain name="secure-storage"/> + </request> + <assign> + <filesystem path="/etc/rc.d/init.d/ss-serverd" label="_" exec_label="none" /> + <filesystem path="/etc/rc.d/rc3.d/S40ss-server" label="_" exec_label="none" /> + <filesystem path="/etc/rc.d/rc5.d/S40ss-server" label="_" exec_label="none" /> + </assign> +</manifest> diff --git a/ss-serverd b/ss-serverd new file mode 100755 index 0000000..79132e9 --- /dev/null +++ b/ss-serverd @@ -0,0 +1,4 @@ +#!/bin/sh + +# start secure-storage server +/usr/bin/ss-server & |