From: Ernest Borowski Date: Fri, 23 Feb 2018 13:38:41 +0000 (+0100) Subject: CKM: Add tests for new API: list alias with information about password protection X-Git-Tag: security-manager_5.5_testing~7^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0c266a534a2c97cc7c0e7d5d62086b72c097d44b;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git CKM: Add tests for new API: list alias with information about password protection Change-Id: Iae18e91e1a3335cd5ca55811d0edbfd98eee59c6 Signed-off-by: Ernest Borowski --- diff --git a/src/ckm/ckm-common.cpp b/src/ckm/ckm-common.cpp index 914757c7..4d4b596a 100644 --- a/src/ckm/ckm-common.cpp +++ b/src/ckm/ckm-common.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include const std::string SMACK_USER_APP_PREFIX = "User::Pkg::"; const char *SYSTEM_LABEL = ckmc_owner_id_system; @@ -159,12 +161,8 @@ std::string CKMCReadableError(int error) { return output; } -void save_data(const char* alias, const char *data, int expected_err) -{ - save_data(alias, data, strlen(data), expected_err); -} - -void save_data(const char* alias, const char *data, size_t len, int expected_err = CKMC_ERROR_NONE) +void save_data(const char* alias, const char *data, size_t len, const char* password, + int expected_err, bool exportable) { RUNNER_ASSERT(alias); RUNNER_ASSERT(data); @@ -173,14 +171,22 @@ void save_data(const char* alias, const char *data, size_t len, int expected_err buffer.data = reinterpret_cast(const_cast(data)); buffer.size = len; ckmc_policy_s policy; - policy.password = NULL; - policy.extractable = true; - + policy.password = const_cast(password); + policy.extractable = exportable; int ret = ckmc_save_data(alias, buffer, policy); RUNNER_ASSERT_MSG(expected_err == ret, "Saving data failed. " - << CKMCErrorToString(ret) << " while expected: " - << CKMCErrorToString(expected_err)); + << CKMCErrorToString(ret) << " while expected: " + << CKMCErrorToString(expected_err)); +} + +void save_data(const char* alias, const char *data, int expected_err, bool exportable) +{ + save_data(alias, data, strlen(data), nullptr, expected_err, exportable); +} +void save_data(const char* alias, const char *data, size_t len, int expected_err, bool exportable) +{ + save_data(alias, data, len, nullptr, expected_err, exportable); } ScopedSaveData::ScopedSaveData(const char* alias, const char *data, int expected_err) : m_alias(alias) @@ -405,6 +411,74 @@ void check_alias_list(const CKM::AliasVector& expected) RUNNER_ASSERT_MSG(expected == actual, "Actual list of aliases differ from expected list."); } +void check_alias_info_list_helper(const CKM::AliasPwdVector& expected, const CKM::AliasPwdVector& actual, + const std::string userSmackLabel) +{ + std::string errorLogMsg; + std::unordered_map aliasPwdMap; + + RUNNER_ASSERT_MSG(expected.size() == actual.size(), "Aliases item count differs, expected: " << + expected.size() << " actual: " << actual.size()); + + for (const auto &it : actual) + { + aliasPwdMap[std::get<0>(it)] = std::get<1>(it); + } + + + for (const auto &it : expected) + { + auto aliasPwd = aliasPwdMap.find(userSmackLabel + std::get<0>(it)); + if (aliasPwd != aliasPwdMap.end()) { + if (aliasPwd->second != std::get<1>(it)) { + errorLogMsg += "Alias: " + std::get<0>(it) + " has wrong encryption status: " + + std::to_string(std::get<1>(it)) + "\n"; + } + } + else { + errorLogMsg += "Expected alias: " + std::get<0>(it) + " not found.\n"; + } + } + + if (!errorLogMsg.empty()) { + for (const auto &it : actual) + { + errorLogMsg += "Actual alias: " + std::get<0>(it) + " status: " + + std::to_string(std::get<1>(it)) + "\n"; + } + RUNNER_FAIL_MSG("Actual list of aliases differ from expected list.\n" + errorLogMsg); + } +} + +void check_alias_info_list(const CKM::AliasPwdVector& expected, const std::string& userSmackLabel) +{ + ckmc_alias_info_list_s *aliasInfoList = NULL; + int ret = ckmc_get_data_alias_info_list(&aliasInfoList); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get the list of data aliases. " << ret << " / " + << CKMCErrorToString(ret)); + + CKM::AliasPwdVector actual; + ckmc_alias_info_list_s *plist = aliasInfoList; + char* alias; + bool isPasswordProtected; + unsigned int it = 0; + while (plist) + { + ret = ckmc_alias_info_get_alias(plist->info, &alias); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get alias. " << ret << " / " + << CKMCErrorToString(ret)); + ret = ckmc_alias_info_is_password_protected(plist->info, &isPasswordProtected); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get password protection status" << ret << " / " + << CKMCErrorToString(ret)); + RUNNER_ASSERT_MSG(alias != nullptr, "Got null alias. Iterator: " << it); + actual.push_back(std::make_pair(alias, isPasswordProtected)); + plist = plist->next; + it++; + } + ckmc_alias_info_list_all_free(aliasInfoList); + check_alias_info_list_helper(expected, actual, userSmackLabel); +} + size_t count_aliases(alias_type_ type, size_t minimum_initial_element_count) { ckmc_alias_list_s *aliasList = NULL; @@ -534,3 +608,10 @@ RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer) { return RawBufferPtr(buffer, ckmc_buffer_free); } + +CKM::Policy generate_ckm_policy(int iterator_nr) { + if (iterator_nr % 2) { // policy with password and with / without extractable flag + return CKM::Policy(CKM::Password("test_pwd"), iterator_nr % 4); + } + return CKM::Policy(); +} diff --git a/src/ckm/ckm-common.h b/src/ckm/ckm-common.h index d5f6081e..5a32bedb 100644 --- a/src/ckm/ckm-common.h +++ b/src/ckm/ckm-common.h @@ -90,8 +90,12 @@ std::string aliasWithLabel(const char *label, const char *alias); std::string aliasWithLabelFromSelf(const char *alias); -void save_data(const char* alias, const char *data, int expected_err = CKMC_ERROR_NONE); -void save_data(const char* alias, const char *data, size_t len, int expected_err); +void save_data(const char* alias, const char *data, size_t len, const char* password, + int expected_err = CKMC_ERROR_NONE, bool exportable = true); +void save_data(const char* alias, const char *data, int expected_err = CKMC_ERROR_NONE, + bool exportable = true); +void save_data(const char* alias, const char *data, size_t len, + int expected_err = CKMC_ERROR_NONE, bool exportable = true); class ScopedSaveData { public: @@ -144,6 +148,10 @@ void reset_user_data(uid_t user_id, const char *passwd); ckmc_raw_buffer_s prepare_message_buffer(const char * input); void check_alias_list(const CKM::AliasVector& expected); +void check_alias_info_list_helper(const CKM::AliasPwdVector& expected, const CKM::AliasPwdVector& actual, + const std::string userSmackLabel = ""); +void check_alias_info_list(const CKM::AliasPwdVector& expected, + const std::string& userSmackLabel = ""); typedef enum { ALIAS_KEY, @@ -158,6 +166,7 @@ ckmc_raw_buffer_s* createRandomBufferCAPI(size_t random_bytes); ckmc_key_s *generate_AES_key(size_t lengthBits, const char *passwd); void validate_AES_key(ckmc_key_s *analyzed); void compare_AES_keys(ckmc_key_s *first, ckmc_key_s *second); // true if equal +CKM::Policy generate_ckm_policy(int iterator_nr); // generates policy based on given number // Test env class for database cleanup. Pass database uids to cleanup before and after test template diff --git a/src/ckm/privileged/system-db.cpp b/src/ckm/privileged/system-db.cpp index bf920fee..e9c7a5d9 100644 --- a/src/ckm/privileged/system-db.cpp +++ b/src/ckm/privileged/system-db.cpp @@ -43,6 +43,7 @@ const char* APP_PASS = "user-pass"; const char* TEST_ALIAS = "test-alias"; const char* INVALID_LABEL = "coco-jumbo"; +const char* TEST_PASSWORD = "ckm-password"; std::string TEST_SYSTEM_ALIAS = sharedDatabase(TEST_ALIAS); std::string TEST_SYSTEM_ALIAS_2 = sharedDatabase("test-alias-2"); @@ -543,3 +544,49 @@ RUNNER_TEST(T5045_SYSTEM_DB_ADD_WITH_INVALID_LABEL, RemoveDataEnv<0>) save_data(aliasWithLabel(SYSTEM_LABEL, TEST_ALIAS).c_str(), TEST_DATA); check_read(TEST_ALIAS, SYSTEM_LABEL, TEST_DATA); } + +RUNNER_TEST(T5046_CLIENT_GET_ALIAS_STATUS_NO_PASSWORD, RemoveDataEnv<0>) +{ + // [prepare] + // start as system service + // add data A to the system DB + // add data B to the system DB + // [test] + // system service list alias status - expect both items to have no password protection + + // [prepare] + save_data(TEST_SYSTEM_ALIAS.c_str(), TEST_DATA); + save_data(TEST_SYSTEM_ALIAS_2.c_str(), TEST_DATA); + + // [test] + CKM::AliasPwdVector aliasPwdVector; + aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS.c_str(), false)); + aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS_2.c_str(), false)); + + check_alias_info_list(aliasPwdVector); +} + +RUNNER_TEST(T5047_CLIENT_GET_ALIAS_STATUS_PASSWORD_PROTECTED, RemoveDataEnv<0>) +{ + // [prepare] + // start as system service + // add data A to the system DB + // add data B with password protection to the system DB + // add data C with password protection to the system DB + // [test] + // system service list alias status - expect: first alias - no password protection, second, third - + // protected with password + + // [prepare] + save_data(TEST_SYSTEM_ALIAS.c_str(), TEST_DATA); + save_data(TEST_SYSTEM_ALIAS_2.c_str(), TEST_DATA, strlen(TEST_DATA), TEST_PASSWORD); + save_data((TEST_SYSTEM_ALIAS_2 + "1").c_str(), TEST_DATA, strlen(TEST_DATA), TEST_PASSWORD); + + // [test] + CKM::AliasPwdVector aliasPwdVector; + aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS.c_str(), false)); + aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS_2.c_str(), true)); + aliasPwdVector.push_back(std::make_pair((TEST_SYSTEM_ALIAS_2 + "1").c_str(),true)); + + check_alias_info_list(aliasPwdVector); +} diff --git a/src/ckm/unprivileged/main.cpp b/src/ckm/unprivileged/main.cpp index 6c2fe632..2f11f2e9 100644 --- a/src/ckm/unprivileged/main.cpp +++ b/src/ckm/unprivileged/main.cpp @@ -50,6 +50,16 @@ const int USER_TEST = 5001; const CKM::CertificateShPtrVector EMPTY_CERT_VECTOR; const CKM::AliasVector EMPTY_ALIAS_VECTOR; +const std::string KEY_PEM = "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2b1bXDa+S8/MGWnMkru4\n" + "T4tUddtZNi0NVjQn9RFH1NMa220GsRhRO56F77FlSVFKfSfVZKIiWg6C+DVCkcLf\n" + "zXJ/Z0pvwOQYBAqVMFjV6efQGN0JzJ1Unu7pPRiZl7RKGEI+cyzzrcDyrLLrQ2W7\n" + "0ZySkNEOv6Frx9JgC5NExuYY4lk2fQQa38JXiZkfyzif2em0px7mXbyf5LjccsKq\n" + "v1e+XLtMsL0ZefRcqsP++NzQAI8fKX7WBT+qK0HJDLiHrKOTWYzx6CwJ66LD/vvf\n" + "j55xtsKDLVDbsotvf8/m6VLMab+vqKk11TP4tq6yo0mwyTADvgl1zowQEO9I1W6o\n" + "zQIDAQAB\n" + "-----END PUBLIC KEY-----"; + } // namespace anonymous /* @@ -391,6 +401,118 @@ RUNNER_TEST(T1023_app_user_save_keys_exportable_flag) "Error=" << CKMErrorToString(temp)); } +RUNNER_TEST(T1024_app_user_save_keys_get_alias_pwd) +{ + remove_user_data(USER_APP); + + int exitCode; + const int aliasNameCount = 10; + auto manager = CKM::Manager::create(); + + CKM::AliasPwdVector expected; + CKM::RawBuffer buffer(KEY_PEM.begin(), KEY_PEM.end()); + auto key = CKM::Key::create(buffer, CKM::Password()); + std::string currentAlias; + + size_t beforeSaveAliasCount = count_aliases(ALIAS_KEY); + // make aliases with & without: password protection, exportable flag + for (int it = 0; it < aliasNameCount; ++it) + { + CKM::Policy policy = generate_ckm_policy(it); + currentAlias = "T1024_appkey" + std::to_string(it); + expected.push_back(std::make_pair(currentAlias, !policy.password.empty())); + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (exitCode = manager->saveKey(currentAlias, key, policy)), + "Error=" << CKMErrorToString(exitCode)); + } + + CKM::AliasPwdVector actual; + + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (exitCode = manager->getKeyAliasPwdVector(actual)), + "Error=" << CKMErrorToString(exitCode)); + RUNNER_ASSERT_MSG( + actual.size() == (beforeSaveAliasCount + aliasNameCount), + "Wrong aliases count: " << actual.size() << " Expected: " + << (beforeSaveAliasCount + aliasNameCount)); + check_alias_info_list_helper(expected, actual, "/User "); + + remove_user_data(USER_APP); +} + +RUNNER_TEST(T1025_app_user_save_certificates_get_alias_pwd) +{ + remove_user_data(USER_APP); + + int exitCode; + const int aliasNameCount = 10; + auto manager = CKM::Manager::create(); + + CKM::AliasPwdVector expected; + auto cert = TestData::getTestCertificate(TestData::THIRD_PARTY_LEAF); + std::string currentAlias; + + size_t beforeSaveAliasCount = count_aliases(ALIAS_CERT); + for (int it = 0; it < aliasNameCount; ++it) + { + CKM::Policy policy = generate_ckm_policy(it); + currentAlias = "T1025_appcert" + std::to_string(it); + expected.push_back(std::make_pair(currentAlias, !policy.password.empty())); + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (exitCode = manager->saveCertificate(currentAlias, cert, policy)), + "Error=" << CKMErrorToString(exitCode)); + } + + CKM::AliasPwdVector actual; + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (exitCode = manager->getCertificateAliasPwdVector(actual)), + "Error=" << CKMErrorToString(exitCode)); + RUNNER_ASSERT_MSG( + actual.size() == (beforeSaveAliasCount + aliasNameCount), + "Wrong aliases count: " << actual.size() << " Expected: " + << (beforeSaveAliasCount + aliasNameCount)); + check_alias_info_list_helper(expected, actual, "/User "); + + remove_user_data(USER_APP); +} + +RUNNER_TEST(T1026_app_user_save_data_get_alias_pwd) +{ + remove_user_data(USER_APP); + + int exitCode; + const int aliasNameCount = 10; + auto manager = CKM::Manager::create(); + + CKM::AliasPwdVector expected; + std::string binData = "My bin data"; + CKM::RawBuffer buffer(binData.begin(), binData.end()); + std::string currentAlias; + + size_t beforeSaveAliasCount = count_aliases(ALIAS_DATA); + for (int it = 0; it < aliasNameCount; ++it) + { + CKM::Policy policy = generate_ckm_policy(it); + currentAlias = "T1026_appdata" + std::to_string(it); + expected.push_back(std::make_pair(currentAlias, !policy.password.empty())); + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (exitCode = manager->saveData(currentAlias, buffer, policy)), + "Error=" << CKMErrorToString(exitCode)); + } + + CKM::AliasPwdVector actual; + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (exitCode = manager->getDataAliasPwdVector(actual)), + "Error=" << CKMErrorToString(exitCode)); + RUNNER_ASSERT_MSG( + actual.size() == (beforeSaveAliasCount + aliasNameCount), + "Wrong aliases count: " << actual.size() << " Expected: " + << (beforeSaveAliasCount + aliasNameCount)); + check_alias_info_list_helper(expected, actual, "/User "); + + remove_user_data(USER_APP); +} + RUNNER_TEST(T1029_deinit) { remove_user_data(USER_APP);