/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License * * * @file test-helper.cpp * @author Kyungwook Tak (k.tak@samsung.com) * @version 1.0 */ #include "test-helper.h" #include #include #include #include #include #include "web_app_enc.h" #include "key_handler.h" #include "crypto_service.h" #include "types.h" #include "key_manager.h" #include "test-common.h" namespace Wae { namespace Test { 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) { const char *pkg_id = "TEST_PKG_ID"; const crypto_element_s *ce = nullptr; uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0; int tmp = create_app_ce(uid, pkg_id, app_type, &ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp); const crypto_element_s *stored_ce = nullptr; tmp = get_app_ce(uid, pkg_id, app_type, true, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp); BOOST_REQUIRE_MESSAGE(ce == stored_ce, "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!"); tmp = remove_app_ce(uid, pkg_id, app_type); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp); if (app_type == WAE_DOWNLOADED_GLOBAL_APP) { tmp = get_app_ce(uid, pkg_id, app_type, true, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE && stored_ce->is_migrated_app, "when getting app ce which is there isn't, it should be migrated case! " "ret("<< tmp << ") and is_migrated_app(" << stored_ce->is_migrated_app << ")"); } else { tmp = get_app_ce(uid, pkg_id, app_type, false, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY, "removed app ce is still remaining. ret(" << tmp << ")"); } } void create_app_ce(wae_app_type_e app_type) { uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0; const char *pkg_id = "TEST_PKG_ID"; remove_app_ce(uid, pkg_id, app_type); const crypto_element_s *ce = nullptr; int tmp = create_app_ce(uid, pkg_id, app_type, &ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp); const crypto_element_s *stored_ce = nullptr; tmp = get_app_ce(uid, pkg_id, app_type, false, &stored_ce); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp); BOOST_REQUIRE_MESSAGE(ce == stored_ce, "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!"); tmp = remove_app_ce(uid, pkg_id, app_type); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp); } void encrypt_decrypt_web_app(wae_app_type_e app_type) { uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0; const char *pkg_id1 = "testpkg_for_normal"; const char *pkg_id2 = "testpkg_for_global"; const char *pkg_id3 = "testpkg_for_preloaded"; const char *pkg_id = nullptr; switch (app_type) { case WAE_DOWNLOADED_NORMAL_APP: pkg_id = pkg_id1; break; case WAE_DOWNLOADED_GLOBAL_APP: pkg_id = pkg_id2; break; case WAE_PRELOADED_APP: default: pkg_id = pkg_id3; break; } // remove old test data if (app_type == WAE_DOWNLOADED_NORMAL_APP) wae_remove_app_dek(uid, pkg_id); else wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP); std::vector plaintext = { 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', 'o', 'q', '2', 'e', 'v', '0', '1', 'x' }; // precondition for preloaded app: // for preloaded app encryption, preloaded app dek kek(pub) is needed. // dek store is removed after preloaded app deks loaded so dek store // does not exists as default. To test encrypt/decrypt(write/read ce) app test, // dek store directory should be made. std::unique_ptr> scoped_store( reinterpret_cast(1), [](void *ptr) { if (ptr == reinterpret_cast(1)) return; else remove_dek_store(); // remove dek store automatically in case of error }); if (app_type == WAE_PRELOADED_APP) { restore_dummy_preloaded_app_dek_keks(); scoped_store.reset(reinterpret_cast(2)); } unsigned char *_encrypted = nullptr; size_t _enc_len = 0; int tmp = 0; if (app_type == WAE_DOWNLOADED_NORMAL_APP) tmp = wae_encrypt_web_application(uid, pkg_id, plaintext.data(), plaintext.size(), &_encrypted, &_enc_len); else tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP, plaintext.data(), plaintext.size(), &_encrypted, &_enc_len); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_encrypt_web_application. ec: " << tmp); free(_encrypted); // encrypt test twice if (app_type == WAE_DOWNLOADED_NORMAL_APP) tmp = wae_encrypt_web_application(uid, pkg_id, plaintext.data(), plaintext.size(), &_encrypted, &_enc_len); else tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP, plaintext.data(), plaintext.size(), &_encrypted, &_enc_len); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_encrypt_web_application second time. ec: " << tmp); auto encrypted = bytearr_to_vec(_encrypted, _enc_len); free(_encrypted); if (app_type == WAE_DOWNLOADED_NORMAL_APP) { char *key_per_user = _create_map_key(uid, pkg_id); _remove_app_ce_from_cache(key_per_user); free(key_per_user); } else { _remove_app_ce_from_cache(pkg_id); } if (app_type == WAE_PRELOADED_APP) load_preloaded_app_deks(); unsigned char *_decrypted = nullptr; size_t _dec_len = 0; if (app_type == WAE_DOWNLOADED_NORMAL_APP) tmp = wae_decrypt_web_application(uid, pkg_id, encrypted.data(), encrypted.size(), &_decrypted, &_dec_len); else tmp = wae_decrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP, encrypted.data(), encrypted.size(), &_decrypted, &_dec_len); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_decrypt_web_application. ec: " << tmp); auto decrypted = bytearr_to_vec(_decrypted, _dec_len); BOOST_REQUIRE_MESSAGE(plaintext == decrypted, "plaintext and decrypted isn't matched! " "plaintext(" << bytes_to_hex(plaintext) << ") " "decrypted(" << bytes_to_hex(decrypted) << ")"); if (app_type == WAE_DOWNLOADED_NORMAL_APP) tmp = wae_remove_app_dek(uid, pkg_id); else tmp = wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to wae_remove_app_dek. ec: " << tmp); } 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