CKM: Additional assert for smack_new_label_from_self
[platform/core/test/security-tests.git] / src / ckm / ckm-common.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 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       ckm-common.cpp
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  */
21 #include <string>
22 #include <fstream>
23
24 #include <sys/smack.h>
25 #include <ckmc/ckmc-type.h>
26 #include <ckm-common.h>
27 #include <tests_common.h>
28 #include <access_provider2.h>
29 #include <ckm/ckm-control.h>
30 #include <ckm/ckm-manager.h>
31 #include <ckmc/ckmc-control.h>
32 #include <ckmc/ckmc-manager.h>
33 #include <service_manager.h>
34 #include <unistd.h>
35
36 const char* SERVICE[] = {
37         "central-key-manager-listener.service",
38         "central-key-manager.service" };
39
40 void start_service(ServiceIdx idx)
41 {
42     ServiceManager sm(SERVICE[idx]);
43     sm.startService();
44 }
45
46 void stop_service(ServiceIdx idx)
47 {
48     ServiceManager sm(SERVICE[idx]);
49     sm.stopService();
50 }
51
52 // returns process label
53 CharPtr get_label()
54 {
55     int ret;
56     char* my_label = NULL;
57     RUNNER_ASSERT_MSG(0 <= (ret = smack_new_label_from_self(&my_label)),
58                          "Failed to get smack label for self. Error: " << ret);
59     RUNNER_ASSERT_MSG(my_label, "NULL smack label");
60     return CharPtr(my_label, free);
61 }
62
63 std::string aliasWithLabel(const char *label, const char *alias)
64 {
65     if(label)
66     {
67         std::stringstream ss;
68         ss << label << std::string(ckmc_label_name_separator) << alias;
69         return ss.str();
70     }
71     return std::string(alias);
72 }
73
74 // changes process label
75 void change_label(const char* label)
76 {
77     int ret = smack_set_label_for_self(label);
78     RUNNER_ASSERT_MSG(0 == ret, "Error in smack_set_label_for_self("<<label<<"). Error: " << ret);
79 }
80
81 ScopedLabel::ScopedLabel(const char* label) : m_original_label(get_label())
82 {
83     change_label(label);
84 }
85
86 ScopedLabel::~ScopedLabel()
87 {
88     /*
89      * Let it throw. If we can't restore label then remaining tests results will be
90      * unreliable anyway.
91      */
92     change_label(m_original_label.get());
93 }
94
95 const char * CKMCErrorToString(int error) {
96 #define ERRORDESCRIBE(name) case name: return #name
97     switch(error) {
98         ERRORDESCRIBE(CKMC_ERROR_NONE);
99         ERRORDESCRIBE(CKMC_ERROR_INVALID_PARAMETER);
100         ERRORDESCRIBE(CKMC_ERROR_OUT_OF_MEMORY);
101         ERRORDESCRIBE(CKMC_ERROR_PERMISSION_DENIED);
102         ERRORDESCRIBE(CKMC_ERROR_SOCKET);
103         ERRORDESCRIBE(CKMC_ERROR_BAD_REQUEST);
104         ERRORDESCRIBE(CKMC_ERROR_BAD_RESPONSE);
105         ERRORDESCRIBE(CKMC_ERROR_SEND_FAILED);
106         ERRORDESCRIBE(CKMC_ERROR_RECV_FAILED);
107         ERRORDESCRIBE(CKMC_ERROR_AUTHENTICATION_FAILED);
108         ERRORDESCRIBE(CKMC_ERROR_BUFFER_TOO_SMALL);
109         ERRORDESCRIBE(CKMC_ERROR_SERVER_ERROR);
110         ERRORDESCRIBE(CKMC_ERROR_DB_LOCKED);
111         ERRORDESCRIBE(CKMC_ERROR_DB_ERROR);
112         ERRORDESCRIBE(CKMC_ERROR_DB_ALIAS_EXISTS);
113         ERRORDESCRIBE(CKMC_ERROR_DB_ALIAS_UNKNOWN);
114         ERRORDESCRIBE(CKMC_ERROR_VERIFICATION_FAILED);
115         ERRORDESCRIBE(CKMC_ERROR_INVALID_FORMAT);
116         ERRORDESCRIBE(CKMC_ERROR_FILE_ACCESS_DENIED);
117         ERRORDESCRIBE(CKMC_ERROR_NOT_EXPORTABLE);
118         ERRORDESCRIBE(CKMC_ERROR_FILE_SYSTEM);
119         ERRORDESCRIBE(CKMC_ERROR_UNKNOWN);
120         default: return "Error not defined";
121     }
122 #undef ERRORDESCRIBE
123 }
124
125 std::string CKMCReadableError(int error) {
126     std::string output("Error: ");
127     output += std::to_string(error);
128     output += " Description: ";
129     output += CKMCErrorToString(error);
130     return output;
131 }
132
133 void save_data(const char* alias, const char *data, int expected_err)
134 {
135     save_data(alias, data, strlen(data), expected_err);
136 }
137
138 void save_data(const char* alias, const char *data, size_t len, int expected_err = CKMC_ERROR_NONE)
139 {
140     RUNNER_ASSERT(alias);
141     RUNNER_ASSERT(data);
142
143     ckmc_raw_buffer_s buffer;
144     buffer.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
145     buffer.size = len;
146     ckmc_policy_s policy;
147     policy.password = NULL;
148     policy.extractable = true;
149
150     int ret = ckmc_save_data(alias, buffer, policy);
151     RUNNER_ASSERT_MSG(expected_err == ret, "Saving data failed. "
152                         << CKMCErrorToString(ret) << " while expected: "
153                         << CKMCErrorToString(expected_err));
154
155 }
156
157 ScopedSaveData::ScopedSaveData(const char* alias, const char *data, int expected_err) : m_alias(alias)
158 {
159     save_data(alias, data, expected_err);
160 }
161
162 ScopedSaveData::~ScopedSaveData()
163 {
164     /*
165      * Let it throw. If we can't remove data then remaining tests results will be
166      * unreliable anyway.
167      */
168     check_remove_allowed(m_alias.c_str());
169 }
170
171 void GarbageCollector::add(const char* alias)
172 {
173     save_item item;
174     item.item_alias = std::string(alias);
175     item.owner_label = std::string(get_label().get());
176     item.owner_uid = geteuid();
177     item.owner_gid = getegid();
178     m_garbage.push_back(item);
179 }
180
181 void GarbageCollector::save(const char* alias, const char *data, int expected_err)
182 {
183     save(alias, data, strlen(data), expected_err);
184 }
185
186 void GarbageCollector::save(const char* alias, const char *data, size_t len, int expected_err)
187 {
188     save_data(alias, data, len, expected_err);
189
190     if(CKMC_ERROR_NONE == expected_err)
191         add(alias);
192 }
193
194 GarbageCollector::~GarbageCollector()
195 {
196     for(auto & item : m_garbage)
197     {
198         ScopedAccessProvider ap(item.owner_label, item.owner_uid, item.owner_gid);
199         check_remove_allowed(item.item_alias.c_str());
200     }
201 }
202
203 ScopedDBUnlock::ScopedDBUnlock(uid_t user_id, const char* passwd) : m_uid(user_id)
204 {
205     int temp;
206     RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_unlock_user_key(user_id, passwd)), CKMCErrorToString(temp));
207 }
208 ScopedDBUnlock::~ScopedDBUnlock()
209 {
210     int temp;
211     RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_lock_user_key(m_uid)), CKMCErrorToString(temp));
212 }
213
214 void check_remove_allowed(const char* alias)
215 {
216     int ret = ckmc_remove_alias(alias);
217     // remove, but ignore non existing
218     RUNNER_ASSERT_MSG((CKMC_ERROR_NONE == ret) || (CKMC_ERROR_DB_ALIAS_UNKNOWN == ret),
219                          "Removing data failed: " << CKMCErrorToString(ret));
220 }
221
222 void check_remove_denied(const char* alias)
223 {
224     int ret = ckmc_remove_alias(alias);
225     RUNNER_ASSERT_MSG(
226             CKMC_ERROR_PERMISSION_DENIED == ret,
227             "App with different label shouldn't have rights to remove this data. "
228             << CKMCReadableError(ret));
229 }
230
231 void check_remove_not_visible(const char* alias)
232 {
233     int ret = ckmc_remove_alias(alias);
234     RUNNER_ASSERT_MSG(
235             CKMC_ERROR_DB_ALIAS_UNKNOWN == ret,
236             "App with different label shouldn't have rights to see this data. "
237             << CKMCReadableError(ret));
238 }
239
240 void check_read(const char* alias,
241                 const char *label,
242                 const char *test_data,
243                 size_t len,
244                 int expected_code)
245 {
246     ckmc_raw_buffer_s* buffer = NULL;
247     int ret = ckmc_get_data(aliasWithLabel(label, alias).c_str(), NULL, &buffer);
248     RUNNER_ASSERT_MSG(expected_code == ret, "Getting data failed. "
249                       "Expected " << CKMCErrorToString(expected_code) << ", "
250                       "while result " << CKMCErrorToString(ret));
251
252     if(expected_code == CKMC_ERROR_NONE)
253     {
254         // compare data with expected
255         RUNNER_ASSERT_MSG(
256                 buffer->size == len,
257                 "Extracted data length do not match expected data length (encrypted?):" <<
258                 buffer->size << "!=" << len);
259
260         RUNNER_ASSERT_MSG(
261                 memcmp(const_cast<const char*>(reinterpret_cast<char*>(buffer->data)),
262                        test_data, buffer->size) == 0,
263                 "Extracted data do not match expected data (encrypted?).");
264
265         ckmc_buffer_free(buffer);
266     }
267 }
268
269 void check_read(const char* alias, const char *label, const char *test_data, int expected_code)
270 {
271     check_read(alias, label, test_data, strlen(test_data), expected_code);
272 }
273
274 void check_read_allowed(const char* alias, const char *data)
275 {
276     // try to read previously saved data - label taken implicitly
277     check_read(alias, NULL, data);
278 }
279
280 void check_read_not_visible(const char* alias)
281 {
282     // try to read previously saved data - label taken implicitly
283     {
284         ckmc_raw_buffer_s* buffer = NULL;
285         int ret = ckmc_get_data(alias, NULL, &buffer);
286         RUNNER_ASSERT_MSG(CKMC_ERROR_DB_ALIAS_UNKNOWN == ret,
287                             "App with different label shouldn't have rights to see this data. " << CKMCErrorToString(ret));
288         ckmc_buffer_free(buffer);
289     }
290 }
291
292 void check_key(const char *alias, int expected_error, ckmc_key_type_e expected_type)
293 {
294     ckmc_key_s *test_key = NULL;
295     int temp = ckmc_get_key(alias, 0, &test_key);
296     RUNNER_ASSERT_MSG(
297             expected_error == temp,
298             "received: " << CKMCReadableError(temp) << " while expected: " << CKMCReadableError(expected_error));
299     if(expected_type != CKMC_KEY_NONE)
300     {
301         RUNNER_ASSERT_MSG(
302                 test_key->key_type == expected_type,
303                 "received type: " << test_key->key_type << " while expected type: " << expected_type);
304     }
305     ckmc_key_free(test_key);
306 }
307 void check_key_allowed(const char *alias, ckmc_key_type_e expected_type)
308 {
309     check_key(alias, CKMC_ERROR_NONE, expected_type);
310 }
311 void check_key_not_visible(const char *alias)
312 {
313     check_key(alias, CKMC_ERROR_DB_ALIAS_UNKNOWN);
314 }
315 void check_cert_allowed(const char *alias)
316 {
317     ckmc_cert_s *test_cert = NULL;
318     int temp = ckmc_get_cert(alias, 0, &test_cert);
319     ckmc_cert_free(test_cert);
320     RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == temp, CKMCReadableError(temp));
321
322 }
323 void check_cert_not_visible(const char *alias)
324 {
325     ckmc_cert_s *test_cert = NULL;
326     int temp = ckmc_get_cert(alias, 0, &test_cert);
327     ckmc_cert_free(test_cert);
328     RUNNER_ASSERT_MSG(CKMC_ERROR_DB_ALIAS_UNKNOWN == temp,
329                       "App with different label shouldn't have rights to see this cert. " << CKMCErrorToString(temp));
330 }
331
332 void allow_access(const char* alias, const char* accessor, int permissionMask)
333 {
334     // data removal should revoke this access
335     int ret = ckmc_set_permission(alias, accessor, permissionMask);
336     RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == ret, "Trying to allow access returned: "
337                         << CKMCErrorToString(ret));
338 }
339
340 void allow_access_negative(const char* alias, const char* accessor, int permissionMask, int expectedCode)
341 {
342     // data removal should revoke this access
343     int ret = ckmc_set_permission(alias, accessor, permissionMask);
344     RUNNER_ASSERT_MSG(expectedCode == ret, "Trying to allow access returned "
345                         << CKMCErrorToString(ret) << ", while expected: "
346                         << CKMCErrorToString(expectedCode));
347 }
348
349 void deny_access(const char* alias, const char* accessor)
350 {
351     int ret = ckmc_set_permission(alias, accessor, CKMC_PERMISSION_NONE);
352     RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == ret, "Denying access failed. Error: "
353                         << CKMCErrorToString(ret));
354 }
355
356 void deny_access_negative(const char* alias, const char* accessor, int expectedCode)
357 {
358     int ret = ckmc_set_permission(alias, accessor, CKMC_PERMISSION_NONE);
359     RUNNER_ASSERT_MSG(expectedCode == ret, "Denying access failed. "
360                         << CKMCErrorToString(ret) << ", while expected: "
361                         << CKMCErrorToString(expectedCode));
362 }
363
364 void unlock_user_data(uid_t user_id, const char *passwd)
365 {
366     int ret;
367     auto control = CKM::Control::create();
368     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->unlockUserKey(user_id, passwd)),
369                       "Error=" << CKM::ErrorToString(ret));
370 }
371
372 void remove_user_data(uid_t user_id)
373 {
374     auto control = CKM::Control::create();
375     control->lockUserKey(user_id);
376     control->removeUserData(user_id);
377 }
378
379 void reset_user_data(uid_t user_id, const char *passwd)
380 {
381     remove_user_data(user_id);
382     unlock_user_data(user_id, passwd);
383 }
384
385 ckmc_raw_buffer_s prepare_message_buffer(const char * input)
386 {
387     ckmc_raw_buffer_s retval;
388     retval.data = const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(input));
389     retval.size = strlen(input);
390     return retval;
391 }
392
393 void check_alias_list(const CKM::AliasVector& expected)
394 {
395     ckmc_alias_list_s *aliasList = NULL;
396     int ret = ckmc_get_data_alias_list(&aliasList);
397     RUNNER_ASSERT_MSG(ret == 0, "Failed to get the list of data aliases. " << ret << " / " << CKMCErrorToString(ret));
398
399     CKM::AliasVector actual;
400     ckmc_alias_list_s *plist = aliasList;
401     while(plist)
402     {
403         actual.push_back(plist->alias);
404         plist = plist->next;
405     }
406     ckmc_alias_list_all_free(aliasList);
407
408     RUNNER_ASSERT_MSG(expected == actual, "Actual list of aliases differ from expected list.");
409 }
410
411 size_t count_aliases(alias_type_ type, size_t minimum_initial_element_count)
412 {
413     ckmc_alias_list_s *aliasList = NULL;
414     int ec;
415     switch(type)
416     {
417         case ALIAS_KEY:
418             ec = ckmc_get_key_alias_list(&aliasList);
419             break;
420
421         case ALIAS_CERT:
422             ec = ckmc_get_cert_alias_list(&aliasList);
423             break;
424
425         case ALIAS_DATA:
426             ec = ckmc_get_data_alias_list(&aliasList);
427             break;
428         default:
429             RUNNER_ASSERT_MSG(false, "Unsupported value ALIAS_KEY == " << (int)type);
430     }
431
432     if(ec == CKMC_ERROR_DB_ALIAS_UNKNOWN)
433         return 0;
434
435     RUNNER_ASSERT_MSG(ec == CKMC_ERROR_NONE,
436                       "Error: alias list failed, ec: " << CKMCErrorToString(ec));
437
438     ckmc_alias_list_s *plist = aliasList;
439     size_t return_count = 0;
440     while(plist)
441     {
442         plist = plist->next;
443         return_count ++;
444     }
445     ckmc_alias_list_all_free(aliasList);
446
447     RUNNER_ASSERT_MSG(
448       return_count >= minimum_initial_element_count,
449       "Error: alias list failed, current element count: " << return_count <<
450       " while expected minimal count of " << minimum_initial_element_count <<
451       " elements");
452
453     return return_count;
454 }
455
456 std::string sharedDatabase(const CKM::Alias & alias)
457 {
458     return aliasWithLabel(ckmc_label_shared_owner, alias.c_str());
459 }
460
461 ckmc_raw_buffer_s* createRandomBuffer(size_t len)
462 {
463     ckmc_raw_buffer_s* buffer = NULL;
464     char* data = static_cast<char*>(malloc(len*sizeof(char)));
465     std::ifstream is("/dev/urandom", std::ifstream::binary);
466     RUNNER_ASSERT_MSG(is, "Failed to read /dev/urandom");
467     is.read(data, len);
468     if(static_cast<std::streamsize>(len) != is.gcount()) {
469         free(data);
470         RUNNER_ASSERT_MSG(false,
471                           "Not enough bytes read from /dev/urandom: " << len << "!=" <<
472                           is.gcount());
473     }
474     int ret = ckmc_buffer_new(reinterpret_cast<unsigned char*>(data), len, &buffer);
475     RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Buffer creation failed: " << CKMCErrorToString(ret));
476     return buffer;
477 }
478
479 ParamListPtr createParamListPtr()
480 {
481     ckmc_param_list_s* list = NULL;
482     assert_positive(ckmc_param_list_new, &list);
483     return ParamListPtr(list, ckmc_param_list_free);
484 }
485
486 void assert_buffers_equal(const ckmc_raw_buffer_s b1, const ckmc_raw_buffer_s b2, bool equal)
487 {
488     if(equal) {
489         RUNNER_ASSERT_MSG(b1.size == b2.size, "Buffer size differs: " << b1.size << "!=" << b2.size);
490         RUNNER_ASSERT_MSG(0 == memcmp(b1.data, b2.data, b1.size), "Buffer contents differ");
491     } else {
492         RUNNER_ASSERT_MSG(b1.size != b2.size, "Buffer sizes equal: " << b1.size << "==" << b2.size);
493         RUNNER_ASSERT_MSG(0 != memcmp(b1.data, b2.data, b1.size), "Buffer contents are identical");
494     }
495 }