Alias is not unique user-wide: (alias, label) pair is unique now.
authorMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Wed, 22 Oct 2014 10:23:00 +0000 (12:23 +0200)
committerMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Tue, 17 Feb 2015 10:00:03 +0000 (11:00 +0100)
Client can address items using label::alias syntax.

Change-Id: Ib9429e652e8a73d2d6c62a4164d54229e85cf7d5

17 files changed:
doc/key-manager_doc.h
src/include/ckmc/ckmc-type.h
src/manager/client-async/client-manager-async-impl.cpp
src/manager/client-async/storage-receiver.cpp
src/manager/client-capi/ckmc-manager.cpp
src/manager/client-capi/ckmc-type.cpp
src/manager/client/client-common.cpp
src/manager/client/client-common.h
src/manager/client/client-manager-impl.cpp
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp
src/manager/service/db-crypto.cpp
src/manager/service/db-crypto.h
tests/test_db_crypto.cpp

index df0a083..bcf9270 100644 (file)
@@ -73,8 +73,8 @@
  * Alias Format
  *   - The format of alias is package_id::name.
  *   - If package_id is not provided by a client, the key-manager will add the package_id of the client to the name internally.
- *   - The client can specify only its own pacakge id in the alias when storing a key, certificate, or data.
- *   - A client should specify the pacakge id of the owner in the alias to retrieve a a key, certificate, or data shared by other applications.
+ *   - The client can specify only its own package id in the alias when storing a key, certificate, or data.
+ *   - A client should specify the package id of the owner in the alias to retrieve a a key, certificate, or data shared by other applications.
  *   - Aliases are returned as the format of package_id::name from the key-manager.
  *
  */
index 7d5b807..19f27ca 100644 (file)
@@ -38,6 +38,14 @@ extern "C" {
  */
 
 /**
+ * alias can be provided as an alias alone,
+ * or together with label - in this case,
+ * separator is used to separate label and alias.
+ * @see key-manager_doc.h
+ */
+extern char const * const ckmc_label_alias_separator;
+
+/**
  * @brief Enumeration for key types of key manager.
  * @since_tizen 2.3
  */
index 128353c..db93c5e 100644 (file)
@@ -105,11 +105,13 @@ void ManagerAsync::Impl::removeBinaryData(const ManagerAsync::ObserverPtr& obser
         return;
     }
     try_catch_async([&] {
+        AliasSupport helper(alias);
         sendToStorage(observer,
                       static_cast<int>(LogicCommand::REMOVE),
                       m_counter,
                       static_cast<int>(dataType),
-                      alias);
+                      helper.getAlias(),
+                      helper.getLabel());
     }, [&observer](int error){ observer->ReceivedError(error); } );
 }
 
@@ -124,11 +126,13 @@ void ManagerAsync::Impl::getBinaryData(const ManagerAsync::ObserverPtr& observer
         return;
     }
     try_catch_async([&] {
+        AliasSupport helper(alias);
         sendToStorage(observer,
                       static_cast<int>(LogicCommand::GET),
                       m_counter,
                       static_cast<int>(sendDataType),
-                      alias,
+                      helper.getAlias(),
+                      helper.getLabel(),
                       password);
     }, [&observer](int error){ observer->ReceivedError(error); } );
 }
index 60d0da6..8ba65a6 100644 (file)
@@ -24,6 +24,7 @@
 #include <dpl/log/log.h>
 #include <key-impl.h>
 #include <certificate-impl.h>
+#include <client-common.h>
 
 namespace CKM {
 
@@ -161,8 +162,8 @@ void StorageReceiver::parseGetCommand()
 void StorageReceiver::parseGetListCommand()
 {
     int dataType, retCode;
-    AliasVector aliasVector;
-    m_buffer.Deserialize(retCode, dataType, aliasVector);
+    LabelAliasVector labelAliasVector;
+    m_buffer.Deserialize(retCode, dataType, labelAliasVector);
 
     // check error code
     if (retCode != CKM_API_SUCCESS) {
@@ -170,6 +171,10 @@ void StorageReceiver::parseGetListCommand()
          return;
     }
 
+    AliasVector aliasVector;
+    for(const auto it : labelAliasVector)
+        aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
+
     switch(type(dataType))
     {
     case DataType::KEY:
index e641c80..f1918e0 100644 (file)
 #include <ckmc/ckmc-manager.h>
 #include <ckmc/ckmc-error.h>
 #include <ckmc-type-converter.h>
+#include <client-common.h>
 #include <iostream>
 #include <string.h>
 
+namespace
+{
 CKM::Password _tostring(const char *str)
 {
     if(str == NULL)
@@ -74,6 +77,9 @@ ckmc_cert_list_s *_toNewCkmCertList(CKM::CertificateShPtrVector &certVector)
     return start;
 }
 
+}
+
+
 KEY_MANAGER_CAPI
 int ckmc_save_key(const char *alias, const ckmc_key_s key, const ckmc_policy_s policy)
 {
@@ -109,9 +115,8 @@ int ckmc_remove_key(const char *alias)
     if(alias == NULL) {
         return CKMC_ERROR_INVALID_PARAMETER;
     }
-    CKM::Alias ckmAlias(alias);
 
-    int ret =  mgr->removeKey(ckmAlias);
+    int ret =  mgr->removeKey(alias);
     return to_ckmc_error(ret);
 }
 
@@ -124,10 +129,9 @@ int ckmc_get_key(const char *alias, const char *password, ckmc_key_s **key)
     if(alias == NULL || key == NULL) {
         return CKMC_ERROR_INVALID_PARAMETER;
     }
-    CKM::Alias ckmAlias(alias);
 
     CKM::ManagerShPtr mgr = CKM::Manager::create();
-    if( (ret = mgr->getKey(ckmAlias, _tostring(password), ckmKey)) != CKM_API_SUCCESS) {
+    if( (ret = mgr->getKey(alias, _tostring(password), ckmKey)) != CKM_API_SUCCESS) {
         return to_ckmc_error(ret);
     }
 
@@ -157,8 +161,8 @@ int ckmc_get_key_alias_list(ckmc_alias_list_s** alias_list)
 
     ckmc_alias_list_s *plist = NULL;
 
-    for (auto it = aliasVector.begin(); it != aliasVector.end(); it++) {
-        char *alias = strndup(it->c_str(), it->size());
+    for (const auto it : aliasVector) {
+        char *alias = strndup(it.c_str(), it.size());
 
         if (plist == NULL) { // first
             ret = ckmc_alias_list_new(alias, &plist);
@@ -175,10 +179,9 @@ int ckmc_get_key_alias_list(ckmc_alias_list_s** alias_list)
     }
 
     if(plist == NULL) { // if the alias_list size is zero
-              return CKMC_ERROR_DB_ALIAS_UNKNOWN ;
+        return CKMC_ERROR_DB_ALIAS_UNKNOWN;
     }
 
-
     return CKMC_ERROR_NONE;
 }
 
@@ -212,10 +215,9 @@ int ckmc_remove_cert(const char *alias)
     if(alias == NULL) {
         return CKMC_ERROR_INVALID_PARAMETER;
     }
-    CKM::Alias ckmAlias(alias);
 
     CKM::ManagerShPtr mgr = CKM::Manager::create();
-    int ret = mgr->removeCertificate(ckmAlias);
+    int ret = mgr->removeCertificate(alias);
 
     return to_ckmc_error(ret);
 }
@@ -229,10 +231,9 @@ int ckmc_get_cert(const char *alias, const char *password, ckmc_cert_s **cert)
     if(alias == NULL || cert == NULL) {
         return CKMC_ERROR_INVALID_PARAMETER;
     }
-    CKM::Alias ckmAlias(alias);
 
     CKM::ManagerShPtr mgr = CKM::Manager::create();
-    if( (ret = mgr->getCertificate(ckmAlias, _tostring(password), ckmCert)) != CKM_API_SUCCESS) {
+    if( (ret = mgr->getCertificate(alias, _tostring(password), ckmCert)) != CKM_API_SUCCESS) {
         return to_ckmc_error(ret);
     }
 
@@ -260,8 +261,8 @@ int ckmc_get_cert_alias_list(ckmc_alias_list_s** alias_list) {
 
     ckmc_alias_list_s *plist = NULL;
 
-    for (auto it = aliasVector.begin(); it != aliasVector.end(); it++) {
-        char *alias = strndup(it->c_str(), it->size());
+    for (const auto it : aliasVector) {
+        char *alias = strndup(it.c_str(), it.size());
 
         if (plist == NULL) { // first
             ret  = ckmc_alias_list_new(alias, &plist);
@@ -278,10 +279,9 @@ int ckmc_get_cert_alias_list(ckmc_alias_list_s** alias_list) {
     }
 
     if(plist == NULL) { // if the alias_list size is zero
-            return CKMC_ERROR_DB_ALIAS_UNKNOWN ;
+        return CKMC_ERROR_DB_ALIAS_UNKNOWN;
     }
 
-
     return CKMC_ERROR_NONE;
 }
 
@@ -312,10 +312,9 @@ int ckmc_remove_data(const char *alias)
     if(alias == NULL) {
         return CKMC_ERROR_INVALID_PARAMETER;
     }
-    CKM::Alias ckmAlias(alias);
 
     CKM::ManagerShPtr mgr = CKM::Manager::create();
-    int ret = mgr->removeData(ckmAlias);
+    int ret = mgr->removeData(alias);
     return to_ckmc_error(ret);
 }
 
@@ -328,10 +327,9 @@ int ckmc_get_data(const char *alias, const char *password, ckmc_raw_buffer_s **d
     if(alias == NULL || data == NULL) {
         return CKMC_ERROR_INVALID_PARAMETER;
     }
-    CKM::Alias ckmAlias(alias);
 
     CKM::ManagerShPtr mgr = CKM::Manager::create();
-    if( (ret = mgr->getData(ckmAlias, _tostring(password), ckmBuff)) != CKM_API_SUCCESS) {
+    if( (ret = mgr->getData(alias, _tostring(password), ckmBuff)) != CKM_API_SUCCESS) {
         return to_ckmc_error(ret);
     }
 
@@ -359,8 +357,8 @@ int ckmc_get_data_alias_list(ckmc_alias_list_s** alias_list){
 
     ckmc_alias_list_s *plist = NULL;
 
-    for(auto it = aliasVector.begin(); it != aliasVector.end(); it++) {
-        char *alias = strndup(it->c_str(), it->size());
+    for (const auto it : aliasVector) {
+        char *alias = strndup(it.c_str(), it.size());
 
         if (plist == NULL) { // first
             ret = ckmc_alias_list_new(alias, &plist);
@@ -377,7 +375,7 @@ int ckmc_get_data_alias_list(ckmc_alias_list_s** alias_list){
     }
 
     if(plist == NULL) { // if the alias_list size is zero
-            return CKMC_ERROR_DB_ALIAS_UNKNOWN ;
+        return CKMC_ERROR_DB_ALIAS_UNKNOWN;
     }
 
     return CKMC_ERROR_NONE;
index a549a96..1793717 100644 (file)
@@ -14,7 +14,7 @@
  *  limitations under the License
  *
  *
- * @file        ckmc-type.h
+ * @file        ckmc-type.cpp
  * @author      Yuseok Jeon(yuseok.jeon@samsung.com)
  * @version     1.0
  * @brief       new and free methods for the struct of CAPI
 #include <ckmc/ckmc-type.h>
 #include <ckmc/ckmc-error.h>
 #include <ckmc-type-converter.h>
+#include <protocols.h>
 #include <openssl/x509v3.h>
 #include <openssl/pkcs12.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 
+
+const char * const ckmc_label_alias_separator = CKM::LABEL_ALIAS_SEPARATOR;
+
+
 int _ckmc_load_cert_from_x509(X509 *xCert, ckmc_cert_s **cert);
 
 KEY_MANAGER_CAPI
index 916e5c4..5522ad5 100644 (file)
@@ -37,7 +37,8 @@
 #include <message-buffer.h>
 
 #include <ckm/ckm-error.h>
-
+#include <ckmc/ckmc-type.h>
+#include <protocols.h>
 #include <client-common.h>
 
 IMPLEMENT_SAFE_SINGLETON(CKM::Log::LogSystem);
@@ -74,6 +75,42 @@ int waitForSocket(int sock, int event, int timeout) {
 
 namespace CKM {
 
+AliasSupport::AliasSupport(const Alias &alias)
+{
+    std::size_t separator_pos = alias.rfind(CKM::LABEL_ALIAS_SEPARATOR);
+    if(separator_pos == std::string::npos)
+    {
+        m_label.clear();
+        m_alias = alias;
+    }
+    else
+    {
+        m_label = alias.substr(0, separator_pos);
+        m_alias = alias.substr(separator_pos + strlen(CKM::LABEL_ALIAS_SEPARATOR));
+    }
+}
+
+Alias AliasSupport::merge(const std::string &label, const std::string &alias)
+{
+    if(label.empty())
+        return alias;
+
+    std::stringstream output;
+    output << label << std::string(CKM::LABEL_ALIAS_SEPARATOR) << alias;
+    return output.str();
+}
+
+const Alias & AliasSupport::getAlias() const {
+    return m_alias;
+}
+const std::string & AliasSupport::getLabel() const {
+    return m_label;
+}
+
+bool AliasSupport::isLabelEmpty() const {
+    return m_label.empty();
+}
+
 
 int connectSocket(int& sock, char const * const interface) {
     sockaddr_un clientAddr;
index af88031..77c8cb3 100644 (file)
@@ -30,6 +30,7 @@
 #include <functional>
 
 #include <noncopyable.h>
+#include <ckm/ckm-type.h>
 #include <message-buffer.h>
 
 #define KEY_MANAGER_API __attribute__((visibility("default")))
@@ -40,6 +41,21 @@ extern "C" {
 
 namespace CKM {
 
+class AliasSupport
+{
+    public:
+        AliasSupport(const Alias &alias);
+
+        const std::string & getLabel() const;
+        const Alias & getAlias() const;
+        bool isLabelEmpty() const;
+
+        static Alias merge(const std::string &label, const std::string &alias);
+    private:
+        std::string m_alias;
+        std::string m_label;
+};
+
 int connectSocket(int& sock, char const * const interface);
 
 int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv);
index a067cf8..ac21097 100644 (file)
@@ -127,10 +127,12 @@ int ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
             return CKM_API_ERROR_INPUT_PARAM;
 
         MessageBuffer recv;
+        AliasSupport helper(alias);
         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
                                              m_counter,
                                              static_cast<int>(dataType),
-                                             alias);
+                                             helper.getAlias(),
+                                             helper.getLabel());
         int retCode = sendToServer(
             SERVICE_SOCKET_CKM_STORAGE,
             send.Pop(),
@@ -177,10 +179,12 @@ int ManagerImpl::getBinaryData(
             return CKM_API_ERROR_INPUT_PARAM;
 
         MessageBuffer recv;
+        AliasSupport helper(alias);
         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
                                              m_counter,
                                              static_cast<int>(sendDataType),
-                                             alias,
+                                             helper.getAlias(),
+                                             helper.getLabel(),
                                              password);
         int retCode = sendToServer(
             SERVICE_SOCKET_CKM_STORAGE,
@@ -299,11 +303,15 @@ int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &alia
         int command;
         int counter;
         int tmpDataType;
-        recv.Deserialize(command, counter, retCode, tmpDataType, aliasVector);
+        LabelAliasVector labelAliasVector;
+        recv.Deserialize(command, counter, retCode, tmpDataType, labelAliasVector);
         if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
             return CKM_API_ERROR_UNKNOWN;
         }
 
+        for(const auto it : labelAliasVector)
+            aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
+
         return retCode;
     });
 }
index fbd050c..2abdd76 100644 (file)
@@ -32,6 +32,7 @@ char const * const SERVICE_SOCKET_ECHO = "/tmp/.central-key-manager-echo.sock";
 char const * const SERVICE_SOCKET_CKM_CONTROL = "/tmp/.central-key-manager-api-control.sock";
 char const * const SERVICE_SOCKET_CKM_STORAGE = "/tmp/.central-key-manager-api-storage.sock";
 char const * const SERVICE_SOCKET_OCSP = "/tmp/.central-key-manager-api-ocsp.sock";
+char const * const LABEL_ALIAS_SEPARATOR = "::";
 
 DBDataType toDBDataType(KeyType key) {
     switch(key) {
index 3f4cec0..176d600 100644 (file)
@@ -32,6 +32,7 @@ extern char const * const SERVICE_SOCKET_ECHO;
 extern char const * const SERVICE_SOCKET_CKM_CONTROL;
 extern char const * const SERVICE_SOCKET_CKM_STORAGE;
 extern char const * const SERVICE_SOCKET_OCSP;
+extern char const * const LABEL_ALIAS_SEPARATOR;
 
 enum class ControlCommand : int {
     UNLOCK_USER_KEY,
@@ -79,6 +80,8 @@ enum class DBDataType : int {
     BINARY_DATA,
 };
 
+typedef std::vector<std::pair<std::string, Alias> > LabelAliasVector;
+
 DBDataType toDBDataType(KeyType key);
 KeyType toKeyType(DBDataType dbDataType);
 const char* toDBAccessRight(AccessRight access_right_type);
index 6e8e13a..c0fc54e 100644 (file)
@@ -364,17 +364,30 @@ RawBuffer CKMLogic::removeData(
     Credentials &cred,
     int commandId,
     DBDataType dataType,
-    const Alias &alias)
+    const Alias &alias,
+    const std::string &label)
 {
     int retCode = CKM_API_SUCCESS;
 
     if (0 < m_userDataMap.count(cred.uid)) {
         Try {
-            auto erased = m_userDataMap[cred.uid].database.deleteDBRow(alias, cred.smackLabel);
-            // check if the data existed or not
-            if(!erased) {
-                LogError("No row for given alias and label");
-                retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+            // use client label if not explicitly provided
+            const std::string & label_to_use = label.empty()?cred.smackLabel:label;
+
+            // verify alias and label are correct
+            if (true == checkAliasAndLabelValid(alias, label_to_use))
+            {
+                auto erased = m_userDataMap[cred.uid].database.deleteDBRow(alias, label_to_use);
+                // check if the data existed or not
+                if(!erased) {
+                    LogError("No row for given alias and label");
+                    retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+                }
+            }
+            else
+            {
+                LogError("Invalid label or alias format");
+                retCode = CKM_API_ERROR_INPUT_PARAM;
             }
         } Catch (DBCrypto::Exception::PermissionDenied) {
             LogError("Error: not enough permissions!");
@@ -394,10 +407,24 @@ RawBuffer CKMLogic::removeData(
     return response.Pop();
 }
 
+bool CKMLogic::checkAliasAndLabelValid(const Alias &alias, const std::string &label)
+{
+    // verify the alias is valid
+    if(alias.find(':') != std::string::npos)
+        return false;
+
+    // verify the label is valid
+    if(label.find(LABEL_ALIAS_SEPARATOR) != std::string::npos)
+        return false;
+
+    return true;
+}
+
 int CKMLogic::getDataHelper(
     Credentials &cred,
     DBDataType dataType,
     const Alias &alias,
+    const std::string &label,
     const Password &password,
     DBRow &row)
 {
@@ -406,14 +433,24 @@ int CKMLogic::getDataHelper(
 
     auto &handler = m_userDataMap[cred.uid];
 
+    // use client label if not explicitly provided
+    const std::string & label_to_use = label.empty()?cred.smackLabel:label;
+
+    // verify alias and label are correct
+    if (true != checkAliasAndLabelValid(alias, label_to_use))
+        return CKM_API_ERROR_INPUT_PARAM;
+
     DBCrypto::DBRowOptional row_optional;
-    if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
-        row_optional = handler.database.getDBRow(alias, cred.smackLabel, dataType);
-    } else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST))
-            && (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
+    if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA)
     {
-        row_optional = handler.database.getKeyDBRow(alias, cred.smackLabel);
-    } else {
+        row_optional = handler.database.getDBRow(alias, label_to_use, dataType);
+    }
+    else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST)) &&
+             (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
+    {
+        row_optional = handler.database.getKeyDBRow(alias, label_to_use);
+    }
+    else {
         LogError("Unknown type of requested data" << (int)dataType);
         return CKM_API_ERROR_BAD_REQUEST;
     }
@@ -445,13 +482,14 @@ RawBuffer CKMLogic::getData(
     int commandId,
     DBDataType dataType,
     const Alias &alias,
+    const std::string &label,
     const Password &password)
 {
     int retCode = CKM_API_SUCCESS;
     DBRow row;
 
     try {
-        retCode = getDataHelper(cred, dataType, alias, password, row);
+        retCode = getDataHelper(cred, dataType, alias, label, password, row);
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with error: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
@@ -496,15 +534,15 @@ RawBuffer CKMLogic::getDataList(
     DBDataType dataType)
 {
     int retCode = CKM_API_SUCCESS;
-    AliasVector aliasVector;
+    LabelAliasVector labelAliasVector;
 
     if (0 < m_userDataMap.count(cred.uid)) {
         auto &handler = m_userDataMap[cred.uid];
         Try {
             if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
-                handler.database.getAliases(cred.smackLabel, dataType, aliasVector);
+                handler.database.getAliases(cred.smackLabel, dataType, labelAliasVector);
             } else {
-                handler.database.getKeyAliases(cred.smackLabel, aliasVector);
+                handler.database.getKeyAliases(cred.smackLabel, labelAliasVector);
             }
         } Catch (CKM::Exception) {
             LogError("Failed to get aliases");
@@ -518,7 +556,7 @@ RawBuffer CKMLogic::getDataList(
                                              commandId,
                                              retCode,
                                              static_cast<int>(dataType),
-                                             aliasVector);
+                                             labelAliasVector);
     return response.Pop();
 }
 
@@ -696,7 +734,7 @@ RawBuffer CKMLogic::getCertificateChain(
         }
 
         for (auto &i: aliasVector) {
-            retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i, Password(), row);
+            retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i, std::string(), Password(), row);
 
             if (retCode != CKM_API_SUCCESS)
                 goto senderror;
@@ -750,7 +788,7 @@ RawBuffer CKMLogic::createSignature(
 
     try {
         do {
-            retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, privateKeyAlias, password, row);
+            retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, privateKeyAlias, std::string(), password, row);
             if (CKM_API_SUCCESS != retCode) {
                 LogError("getDataHelper return error");
                 break;
@@ -804,12 +842,12 @@ RawBuffer CKMLogic::verifySignature(
             DBRow row;
             KeyImpl key;
 
-            retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertAlias, password, row);
+            retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertAlias, std::string(), password, row);
 
             if (retCode == CKM_API_SUCCESS) {
                 key = KeyImpl(row.data);
             } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
-                retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertAlias, password, row);
+                retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertAlias, std::string(), password, row);
                 if (retCode != CKM_API_SUCCESS)
                     break;
                 CertificateImpl cert(row.data, DataFormat::FORM_DER);
index e56a727..2a0817d 100644 (file)
@@ -86,13 +86,15 @@ public:
         Credentials &cred,
         int commandId,
         DBDataType dataType,
-        const Alias &alias);
+        const Alias &alias,
+        const std::string &label);
 
     RawBuffer getData(
         Credentials &cred,
         int commandId,
         DBDataType dataType,
         const Alias &alias,
+        const std::string &label,
         const Password &password);
 
     RawBuffer getDataList(
@@ -175,6 +177,7 @@ private:
         Credentials &cred,
         DBDataType dataType,
         const Alias &alias,
+        const std::string &label,
         const Password &password,
         DBRow &row);
 
@@ -193,6 +196,11 @@ private:
         const Password &password,           // password for public_key (optional)
         const KeyImpl &genericKey);
 
+    // @return true if alias & label are proper, false otherwise
+    static bool checkAliasAndLabelValid(
+        const Alias &alias,
+        const std::string &label);
+
     std::map<uid_t, UserData> m_userDataMap;
     CertificateStore m_certStore;
     CCModeState cc_mode_status;
index 4cc3120..fff8313 100644 (file)
@@ -192,6 +192,7 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
     int msgID;
     int tmpDataType;
     Alias alias;
+    std::string label;
     std::string user;
 
     buffer.Deserialize(command);
@@ -223,22 +224,24 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
         }
         case LogicCommand::REMOVE:
         {
-            buffer.Deserialize(tmpDataType, alias);
+            buffer.Deserialize(tmpDataType, alias, label);
             return m_logic->removeData(
                 cred,
                 msgID,
                 static_cast<DBDataType>(tmpDataType),
-                alias);
+                alias,
+                label);
         }
         case LogicCommand::GET:
         {
             Password password;
-            buffer.Deserialize(tmpDataType, alias, password);
+            buffer.Deserialize(tmpDataType, alias, label, password);
             return m_logic->getData(
                 cred,
                 msgID,
                 static_cast<DBDataType>(tmpDataType),
                 alias,
+                label,
                 password);
         }
         case LogicCommand::GET_LIST:
@@ -339,28 +342,26 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
         case LogicCommand::ALLOW_ACCESS:
         {
             Alias item_alias;
-            std::string accessor_label;
             int req_rights;
-            buffer.Deserialize(item_alias, accessor_label, req_rights);
+            buffer.Deserialize(item_alias, label, req_rights);
             return m_logic->allowAccess(
                 cred,
                 command,
                 msgID,
                 item_alias,
-                accessor_label,
+                label,
                 static_cast<AccessRight>(req_rights));
         }
         case LogicCommand::DENY_ACCESS:
         {
             Alias item_alias;
-            std::string accessor_label;
-            buffer.Deserialize(item_alias, accessor_label);
+            buffer.Deserialize(item_alias, label);
             return m_logic->denyAccess(
                 cred,
                 command,
                 msgID,
                 item_alias,
-                accessor_label);
+                label);
         }
         default:
             Throw(Exception::BrokenProtocol);
index 7155846..d2103b5 100644 (file)
@@ -33,8 +33,8 @@ namespace {
     const char *key_table = "KEY_TABLE";
     const char *permission_table = "PERMISSION_TABLE";
 
-// CKM_TABLE (alias TEXT, label TEXT, restricted INT, exportable INT, dataType INT,
-//            algorithmType INT, encryptionScheme INT, iv BLOB, dataSize INT, data BLOB)
+// CKM_TABLE (alias TEXT, label TEXT, restricted INT, exportable INT, dataType INT, algorithmType INT,
+//            encryptionScheme INT, iv BLOB, dataSize INT, data BLOB, tag BLOB, idx INT )
 
     const char *db_create_main_cmd =
             "CREATE TABLE CKM_TABLE("
@@ -48,8 +48,9 @@ namespace {
             "   dataSize INTEGER NOT NULL,"
             "   data BLOB NOT NULL,"
             "   tag BLOB NOT NULL,"
-            "   PRIMARY KEY(alias)"
-            "); CREATE INDEX alias_idx ON CKM_TABLE(alias);";
+            "   idx INTEGER PRIMARY KEY AUTOINCREMENT,"
+            "   UNIQUE(alias, label)"
+            "); CREATE INDEX ckm_index_label ON CKM_TABLE(label);"; // based on ANALYZE and performance test result
 
     const char *insert_main_cmd =
             "INSERT INTO CKM_TABLE("
@@ -70,10 +71,14 @@ namespace {
             //                                          1
             "SELECT dataType FROM CKM_TABLE WHERE alias=?;";
 
-    const char *select_check_global_alias_cmd =
+    const char *select_label_global_alias_cmd =
             //                                       1
             "SELECT label FROM CKM_TABLE WHERE alias=?;";
 
+    const char *select_label_index_global_alias_cmd =
+            //                                       1
+            "SELECT label, idx FROM CKM_TABLE WHERE alias=?;";
+
     const char *select_key_alias_cmd =
             //                                   1
             "SELECT * FROM CKM_TABLE WHERE alias=?"
@@ -104,19 +109,20 @@ namespace {
             "DELETE FROM KEY_TABLE WHERE label=?";
 
 
-// PERMISSION_TABLE (label TEXT, label TEXT, access_flags TEXT)
+// PERMISSION_TABLE (alias TEXT, label TEXT, access_flags TEXT, idx INT)
 
     const char *db_create_permission_cmd =
             "CREATE TABLE PERMISSION_TABLE("
             "   alias TEXT NOT NULL,"
             "   label TEXT NOT NULL,"
             "   accessFlags TEXT NOT NULL,"
-            "   FOREIGN KEY(alias) REFERENCES CKM_TABLE(alias) ON DELETE CASCADE,"
+            "   idx INTEGER NOT NULL,"
+            "   FOREIGN KEY(idx) REFERENCES CKM_TABLE(idx) ON DELETE CASCADE,"
             "   PRIMARY KEY(alias, label)"
-            "); CREATE INDEX alias_label_idx ON PERMISSION_TABLE(alias, label);";
+            "); CREATE INDEX perm_index_idx ON PERMISSION_TABLE(idx);"; // based on ANALYZE and performance test result
 
     const char *set_permission_alias_cmd =
-            "REPLACE INTO PERMISSION_TABLE(alias, label, accessFlags) VALUES (?, ?, ?);";
+            "REPLACE INTO PERMISSION_TABLE(alias, label, accessFlags, idx) VALUES (?, ?, ?, ?);";
 
     const char *select_permission_cmd =
             //                                                    1           2
@@ -131,11 +137,11 @@ namespace {
 
     const char *select_type_cross_cmd =
             //                                                                                                        1              2             3
-            "SELECT C.alias FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.alias = P.alias WHERE C.dataType=? AND (C.label=? OR (P.label=? AND P.accessFlags IS NOT NULL)) GROUP BY C.alias;";
+            "SELECT C.label, C.alias FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.alias = P.alias WHERE C.dataType=? AND (C.label=? OR (P.label=? AND P.accessFlags IS NOT NULL)) GROUP BY C.alias;";
 
     const char *select_key_type_cross_cmd =
             //                                                                                                       1                 2              3             4
-            "SELECT C.alias FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.alias=P.alias WHERE C.dataType>=? AND C.dataType<=? AND (C.label=? OR (P.label=? AND P.accessFlags IS NOT NULL)) GROUP BY C.alias;";
+            "SELECT C.label, C.alias FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.alias=P.alias WHERE C.dataType>=? AND C.dataType<=? AND (C.label=? OR (P.label=? AND P.accessFlags IS NOT NULL)) GROUP BY C.alias;";
 }
 
 namespace CKM {
@@ -218,17 +224,35 @@ using namespace DB;
         transaction.commit();
     }
 
-    std::string DBCrypto::getLabelForAlias(const std::string& alias) const {
+    void DBCrypto::getLabelForAlias(const std::string& alias, std::string & label) const {
         SqlConnection::DataCommandUniquePtr checkCmd =
-                m_connection->PrepareDataCommand(select_check_global_alias_cmd);
+                m_connection->PrepareDataCommand(select_label_global_alias_cmd);
         checkCmd->BindString(1, alias.c_str());
         if(checkCmd->Step()) {
-            return checkCmd->GetColumnString(0);
+            label = checkCmd->GetColumnString(0);
         } else
-            return std::string();
+            label.clear();
+    }
+
+    void DBCrypto::getLabelForAlias(const std::string& alias, std::string & label, int & index) const
+    {
+        SqlConnection::DataCommandUniquePtr checkCmd =
+                m_connection->PrepareDataCommand(select_label_index_global_alias_cmd);
+        checkCmd->BindString(1, alias.c_str());
+        if(checkCmd->Step()) {
+            label = checkCmd->GetColumnString(0);
+            index = checkCmd->GetColumnInteger(1);
+        }
+        else
+        {
+            label.clear();
+            index = -1;
+        }
     }
+
     bool DBCrypto::checkGlobalAliasExist(const std::string& alias) const {
-        std::string label = this->getLabelForAlias(alias);
+        std::string label;
+        getLabelForAlias(alias, label);
         if(label.empty() == false) {
             LogDebug("Global alias '" << alias  << "' exists already for label " << label);
             return true;
@@ -436,7 +460,7 @@ using namespace DB;
     void DBCrypto::getSingleType(
             const std::string &clnt_label,
             DBDataType type,
-            AliasVector& aliases) const
+            LabelAliasVector& aliases) const
     {
         Try{
             SqlConnection::DataCommandUniquePtr selectCommand =
@@ -446,9 +470,9 @@ using namespace DB;
             selectCommand->BindString(3, clnt_label.c_str());
 
             while(selectCommand->Step()) {
-                Alias alias;
-                alias = selectCommand->GetColumnString(0);
-                aliases.push_back(alias);
+                std::string label = selectCommand->GetColumnString(0);
+                Alias alias = selectCommand->GetColumnString(1);
+                aliases.push_back(std::make_pair(label, alias));
             }
             return;
         } Catch (SqlConnection::Exception::InvalidColumn) {
@@ -465,13 +489,13 @@ using namespace DB;
     void DBCrypto::getAliases(
         const std::string &clnt_label,
         DBDataType type,
-        AliasVector& aliases)
+        LabelAliasVector& aliases)
     {
         getSingleType(clnt_label, type, aliases);
     }
 
 
-    void DBCrypto::getKeyAliases(const std::string &clnt_label, AliasVector &aliases)
+    void DBCrypto::getKeyAliases(const std::string &clnt_label, LabelAliasVector &aliases)
     {
         Try{
             Transaction transaction(this);
@@ -483,9 +507,9 @@ using namespace DB;
             selectCommand->BindString(4, clnt_label.c_str());
 
             while(selectCommand->Step()) {
-                Alias alias;
-                alias = selectCommand->GetColumnString(0);
-                aliases.push_back(alias);
+                std::string label = selectCommand->GetColumnString(0);
+                Alias alias = selectCommand->GetColumnString(1);
+                aliases.push_back(std::make_pair(label, alias));
             }
             transaction.commit();
             return;
@@ -504,7 +528,8 @@ using namespace DB;
         Try {
             Transaction transaction(this);
 
-            std::string owner_label = getLabelForAlias(alias);
+            std::string owner_label;
+            getLabelForAlias(alias, owner_label);
             if( ! owner_label.empty() )
             {
                 // check access rights here
@@ -621,7 +646,9 @@ using namespace DB;
             Transaction transaction(this);
 
             // check if label is present
-            std::string owner_label = getLabelForAlias(alias);
+            int ckm_tab_index;
+            std::string owner_label;
+            getLabelForAlias(alias, owner_label, ckm_tab_index);
             if( ! owner_label.empty() )
             {
                 // owner can not add permissions to itself
@@ -638,6 +665,7 @@ using namespace DB;
                 setPermissionCommand->BindString(1, alias.c_str());
                 setPermissionCommand->BindString(2, accessor_label.c_str());
                 setPermissionCommand->BindString(3, toDBAccessRight(value_to_set));
+                setPermissionCommand->BindInteger(4, ckm_tab_index);
                 setPermissionCommand->Step();
                 transaction.commit();
                 return CKM_API_SUCCESS;
@@ -663,7 +691,8 @@ using namespace DB;
         Try {
             Transaction transaction(this);
 
-            std::string owner_label = getLabelForAlias(alias);
+            std::string owner_label;
+            getLabelForAlias(alias, owner_label);
             if( ! owner_label.empty() )
             {
                 // check access rights here - only owner can modify permissions
index cf6922e..ab024db 100644 (file)
@@ -75,8 +75,8 @@ namespace CKM {
             void getAliases(
                     const std::string &clnt_label,
                     DBDataType dataType,
-                    AliasVector &aliases);
-            void getKeyAliases(const std::string &clnt_label, AliasVector &aliases);
+                    LabelAliasVector &aliases);
+            void getKeyAliases(const std::string &clnt_label, LabelAliasVector &aliases);
             bool deleteDBRow(
                     const Alias& alias,
                     const std::string &clnt_label);
@@ -206,9 +206,10 @@ namespace CKM {
                     const char *create_cmd,
                     const char *table_name);
             bool checkAliasExist(const std::string &alias) const;
-            std::string getLabelForAlias(const std::string& alias) const;
+            void getLabelForAlias(const std::string& alias, std::string & label) const;
+            void getLabelForAlias(const std::string& alias, std::string & label, int & index) const;
             bool checkGlobalAliasExist(const std::string& alias) const;
-            void getSingleType(const std::string &clnt_label, DBDataType type, AliasVector& aliases) const;
+            void getSingleType(const std::string &clnt_label, DBDataType type, LabelAliasVector& aliases) const;
    };
 } // namespace CKM
 
index 4344541..aeceb3f 100644 (file)
@@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
     for(unsigned int l=0; l<num_labels; l++)
     {
         generate_label(l, label);
-        AliasVector expect_no_data;
+        LabelAliasVector expect_no_data;
         BOOST_REQUIRE_NO_THROW(m_db.getAliases(label, DBDataType::BINARY_DATA, expect_no_data));
         BOOST_REQUIRE(0 == expect_no_data.size());
     }
@@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(DBperfGetAliasList)
     performance_start("getAliases");
     for(unsigned int t=0; t<(c_test_retries/num_labels); t++)
     {
-        AliasVector ret_list;
+        LabelAliasVector ret_list;
         generate_label(rand()%num_labels, label);
 
         BOOST_REQUIRE_NO_THROW(m_db.getAliases(label, DBDataType::BINARY_DATA, ret_list));