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)
23 #include <sys/smack.h>
24 #include <ckmc/ckmc-type.h>
25 #include <ckm-common.h>
26 #include <tests_common.h>
27 #include <access_provider2.h>
28 #include <ckm/ckm-control.h>
29 #include <ckm/ckm-manager.h>
30 #include <ckmc/ckmc-control.h>
31 #include <ckmc/ckmc-manager.h>
32 #include <service_manager.h>
36 const std::string SMACK_USER_APP_PREFIX = "User::App::";
37 const char *SYSTEM_LABEL = ckmc_owner_id_system;
38 const char *TEST_LABEL = "test_label";
39 const char *TEST_LABEL_2 = "test_label_2";
40 const char *TEST_LABEL_3 = "test_label_3";
41 const char *TEST_LABEL_4 = "test_label_4";
42 const char *TEST_LABEL_5 = "test_label_5";
44 void generate_random(size_t random_bytes, char *output)
46 RUNNER_ASSERT(random_bytes>0 && output);
48 std::ifstream is("/dev/urandom", std::ifstream::binary);
49 RUNNER_ASSERT_MSG(is, "Failed to read /dev/urandom");
50 is.read(output, random_bytes);
51 if(static_cast<std::streamsize>(random_bytes) != is.gcount()) {
52 RUNNER_ASSERT_MSG(false,
53 "Not enough bytes read from /dev/urandom: " << random_bytes << "!=" <<
58 const char* SERVICE[] = {
59 "central-key-manager-listener.service",
60 "central-key-manager.service" };
62 void start_service(ServiceIdx idx)
64 ServiceManager sm(SERVICE[idx]);
68 void stop_service(ServiceIdx idx)
70 ServiceManager sm(SERVICE[idx]);
74 std::string getLabel() {
77 RUNNER_ASSERT_MSG(0 <= (ret = smack_new_label_from_self(&myLabel)),
78 "Failed to get smack label for self. Error: " << ret);
79 RUNNER_ASSERT_MSG(myLabel, "NULL smack label");
80 std::string result = myLabel;
85 std::string getOwnerIdFromSelf() {
86 const std::string& prefix = SMACK_USER_APP_PREFIX;
87 std::string smack = getLabel();
88 if (0 == smack.compare(0, prefix.size(), prefix))
89 return smack.substr(prefix.size(), std::string::npos);
93 std::string aliasWithLabel(const char *label, const char *alias)
98 ss << label << std::string(ckmc_label_name_separator) << alias;
101 return std::string(alias);
104 // changes process label
105 void change_label(const char* label)
107 int ret = smack_set_label_for_self(label);
108 RUNNER_ASSERT_MSG(0 == ret, "Error in smack_set_label_for_self("<<label<<"). Error: " << ret);
111 ScopedLabel::ScopedLabel(const char* label) : m_original_label(getLabel())
116 ScopedLabel::~ScopedLabel()
119 * Let it throw. If we can't restore label then remaining tests results will be
122 change_label(m_original_label.c_str());
125 #define ERRORDESCRIBE(name) case name: return #name
126 const char * CKMCErrorToString(int error) {
128 ERRORDESCRIBE(CKMC_ERROR_NONE);
129 ERRORDESCRIBE(CKMC_ERROR_INVALID_PARAMETER);
130 ERRORDESCRIBE(CKMC_ERROR_OUT_OF_MEMORY);
131 ERRORDESCRIBE(CKMC_ERROR_PERMISSION_DENIED);
132 ERRORDESCRIBE(CKMC_ERROR_SOCKET);
133 ERRORDESCRIBE(CKMC_ERROR_BAD_REQUEST);
134 ERRORDESCRIBE(CKMC_ERROR_BAD_RESPONSE);
135 ERRORDESCRIBE(CKMC_ERROR_SEND_FAILED);
136 ERRORDESCRIBE(CKMC_ERROR_RECV_FAILED);
137 ERRORDESCRIBE(CKMC_ERROR_AUTHENTICATION_FAILED);
138 ERRORDESCRIBE(CKMC_ERROR_BUFFER_TOO_SMALL);
139 ERRORDESCRIBE(CKMC_ERROR_SERVER_ERROR);
140 ERRORDESCRIBE(CKMC_ERROR_DB_LOCKED);
141 ERRORDESCRIBE(CKMC_ERROR_DB_ERROR);
142 ERRORDESCRIBE(CKMC_ERROR_DB_ALIAS_EXISTS);
143 ERRORDESCRIBE(CKMC_ERROR_DB_ALIAS_UNKNOWN);
144 ERRORDESCRIBE(CKMC_ERROR_VERIFICATION_FAILED);
145 ERRORDESCRIBE(CKMC_ERROR_INVALID_FORMAT);
146 ERRORDESCRIBE(CKMC_ERROR_FILE_ACCESS_DENIED);
147 ERRORDESCRIBE(CKMC_ERROR_NOT_EXPORTABLE);
148 ERRORDESCRIBE(CKMC_ERROR_FILE_SYSTEM);
149 ERRORDESCRIBE(CKMC_ERROR_NOT_SUPPORTED);
150 ERRORDESCRIBE(CKMC_ERROR_UNKNOWN);
151 default: return "Error not defined";
155 const char * CKMErrorToString(int error) {
157 ERRORDESCRIBE(CKM_API_SUCCESS);
158 ERRORDESCRIBE(CKM_API_ERROR_SOCKET);
159 ERRORDESCRIBE(CKM_API_ERROR_BAD_REQUEST);
160 ERRORDESCRIBE(CKM_API_ERROR_BAD_RESPONSE);
161 ERRORDESCRIBE(CKM_API_ERROR_SEND_FAILED);
162 ERRORDESCRIBE(CKM_API_ERROR_RECV_FAILED);
163 ERRORDESCRIBE(CKM_API_ERROR_AUTHENTICATION_FAILED);
164 ERRORDESCRIBE(CKM_API_ERROR_INPUT_PARAM);
165 ERRORDESCRIBE(CKM_API_ERROR_BUFFER_TOO_SMALL);
166 ERRORDESCRIBE(CKM_API_ERROR_OUT_OF_MEMORY);
167 ERRORDESCRIBE(CKM_API_ERROR_ACCESS_DENIED);
168 ERRORDESCRIBE(CKM_API_ERROR_SERVER_ERROR);
169 ERRORDESCRIBE(CKM_API_ERROR_DB_LOCKED);
170 ERRORDESCRIBE(CKM_API_ERROR_DB_ERROR);
171 ERRORDESCRIBE(CKM_API_ERROR_DB_ALIAS_EXISTS);
172 ERRORDESCRIBE(CKM_API_ERROR_DB_ALIAS_UNKNOWN);
173 ERRORDESCRIBE(CKM_API_ERROR_VERIFICATION_FAILED);
174 ERRORDESCRIBE(CKM_API_ERROR_INVALID_FORMAT);
175 ERRORDESCRIBE(CKM_API_ERROR_FILE_ACCESS_DENIED);
176 ERRORDESCRIBE(CKM_API_ERROR_NOT_EXPORTABLE);
177 ERRORDESCRIBE(CKM_API_ERROR_FILE_SYSTEM);
178 ERRORDESCRIBE(CKM_API_ERROR_NOT_SUPPORTED);
179 ERRORDESCRIBE(CKM_API_ERROR_UNKNOWN);
180 default: return "Error not defined";
185 std::string CKMCReadableError(int error) {
186 std::string output("Error: ");
187 output += std::to_string(error);
188 output += " Description: ";
189 output += CKMCErrorToString(error);
193 void save_data(const char* alias, const char *data, int expected_err)
195 save_data(alias, data, strlen(data), expected_err);
198 void save_data(const char* alias, const char *data, size_t len, int expected_err = CKMC_ERROR_NONE)
200 RUNNER_ASSERT(alias);
203 ckmc_raw_buffer_s buffer;
204 buffer.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
206 ckmc_policy_s policy;
207 policy.password = NULL;
208 policy.extractable = true;
210 int ret = ckmc_save_data(alias, buffer, policy);
211 RUNNER_ASSERT_MSG(expected_err == ret, "Saving data failed. "
212 << CKMCErrorToString(ret) << " while expected: "
213 << CKMCErrorToString(expected_err));
217 ScopedSaveData::ScopedSaveData(const char* alias, const char *data, int expected_err) : m_alias(alias)
219 save_data(alias, data, expected_err);
222 ScopedSaveData::~ScopedSaveData()
225 * Let it throw. If we can't remove data then remaining tests results will be
228 check_remove_allowed(m_alias.c_str());
231 ScopedDBUnlock::ScopedDBUnlock(uid_t user_id, const char* passwd) : m_uid(user_id)
234 RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_unlock_user_key(user_id, passwd)), CKMCErrorToString(temp));
236 ScopedDBUnlock::~ScopedDBUnlock()
239 RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_lock_user_key(m_uid)), CKMCErrorToString(temp));
242 void check_remove_allowed(const char* alias)
244 int ret = ckmc_remove_alias(alias);
245 // remove, but ignore non existing
246 RUNNER_ASSERT_MSG((CKMC_ERROR_NONE == ret) || (CKMC_ERROR_DB_ALIAS_UNKNOWN == ret),
247 "Removing data failed: " << CKMCErrorToString(ret));
250 void check_remove_denied(const char* alias)
252 int ret = ckmc_remove_alias(alias);
254 CKMC_ERROR_PERMISSION_DENIED == ret,
255 "App with different label shouldn't have rights to remove this data. "
256 << CKMCReadableError(ret));
259 void check_remove_not_visible(const char* alias)
261 int ret = ckmc_remove_alias(alias);
263 CKMC_ERROR_DB_ALIAS_UNKNOWN == ret,
264 "App with different label shouldn't have rights to see this data. "
265 << CKMCReadableError(ret));
268 void check_read(const char* alias,
270 const char *test_data,
274 ckmc_raw_buffer_s* buffer = NULL;
275 int ret = ckmc_get_data(aliasWithLabel(label, alias).c_str(), NULL, &buffer);
276 RUNNER_ASSERT_MSG(expected_code == ret, "Getting data failed. "
277 "Expected " << CKMCErrorToString(expected_code) << ", "
278 "while result " << CKMCErrorToString(ret));
280 if(expected_code == CKMC_ERROR_NONE)
282 // compare data with expected
285 "Extracted data length do not match expected data length (encrypted?):" <<
286 buffer->size << "!=" << len);
289 memcmp(const_cast<const char*>(reinterpret_cast<char*>(buffer->data)),
290 test_data, buffer->size) == 0,
291 "Extracted data do not match expected data (encrypted?).");
293 ckmc_buffer_free(buffer);
297 void check_read(const char* alias, const char *label, const char *test_data, int expected_code)
299 check_read(alias, label, test_data, strlen(test_data), expected_code);
302 void check_read_allowed(const char* alias, const char *data)
304 // try to read previously saved data - label taken implicitly
305 check_read(alias, NULL, data);
308 void check_read_not_visible(const char* alias)
310 // try to read previously saved data - label taken implicitly
312 ckmc_raw_buffer_s* buffer = NULL;
313 int ret = ckmc_get_data(alias, NULL, &buffer);
314 RUNNER_ASSERT_MSG(CKMC_ERROR_DB_ALIAS_UNKNOWN == ret,
315 "App with different label shouldn't have rights to see this data. " << CKMCErrorToString(ret));
316 ckmc_buffer_free(buffer);
320 void check_key(const char *alias, int expected_error, ckmc_key_type_e expected_type)
322 ckmc_key_s *test_key = NULL;
323 int temp = ckmc_get_key(alias, 0, &test_key);
325 expected_error == temp,
326 "received: " << CKMCReadableError(temp) << " while expected: " << CKMCReadableError(expected_error));
327 if(expected_type != CKMC_KEY_NONE)
330 test_key->key_type == expected_type,
331 "received type: " << test_key->key_type << " while expected type: " << expected_type);
333 ckmc_key_free(test_key);
335 void check_key_allowed(const char *alias, ckmc_key_type_e expected_type)
337 check_key(alias, CKMC_ERROR_NONE, expected_type);
339 void check_key_not_visible(const char *alias)
341 check_key(alias, CKMC_ERROR_DB_ALIAS_UNKNOWN);
343 void check_cert_allowed(const char *alias)
345 ckmc_cert_s *test_cert = NULL;
346 int temp = ckmc_get_cert(alias, 0, &test_cert);
347 ckmc_cert_free(test_cert);
348 RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == temp, CKMCReadableError(temp));
351 void check_cert_not_visible(const char *alias)
353 ckmc_cert_s *test_cert = NULL;
354 int temp = ckmc_get_cert(alias, 0, &test_cert);
355 ckmc_cert_free(test_cert);
356 RUNNER_ASSERT_MSG(CKMC_ERROR_DB_ALIAS_UNKNOWN == temp,
357 "App with different label shouldn't have rights to see this cert. " << CKMCErrorToString(temp));
360 void allow_access(const char* alias, const char* accessor, int permissionMask)
362 // data removal should revoke this access
363 int ret = ckmc_set_permission(alias, accessor, permissionMask);
364 RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == ret, "Trying to allow access returned: "
365 << CKMCErrorToString(ret));
368 void allow_access_negative(const char* alias, const char* accessor, int permissionMask, int expectedCode)
370 // data removal should revoke this access
371 int ret = ckmc_set_permission(alias, accessor, permissionMask);
372 RUNNER_ASSERT_MSG(expectedCode == ret, "Trying to allow access returned "
373 << CKMCErrorToString(ret) << ", while expected: "
374 << CKMCErrorToString(expectedCode));
377 void deny_access(const char* alias, const char* accessor)
379 int ret = ckmc_set_permission(alias, accessor, CKMC_PERMISSION_NONE);
380 RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == ret, "Denying access failed. Error: "
381 << CKMCErrorToString(ret));
384 void deny_access_negative(const char* alias, const char* accessor, int expectedCode)
386 int ret = ckmc_set_permission(alias, accessor, CKMC_PERMISSION_NONE);
387 RUNNER_ASSERT_MSG(expectedCode == ret, "Denying access failed. "
388 << CKMCErrorToString(ret) << ", while expected: "
389 << CKMCErrorToString(expectedCode));
392 void unlock_user_data(uid_t user_id, const char *passwd)
395 auto control = CKM::Control::create();
396 RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->unlockUserKey(user_id, passwd)),
397 "Error=" << CKMErrorToString(ret));
400 void remove_user_data(uid_t user_id)
402 auto control = CKM::Control::create();
403 control->lockUserKey(user_id);
404 control->removeUserData(user_id);
407 void reset_user_data(uid_t user_id, const char *passwd)
409 remove_user_data(user_id);
410 unlock_user_data(user_id, passwd);
413 ckmc_raw_buffer_s prepare_message_buffer(const char * input)
415 ckmc_raw_buffer_s retval;
416 retval.data = const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(input));
417 retval.size = strlen(input);
421 void check_alias_list(const CKM::AliasVector& expected)
423 ckmc_alias_list_s *aliasList = NULL;
424 int ret = ckmc_get_data_alias_list(&aliasList);
425 RUNNER_ASSERT_MSG(ret == 0, "Failed to get the list of data aliases. " << ret << " / " << CKMCErrorToString(ret));
427 CKM::AliasVector actual;
428 ckmc_alias_list_s *plist = aliasList;
431 actual.push_back(plist->alias);
434 ckmc_alias_list_all_free(aliasList);
436 RUNNER_ASSERT_MSG(expected == actual, "Actual list of aliases differ from expected list.");
439 size_t count_aliases(alias_type_ type, size_t minimum_initial_element_count)
441 ckmc_alias_list_s *aliasList = NULL;
446 ec = ckmc_get_key_alias_list(&aliasList);
450 ec = ckmc_get_cert_alias_list(&aliasList);
454 ec = ckmc_get_data_alias_list(&aliasList);
457 RUNNER_ASSERT_MSG(false, "Unsupported value ALIAS_KEY == " << (int)type);
460 if(ec == CKMC_ERROR_DB_ALIAS_UNKNOWN)
463 RUNNER_ASSERT_MSG(ec == CKMC_ERROR_NONE,
464 "Error: alias list failed, ec: " << CKMCErrorToString(ec));
466 ckmc_alias_list_s *plist = aliasList;
467 size_t return_count = 0;
473 ckmc_alias_list_all_free(aliasList);
476 return_count >= minimum_initial_element_count,
477 "Error: alias list failed, current element count: " << return_count <<
478 " while expected minimal count of " << minimum_initial_element_count <<
484 std::string sharedDatabase(const CKM::Alias & alias)
486 return aliasWithLabel(ckmc_owner_id_system, alias.c_str());
489 ckmc_raw_buffer_s* createRandomBufferCAPI(size_t random_bytes)
491 ckmc_raw_buffer_s* buffer = NULL;
492 char* data = static_cast<char*>(malloc(random_bytes*sizeof(char)));
494 generate_random(random_bytes, data);
495 int ret = ckmc_buffer_new(reinterpret_cast<unsigned char*>(data), random_bytes, &buffer);
496 RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Buffer creation failed: " << CKMCErrorToString(ret));
500 CKM::RawBuffer createRandomBuffer(size_t random_bytes)
502 char buffer[random_bytes];
503 generate_random(random_bytes, buffer);
504 return CKM::RawBuffer(buffer, buffer + random_bytes);
507 ckmc_key_s *generate_AES_key(size_t lengthBits, const char *passwd)
509 ckmc_key_s *retval = reinterpret_cast<ckmc_key_s *>(malloc(sizeof(ckmc_key_s)));
510 RUNNER_ASSERT(retval != NULL);
512 RUNNER_ASSERT(lengthBits%8 == 0);
513 char *char_key_AES = reinterpret_cast<char*>(malloc(lengthBits/8));
514 RUNNER_ASSERT(char_key_AES != NULL);
515 generate_random(lengthBits/8, char_key_AES);
517 retval->raw_key = reinterpret_cast<unsigned char *>(char_key_AES);
518 retval->key_size = lengthBits/8;
519 retval->key_type = CKMC_KEY_AES;
520 retval->password = passwd?strdup(passwd):NULL;
525 void validate_AES_key(ckmc_key_s *analyzed)
527 RUNNER_ASSERT_MSG(analyzed, "provided key is NULL");
528 RUNNER_ASSERT_MSG(analyzed->raw_key != NULL, "provided key is empty");
529 RUNNER_ASSERT_MSG(analyzed->key_size==(128/8) ||
530 analyzed->key_size==(192/8) ||
531 analyzed->key_size==(256/8), "provided key length is invalid");
532 RUNNER_ASSERT_MSG(analyzed->key_type = CKMC_KEY_AES, "expected AES key, while got: " << analyzed->key_type);
535 void compare_AES_keys(ckmc_key_s *first, ckmc_key_s *second)
537 validate_AES_key(first);
538 validate_AES_key(second);
540 (first->key_size==second->key_size) &&
541 (memcmp(first->raw_key, second->raw_key, first->key_size)==0),
542 "data has been modified in key manager");
543 // bypassing password intentionally
546 ParamListPtr createParamListPtr()
548 ckmc_param_list_h list = NULL;
549 assert_positive(ckmc_param_list_new, &list);
550 return ParamListPtr(list, ckmc_param_list_free);
553 void assert_buffers_equal(const ckmc_raw_buffer_s b1, const ckmc_raw_buffer_s b2, bool equal)
556 RUNNER_ASSERT_MSG(b1.size == b2.size, "Buffer size differs: " << b1.size << "!=" << b2.size);
557 RUNNER_ASSERT_MSG(0 == memcmp(b1.data, b2.data, b1.size), "Buffer contents differ");
559 RUNNER_ASSERT_MSG(b1.size != b2.size || 0 != memcmp(b1.data, b2.data, b1.size),
560 "Buffers should be different");
564 RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer)
566 return RawBufferPtr(buffer, ckmc_buffer_free);