2 * Copyright (c) 2000 - 2014 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 ckm-common.cpp
18 * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
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>
36 const char* SERVICE[] = {
37 "central-key-manager-listener.service",
38 "central-key-manager.service" };
40 void start_service(ServiceIdx idx)
42 ServiceManager sm(SERVICE[idx]);
46 void stop_service(ServiceIdx idx)
48 ServiceManager sm(SERVICE[idx]);
52 // returns process label
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);
63 std::string aliasWithLabel(const char *label, const char *alias)
68 ss << label << std::string(ckmc_label_name_separator) << alias;
71 return std::string(alias);
74 // changes process label
75 void change_label(const char* label)
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);
81 ScopedLabel::ScopedLabel(const char* label) : m_original_label(get_label())
86 ScopedLabel::~ScopedLabel()
89 * Let it throw. If we can't restore label then remaining tests results will be
92 change_label(m_original_label.get());
95 const char * CKMCErrorToString(int error) {
96 #define ERRORDESCRIBE(name) case name: return #name
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";
125 std::string CKMCReadableError(int error) {
126 std::string output("Error: ");
127 output += std::to_string(error);
128 output += " Description: ";
129 output += CKMCErrorToString(error);
133 void save_data(const char* alias, const char *data, int expected_err)
135 save_data(alias, data, strlen(data), expected_err);
138 void save_data(const char* alias, const char *data, size_t len, int expected_err = CKMC_ERROR_NONE)
140 RUNNER_ASSERT(alias);
143 ckmc_raw_buffer_s buffer;
144 buffer.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
146 ckmc_policy_s policy;
147 policy.password = NULL;
148 policy.extractable = true;
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));
157 ScopedSaveData::ScopedSaveData(const char* alias, const char *data, int expected_err) : m_alias(alias)
159 save_data(alias, data, expected_err);
162 ScopedSaveData::~ScopedSaveData()
165 * Let it throw. If we can't remove data then remaining tests results will be
168 check_remove_allowed(m_alias.c_str());
171 void GarbageCollector::add(const char* alias)
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);
181 void GarbageCollector::save(const char* alias, const char *data, int expected_err)
183 save(alias, data, strlen(data), expected_err);
186 void GarbageCollector::save(const char* alias, const char *data, size_t len, int expected_err)
188 save_data(alias, data, len, expected_err);
190 if(CKMC_ERROR_NONE == expected_err)
194 GarbageCollector::~GarbageCollector()
196 for(auto & item : m_garbage)
198 ScopedAccessProvider ap(item.owner_label, item.owner_uid, item.owner_gid);
199 check_remove_allowed(item.item_alias.c_str());
203 ScopedDBUnlock::ScopedDBUnlock(uid_t user_id, const char* passwd) : m_uid(user_id)
206 RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_unlock_user_key(user_id, passwd)), CKMCErrorToString(temp));
208 ScopedDBUnlock::~ScopedDBUnlock()
211 RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_lock_user_key(m_uid)), CKMCErrorToString(temp));
214 void check_remove_allowed(const char* alias)
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));
222 void check_remove_denied(const char* alias)
224 int ret = ckmc_remove_alias(alias);
226 CKMC_ERROR_PERMISSION_DENIED == ret,
227 "App with different label shouldn't have rights to remove this data. "
228 << CKMCReadableError(ret));
231 void check_remove_not_visible(const char* alias)
233 int ret = ckmc_remove_alias(alias);
235 CKMC_ERROR_DB_ALIAS_UNKNOWN == ret,
236 "App with different label shouldn't have rights to see this data. "
237 << CKMCReadableError(ret));
240 void check_read(const char* alias,
242 const char *test_data,
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));
252 if(expected_code == CKMC_ERROR_NONE)
254 // compare data with expected
257 "Extracted data length do not match expected data length (encrypted?):" <<
258 buffer->size << "!=" << len);
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?).");
265 ckmc_buffer_free(buffer);
269 void check_read(const char* alias, const char *label, const char *test_data, int expected_code)
271 check_read(alias, label, test_data, strlen(test_data), expected_code);
274 void check_read_allowed(const char* alias, const char *data)
276 // try to read previously saved data - label taken implicitly
277 check_read(alias, NULL, data);
280 void check_read_not_visible(const char* alias)
282 // try to read previously saved data - label taken implicitly
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);
292 void check_key(const char *alias, int expected_error, ckmc_key_type_e expected_type)
294 ckmc_key_s *test_key = NULL;
295 int temp = ckmc_get_key(alias, 0, &test_key);
297 expected_error == temp,
298 "received: " << CKMCReadableError(temp) << " while expected: " << CKMCReadableError(expected_error));
299 if(expected_type != CKMC_KEY_NONE)
302 test_key->key_type == expected_type,
303 "received type: " << test_key->key_type << " while expected type: " << expected_type);
305 ckmc_key_free(test_key);
307 void check_key_allowed(const char *alias, ckmc_key_type_e expected_type)
309 check_key(alias, CKMC_ERROR_NONE, expected_type);
311 void check_key_not_visible(const char *alias)
313 check_key(alias, CKMC_ERROR_DB_ALIAS_UNKNOWN);
315 void check_cert_allowed(const char *alias)
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));
323 void check_cert_not_visible(const char *alias)
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));
332 void allow_access(const char* alias, const char* accessor, int permissionMask)
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));
340 void allow_access_negative(const char* alias, const char* accessor, int permissionMask, int expectedCode)
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));
349 void deny_access(const char* alias, const char* accessor)
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));
356 void deny_access_negative(const char* alias, const char* accessor, int expectedCode)
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));
364 void unlock_user_data(uid_t user_id, const char *passwd)
367 auto control = CKM::Control::create();
368 RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->unlockUserKey(user_id, passwd)),
369 "Error=" << CKM::ErrorToString(ret));
372 void remove_user_data(uid_t user_id)
374 auto control = CKM::Control::create();
375 control->lockUserKey(user_id);
376 control->removeUserData(user_id);
379 void reset_user_data(uid_t user_id, const char *passwd)
381 remove_user_data(user_id);
382 unlock_user_data(user_id, passwd);
385 ckmc_raw_buffer_s prepare_message_buffer(const char * input)
387 ckmc_raw_buffer_s retval;
388 retval.data = const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(input));
389 retval.size = strlen(input);
393 void check_alias_list(const CKM::AliasVector& expected)
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));
399 CKM::AliasVector actual;
400 ckmc_alias_list_s *plist = aliasList;
403 actual.push_back(plist->alias);
406 ckmc_alias_list_all_free(aliasList);
408 RUNNER_ASSERT_MSG(expected == actual, "Actual list of aliases differ from expected list.");
411 size_t count_aliases(alias_type_ type, size_t minimum_initial_element_count)
413 ckmc_alias_list_s *aliasList = NULL;
418 ec = ckmc_get_key_alias_list(&aliasList);
422 ec = ckmc_get_cert_alias_list(&aliasList);
426 ec = ckmc_get_data_alias_list(&aliasList);
429 RUNNER_ASSERT_MSG(false, "Unsupported value ALIAS_KEY == " << (int)type);
432 if(ec == CKMC_ERROR_DB_ALIAS_UNKNOWN)
435 RUNNER_ASSERT_MSG(ec == CKMC_ERROR_NONE,
436 "Error: alias list failed, ec: " << CKMCErrorToString(ec));
438 ckmc_alias_list_s *plist = aliasList;
439 size_t return_count = 0;
445 ckmc_alias_list_all_free(aliasList);
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 <<
456 std::string sharedDatabase(const CKM::Alias & alias)
458 return aliasWithLabel(ckmc_label_shared_owner, alias.c_str());
461 ckmc_raw_buffer_s* createRandomBuffer(size_t len)
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");
468 if(static_cast<std::streamsize>(len) != is.gcount()) {
470 RUNNER_ASSERT_MSG(false,
471 "Not enough bytes read from /dev/urandom: " << len << "!=" <<
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));
479 ParamListPtr createParamListPtr()
481 ckmc_param_list_s* list = NULL;
482 assert_positive(ckmc_param_list_new, &list);
483 return ParamListPtr(list, ckmc_param_list_free);
486 void assert_buffers_equal(const ckmc_raw_buffer_s b1, const ckmc_raw_buffer_s b2, bool 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");
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");