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