CKM: Add tests for new API: list alias with information about password protection 23/186023/6
authorErnest Borowski <e.borowski@partner.samsung.com>
Fri, 23 Feb 2018 13:38:41 +0000 (14:38 +0100)
committerErnest Borowski <e.borowski@partner.samsung.com>
Wed, 20 Feb 2019 15:50:47 +0000 (16:50 +0100)
Change-Id: Iae18e91e1a3335cd5ca55811d0edbfd98eee59c6
Signed-off-by: Ernest Borowski <e.borowski@partner.samsung.com>
src/ckm/ckm-common.cpp
src/ckm/ckm-common.h
src/ckm/privileged/system-db.cpp
src/ckm/unprivileged/main.cpp

index 914757c..4d4b596 100644 (file)
@@ -21,6 +21,7 @@
 #include <string>
 #include <fstream>
 #include <sys/smack.h>
+#include <ckm/ckm-type.h>
 #include <ckmc/ckmc-type.h>
 #include <ckm-common.h>
 #include <tests_common.h>
@@ -30,6 +31,7 @@
 #include <ckmc/ckmc-manager.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <unordered_map>
 
 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<unsigned char*>(const_cast<char*>(data));
     buffer.size = len;
     ckmc_policy_s policy;
-    policy.password = NULL;
-    policy.extractable = true;
-
+    policy.password = const_cast<char*>(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<std::string, bool> 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();
+}
index d5f6081..5a32bed 100644 (file)
@@ -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 <uid_t ...Args>
index bf920fe..e9c7a5d 100644 (file)
@@ -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);
+}
index 6c2fe63..2f11f2e 100644 (file)
@@ -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);