summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKyungwook Tak <k.tak@samsung.com>2016-12-07 17:22:40 +0900
committerKyungwook Tak <k.tak@samsung.com>2016-12-08 15:09:41 +0900
commit66f4515064566676869fd3c3a8970fcf24b00b5f (patch)
treeab44c28901de718ad736b8e0517d591b50961eef /tests
parent9efcb91aed4e7365aa945fc9c6ffe2d111ca1496 (diff)
downloadlibwebappenc-66f4515064566676869fd3c3a8970fcf24b00b5f.tar.gz
libwebappenc-66f4515064566676869fd3c3a8970fcf24b00b5f.tar.bz2
libwebappenc-66f4515064566676869fd3c3a8970fcf24b00b5f.zip
Remove reload option to wae initializer service
Reload option is not needed anymore. To be secure, remove all KEKs from dek store (also adek) after loading preloaded adeks once. Loaded adeks are stored in key-manager so they're useless. Related test cases are added. (load preloaded app deks) (TODO) To use key-manager initial value feature is highly considered to store KEK private key more securely. Change-Id: I2f6c645398277968cd7d480236d1802a07fa33df Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/internals.cpp103
-rw-r--r--tests/resources/CMakeLists.txt19
-rw-r--r--tests/resources/prikey.pem30
-rw-r--r--tests/resources/pubkey.pem9
-rw-r--r--tests/test-helper.cpp72
-rw-r--r--tests/test-helper.h3
7 files changed, 217 insertions, 21 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7c9e2c9..07d2082 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -97,3 +97,5 @@ INSTALL(TARGETS ${TARGET_WAE_TEST}
WORLD_READ
WORLD_EXECUTE
)
+
+ADD_SUBDIRECTORY(resources)
diff --git a/tests/internals.cpp b/tests/internals.cpp
index 1fa9aff..7a13df7 100644
--- a/tests/internals.cpp
+++ b/tests/internals.cpp
@@ -24,7 +24,12 @@
#include <string>
#include <cstring>
+#include <functional>
+#include <memory>
+#include <fstream>
#include <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
#include <boost/test/unit_test.hpp>
@@ -32,6 +37,7 @@
#include "crypto_service.h"
#include "test-common.h"
+#include "test-helper.h"
namespace {
@@ -76,7 +82,7 @@ crypto_element_s *_create_ce(void)
return ce;
}
-}
+} // namespace anonymous
BOOST_AUTO_TEST_SUITE(SYSTEM)
@@ -261,6 +267,15 @@ BOOST_AUTO_TEST_CASE(read_write_encrypted_app_dek)
BOOST_REQUIRE(dek != nullptr);
BOOST_REQUIRE(_get_random(dek) == WAE_ERROR_NONE);
+ // precondition
+ // dek store is removed after preloaded app deks loaded so dek store
+ // does not exists as default. To test write/read app dek test(they're working on
+ // dek store), dek store directory should be made
+ Wae::Test::restore_dek_store();
+ // make unique_ptr to remove directory automatically
+ std::unique_ptr<void, std::function<void(void *)>> scoped_store(
+ reinterpret_cast<void *>(1), [](void *) { Wae::Test::remove_dek_store(); });
+
int ret = _write_encrypted_app_dek_to_file(pkg_id, dek);
BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to write_encrypted_app_dek_to_file. ec: " << ret);
@@ -276,7 +291,7 @@ BOOST_AUTO_TEST_CASE(read_write_encrypted_app_dek)
"readed(" << Wae::Test::bytes_to_hex(readed) << ")");
}
-BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1)
+BOOST_AUTO_TEST_CASE(cache_create_preloaded_app_dek)
{
const char *pkg_id = "TEST_PKG_ID_FOR_CREATE";
@@ -287,7 +302,22 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1)
"preloaded app ce to create is already exist. ec: " << ret);
const crypto_element_s *ce = nullptr;
- ret = create_preloaded_app_ce(pkg_id, &ce);
+
+ {
+ // precondition:
+ // for create_preloaded_app_ce, public key(kek) is needed
+ Wae::Test::restore_dummy_preloaded_app_dek_keks();
+ // postcondition:
+ // get_preloaded_app_ce retrieves app ce from cache which is created on
+ // create_preloaded_app_ce so private key in dek store shouldn't be needed
+ // make unique_ptr to remove directory automatically
+ std::unique_ptr<void, std::function<void(void *)>> scoped_store(
+ reinterpret_cast<void *>(1), [](void *) { Wae::Test::remove_dek_store(); });
+
+ // created preloaded app ce is just written in file, not into key-manager repo so
+ // no need to call remove_app_ce.
+ ret = create_preloaded_app_ce(pkg_id, &ce);
+ }
BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE,
"Failed to create_preloaded_app_ce. ec: " << ret);
@@ -299,22 +329,21 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1)
BOOST_REQUIRE_MESSAGE(readed == ce, "cached ce address and actual is different!");
}
-BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2)
+BOOST_AUTO_TEST_CASE(load_preloaded_app_dek)
{
+ // steps
+ // 1) restore KEKs : restore_dummy_preloaded_app_dek_keks
+ // 2) create app deks based on KEK (public key) : create_preloaded_app_ce
+ // -> originally this step runs in image server so result(adek) is written to file
+ // 3) load preloaded app deks (.adek) in file : load_preloaded_app_deks
+ // -> After load, pri/pub key pair and adek in file is no longer needed so they're
+ // automatically cleared by load_preloaded_app_deks()
+ // 4) clear app deks from key-manager for remove it (associated to TEST_PKG_ID_*)
+ Wae::Test::restore_dummy_preloaded_app_dek_keks();
+
const char *pkg_id1 = "TEST_PKGID_1";
const char *pkg_id2 = "TEST_PKGID_2";
- char path1[MAX_PATH_LEN] = {0, };
- char path2[MAX_PATH_LEN] = {0, };
- _get_preloaded_app_dek_file_path(pkg_id1, sizeof(path1), path1);
- _get_preloaded_app_dek_file_path(pkg_id2, sizeof(path2), path2);
-
- // remove old test data
- remove_app_ce(0, pkg_id1, WAE_PRELOADED_APP);
- remove_app_ce(0, pkg_id2, WAE_PRELOADED_APP);
- unlink(path1);
- unlink(path2);
-
// create 2 ces for preloaded app
const crypto_element_s *ce1 = nullptr;
int ret = create_preloaded_app_ce(pkg_id1, &ce1);
@@ -326,7 +355,7 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2)
BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE,
"Failed to create_preloaded_app_ce. ec: " << ret);
- ret = load_preloaded_app_deks(true);
+ ret = load_preloaded_app_deks();
BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE,
"Failed to load_preloaded_app_deks. ec: " << ret);
@@ -348,6 +377,48 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2)
BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret);
}
+BOOST_AUTO_TEST_CASE(load_preloaded_app_dek_tolerances)
+{
+ std::function<bool()> does_dek_store_exist = []() {
+ if (DIR *dir = opendir(_get_dek_store_path())) {
+ closedir(dir);
+ return true;
+ } else if (errno != ENOENT) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ // without dek store directory
+ BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_NONE);
+ BOOST_REQUIRE(does_dek_store_exist() == false);
+
+ // without kek(private key)
+ Wae::Test::restore_dek_store();
+ BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_FILE);
+ BOOST_REQUIRE(does_dek_store_exist() == false);
+
+ // with invalid file in dek store
+ Wae::Test::restore_dummy_preloaded_app_dek_keks();
+ std::ofstream dst;
+ dst.exceptions(std::ofstream::failbit | std::ofstream::badbit);
+ dst.open(std::string(_get_dek_store_path()) + "/invalids", std::ofstream::binary);
+ dst << "touch invalid file to dek store";
+ // std::ofstream destructor will call close automatically so no need to handle
+ // close in the exception cases
+ dst.close();
+ BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_FILE);
+ BOOST_REQUIRE(does_dek_store_exist() == false);
+
+ // with invalid directory in dek store
+ Wae::Test::restore_dummy_preloaded_app_dek_keks();
+ std::string invalid_dir = std::string(_get_dek_store_path()) + "/invalid_dir";
+ mkdir(invalid_dir.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
+ BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_FILE);
+ BOOST_REQUIRE(does_dek_store_exist() == false);
+}
+
BOOST_AUTO_TEST_SUITE_END() // INTERNALS
BOOST_AUTO_TEST_SUITE_END() // SYSTEM
diff --git a/tests/resources/CMakeLists.txt b/tests/resources/CMakeLists.txt
new file mode 100644
index 0000000..fa0856f
--- /dev/null
+++ b/tests/resources/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+INSTALL(
+ FILES pubkey.pem prikey.pem
+ DESTINATION ${RW_SHARE_DIR}/wae/test/app_dek
+ PERMISSIONS OWNER_READ
+)
diff --git a/tests/resources/prikey.pem b/tests/resources/prikey.pem
new file mode 100644
index 0000000..e27950c
--- /dev/null
+++ b/tests/resources/prikey.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,F4C783D75B0679F29398E9A3CAB4733D
+
+kxgW1wGX3TZZ/wtv3g4AOLlZCHoQ6uXVQ0h2ofWjnJs8tas/alR6o8UBRIqCw44t
+znUvQ8HlThvzhGgxje/yDDSxCy9mqhgsi2XeTtAeUbMhFL6UArb3cs6M4a37lYoT
+llZdFyYkRWJ3vRS33TDrhXDV6GjZWQ05SJ0OYdPJsmA1ENwdH+5NE/xLnqLdTtWr
+O3Mn2vi6P9CVqZroCvYBzUaypGcmFhjTIbWmB6inXjoXyddzerh7PTDBDWWacBab
+C7gcZC5SrK5YOt6f54ANsVQO8jnkLDx95gUSHYthX1hrQ3Da5Gb6nfYP9RNrHCum
+O8RKxSOvv8zwbMlzqtld8xCOb7Nh04f8bofrzZVLZ0T92FcyFQmt1F4U6DNQqHsn
+AAqxRxUWsC5k2dX9uZ6RCpEzNYWyPvNe24I/Kt01Geoh1NtCns8CVZcrxyMMtZRK
+ZJnYhvNDXDQCDtMJjRBiEXXE++AdA2O6uFoGX3alKwtxAIjGI++pSRlz1GTps26x
+5mmLil5wb3KGBfMN4L0R0heDOeiPQrNv7CwX8OlHtA1OKFBtViWdd/uZ2hAko1Tz
+YkoYpHPQOV5LZ7dem/XNnwwel9g6AkHhLNJv5ih4Y0CQfPBSs+iiLbMHh/NaGDD9
++kbcf5Lk4FQGVbJDW9nDAXT6jjMyliTI+hIh5fM2k22qbq6OqBkW6EbOQDMP/R2P
+LhFqTgHceNt0mqpcDJdJQ0YKbxVpdkv5f1C4rW+pgUEeHDCQ7vPe4p44xQJ/Z/7Y
+AtPwPKzPPJze2cfoUkZd9jXN9g2v2555xnQZU78IEm1nPVBA+hLIaqN1hu1Lkzxy
+CwFNo7bMVh3FSBmZVtJlcLsyLxZ9UdoaSr+anfA0lWJPiBzE0whQljZp56l1rL1V
+1K8m/dc9rLJ3uDQmYoSRmBZG5zZlVWCip+R9VAHMxRi1x29dFk1jbtQscr63dMI8
+0eOUf28Mw719WWUZVzD08b431DPqWiqrpexUKEXPW8EsrINPfIg180QYt1VUoshs
+Tqi/LKM0OV6nlMGh9ieCK8WzVDW8F16krSLo6eJpIPYPZgkHE7fC7Jws1kpUrSnF
+GgT6rBA97tJ0EalinuFXbip1X087Quz5USURq18f7/B6nFu0Kd4GhlICsR24j3eB
+75SsTNmfUcko8s5QT4rwONEwtRffkGbbNEisCPcleJV68zHvN58mfD7Dl8W3zIO4
+Qk6B1Xy0C4EEniKFfjxIaMEaxrqntBIc+nZE6/+UoGp/Hj9r5ZdzQX2j4837IIdR
+CxT4tjXiWBA6u3WaLAZUSM0W0SEORUF9NwzlId1b8A3WxA8XewhAKPaJEr677vzZ
+083+neUOuXqqs597romLH1omuffxmHxBzmP+koUtemP78XxCBVWUAB1T+fBRJMz6
+9ZEgDWrMntJ1IaFoGdOWZELgwcXJ0KwWFuk+sieZ5WCCzNmFli9WPN/xSqwmdYw6
+RK9er5Vc8D9mAlmGlz2mpAmzNJHH30zYKT/d0XzBS8z6WBRthaTS3NLsiSeWdELH
+b5+WEMOiKvZ19AXU2unHw/XpeVnAISOHhumAqFCwXkjVoMt8LMDawt6ra8N8G+gD
+-----END RSA PRIVATE KEY-----
diff --git a/tests/resources/pubkey.pem b/tests/resources/pubkey.pem
new file mode 100644
index 0000000..f0dfcea
--- /dev/null
+++ b/tests/resources/pubkey.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kWtjpRO7Zh2KX2naVE/
+BDJdrfwK9xexfNA0MkY2VJ4J2AKMYTj1D1jntceryupCEHOvP3rum+WsFvPXduz9
++VKnSsSqj4jcTUubtpDUGA5G79IqLEPFuSBaqI8Uwkzd08pE+s30oaJDnNazMhSq
+8JkqBPoCCwtUs73ruE9VbtsBO/kTlASIAfe8nXqcJLcDQgWYhizjJw0Pi6d74oCw
+S2OTvQDNvsXfFnA0ZJEEYw/rZLirj7OHoOjz+Sh5N+1uA3Up6SPPEbHuP6L12Yxq
+Hdy7gnJXodLhvE/cR4SN9VW7+qmCMBjmLkBejGrEX3STS9sLI7MZHu9Y26dwuYb4
++wIDAQAB
+-----END PUBLIC KEY-----
diff --git a/tests/test-helper.cpp b/tests/test-helper.cpp
index d0ca263..b7fdf6a 100644
--- a/tests/test-helper.cpp
+++ b/tests/test-helper.cpp
@@ -22,6 +22,9 @@
#include <cstring>
#include <vector>
+#include <fstream>
+#include <unistd.h>
+#include <sys/stat.h>
#include "web_app_enc.h"
#include "key_handler.h"
@@ -37,6 +40,25 @@ namespace {
const uid_t UID_OWNER = 5001;
+void copy_file(const char *src_path, const char *dst_path)
+{
+ std::ifstream src;
+ std::ofstream dst;
+
+ src.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+ dst.exceptions(std::ofstream::failbit | std::ofstream::badbit);
+
+ src.open(src_path, std::ifstream::binary);
+ dst.open(dst_path, std::ofstream::binary);
+
+ dst << src.rdbuf();
+
+ // std::ofstream destructor will call close automatically so no need to handle
+ // close in the exception cases
+ src.close();
+ dst.close();
+}
+
} // namespace anonymous
void add_get_remove_ce(wae_app_type_e app_type)
@@ -123,15 +145,29 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type)
else
wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP);
- if (app_type == WAE_PRELOADED_APP)
- clear_app_deks_loaded_from_key_manager();
-
std::vector<unsigned char> plaintext = {
'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y',
'o', 'q', '2', 'e', 'v', '0', '1', 'x'
};
- // test for downloaded web application
+ // precondition for preloaded app:
+ // for preloaded app encryption, preloaded app dek kek(pub) is needed.
+ // dek store is removed after preloaded app deks loaded so dek store
+ // does not exists as default. To test encrypt/decrypt(write/read ce) app test,
+ // dek store directory should be made.
+ std::unique_ptr<void, std::function<void(void *)>> scoped_store(
+ reinterpret_cast<void *>(1), [](void *ptr) {
+ if (ptr == reinterpret_cast<void *>(1))
+ return;
+ else
+ remove_dek_store(); // remove dek store automatically in case of error
+ });
+
+ if (app_type == WAE_PRELOADED_APP) {
+ restore_dummy_preloaded_app_dek_keks();
+ scoped_store.reset(reinterpret_cast<void *>(2));
+ }
+
unsigned char *_encrypted = nullptr;
size_t _enc_len = 0;
int tmp = 0;
@@ -171,7 +207,7 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type)
}
if (app_type == WAE_PRELOADED_APP)
- load_preloaded_app_deks(true);
+ load_preloaded_app_deks();
unsigned char *_decrypted = nullptr;
size_t _dec_len = 0;
@@ -201,5 +237,31 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type)
"Failed to wae_remove_app_dek. ec: " << tmp);
}
+void restore_dek_store()
+{
+ mkdir(
+ _get_dek_store_path(),
+ S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP);
+}
+
+void remove_dek_store()
+{
+ _remove_directory(_get_dek_store_path());
+}
+
+void restore_dummy_preloaded_app_dek_keks()
+{
+ // Generate pri/pub key pair. Private key is protected
+ // with assigned password: APP_DEK_KEK_PRIKEY_PASSWORD) which is same to password
+ // of real private key because it's built in source of srcs/key_handler.c
+ // It should be removed after private key goes into key-manager initial-value.
+ restore_dek_store();
+
+ copy_file("/opt/share/wae/test/app_dek/prikey.pem", _get_dek_kek_pri_key_path());
+ copy_file("/opt/share/wae/test/app_dek/pubkey.pem", _get_dek_kek_pub_key_path());
+
+ BOOST_MESSAGE("copying dummy pri/pub key pair to dek store done");
+}
+
} // namespace Test
} // namespace Wae
diff --git a/tests/test-helper.h b/tests/test-helper.h
index b4d1f42..cd2fae2 100644
--- a/tests/test-helper.h
+++ b/tests/test-helper.h
@@ -29,5 +29,8 @@ void add_get_remove_ce(wae_app_type_e app_type);
void create_app_ce(wae_app_type_e app_type);
void encrypt_decrypt_web_app(wae_app_type_e app_type);
+void remove_dek_store();
+void restore_dek_store();
+void restore_dummy_preloaded_app_dek_keks();
} // namespace Test
} // namespace Wae