2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 * @file test-helper.cpp
18 * @author Kyungwook Tak (k.tak@samsung.com)
21 #include "test-helper.h"
29 #include "web_app_enc.h"
30 #include "key_handler.h"
31 #include "crypto_service.h"
33 #include "key_manager.h"
35 #include "test-common.h"
41 const uid_t UID_OWNER = 5001;
43 void copy_file(const char *src_path, const char *dst_path)
48 src.exceptions(std::ifstream::failbit | std::ifstream::badbit);
49 dst.exceptions(std::ofstream::failbit | std::ofstream::badbit);
51 src.open(src_path, std::ifstream::binary);
52 dst.open(dst_path, std::ofstream::binary);
56 // std::ofstream destructor will call close automatically so no need to handle
57 // close in the exception cases
62 } // namespace anonymous
64 void add_get_remove_ce(wae_app_type_e app_type)
66 const char *pkg_id = "TEST_PKG_ID";
68 const crypto_element_s *ce = nullptr;
69 uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0;
71 int tmp = create_app_ce(uid, pkg_id, app_type, &ce);
72 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp);
74 const crypto_element_s *stored_ce = nullptr;
75 tmp = get_app_ce(uid, pkg_id, app_type, true, &stored_ce);
76 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp);
78 BOOST_REQUIRE_MESSAGE(ce == stored_ce,
79 "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!");
81 tmp = remove_app_ce(uid, pkg_id, app_type);
82 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp);
84 if (app_type == WAE_DOWNLOADED_GLOBAL_APP) {
85 tmp = get_app_ce(uid, pkg_id, app_type, true, &stored_ce);
86 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE && stored_ce->is_migrated_app,
87 "when getting app ce which is there isn't, it should be migrated case! "
88 "ret("<< tmp << ") and is_migrated_app(" << stored_ce->is_migrated_app << ")");
90 tmp = get_app_ce(uid, pkg_id, app_type, false, &stored_ce);
91 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY,
92 "removed app ce is still remaining. ret(" << tmp << ")");
96 void create_app_ce(wae_app_type_e app_type)
98 uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0;
99 const char *pkg_id = "TEST_PKG_ID";
101 remove_app_ce(uid, pkg_id, app_type);
103 const crypto_element_s *ce = nullptr;
105 int tmp = create_app_ce(uid, pkg_id, app_type, &ce);
106 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp);
108 const crypto_element_s *stored_ce = nullptr;
109 tmp = get_app_ce(uid, pkg_id, app_type, false, &stored_ce);
110 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp);
112 BOOST_REQUIRE_MESSAGE(ce == stored_ce,
113 "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!");
115 tmp = remove_app_ce(uid, pkg_id, app_type);
116 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp);
119 void encrypt_decrypt_web_app(wae_app_type_e app_type)
121 uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0;
122 const char *pkg_id1 = "testpkg_for_normal";
123 const char *pkg_id2 = "testpkg_for_global";
124 const char *pkg_id3 = "testpkg_for_preloaded";
126 const char *pkg_id = nullptr;
128 case WAE_DOWNLOADED_NORMAL_APP:
132 case WAE_DOWNLOADED_GLOBAL_APP:
136 case WAE_PRELOADED_APP:
142 // remove old test data
143 if (app_type == WAE_DOWNLOADED_NORMAL_APP)
144 wae_remove_app_dek(uid, pkg_id);
146 wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP);
148 std::vector<unsigned char> plaintext = {
149 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y',
150 'o', 'q', '2', 'e', 'v', '0', '1', 'x'
153 // precondition for preloaded app:
154 // for preloaded app encryption, preloaded app dek kek(pub) is needed.
155 // dek store is removed after preloaded app deks loaded so dek store
156 // does not exists as default. To test encrypt/decrypt(write/read ce) app test,
157 // dek store directory should be made.
158 std::unique_ptr<void, std::function<void(void *)>> scoped_store(
159 reinterpret_cast<void *>(1), [](void *ptr) {
160 if (ptr == reinterpret_cast<void *>(1))
163 remove_dek_store(); // remove dek store automatically in case of error
166 if (app_type == WAE_PRELOADED_APP) {
167 restore_dummy_preloaded_app_dek_keks();
168 scoped_store.reset(reinterpret_cast<void *>(2));
171 unsigned char *_encrypted = nullptr;
174 if (app_type == WAE_DOWNLOADED_NORMAL_APP)
175 tmp = wae_encrypt_web_application(uid, pkg_id, plaintext.data(), plaintext.size(),
176 &_encrypted, &_enc_len);
178 tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP,
179 plaintext.data(), plaintext.size(),
180 &_encrypted, &_enc_len);
182 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE,
183 "Failed to wae_encrypt_web_application. ec: " << tmp);
186 // encrypt test twice
187 if (app_type == WAE_DOWNLOADED_NORMAL_APP)
188 tmp = wae_encrypt_web_application(uid, pkg_id, plaintext.data(),
189 plaintext.size(), &_encrypted, &_enc_len);
191 tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP,
192 plaintext.data(), plaintext.size(),
193 &_encrypted, &_enc_len);
195 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE,
196 "Failed to wae_encrypt_web_application second time. ec: " << tmp);
198 auto encrypted = bytearr_to_vec(_encrypted, _enc_len);
201 if (app_type == WAE_DOWNLOADED_NORMAL_APP) {
202 char *key_per_user = _create_map_key(uid, pkg_id);
203 _remove_app_ce_from_cache(key_per_user);
206 _remove_app_ce_from_cache(pkg_id);
209 if (app_type == WAE_PRELOADED_APP)
210 BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_NONE);
212 unsigned char *_decrypted = nullptr;
214 if (app_type == WAE_DOWNLOADED_NORMAL_APP)
215 tmp = wae_decrypt_web_application(uid, pkg_id, encrypted.data(), encrypted.size(),
216 &_decrypted, &_dec_len);
218 tmp = wae_decrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP,
219 encrypted.data(), encrypted.size(),
220 &_decrypted, &_dec_len);
222 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE,
223 "Failed to wae_decrypt_web_application. ec: " << tmp);
225 auto decrypted = bytearr_to_vec(_decrypted, _dec_len);
227 BOOST_REQUIRE_MESSAGE(plaintext == decrypted,
228 "plaintext and decrypted isn't matched! "
229 "plaintext(" << bytes_to_hex(plaintext) << ") "
230 "decrypted(" << bytes_to_hex(decrypted) << ")");
232 if (app_type == WAE_DOWNLOADED_NORMAL_APP)
233 tmp = wae_remove_app_dek(uid, pkg_id);
235 tmp = wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP);
236 BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE,
237 "Failed to wae_remove_app_dek. ec: " << tmp);
240 void restore_dek_store()
243 _get_dek_store_path(),
244 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP);
247 void remove_dek_store()
249 _remove_directory(_get_dek_store_path());
252 void restore_dummy_preloaded_app_dek_keks()
254 // Generate pri/pub key pair. Private key is protected
255 // with assigned password: APP_DEK_KEK_PRIKEY_PASSWORD) which is same to password
256 // of real private key because it's built in source of srcs/key_handler.c
257 // It should be removed after private key goes into key-manager initial-value.
260 copy_file("/opt/share/wae/test/app_dek/prikey.pem", _get_dek_kek_pri_key_path());
261 copy_file("/opt/share/wae/test/app_dek/pubkey.pem", _get_dek_kek_pub_key_path());
263 BOOST_MESSAGE("copying dummy pri/pub key pair to dek store done");