Fix svace defect
[platform/core/security/libwebappenc.git] / tests / test-helper.cpp
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  *
16  *
17  * @file        test-helper.cpp
18  * @author      Kyungwook Tak (k.tak@samsung.com)
19  * @version     1.0
20  */
21 #include "test-helper.h"
22
23 #include <cstring>
24 #include <vector>
25 #include <fstream>
26 #include <unistd.h>
27 #include <sys/stat.h>
28
29 #include "web_app_enc.h"
30 #include "key_handler.h"
31 #include "crypto_service.h"
32 #include "types.h"
33 #include "key_manager.h"
34
35 #include "test-common.h"
36
37 namespace Wae {
38 namespace Test {
39 namespace {
40
41 const uid_t UID_OWNER = 5001;
42
43 void copy_file(const char *src_path, const char *dst_path)
44 {
45         std::ifstream src;
46         std::ofstream dst;
47
48         src.exceptions(std::ifstream::failbit | std::ifstream::badbit);
49         dst.exceptions(std::ofstream::failbit | std::ofstream::badbit);
50
51         src.open(src_path, std::ifstream::binary);
52         dst.open(dst_path, std::ofstream::binary);
53
54         dst << src.rdbuf();
55
56         // std::ofstream destructor will call close automatically so no need to handle
57         // close in the exception cases
58         src.close();
59         dst.close();
60 }
61
62 } // namespace anonymous
63
64 void add_get_remove_ce(wae_app_type_e app_type)
65 {
66         const char *pkg_id = "TEST_PKG_ID";
67
68         const crypto_element_s *ce = nullptr;
69         uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0;
70
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);
73
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);
77
78         BOOST_REQUIRE_MESSAGE(ce == stored_ce,
79                 "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!");
80
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);
83
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 << ")");
89         } else {
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 << ")");
93         }
94 }
95
96 void create_app_ce(wae_app_type_e app_type)
97 {
98         uid_t uid = app_type == WAE_DOWNLOADED_NORMAL_APP ? UID_OWNER : 0;
99         const char *pkg_id = "TEST_PKG_ID";
100
101         remove_app_ce(uid, pkg_id, app_type);
102
103         const crypto_element_s *ce = nullptr;
104
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);
107
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);
111
112         BOOST_REQUIRE_MESSAGE(ce == stored_ce,
113                 "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!");
114
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);
117 }
118
119 void encrypt_decrypt_web_app(wae_app_type_e app_type)
120 {
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";
125
126         const char *pkg_id = nullptr;
127         switch (app_type) {
128         case WAE_DOWNLOADED_NORMAL_APP:
129                 pkg_id = pkg_id1;
130                 break;
131
132         case WAE_DOWNLOADED_GLOBAL_APP:
133                 pkg_id = pkg_id2;
134                 break;
135
136         case WAE_PRELOADED_APP:
137         default:
138                 pkg_id = pkg_id3;
139                 break;
140         }
141
142         // remove old test data
143         if (app_type == WAE_DOWNLOADED_NORMAL_APP)
144                 wae_remove_app_dek(uid, pkg_id);
145         else
146                 wae_remove_global_app_dek(pkg_id, app_type == WAE_PRELOADED_APP);
147
148         std::vector<unsigned char> plaintext = {
149                 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y',
150                 'o', 'q', '2', 'e', 'v', '0', '1', 'x'
151         };
152
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))
161                                 return;
162                         else
163                                 remove_dek_store(); // remove dek store automatically in case of error
164                 });
165
166         if (app_type == WAE_PRELOADED_APP) {
167                 restore_dummy_preloaded_app_dek_keks();
168                 scoped_store.reset(reinterpret_cast<void *>(2));
169         }
170
171         unsigned char *_encrypted = nullptr;
172         size_t _enc_len = 0;
173         int tmp = 0;
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);
177         else
178                 tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP,
179                                                                                                  plaintext.data(), plaintext.size(),
180                                                                                                  &_encrypted, &_enc_len);
181
182         BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE,
183                         "Failed to wae_encrypt_web_application. ec: " << tmp);
184         free(_encrypted);
185
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);
190         else
191                 tmp = wae_encrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP,
192                                                                                                  plaintext.data(), plaintext.size(),
193                                                                                                  &_encrypted, &_enc_len);
194
195         BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE,
196                         "Failed to wae_encrypt_web_application second time. ec: " << tmp);
197
198         auto encrypted = bytearr_to_vec(_encrypted, _enc_len);
199         free(_encrypted);
200
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);
204                 free(key_per_user);
205         } else {
206                 _remove_app_ce_from_cache(pkg_id);
207         }
208
209         if (app_type == WAE_PRELOADED_APP)
210                 BOOST_REQUIRE(load_preloaded_app_deks() == WAE_ERROR_NONE);
211
212         unsigned char *_decrypted = nullptr;
213         size_t _dec_len = 0;
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);
217         else
218                 tmp = wae_decrypt_global_web_application(pkg_id, app_type == WAE_PRELOADED_APP,
219                                                                                                  encrypted.data(), encrypted.size(),
220                                                                                                  &_decrypted, &_dec_len);
221
222         BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE,
223                         "Failed to wae_decrypt_web_application. ec: " << tmp);
224
225         auto decrypted = bytearr_to_vec(_decrypted, _dec_len);
226
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) << ")");
231
232         if (app_type == WAE_DOWNLOADED_NORMAL_APP)
233                 tmp = wae_remove_app_dek(uid, pkg_id);
234         else
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);
238 }
239
240 void restore_dek_store()
241 {
242         mkdir(
243                 _get_dek_store_path(),
244                 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP);
245 }
246
247 void remove_dek_store()
248 {
249         _remove_directory(_get_dek_store_path());
250 }
251
252 void restore_dummy_preloaded_app_dek_keks()
253 {
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.
258         restore_dek_store();
259
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());
262
263         BOOST_MESSAGE("copying dummy pri/pub key pair to dek store done");
264 }
265
266 } // namespace Test
267 } // namespace Wae