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