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