DBCrypto access control re-factor: access control moved into additional layer.
authorMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Thu, 6 Nov 2014 15:14:49 +0000 (16:14 +0100)
committerMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Tue, 17 Feb 2015 10:18:49 +0000 (11:18 +0100)
Change-Id: I3ea1ce1a858b69c4a5a7365dffa1344b64aab0b6

30 files changed:
src/CMakeLists.txt
src/include/ckm/ckm-control.h
src/include/ckm/ckm-manager-async.h
src/include/ckm/ckm-manager.h
src/include/ckm/ckm-type.h
src/manager/client-async/client-manager-async-impl.cpp
src/manager/client-async/client-manager-async-impl.h
src/manager/client-async/client-manager-async.cpp
src/manager/client-async/storage-receiver.cpp
src/manager/client-async/storage-receiver.h
src/manager/client-capi/ckmc-control.cpp
src/manager/client-capi/ckmc-manager.cpp
src/manager/client/client-control.cpp
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/service/access-control.cpp [new file with mode: 0644]
src/manager/service/access-control.h [new file with mode: 0644]
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp
src/manager/service/crypto-logic.cpp
src/manager/service/db-crypto.cpp
src/manager/service/db-crypto.h
src/manager/service/db-row.h
src/manager/service/permission.h [new file with mode: 0644]
tests/DBFixture.cpp
tests/DBFixture.h
tests/test_db_crypto.cpp

index bd28ff6..b3bfc10 100644 (file)
@@ -19,6 +19,7 @@ SET(KEY_MANAGER_SOURCES
     ${KEY_MANAGER_PATH}/main/generic-socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/key-manager-main.cpp
+    ${KEY_MANAGER_PATH}/service/access-control.cpp
     ${KEY_MANAGER_PATH}/service/ckm-service.cpp
     ${KEY_MANAGER_PATH}/service/ckm-logic.cpp
     ${KEY_MANAGER_PATH}/service/key-provider.cpp
index 723a8d4..09adb58 100644 (file)
@@ -63,16 +63,11 @@ public:
 
     virtual int updateCCMode() = 0;
 
-    virtual int allowAccess(uid_t user,
-                            const std::string &owner,
-                            const std::string &alias,
-                            const std::string &accessor,
-                            AccessRight granted) = 0;
-
-    virtual int denyAccess(uid_t user,
-                           const std::string &owner,
-                           const std::string &alias,
-                           const std::string &accessor) = 0;
+    virtual int setPermission(uid_t user,
+                              const std::string &owner,
+                              const std::string &alias,
+                              const std::string &accessor,
+                              Permission newPermission) = 0;
 
     virtual ~Control(){}
 
index bfbcf66..2df85df 100644 (file)
@@ -74,8 +74,7 @@ public:
 
         virtual void ReceivedOCSPCheck(int) {}
 
-        virtual void ReceivedAllowAccess() {}
-        virtual void ReceivedDenyAccess() {}
+        virtual void ReceivedSetPermission() {}
 
         virtual ~Observer() {}
     };
@@ -167,15 +166,11 @@ public:
             const ObserverPtr& observer,
             const CertificateShPtrVector& certificateChainVector);
 
-    void allowAccess(
+    void setPermission(
             const ObserverPtr& observer,
             const Alias& alias,
             const Label& accessor,
-            AccessRight granted);
-    void denyAccess(
-            const ObserverPtr& observer,
-            const Alias& alias,
-            const Label& accessor);
+            Permission newPermission);
 
 private:
     std::unique_ptr<Impl> m_impl;
index d995f5f..ac1f72b 100644 (file)
@@ -116,8 +116,7 @@ public:
     // if application does not have permission to use network.
     virtual int ocspCheck(const CertificateShPtrVector &certificateChainVector, int &ocspStatus) = 0;
 
-    virtual int allowAccess(const Alias &alias, const Label &accessor, AccessRight granted) = 0;
-    virtual int denyAccess(const Alias &alias, const Label &accessor) = 0;
+    virtual int setPermission(const Alias &alias, const Label &accessor, Permission newPermission) = 0;
 
 
     static ManagerShPtr create();
index bd8ef2f..29ad554 100644 (file)
@@ -93,9 +93,11 @@ enum class DBCMAlgType : int {
     COUNT
 };
 
-enum class AccessRight: int {
-    AR_READ = 0,
-    AR_READ_REMOVE
+enum class Permission: int {
+    READ = 0,
+    READ_REMOVE,
+    // .. new values here
+    NONE = -1,
 };
 
 const char * ErrorToString(int error);
index d737201..79df43d 100644 (file)
@@ -215,10 +215,10 @@ void ManagerAsync::Impl::ocspCheck(const ObserverPtr& observer,
     }, [&observer](int error){ observer->ReceivedError(error); } );
 }
 
-void ManagerAsync::Impl::allowAccess(const ObserverPtr& observer,
-                                     const Alias& alias,
-                                     const Label& accessor,
-                                     AccessRight granted)
+void ManagerAsync::Impl::setPermission(const ObserverPtr& observer,
+                                         const Alias& alias,
+                                         const Label& accessor,
+                                         Permission newPermission)
 {
     observerCheck(observer);
     if (alias.empty() || accessor.empty()) {
@@ -227,29 +227,11 @@ void ManagerAsync::Impl::allowAccess(const ObserverPtr& observer,
     }
     try_catch_async([&] {
         sendToStorage(observer,
-                      static_cast<int>(LogicCommand::ALLOW_ACCESS),
+                      static_cast<int>(LogicCommand::SET_PERMISSION),
                       m_counter,
                       alias,
                       accessor,
-                      static_cast<int>(granted));
-    }, [&observer](int error){ observer->ReceivedError(error); } );
-}
-
-void ManagerAsync::Impl::denyAccess(const ObserverPtr& observer,
-                                    const Alias& alias,
-                                    const Label& accessor)
-{
-    observerCheck(observer);
-    if (alias.empty() || accessor.empty()) {
-        observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM);
-        return;
-    }
-    try_catch_async([&] {
-        sendToStorage(observer,
-                      static_cast<int>(LogicCommand::DENY_ACCESS),
-                      m_counter,
-                      alias,
-                      accessor);
+                      static_cast<int>(newPermission));
     }, [&observer](int error){ observer->ReceivedError(error); } );
 }
 
index 56f5cc0..b41d3d4 100644 (file)
@@ -74,15 +74,11 @@ public:
             const ObserverPtr& observer,
             const CertificateShPtrVector& certificateChainVector);
 
-    void allowAccess(
+    void setPermission(
             const ObserverPtr& observer,
             const Alias& alias,
             const Label& accessor,
-            AccessRight granted);
-    void denyAccess(
-            const ObserverPtr& observer,
-            const Alias& alias,
-            const Label& accessor);
+            Permission newPermission);
 
     // generic methods
     void saveBinaryData(
index cde7589..e1bc5ec 100644 (file)
@@ -214,19 +214,12 @@ void ManagerAsync::ocspCheck(const ObserverPtr& observer,
     m_impl->ocspCheck(observer, certificateChainVector);
 }
 
-void ManagerAsync::allowAccess(const ObserverPtr& observer,
-                               const Alias& alias,
-                               const Label& accessor,
-                               AccessRight granted)
-{
-    m_impl->allowAccess(observer, alias, accessor, granted);
-}
-
-void ManagerAsync::denyAccess(const ObserverPtr& observer,
-                              const Alias& alias,
-                              const Label& accessor)
+void ManagerAsync::setPermission(const ObserverPtr& observer,
+                                   const Alias& alias,
+                                   const Label& accessor,
+                                   Permission newPermission)
 {
-    m_impl->denyAccess(observer, alias, accessor);
+    m_impl->setPermission(observer, alias, accessor, newPermission);
 }
 
 } // namespace CKM
index 51598f9..8ca5717 100644 (file)
@@ -119,11 +119,8 @@ void StorageReceiver::parseResponse()
     case LogicCommand::CREATE_KEY_PAIR_DSA:
         parseRetCode(&ManagerAsync::Observer::ReceivedCreateKeyPairDSA);
         break;
-    case LogicCommand::ALLOW_ACCESS:
-        parseRetCode(&ManagerAsync::Observer::ReceivedAllowAccess);
-        break;
-    case LogicCommand::DENY_ACCESS:
-        parseRetCode(&ManagerAsync::Observer::ReceivedDenyAccess);
+    case LogicCommand::SET_PERMISSION:
+        parseRetCode(&ManagerAsync::Observer::ReceivedSetPermission);
         break;
 
     default:
@@ -278,23 +275,9 @@ void StorageReceiver::parseCreateSignatureCommand()
     m_observer->ReceivedCreateSignature(std::move(signature));
 }
 
-void StorageReceiver::parseAllowAccessCommand()
-{
-    int retCode = 0;
-    m_buffer.Deserialize(retCode);
-
-    // check error code
-    if (retCode != CKM_API_SUCCESS) {
-         m_observer->ReceivedError(retCode);
-         return;
-    }
-
-    m_observer->ReceivedAllowAccess();
-}
-
-void StorageReceiver::parseDenyAccessCommand()
+void StorageReceiver::parseSetPermission()
 {
-    int retCode = 0;
+    int retCode;
     m_buffer.Deserialize(retCode);
 
     // check error code
@@ -303,7 +286,7 @@ void StorageReceiver::parseDenyAccessCommand()
          return;
     }
 
-    m_observer->ReceivedDenyAccess();
+    m_observer->ReceivedSetPermission();
 }
 
 void StorageReceiver::parseRetCode(ObserverCb callback)
index d9e6b47..0560892 100644 (file)
@@ -46,8 +46,7 @@ private:
     void parseRemoveCommand();
     void parseGetChainCertCommand();
     void parseCreateSignatureCommand();
-    void parseAllowAccessCommand();
-    void parseDenyAccessCommand();
+    void parseSetPermission();
 
     typedef void (ManagerAsync::Observer::*ObserverCb)();
 
index 4e057b4..a597ee9 100644 (file)
@@ -83,8 +83,8 @@ int ckmc_allow_access_by_adm(uid_t user, const char* owner, const char *alias, c
 
     auto control = CKM::Control::create();
 
-    CKM::AccessRight ar = static_cast<CKM::AccessRight>(static_cast<int>(granted));
-    return to_ckmc_error(control->allowAccess(user, owner, alias, accessor, ar));
+    CKM::Permission ar = static_cast<CKM::Permission>(static_cast<int>(granted));
+    return to_ckmc_error(control->setPermission(user, owner, alias, accessor, ar));
 }
 
 KEY_MANAGER_CAPI
@@ -95,5 +95,5 @@ int ckmc_deny_access_by_adm(uid_t user, const char* owner, const char *alias, co
 
     auto control = CKM::Control::create();
 
-    return to_ckmc_error(control->denyAccess(user, owner, alias, accessor));
+    return to_ckmc_error(control->setPermission(user, owner, alias, accessor, CKM::Permission::NONE));
 }
index f1918e0..86343ab 100644 (file)
@@ -611,8 +611,8 @@ int ckmc_allow_access(const char *alias, const char *accessor, ckmc_access_right
 
     CKM::ManagerShPtr mgr = CKM::Manager::create();
 
-    CKM::AccessRight ar = static_cast<CKM::AccessRight>(static_cast<int>(granted));
-    return to_ckmc_error(mgr->allowAccess(alias, accessor, ar));
+    CKM::Permission ar = static_cast<CKM::Permission>(static_cast<int>(granted));
+    return to_ckmc_error(mgr->setPermission(alias, accessor, ar));
 }
 
 KEY_MANAGER_CAPI
@@ -623,5 +623,5 @@ int ckmc_deny_access(const char *alias, const char *accessor)
 
     CKM::ManagerShPtr mgr = CKM::Manager::create();
 
-    return to_ckmc_error(mgr->denyAccess(alias, accessor));
+    return to_ckmc_error(mgr->setPermission(alias, accessor, CKM::Permission::NONE));
 }
index 2abdef7..6c0675d 100644 (file)
@@ -176,45 +176,20 @@ public:
         });
     }
 
-    virtual int allowAccess(uid_t user,
-                            const Label &owner,
-                            const Alias &alias,
-                            const Label &accessor,
-                            AccessRight granted)
+    virtual int setPermission(uid_t user,
+                                const Label &owner,
+                                const Alias &alias,
+                                const Label &accessor,
+                                Permission newPermission)
     {
         return try_catch([&] {
             MessageBuffer recv;
-            auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::ALLOW_ACCESS),
+            auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::SET_PERMISSION),
                                                  static_cast<int>(user),
                                                  owner,
                                                  alias,
                                                  accessor,
-                                                 static_cast<int>(granted));
-
-            int retCode = m_controlConnection.processRequest(send.Pop(), recv);
-            if (CKM_API_SUCCESS != retCode)
-                return retCode;
-
-            int command;
-            int counter;
-            recv.Deserialize(command, counter, retCode);
-
-            return retCode;
-        });
-    }
-
-    virtual int denyAccess(uid_t user,
-                           const Label &owner,
-                           const Alias &alias,
-                           const Label &accessor)
-    {
-        return try_catch([&] {
-            MessageBuffer recv;
-            auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::DENY_ACCESS),
-                                                 static_cast<int>(user),
-                                                 owner,
-                                                 alias,
-                                                 accessor);
+                                                 static_cast<int>(newPermission));
 
             int retCode = m_controlConnection.processRequest(send.Pop(), recv);
             if (CKM_API_SUCCESS != retCode)
index 2760ec4..8b06568 100644 (file)
@@ -600,46 +600,19 @@ int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspSta
     });
 }
 
-int ManagerImpl::allowAccess(const Alias &alias,
-                             const Label &accessor,
-                             AccessRight granted)
+int ManagerImpl::setPermission(const Alias &alias,
+                                 const Label &accessor,
+                                 Permission newPermission)
 {
     m_counter++;
     int my_counter = m_counter;
     return try_catch([&] {
         MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::ALLOW_ACCESS),
+        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
                                              my_counter,
                                              alias,
                                              accessor,
-                                             static_cast<int>(granted));
-
-        int retCode = m_storageConnection.processRequest(send.Pop(), recv);
-        if (CKM_API_SUCCESS != retCode)
-            return retCode;
-
-        int command;
-        int counter;
-        recv.Deserialize(command, counter, retCode);
-
-        if (my_counter != counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
-
-        return retCode;
-    });
-}
-
-int ManagerImpl::denyAccess(const Alias &alias, const Label &accessor)
-{
-    m_counter++;
-    int my_counter = m_counter;
-    return try_catch([&] {
-        MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::DENY_ACCESS),
-                                             my_counter,
-                                             alias,
-                                             accessor);
+                                             static_cast<int>(newPermission));
 
         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
         if (CKM_API_SUCCESS != retCode)
index 94dd881..f1a89fc 100644 (file)
@@ -97,8 +97,7 @@ public:
 
     int ocspCheck(const CertificateShPtrVector &certificateChain, int &ocspCheck);
 
-    int allowAccess(const Alias &alias, const Label &accessor, AccessRight granted);
-    int denyAccess(const Alias &alias, const Label &accessor);
+    int setPermission(const Alias &alias, const Label &accessor, Permission newPermission);
 
 protected:
     int saveBinaryData(
index c4df066..a9c9bdc 100644 (file)
@@ -64,15 +64,29 @@ KeyType toKeyType(DBDataType dbtype) {
     }
 }
 
-const char* toDBAccessRight(AccessRight access_right_type) {
+namespace {
+const char* const DB_PERM_READ        = "R";
+const char* const DB_PERM_READ_REMOVE = "RD";
+}
+
+const char* toDBPermission(Permission access_right_type) {
     switch(access_right_type) {
-    case AccessRight::AR_READ:          return "R";
-    case AccessRight::AR_READ_REMOVE:   return "RD";
+    case Permission::READ:          return DB_PERM_READ;
+    case Permission::READ_REMOVE:   return DB_PERM_READ_REMOVE;
     default:
         // TODO
         throw 1;
     }
 }
 
+Permission toPermission(const std::string &input_DB_data) {
+    if(input_DB_data == DB_PERM_READ_REMOVE)
+        return Permission::READ_REMOVE;
+    else if(input_DB_data == DB_PERM_READ)
+        return Permission::READ;
+    else
+        return Permission::NONE;
+}
+
 } // namespace CKM
 
index 594d0e1..fe439f5 100644 (file)
@@ -22,6 +22,7 @@
  */
 #pragma once
 
+#include <string>
 #include <ckm/ckm-type.h>
 
 #include <dpl/serialization.h>
@@ -41,8 +42,7 @@ enum class ControlCommand : int {
     RESET_USER_PASSWORD,
     REMOVE_APP_DATA,
     UPDATE_CC_MODE,
-    ALLOW_ACCESS,
-    DENY_ACCESS,
+    SET_PERMISSION
     // for backward compatibility append new at the end
 };
 
@@ -58,16 +58,17 @@ enum class LogicCommand : int {
     CREATE_SIGNATURE,
     VERIFY_SIGNATURE,
     CREATE_KEY_PAIR_DSA,
-    ALLOW_ACCESS,
-    DENY_ACCESS,
+    SET_PERMISSION
     // for backward compatibility append new at the end
 };
 
 // Do not use DB_KEY_FIRST and DB_KEY_LAST in the code.
 // This values are only for db module!
 enum class DBDataType : int {
-    KEY_RSA_PUBLIC,
-    DB_KEY_FIRST = KEY_RSA_PUBLIC,
+    DB_DATA_TYPE_FIRST,
+    DB_KEY_FIRST = DB_DATA_TYPE_FIRST,
+
+    KEY_RSA_PUBLIC = DB_KEY_FIRST,
     KEY_RSA_PRIVATE,
     KEY_ECDSA_PUBLIC,
     KEY_ECDSA_PRIVATE,
@@ -77,6 +78,10 @@ enum class DBDataType : int {
     DB_KEY_LAST = KEY_AES,
     CERTIFICATE,
     BINARY_DATA,
+    // add new items here
+
+    // keep in mind to modify DB_DATA_TYPE_LAST when doing changes!
+    DB_DATA_TYPE_LAST = BINARY_DATA
 };
 
 // (client side) Alias = (service side) Label::Name
@@ -87,7 +92,8 @@ typedef std::vector<std::pair<Label, Name> > LabelNameVector;
 
 DBDataType toDBDataType(KeyType key);
 KeyType toKeyType(DBDataType dbDataType);
-const char* toDBAccessRight(AccessRight access_right_type);
+const char* toDBPermission(Permission access_right_type);
+Permission toPermission(const std::string &input_DB_data);
 
 class IStream;
 
diff --git a/src/manager/service/access-control.cpp b/src/manager/service/access-control.cpp
new file mode 100644 (file)
index 0000000..c007edc
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ *
+ * @file        access-control.cpp
+ * @author      Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @version     1.0
+ * @brief       DB access control layer implementation.
+ */
+#include <vconf/vconf.h>
+#include <access-control.h>
+#include <dpl/log/log.h>
+#include <ckm/ckm-error.h>
+#include <ckm/ckm-type.h>
+#include <openssl/crypto.h>
+
+#ifndef VCONFKEY_SECURITY_MDPP_STATE
+#define VCONFKEY_SECURITY_MDPP_STATE   "file/security_mdpp/security_mdpp_state"
+#endif
+
+namespace {
+const char* const MDPP_MODE_ENFORCING = "Enforcing";
+const char* const MDPP_MODE_ENABLED = "Enabled";
+const char* const MDPP_MODE_DISABLED = "Disabled";
+} // anonymous namespace
+
+namespace CKM {
+
+void AccessControl::updateCCMode() {
+    int fipsModeStatus = 0;
+    int rc = 0;
+    bool newMode;
+
+    char *mdppState = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
+    newMode = ( mdppState && (!strcmp(mdppState, MDPP_MODE_ENABLED) ||
+                              !strcmp(mdppState, MDPP_MODE_ENFORCING) ||
+                              !strcmp(mdppState, MDPP_MODE_DISABLED)));
+    if (newMode == m_ccMode)
+        return;
+
+    m_ccMode = newMode;
+
+    fipsModeStatus = FIPS_mode();
+
+    if(m_ccMode) {
+        if(fipsModeStatus == 0) { // If FIPS mode off
+            rc = FIPS_mode_set(1); // Change FIPS_mode from off to on
+            if(rc == 0) {
+                LogError("Error in FIPS_mode_set function");
+            }
+        }
+    } else {
+        if(fipsModeStatus == 1) { // If FIPS mode on
+            rc = FIPS_mode_set(0); // Change FIPS_mode from on to off
+            if(rc == 0) {
+                LogError("Error in FIPS_mode_set function");
+            }
+        }
+    }
+}
+
+bool AccessControl::isCCMode() const
+{
+    return m_ccMode;
+}
+
+
+int AccessControl::canRead(
+        const DBRow & row,
+        const PermissionForLabel & permissionLabel) const
+{
+    // owner can do everything by default
+    if (row.ownerLabel == permissionLabel.accessorLabel)
+        return CKM_API_SUCCESS;
+
+    switch(permissionLabel.permissions)
+    {
+        case Permission::READ:
+        case Permission::READ_REMOVE:
+            return CKM_API_SUCCESS;
+
+        default:
+            return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+    }
+}
+
+int AccessControl::canExport(
+        const DBRow & row,
+        const PermissionForLabel & permissionLabel) const
+{
+    int ec;
+    if(CKM_API_SUCCESS != (ec = canRead(row, permissionLabel)))
+        return ec;
+
+    // check if can export
+    if(row.exportable == 0)
+        return CKM_API_ERROR_NOT_EXPORTABLE;
+
+    // prevent extracting private keys during cc-mode on
+    if( isCCMode() )
+    {
+        switch(row.dataType)
+        {
+            case DBDataType::KEY_RSA_PRIVATE:
+            case DBDataType::KEY_ECDSA_PRIVATE:
+            case DBDataType::KEY_DSA_PRIVATE:
+                return CKM_API_ERROR_BAD_REQUEST;
+
+            default:
+                break;
+        }
+    }
+
+    return CKM_API_SUCCESS;
+}
+
+int AccessControl::canDelete(
+        const Label & ownerLabel,
+        const PermissionForLabel & permissionLabel) const
+{
+    // owner can do everything by default
+    if (ownerLabel == permissionLabel.accessorLabel)
+        return CKM_API_SUCCESS;
+
+    switch(permissionLabel.permissions)
+    {
+        case Permission::READ:
+            return CKM_API_ERROR_ACCESS_DENIED;
+
+        case Permission::READ_REMOVE:
+            return CKM_API_SUCCESS;
+
+        default:
+            return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+    }
+}
+
+
+
+} // namespace CKM
diff --git a/src/manager/service/access-control.h b/src/manager/service/access-control.h
new file mode 100644 (file)
index 0000000..169be68
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ *
+ * @file        access-control.h
+ * @author      Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @version     1.0
+ * @brief       DB access control layer.
+ */
+#pragma once
+
+#include <string>
+#include <ckm/ckm-type.h>
+#include <ckm/ckm-raw-buffer.h>
+#include <protocols.h>
+#include <db-row.h>
+#include <permission.h>
+
+namespace CKM {
+
+class AccessControl
+{
+public:
+    /**
+     * check if given row can be read (for internal use)
+     * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code
+     */
+    int canRead(const DBRow & row,
+                const PermissionForLabel & permissionLabel) const;
+
+    /**
+     * check if given row can be exported (data provided to the client)
+     * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code
+     */
+    int canExport(const DBRow & row,
+                const PermissionForLabel & permissionLabel) const;
+
+    /**
+     * check if given accessor can delete ownerLabel's items.
+     * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code
+     */
+    int canDelete(const Label & ownerLabel,
+                  const PermissionForLabel & permissionLabel) const;
+
+    void updateCCMode();
+    bool isCCMode() const;
+private:
+    bool m_ccMode;
+};
+
+} // namespace CKM
index c611ee6..9e71004 100644 (file)
 #include <ckm-logic.h>
 #include <key-impl.h>
 
-#ifndef VCONFKEY_SECURITY_MDPP_STATE
-#define VCONFKEY_SECURITY_MDPP_STATE = "file/security_mdpp/security_mdpp_state";
-#endif
-
 namespace {
 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
-
-const char* const MDPP_MODE_ENFORCING = "Enforcing";
-const char* const MDPP_MODE_ENABLED = "Enabled";
-const char* const MDPP_MODE_DISABLED = "Disabled";
-
 } // anonymous namespace
 
 namespace CKM {
 
-CKMLogic::CKMLogic() : m_ccMode(false)
+CKMLogic::CKMLogic()
 {
     if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
         LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
     }
 
-    updateCCMode_internal();
+    m_accessControl.updateCCMode();
 }
 
 CKMLogic::~CKMLogic(){}
@@ -115,41 +106,8 @@ RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
     return MessageBuffer::Serialize(retCode).Pop();
 }
 
-void CKMLogic::updateCCMode_internal() {
-    int fipsModeStatus = 0;
-    int rc = 0;
-    bool newMode;
-
-    char *mdppState = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
-    newMode = (mdppState && (  !strcmp(mdppState, MDPP_MODE_ENABLED)
-                            || !strcmp(mdppState, MDPP_MODE_ENFORCING)
-                            || !strcmp(mdppState, MDPP_MODE_DISABLED)));
-    if (newMode == m_ccMode)
-        return;
-
-    m_ccMode = newMode;
-
-    fipsModeStatus = FIPS_mode();
-
-    if(m_ccMode) {
-        if(fipsModeStatus == 0) { // If FIPS mode off
-            rc = FIPS_mode_set(1); // Change FIPS_mode from off to on
-            if(rc == 0) {
-                LogError("Error in FIPS_mode_set function");
-            }
-        }
-    } else {
-        if(fipsModeStatus == 1) { // If FIPS mode on
-            rc = FIPS_mode_set(0); // Change FIPS_mode from on to off
-            if(rc == 0) {
-                LogError("Error in FIPS_mode_set function");
-            }
-        }
-    }
-}
-
 RawBuffer CKMLogic::updateCCMode() {
-    updateCCMode_internal();
+    m_accessControl.updateCCMode();
     return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
 }
 
@@ -251,7 +209,7 @@ RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
 }
 
 int CKMLogic::saveDataHelper(
-    Credentials &cred,
+    const Credentials &cred,
     DBDataType dataType,
     const Name &name,
     const RawBuffer &key,
@@ -267,6 +225,12 @@ int CKMLogic::saveDataHelper(
 
     auto &handler = m_userDataMap[cred.uid];
     DBCrypto::Transaction transaction(&handler.database);
+
+    // check if not a duplicate
+    if( handler.database.isNameLabelPresent(name, cred.smackLabel) )
+        return CKM_API_ERROR_DB_ALIAS_EXISTS;
+
+    // encryption section
     if (!handler.crypto.haveKey(cred.smackLabel)) {
         RawBuffer got_key;
         auto key_optional = handler.database.getKey(cred.smackLabel);
@@ -284,8 +248,8 @@ int CKMLogic::saveDataHelper(
         handler.crypto.pushKey(cred.smackLabel, got_key);
     }
 
-    // Do not encrypt data with password during cc_mode on
-    if(m_ccMode) {
+    // do not encrypt data with password during cc_mode on
+    if(m_accessControl.isCCMode()) {
         handler.crypto.encryptRow("", row);
     } else {
         handler.crypto.encryptRow(policy.password, row);
@@ -330,7 +294,7 @@ void CKMLogic::verifyBinaryData(DBDataType dataType, const RawBuffer &input_data
 }
 
 RawBuffer CKMLogic::saveData(
-    Credentials &cred,
+    const Credentials &cred,
     int commandId,
     DBDataType dataType,
     const Name &name,
@@ -355,9 +319,6 @@ RawBuffer CKMLogic::saveData(
     } catch (const DBCrypto::Exception::InternalError &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
-    } catch (const DBCrypto::Exception::NameExists &e) {
-        LogError("DBCrypto couldn't save duplicate name");
-        retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
     } catch (const DBCrypto::Exception::TransactionError &e) {
         LogError("DBCrypto transaction failed with message " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -370,44 +331,62 @@ RawBuffer CKMLogic::saveData(
     return response.Pop();
 }
 
+int CKMLogic::removeDataHelper(
+        const Credentials &cred,
+        const Name &name,
+        const Label &ownerLabel)
+{
+    if (0 == m_userDataMap.count(cred.uid))
+        return CKM_API_ERROR_DB_LOCKED;
+
+    // verify name and label are correct
+    if( !checkNameAndLabelValid(name, ownerLabel) )
+    {
+        LogError("Invalid label or name format");
+        return CKM_API_ERROR_INPUT_PARAM;
+    }
+
+    auto &database = m_userDataMap[cred.uid].database;
+    DBCrypto::Transaction transaction(&database);
+
+    // read and check permissions
+    PermissionOptional permissionRowOpt =
+            database.getPermissionRow(name, ownerLabel, cred.smackLabel);
+    int access_ec = m_accessControl.canDelete(ownerLabel, PermissionForLabel(cred.smackLabel, permissionRowOpt));
+    if(access_ec != CKM_API_SUCCESS)
+    {
+        LogWarning("access control check result: " << access_ec);
+        return access_ec;
+    }
+
+    auto erased = database.deleteDBRow(name, ownerLabel);
+    // check if the data existed or not
+    if(erased)
+        transaction.commit();
+    else {
+        LogError("No row for given name and label");
+        return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+    }
+
+    return CKM_API_SUCCESS;
+}
+
 RawBuffer CKMLogic::removeData(
-    Credentials &cred,
+    const Credentials &cred,
     int commandId,
     DBDataType dataType,
     const Name &name,
     const Label &label)
 {
-    int retCode = CKM_API_SUCCESS;
-
-    if (0 < m_userDataMap.count(cred.uid)) {
-        Try {
-            // use client label if not explicitly provided
-            const Label & ownerLabel = label.empty() ? cred.smackLabel : label;
+    int retCode;
+    Try {
+        // use client label if not explicitly provided
+        const Label & ownerLabel = label.empty() ? cred.smackLabel : label;
 
-            // verify name and label are correct
-            if (true == checkNameAndLabelValid(name, ownerLabel))
-            {
-                auto erased = m_userDataMap[cred.uid].database.deleteDBRow(name, ownerLabel, cred.smackLabel);
-                // check if the data existed or not
-                if(!erased) {
-                    LogError("No row for given name and label");
-                    retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
-                }
-            }
-            else
-            {
-                LogError("Invalid label or name format");
-                retCode = CKM_API_ERROR_INPUT_PARAM;
-            }
-        } Catch (DBCrypto::Exception::PermissionDenied) {
-            LogError("Error: not enough permissions!");
-            retCode = CKM_API_ERROR_ACCESS_DENIED;
-        } Catch (CKM::Exception) {
-            LogError("Error in deleting row!");
-            retCode = CKM_API_ERROR_DB_ERROR;
-        }
-    } else {
-        retCode = CKM_API_ERROR_DB_LOCKED;
+        retCode = removeDataHelper(cred, name, ownerLabel);
+    } Catch (CKM::Exception) {
+        LogError("Error in deleting row!");
+        retCode = CKM_API_ERROR_DB_ERROR;
     }
 
     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
@@ -430,8 +409,66 @@ bool CKMLogic::checkNameAndLabelValid(const Name &name, const Label &label)
     return true;
 }
 
-int CKMLogic::getDataHelper(
-    Credentials &cred,
+int CKMLogic::readDataRowHelper(const Name &name,
+                                const Label &ownerLabel,
+                                DBDataType dataType,
+                                DBCrypto & database,
+                                DBRow &row)
+{
+    // read row
+    DBCrypto::DBRowOptional row_optional;
+    // TODO: move this check into request deserialization
+    if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
+       (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
+    {
+        LogError("Unknown type of requested data: " << (int)dataType);
+        return CKM_API_ERROR_BAD_REQUEST;
+    }
+    // TODO: provide internal type rather than using DB types in socket comms
+    else if ((dataType >= DBDataType::DB_KEY_FIRST) &&
+             (dataType <= DBDataType::DB_KEY_LAST))
+    {
+        // read all key types
+        row_optional = database.getDBRow(name,
+                                         ownerLabel,
+                                         DBDataType::DB_KEY_FIRST,
+                                         DBDataType::DB_KEY_LAST);
+    }
+    else {
+        // read anything else
+        row_optional = database.getDBRow(name,
+                                         ownerLabel,
+                                         dataType);
+    }
+
+    if(!row_optional) {
+        LogError("No row for given name, label and type");
+        return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+    } else {
+        row = *row_optional;
+    }
+
+    return CKM_API_SUCCESS;
+}
+
+int CKMLogic::checkDataPermissionsHelper(const Name &name,
+                                         const Label &ownerLabel,
+                                         const Label &accessorLabel,
+                                         const DBRow &row,
+                                         bool exportFlag,
+                                         DBCrypto & database)
+{
+    PermissionOptional permissionRowOpt =
+            database.getPermissionRow(name, ownerLabel, accessorLabel);
+
+    if(exportFlag)
+        return m_accessControl.canExport(row, PermissionForLabel(accessorLabel, permissionRowOpt));
+    return m_accessControl.canRead(row, PermissionForLabel(accessorLabel, permissionRowOpt));
+}
+
+int CKMLogic::readDataHelper(
+    bool exportFlag,
+    const Credentials &cred,
     DBDataType dataType,
     const Name &name,
     const Label &label,
@@ -441,8 +478,6 @@ int CKMLogic::getDataHelper(
     if (0 == m_userDataMap.count(cred.uid))
         return CKM_API_ERROR_DB_LOCKED;
 
-    auto &handler = m_userDataMap[cred.uid];
-
     // use client label if not explicitly provided
     const Label ownerLabel = label.empty() ? cred.smackLabel : label;
 
@@ -450,38 +485,31 @@ int CKMLogic::getDataHelper(
     if (true != checkNameAndLabelValid(name, ownerLabel))
         return CKM_API_ERROR_INPUT_PARAM;
 
-    DBCrypto::DBRowOptional row_optional;
-    if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA)
-    {
-        row_optional = handler.database.getDBRow(name, ownerLabel, 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)))
-    {
-        row_optional = handler.database.getKeyDBRow(name, ownerLabel, cred.smackLabel);
-    }
-    else
-    {
-        LogError("Unknown type of requested data" << (int)dataType);
-        return CKM_API_ERROR_BAD_REQUEST;
-    }
-    if(!row_optional) {
-        LogError("No row for given name, label and type");
-        return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
-    } else {
-        row = *row_optional;
-    }
+    auto &handler = m_userDataMap[cred.uid];
 
-    if (!handler.crypto.haveKey(row.smackLabel)) {
+    // read row
+    DBCrypto::Transaction transaction(&handler.database);
+    int ec = readDataRowHelper(name, ownerLabel, dataType, handler.database, row);
+    if(CKM_API_SUCCESS != ec)
+        return ec;
+
+
+    // check access rights
+    ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
+    if(CKM_API_SUCCESS != ec)
+        return ec;
+
+    // decrypt row
+    if (!handler.crypto.haveKey(row.ownerLabel)) {
         RawBuffer key;
-        auto key_optional = handler.database.getKey(row.smackLabel);
+        auto key_optional = handler.database.getKey(row.ownerLabel);
         if(!key_optional) {
             LogError("No key for given label in database");
             return CKM_API_ERROR_DB_ERROR;
         }
         key = *key_optional;
         key = handler.keyProvider.getPureDEK(key);
-        handler.crypto.pushKey(row.smackLabel, key);
+        handler.crypto.pushKey(row.ownerLabel, key);
     }
     handler.crypto.decryptRow(password, row);
 
@@ -489,7 +517,7 @@ int CKMLogic::getDataHelper(
 }
 
 RawBuffer CKMLogic::getData(
-    Credentials &cred,
+    const Credentials &cred,
     int commandId,
     DBDataType dataType,
     const Name &name,
@@ -500,16 +528,13 @@ RawBuffer CKMLogic::getData(
     DBRow row;
 
     try {
-        retCode = getDataHelper(cred, dataType, name, label, password, row);
+        retCode = readDataHelper(true, cred, dataType, name, label, password, row);
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with error: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const CryptoLogic::Exception::Base &e) {
         LogError("CryptoLogic failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCrypto::Exception::PermissionDenied &e) {
-        LogError("DBCrypto failed with message: " << e.GetMessage());
-        retCode = CKM_API_ERROR_ACCESS_DENIED;
     } catch (const DBCrypto::Exception::Base &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -520,20 +545,6 @@ RawBuffer CKMLogic::getData(
         row.dataType = dataType;
     }
 
-    if ((CKM_API_SUCCESS == retCode) && (row.exportable == 0)) {
-        row.data.clear();
-        retCode = CKM_API_ERROR_NOT_EXPORTABLE;
-    }
-
-    // Prevent extracting private keys during cc-mode on
-    if((m_ccMode) && (row.dataType == DBDataType::KEY_RSA_PRIVATE ||
-                      row.dataType == DBDataType::KEY_ECDSA_PRIVATE ||
-                      row.dataType == DBDataType::KEY_DSA_PRIVATE))
-    {
-        row.data.clear();
-        retCode = CKM_API_ERROR_BAD_REQUEST;
-    }
-
     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
                                              commandId,
                                              retCode,
@@ -543,7 +554,7 @@ RawBuffer CKMLogic::getData(
 }
 
 RawBuffer CKMLogic::getDataList(
-    Credentials &cred,
+    const Credentials &cred,
     int commandId,
     DBDataType dataType)
 {
@@ -551,14 +562,34 @@ RawBuffer CKMLogic::getDataList(
     LabelNameVector labelNameVector;
 
     if (0 < m_userDataMap.count(cred.uid)) {
-        auto &handler = m_userDataMap[cred.uid];
+        auto &database = m_userDataMap[cred.uid].database;
+
         Try {
-            if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
-                handler.database.getNames(cred.smackLabel, dataType, labelNameVector);
-            } else {
-                handler.database.getKeyNames(cred.smackLabel, labelNameVector);
+            // list names
+            // TODO: move this check into request deserialization
+            if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
+               (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
+            {
+                LogError("Unknown type of requested data: " << (int)dataType);
+                retCode = CKM_API_ERROR_BAD_REQUEST;
+            }
+            // TODO: provide internal type rather than using DB types in socket comms
+            else if ((dataType >= DBDataType::DB_KEY_FIRST) && (dataType <= DBDataType::DB_KEY_LAST))
+            {
+                // list all key types
+                database.listNames(cred.smackLabel,
+                                   labelNameVector,
+                                   DBDataType::DB_KEY_FIRST,
+                                   DBDataType::DB_KEY_LAST);
             }
-        } Catch (CKM::Exception) {
+            else {
+                // list anything else
+                database.listNames(cred.smackLabel,
+                                   labelNameVector,
+                                   dataType);
+            }
+        }
+        Catch (CKM::Exception) {
             LogError("Failed to get names");
             retCode = CKM_API_ERROR_DB_ERROR;
         }
@@ -576,7 +607,7 @@ RawBuffer CKMLogic::getDataList(
 
 
 int CKMLogic::createKeyPairHelper(
-    Credentials &cred,
+    const Credentials &cred,
     const KeyType key_type,
     const int additional_param,
     const Name &namePrivate,
@@ -584,10 +615,9 @@ int CKMLogic::createKeyPairHelper(
     const PolicySerializable &policyPrivate,
     const PolicySerializable &policyPublic)
 {
-    if (0 >= m_userDataMap.count(cred.uid))
+    if (0 == m_userDataMap.count(cred.uid))
         return CKM_API_ERROR_DB_LOCKED;
 
-    auto &handler = m_userDataMap[cred.uid];
     KeyImpl prv, pub;
     int retCode;
     switch(key_type)
@@ -617,7 +647,8 @@ int CKMLogic::createKeyPairHelper(
         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
     }
 
-    DBCrypto::Transaction transaction(&handler.database);
+    auto &database = m_userDataMap[cred.uid].database;
+    DBCrypto::Transaction transaction(&database);
     retCode = saveDataHelper(cred,
                             toDBDataType(prv.getType()),
                             namePrivate,
@@ -642,7 +673,7 @@ int CKMLogic::createKeyPairHelper(
 }
 
 RawBuffer CKMLogic::createKeyPair(
-    Credentials &cred,
+    const Credentials &cred,
     LogicCommand protocol_cmd,
     int commandId,
     const int additional_param,
@@ -678,10 +709,6 @@ RawBuffer CKMLogic::createKeyPair(
                         namePublic,
                         policyPrivate,
                         policyPublic);
-
-    } catch (DBCrypto::Exception::NameExists &e) {
-        LogDebug("DBCrypto error: name exists: " << e.GetMessage());
-        retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
     } catch (DBCrypto::Exception::TransactionError &e) {
         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -697,7 +724,7 @@ RawBuffer CKMLogic::createKeyPair(
 }
 
 RawBuffer CKMLogic::getCertificateChain(
-    Credentials &cred,
+    const Credentials &cred,
     int commandId,
     const RawBuffer &certificate,
     const RawBufferVector &untrustedRawCertVector)
@@ -728,8 +755,40 @@ RawBuffer CKMLogic::getCertificateChain(
     return response.Pop();
 }
 
+int CKMLogic::getCertificateChainHelper(
+        const Credentials &cred,
+        const RawBuffer &certificate,
+        const LabelNameVector &labelNameVector,
+        RawBufferVector & chainRawVector)
+{
+    CertificateImpl cert(certificate, DataFormat::FORM_DER);
+    CertificateImplVector untrustedCertVector;
+    CertificateImplVector chainVector;
+    DBRow row;
+
+    if (cert.empty())
+        return CKM_API_ERROR_SERVER_ERROR;
+
+    for (auto &i: labelNameVector) {
+        int ec = readDataHelper(false, cred, DBDataType::CERTIFICATE, i.second, i.first, Password(), row);
+        if (ec != CKM_API_SUCCESS)
+            return ec;
+
+        untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
+    }
+
+    int ec = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
+    if (ec != CKM_API_SUCCESS)
+        return ec;
+
+    for (auto &i: chainVector)
+        chainRawVector.push_back(i.getDER());
+
+    return CKM_API_SUCCESS;
+}
+
 RawBuffer CKMLogic::getCertificateChain(
-    Credentials &cred,
+    const Credentials &cred,
     int commandId,
     const RawBuffer &certificate,
     const LabelNameVector &labelNameVector)
@@ -737,39 +796,11 @@ RawBuffer CKMLogic::getCertificateChain(
     int retCode = CKM_API_SUCCESS;
     RawBufferVector chainRawVector;
     try {
-        CertificateImpl cert(certificate, DataFormat::FORM_DER);
-        CertificateImplVector untrustedCertVector;
-        CertificateImplVector chainVector;
-        DBRow row;
-
-        if (cert.empty()) {
-            retCode = CKM_API_ERROR_SERVER_ERROR;
-            goto senderror;
-        }
-
-        for (auto &i: labelNameVector) {
-            retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i.second, i.first, Password(), row);
-
-            if (retCode != CKM_API_SUCCESS)
-                goto senderror;
-
-            untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
-        }
-
-        retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
-
-        if (retCode != CKM_API_SUCCESS)
-            goto senderror;
-
-        for (auto &i: chainVector)
-            chainRawVector.push_back(i.getDER());
 
+        retCode = getCertificateChainHelper(cred, certificate, labelNameVector, chainRawVector);
     } catch (const CryptoLogic::Exception::Base &e) {
         LogError("DBCyptorModule failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCrypto::Exception::PermissionDenied &e) {
-        LogError("DBCrypto failed with message: " << e.GetMessage());
-        retCode = CKM_API_ERROR_ACCESS_DENIED;
     } catch (const DBCrypto::Exception::Base &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -777,7 +808,6 @@ RawBuffer CKMLogic::getCertificateChain(
         LogError("Unknown error.");
     }
 
-senderror:
     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
                                              commandId,
                                              retCode,
@@ -786,7 +816,7 @@ senderror:
 }
 
 RawBuffer CKMLogic::createSignature(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         const Name &privateKeyName,
         const Label & ownerLabel,
@@ -802,28 +832,21 @@ RawBuffer CKMLogic::createSignature(
     int retCode = CKM_API_SUCCESS;
 
     try {
-        do {
-            retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
-            if (CKM_API_SUCCESS != retCode) {
-                LogError("getDataHelper return error");
-                break;
-            }
-
+        retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
+        if(retCode == CKM_API_SUCCESS)
+        {
             KeyImpl keyParsed(row.data, Password());
             if (keyParsed.empty())
                 retCode = CKM_API_ERROR_SERVER_ERROR;
             else
                 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
-        } while(0);
+        }
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const CryptoLogic::Exception::Base &e) {
         LogError("CryptoLogic failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCrypto::Exception::PermissionDenied &e) {
-        LogError("DBCrypto failed with message: " << e.GetMessage());
-        retCode = CKM_API_ERROR_ACCESS_DENIED;
     } catch (const DBCrypto::Exception::Base &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -840,7 +863,7 @@ RawBuffer CKMLogic::createSignature(
 }
 
 RawBuffer CKMLogic::verifySignature(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         const Name &publicKeyOrCertName,
         const Label & ownerLabel,
@@ -858,12 +881,12 @@ RawBuffer CKMLogic::verifySignature(
             DBRow row;
             KeyImpl key;
 
-            retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
+            retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, 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, publicKeyOrCertName, ownerLabel, password, row);
+                retCode = readDataHelper(false, cred, DBDataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
                 if (retCode != CKM_API_SUCCESS)
                     break;
                 CertificateImpl cert(row.data, DataFormat::FORM_DER);
@@ -891,9 +914,6 @@ RawBuffer CKMLogic::verifySignature(
     } catch (const CryptoLogic::Exception::Base &e) {
         LogError("CryptoLogic failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCrypto::Exception::PermissionDenied &e) {
-        LogError("DBCrypto failed with message: " << e.GetMessage());
-        retCode = CKM_API_ERROR_ACCESS_DENIED;
     } catch (const DBCrypto::Exception::Base &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -908,68 +928,55 @@ RawBuffer CKMLogic::verifySignature(
     return response.Pop();
 }
 
-RawBuffer CKMLogic::allowAccess(
-        Credentials &cred,
-        int command,
-        int msgID,
+int CKMLogic::setPermissionHelper(
+        const Credentials &cred,
         const Name &name,
         const Label &accessorLabel,
-        const AccessRight reqRights)
+        const Permission reqRights)
 {
-    int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
+    int retCode;
+    if(cred.smackLabel.empty() || cred.smackLabel==accessorLabel)
+        return CKM_API_ERROR_INPUT_PARAM;
 
-    if (cred.smackLabel.empty()) {
-        retCode = CKM_API_ERROR_INPUT_PARAM;
-    } else if (0 < m_userDataMap.count(cred.uid) && !cred.smackLabel.empty()) {
-        Try {
-            retCode = m_userDataMap[cred.uid].database.setAccessRights(
-                name,
-                cred.smackLabel,
-                accessorLabel,
-                reqRights);
-        } Catch (DBCrypto::Exception::InvalidArgs) {
-            LogError("Error: invalid args!");
-            retCode = CKM_API_ERROR_INPUT_PARAM;
-        } Catch (DBCrypto::Exception::PermissionDenied) {
-            LogError("Error: not enough permissions!");
-            retCode = CKM_API_ERROR_ACCESS_DENIED;
-        } Catch (CKM::Exception) {
-            LogError("Error in set row!");
-            retCode = CKM_API_ERROR_DB_ERROR;
-        }
-    } else {
-        retCode = CKM_API_ERROR_DB_LOCKED;
+    if (0 == m_userDataMap.count(cred.uid))
+        return CKM_API_ERROR_DB_LOCKED;
+    auto &database = m_userDataMap[cred.uid].database;
+    DBCrypto::Transaction transaction(&database);
+
+    if( ! database.isNameLabelPresent(name, cred.smackLabel) )
+        return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+
+    // removing non-existing permissions: fail
+    if(reqRights == Permission::NONE)
+    {
+        if( !database.getPermissionRow(name, cred.smackLabel, accessorLabel) )
+            return CKM_API_ERROR_INPUT_PARAM;
     }
 
-    return MessageBuffer::Serialize(command, msgID, retCode).Pop();
+    retCode = database.setPermission(name,
+                                       cred.smackLabel,
+                                       accessorLabel,
+                                       reqRights);
+
+    transaction.commit();
+
+    return retCode;
 }
 
-RawBuffer CKMLogic::denyAccess(
-        Credentials &cred,
+RawBuffer CKMLogic::setPermission(
+        const Credentials &cred,
         int command,
         int msgID,
         const Name &name,
-        const Label &accessorLabel)
+        const Label &accessorLabel,
+        const Permission reqRights)
 {
-    int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
-
-    if (cred.smackLabel.empty()) {
-        retCode = CKM_API_ERROR_INPUT_PARAM;
-    } else if (0 < m_userDataMap.count(cred.uid)) {
-        Try {
-            retCode = m_userDataMap[cred.uid].database.clearAccessRights(name, cred.smackLabel, accessorLabel);
-        } Catch (DBCrypto::Exception::PermissionDenied) {
-            LogError("Error: not enough permissions!");
-            retCode = CKM_API_ERROR_ACCESS_DENIED;
-        } Catch (DBCrypto::Exception::InvalidArgs) {
-            LogError("Error: permission not found!");
-            retCode = CKM_API_ERROR_INPUT_PARAM;
-        } Catch (CKM::Exception) {
-            LogError("Error in deleting row!");
-            retCode = CKM_API_ERROR_DB_ERROR;
-        }
-    } else {
-        retCode = CKM_API_ERROR_DB_LOCKED;
+    int retCode;
+    Try {
+        retCode = setPermissionHelper(cred, name, accessorLabel, reqRights);
+    } Catch (CKM::Exception) {
+        LogError("Error in set row!");
+        retCode = CKM_API_ERROR_DB_ERROR;
     }
 
     return MessageBuffer::Serialize(command, msgID, retCode).Pop();
index e462631..4428bee 100644 (file)
@@ -33,6 +33,7 @@
 #include <crypto-logic.h>
 #include <certificate-store.h>
 #include <file-lock.h>
+#include <access-control.h>
 
 namespace CKM {
 
@@ -73,10 +74,11 @@ public:
         uid_t user,
         const Password &newPassword);
 
-    RawBuffer removeApplicationData(const Label &smackLabel);
+    RawBuffer removeApplicationData(
+        const Label &smackLabel);
 
     RawBuffer saveData(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         DBDataType dataType,
         const Name &name,
@@ -84,14 +86,14 @@ public:
         const PolicySerializable &policy);
 
     RawBuffer removeData(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         DBDataType dataType,
         const Name &name,
         const Label &label);
 
     RawBuffer getData(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         DBDataType dataType,
         const Name &name,
@@ -99,12 +101,12 @@ public:
         const Password &password);
 
     RawBuffer getDataList(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         DBDataType dataType);
 
     RawBuffer createKeyPair(
-        Credentials &cred,
+        const Credentials &cred,
         LogicCommand protocol_cmd,
         int commandId,
         const int additional_param,
@@ -114,19 +116,19 @@ public:
         const PolicySerializable &policyPublic);
 
     RawBuffer getCertificateChain(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         const RawBuffer &certificate,
         const RawBufferVector &untrustedCertificates);
 
     RawBuffer getCertificateChain(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         const RawBuffer &certificate,
         const LabelNameVector &labelNameVector);
 
     RawBuffer  createSignature(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         const Name &privateKeyName,
         const Label & ownerLabel,
@@ -136,7 +138,7 @@ public:
         const RSAPaddingAlgorithm padding);
 
     RawBuffer verifySignature(
-        Credentials &cred,
+        const Credentials &cred,
         int commandId,
         const Name &publicKeyOrCertName,
         const Label & ownerLabel,
@@ -148,20 +150,13 @@ public:
 
     RawBuffer updateCCMode();
 
-    RawBuffer allowAccess(
-        Credentials &cred,
+    RawBuffer setPermission(
+        const Credentials &cred,
         int command,
         int msgID,
         const Name &name,
         const Label &accessor_label,
-        const AccessRight req_rights);
-
-    RawBuffer denyAccess(
-        Credentials &cred,
-        int command,
-        int msgID,
-        const Name &name,
-        const Label &accessor_label);
+        const Permission req_rights);
 
 private:
 
@@ -170,14 +165,35 @@ private:
         const RawBuffer &input_data) const;
 
     int saveDataHelper(
-        Credentials &cred,
+        const Credentials &cred,
         DBDataType dataType,
         const Name &name,
         const RawBuffer &key,
         const PolicySerializable &policy);
 
-    int getDataHelper(
-        Credentials &cred,
+    int removeDataHelper(
+        const Credentials &cred,
+        const Name &name,
+        const Label &ownerLabel);
+
+    int readDataRowHelper(
+        const Name &name,
+        const Label &ownerLabel,
+        DBDataType dataType,
+        DBCrypto & database,
+        DBRow &row);
+
+    int checkDataPermissionsHelper(
+        const Name &name,
+        const Label &ownerLabel,
+        const Label &accessorLabel,
+        const DBRow &row,
+        bool exportFlag,
+        DBCrypto & database);
+
+    int readDataHelper(
+        bool exportFlag,
+        const Credentials &cred,
         DBDataType dataType,
         const Name &name,
         const Label &label,
@@ -185,7 +201,7 @@ private:
         DBRow &row);
 
     int createKeyPairHelper(
-        Credentials &cred,
+        const Credentials &cred,
         const KeyType key_type,
         const int additional_param,
         const Name &namePrivate,
@@ -193,22 +209,26 @@ private:
         const PolicySerializable &policyPrivate,
         const PolicySerializable &policyPublic);
 
-    int getKeyHelper(
-        Credentials &cred,
-        const Name &publicKeyOrCertName,
-        const Password &password,           // password for public_key (optional)
-        const KeyImpl &genericKey);
+    int getCertificateChainHelper(
+        const Credentials &cred,
+        const RawBuffer &certificate,
+        const LabelNameVector &labelNameVector,
+        RawBufferVector & chainRawVector);
 
+    int setPermissionHelper(
+        const Credentials &cred,
+        const Name &name,
+        const Label &accessorLabel,
+        const Permission reqRights);
 
     // @return true if name & label are proper, false otherwise
     static bool checkNameAndLabelValid(
         const Name &name,
         const Label &label);
-    void updateCCMode_internal();
 
     std::map<uid_t, UserData> m_userDataMap;
     CertificateStore m_certStore;
-    bool m_ccMode;
+    AccessControl m_accessControl;
     //FileLock m_lock;
 };
 
index adbe447..dba29c7 100644 (file)
@@ -139,37 +139,22 @@ RawBuffer CKMService::processControl(MessageBuffer &buffer) {
         return m_logic->removeApplicationData(smackLabel);
     case ControlCommand::UPDATE_CC_MODE:
         return m_logic->updateCCMode();
-    case ControlCommand::ALLOW_ACCESS:
+    case ControlCommand::SET_PERMISSION:
     {
         Name name;
         Label ownerLabel;
         Label accessorLabel;
-        int accessorRights = 0;
+        int accessorPermissions = 0;
 
-        buffer.Deserialize(user, ownerLabel, name, accessorLabel, accessorRights);
+        buffer.Deserialize(user, ownerLabel, name, accessorLabel, accessorPermissions);
         Credentials cred = { user, ownerLabel };
-        return m_logic->allowAccess(
+        return m_logic->setPermission(
             cred,
             command,
             0, // dummy
             name,
             accessorLabel,
-            static_cast<AccessRight>(accessorRights));
-    }
-    case ControlCommand::DENY_ACCESS:
-    {
-        Name name;
-        Label ownerLabel;
-        Label accessorLabel;
-
-        buffer.Deserialize(user, ownerLabel, name, accessorLabel);
-        Credentials cred = { user, ownerLabel };
-        return m_logic->denyAccess(
-            cred,
-            command,
-            0, // dummy
-            name,
-            accessorLabel);
+            static_cast<Permission>(accessorPermissions));
     }
     default:
         Throw(Exception::BrokenProtocol);
@@ -330,27 +315,17 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
                 static_cast<const HashAlgorithm>(hash),
                 static_cast<const RSAPaddingAlgorithm>(padding));
         }
-        case LogicCommand::ALLOW_ACCESS:
+        case LogicCommand::SET_PERMISSION:
         {
-            int reqRights = 0;
-            buffer.Deserialize(name, label, reqRights);
-            return m_logic->allowAccess(
+            int accessorPermissions = 0;
+            buffer.Deserialize(name, label, accessorPermissions);
+            return m_logic->setPermission(
                 cred,
                 command,
                 msgID,
                 name,
                 label,
-                static_cast<AccessRight>(reqRights));
-        }
-        case LogicCommand::DENY_ACCESS:
-        {
-            buffer.Deserialize(name, label);
-            return m_logic->denyAccess(
-                cred,
-                command,
-                msgID,
-                name,
-                label);
+                static_cast<Permission>(accessorPermissions));
         }
         default:
             Throw(Exception::BrokenProtocol);
index 603e8f7..4a34e27 100644 (file)
@@ -185,16 +185,16 @@ void CryptoLogic::encryptRow(const Password &password, DBRow &row)
             ThrowMsg(Exception::EncryptDBRowError, "Invalid dataSize.");
         }
 
-        if (!haveKey(row.smackLabel)) {
+        if (!haveKey(row.ownerLabel)) {
             ThrowMsg(Exception::EncryptDBRowError, "Missing application key for " <<
-              row.smackLabel << " label.");
+              row.ownerLabel << " label.");
         }
 
         if (crow.iv.empty()) {
             crow.iv = generateRandIV();
         }
 
-        key = m_keyMap[row.smackLabel];
+        key = m_keyMap[row.ownerLabel];
         crow.encryptionScheme = ENCR_APPKEY;
 
         auto dataPair = encryptDataAesGcm(crow.data, key, crow.iv);
@@ -241,9 +241,9 @@ void CryptoLogic::decryptRow(const Password &password, DBRow &row)
               "empty.");
         }
 
-        if ((row.encryptionScheme & ENCR_APPKEY) && !haveKey(row.smackLabel)) {
+        if ((row.encryptionScheme & ENCR_APPKEY) && !haveKey(row.ownerLabel)) {
             ThrowMsg(Exception::DecryptDBRowError, "Missing application key for " <<
-              row.smackLabel << " label.");
+              row.ownerLabel << " label.");
         }
 
         decBase64(crow.iv);
@@ -257,7 +257,7 @@ void CryptoLogic::decryptRow(const Password &password, DBRow &row)
         }
 
         if (crow.encryptionScheme & ENCR_APPKEY) {
-            key = m_keyMap[crow.smackLabel];
+            key = m_keyMap[crow.ownerLabel];
             crow.data = decryptDataAesGcm(crow.data, key, crow.iv, crow.tag);
         }
 
index 85f6305..92ba10a 100644 (file)
@@ -63,43 +63,19 @@ namespace {
             "VALUES("
             "   ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
 
-    const char *select_name_cmd =
-            "SELECT * FROM CKM_TABLE WHERE name=?001 AND label=?002 AND dataType=?003; ";
-
-    const char *select_name_cmd_join =
-            "SELECT * FROM CKM_TABLE WHERE name=?001 AND label=?002 AND dataType=?004 AND "
-            " idx in (SELECT idx FROM PERMISSION_TABLE WHERE label = ?003); ";
-
     const char *select_check_name_cmd =
             "SELECT dataType FROM CKM_TABLE WHERE name=?001 AND label=?002;";
 
-    const char *select_label_global_name_cmd =
-            "SELECT count(*) FROM CKM_TABLE WHERE name=?001 AND label=?002; ";
-
-//    const char *select_label_index_global_name_cmd =
-//            //                                           1
-//            "SELECT label, idx FROM CKM_TABLE WHERE name=?;";
-
-    const char *select_key_name_cmd =
+    const char *select_row_by_name_label_type_cmd =
             "SELECT * FROM CKM_TABLE WHERE name=?001 AND label=?002"
             " AND dataType BETWEEN ?003 AND ?004;";
 
-    const char *select_key_name_cmd_join =
-            "SELECT * FROM CKM_TABLE WHERE name=?001 AND label=?002"
-            " AND dataType BETWEEN ?004 AND ?005 " 
-            " AND idx in (SELECT idx FROM PERMISSION_TABLE WHERE label = ?003);";
-
     const char *select_count_rows_cmd =
             "SELECT COUNT(idx) FROM CKM_TABLE WHERE name=?001 AND label=?002;";
 
     const char *delete_name_cmd =
             "DELETE FROM CKM_TABLE WHERE name=?001 AND label=?002;";
 
-    const char *delete_name_cmd_join =
-            "DELETE FROM CKM_TABLE WHERE name=?001 AND label=?002 AND "
-            " idx in (SELECT idx FROM PERMISSION_TABLE WHERE label=?003);";
-
-
     const char *delete_data_with_key_cmd =
             //                                 1
             "DELETE FROM CKM_TABLE WHERE label=?;";
@@ -146,10 +122,6 @@ namespace {
 
 // CKM_TABLE x PERMISSION_TABLE
 
-    const char *select_type_cross_cmd =
-            "SELECT C.label, C.name FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.idx = P.idx WHERE "
-            "C.dataType=?001 AND (C.label=?002 OR (P.label=?002 AND P.accessFlags IS NOT NULL)) GROUP BY C.name;";
-
     const char *select_key_type_cross_cmd =
             "SELECT C.label, C.name FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.idx=P.idx WHERE "
             " C.dataType>=?001 AND C.dataType<=?002 AND "
@@ -236,70 +208,35 @@ using namespace DB;
         transaction.commit();
     }
 
-//    void DBCrypto::getLabelForName(const Name &name, Label & label) const {
-//        SqlConnection::DataCommandUniquePtr checkCmd =
-//                m_connection->PrepareDataCommand(select_label_global_name_cmd);
-//        checkCmd->BindString(1, name.c_str());
-//        if(checkCmd->Step()) {
-//            label = checkCmd->GetColumnString(0);
-//        } else
-//            label.clear();
-//    }
-
-//    void DBCrypto::getLabelForName(const Name &name, Label & label, int & index) const
-//    {
-//        SqlConnection::DataCommandUniquePtr checkCmd =
-//                m_connection->PrepareDataCommand(select_label_index_global_name_cmd);
-//        checkCmd->BindString(1, name.c_str());
-//        if(checkCmd->Step()) {
-//            label = checkCmd->GetColumnString(0);
-//            index = checkCmd->GetColumnInteger(1);
-//        }
-//        else
-//        {
-//            label.clear();
-//            index = -1;
-//        }
-//    }
-
-    bool DBCrypto::checkGlobalNameExist(const Name &name, const Label &ownerLabel) const {
-        SqlConnection::DataCommandUniquePtr checkCmd =
-                m_connection->PrepareDataCommand(select_label_global_name_cmd);
-        checkCmd->BindString(1, name.c_str());
-        checkCmd->BindString(2, ownerLabel.c_str());
-        if(checkCmd->Step())
-            return checkCmd->GetColumnInteger(0)?true:false;
-        return false;
-    }
-
-    bool DBCrypto::checkNameExist(const Name &name, const Label &owner) const {
-        SqlConnection::DataCommandUniquePtr checkCmd =
-                m_connection->PrepareDataCommand(select_check_name_cmd);
-        checkCmd->BindString(1, name.c_str());
-        checkCmd->BindString(2, owner.c_str());
-        if(checkCmd->Step()) {
-            LogDebug("Private name '" << name  << "' exists already for type "
-                    << checkCmd->GetColumnInteger(0));
-            return true;
-        } else
+    bool DBCrypto::isNameLabelPresent(const Name &name, const Label &owner) const {
+        Try {
+            SqlConnection::DataCommandUniquePtr checkCmd =
+                    m_connection->PrepareDataCommand(select_check_name_cmd);
+            checkCmd->BindString(1, name.c_str());
+            checkCmd->BindString(2, owner.c_str());
+            if(checkCmd->Step()) {
+                LogDebug("Private name '" << name  << "' exists already for type "
+                        << checkCmd->GetColumnInteger(0));
+                return true;
+            }
             return false;
+        } Catch(SqlConnection::Exception::SyntaxError) {
+            LogError("Couldn't prepare insert statement");
+        } Catch(SqlConnection::Exception::InternalError) {
+            LogError("Couldn't execute insert statement");
+        }
+        ThrowMsg(DBCrypto::Exception::InternalError,
+                "Couldn't check if name and label pair is present");
     }
 
     void DBCrypto::saveDBRow(const DBRow &row){
         Try {
-
-            //Sqlite does not support partial index in our version,
-            //so we do it by hand
-            Transaction transaction(this);
-            if(checkNameExist(row.name, row.smackLabel)) {
-                ThrowMsg(DBCrypto::Exception::NameExists,
-                        "Name exists for name: " << row.name);
-            }
-
+            // Sqlite does not support partial index in our version,
+            // so we do it by hand
             SqlConnection::DataCommandUniquePtr insertCommand =
                     m_connection->PrepareDataCommand(insert_main_cmd);
             insertCommand->BindString(1, row.name.c_str());
-            insertCommand->BindString(2, row.smackLabel.c_str());
+            insertCommand->BindString(2, row.ownerLabel.c_str());
             insertCommand->BindInteger(3, row.exportable);
             insertCommand->BindInteger(4, static_cast<int>(row.dataType));
             insertCommand->BindInteger(5, static_cast<int>(row.algorithmType));
@@ -310,7 +247,6 @@ using namespace DB;
             insertCommand->BindBlob(10, row.tag);
 
             insertCommand->Step();
-            transaction.commit();
             return;
 
         } Catch(SqlConnection::Exception::SyntaxError) {
@@ -325,7 +261,7 @@ using namespace DB;
     DBRow DBCrypto::getRow(const SqlConnection::DataCommandUniquePtr &selectCommand) {
         DBRow row;
         row.name = selectCommand->GetColumnString(0);
-        row.smackLabel = selectCommand->GetColumnString(1);
+        row.ownerLabel = selectCommand->GetColumnString(1);
         row.exportable = selectCommand->GetColumnInteger(2);
         row.dataType = static_cast<DBDataType>(selectCommand->GetColumnInteger(3));
         row.algorithmType = static_cast<DBCMAlgType>(selectCommand->GetColumnInteger(4));
@@ -337,19 +273,20 @@ using namespace DB;
         return row;
     }
 
-    std::string DBCrypto::getPermissions(const Name &name, const Label &ownerLabel, const Label &smackLabel) const
+    PermissionOptional DBCrypto::getPermissionRow(
+        const Name &name,
+        const Label &ownerLabel,
+        const Label &accessorLabel) const
     {
         Try{
             SqlConnection::DataCommandUniquePtr selectCommand =
                             m_connection->PrepareDataCommand(select_permission_cmd);
-            selectCommand->BindString(1, smackLabel.c_str());
+            selectCommand->BindString(1, accessorLabel.c_str());
             selectCommand->BindString(2, name.c_str());
             selectCommand->BindString(3, ownerLabel.c_str());
 
             if(selectCommand->Step())
-                return selectCommand->GetColumnString(0);
-
-            return std::string();
+                return PermissionOptional(toPermission(selectCommand->GetColumnString(0)));
         } Catch (SqlConnection::Exception::InvalidColumn) {
             LogError("Select statement invalid column error");
         } Catch (SqlConnection::Exception::SyntaxError) {
@@ -357,81 +294,35 @@ using namespace DB;
         } Catch (SqlConnection::Exception::InternalError) {
             LogError("Couldn't execute select statement");
         }
-        return std::string();
+        return PermissionOptional();
     }
 
     DBCrypto::DBRowOptional DBCrypto::getDBRow(
         const Name &name,
         const Label &ownerLabel,
-        const Label &smackLabel,
         DBDataType type)
     {
-        if (ownerLabel == smackLabel)
-            return getDBRowSimple(name, ownerLabel, type);
-        return getDBRowJoin(name, ownerLabel, smackLabel, type);
-    }
-
-    DBCrypto::DBRowOptional DBCrypto::getDBRowSimple(
-        const Name &name,
-        const Label &owner,
-        DBDataType type)
-    {
-        Try {
-            Transaction transaction(this);
-            SqlConnection::DataCommandUniquePtr selectCommand =
-                    m_connection->PrepareDataCommand(select_name_cmd);
-            selectCommand->BindString(1, name.c_str());
-            selectCommand->BindString(2, owner.c_str());
-            selectCommand->BindInteger(3, static_cast<int>(type));
-
-            if(selectCommand->Step())
-            {
-                // extract data
-                DBRow current_row = getRow(selectCommand);
-
-                // finalize DB operations
-                transaction.commit();
-
-                // all okay, proceed
-                return DBRowOptional(current_row);
-            } else {
-                return DBRowOptional();
-            }
-        } Catch (SqlConnection::Exception::InvalidColumn) {
-            LogError("Select statement invalid column error");
-        } Catch (SqlConnection::Exception::SyntaxError) {
-            LogError("Couldn't prepare select statement");
-        } Catch (SqlConnection::Exception::InternalError) {
-            LogError("Couldn't execute select statement");
-        }
-        ThrowMsg(DBCrypto::Exception::InternalError,
-                "Couldn't get row for type " << static_cast<int>(type) <<
-                " name " << name << " using client label " << owner);
+        return getDBRow(name, ownerLabel, type, type);
     }
-
-    DBCrypto::DBRowOptional DBCrypto::getDBRowJoin(
+    DBCrypto::DBRowOptional DBCrypto::getDBRow(
         const Name &name,
         const Label &ownerLabel,
-        const Label &smackLabel,
-        DBDataType type)
+        DBDataType typeRangeStart,
+        DBDataType typeRangeStop)
     {
         Try {
-            Transaction transaction(this);
             SqlConnection::DataCommandUniquePtr selectCommand =
-                    m_connection->PrepareDataCommand(select_name_cmd_join);
+                    m_connection->PrepareDataCommand(select_row_by_name_label_type_cmd);
             selectCommand->BindString(1, name.c_str());
             selectCommand->BindString(2, ownerLabel.c_str());
-            selectCommand->BindString(3, smackLabel.c_str());
-            selectCommand->BindInteger(4, static_cast<int>(type));
+            selectCommand->BindInteger(3, static_cast<int>(typeRangeStart));
+            selectCommand->BindInteger(4, static_cast<int>(typeRangeStop));
 
             if(selectCommand->Step())
             {
                 // extract data
                 DBRow current_row = getRow(selectCommand);
 
-                // finalize DB operations
-                transaction.commit();
-
                 // all okay, proceed
                 return DBRowOptional(current_row);
             } else {
@@ -445,114 +336,38 @@ using namespace DB;
             LogError("Couldn't execute select statement");
         }
         ThrowMsg(DBCrypto::Exception::InternalError,
-                "Couldn't get row for type " << static_cast<int>(type) <<
-                " name " << name << " using client label " << smackLabel);
+                "Couldn't get row of type <" <<
+                static_cast<int>(typeRangeStart) << "," <<
+                static_cast<int>(typeRangeStop)  << ">" <<
+                " name " << name << " with owner label " << ownerLabel);
     }
 
-    DBCrypto::DBRowOptional DBCrypto::getKeyDBRow(
-        const Name &name,
-        const Label &ownerLabel,
-        const Label &smackLabel)
+    void DBCrypto::listNames(
+        const Label &smackLabel,
+        LabelNameVector& labelNameVector,
+        DBDataType type)
     {
-        if (ownerLabel == smackLabel)
-            return getKeyDBRowSimple(name, ownerLabel);
-        else
-            return getKeyDBRowJoin(name, ownerLabel, smackLabel);
+        listNames(smackLabel, labelNameVector, type, type);
     }
 
-    DBCrypto::DBRowOptional DBCrypto::getKeyDBRowSimple(
-        const Name &name,
-        const Label &ownerLabel)
-    {
-        Try{
-            Transaction transaction(this);
-            SqlConnection::DataCommandUniquePtr selectCommand =
-                    m_connection->PrepareDataCommand(select_key_name_cmd);
-            selectCommand->BindString(1, name.c_str());
-            selectCommand->BindString(2, ownerLabel.c_str());
-            selectCommand->BindInteger(3, static_cast<int>(DBDataType::DB_KEY_FIRST));
-            selectCommand->BindInteger(4, static_cast<int>(DBDataType::DB_KEY_LAST));
-
-            if(selectCommand->Step())
-            {
-                // extract data
-                DBRow current_row = getRow(selectCommand);
-
-                // finalize DB operations
-                transaction.commit();
-
-                // all okay, proceed
-                return DBRowOptional(current_row);
-            } else {
-                return DBRowOptional();
-            }
-        } Catch (SqlConnection::Exception::InvalidColumn) {
-            LogError("Select statement invalid column error");
-        } Catch (SqlConnection::Exception::SyntaxError) {
-            LogError("Couldn't prepare select statement");
-        } Catch (SqlConnection::Exception::InternalError) {
-            LogError("Couldn't execute select statement");
-        }
-        ThrowMsg(DBCrypto::Exception::InternalError,
-                "Couldn't get Key for name " << name
-                << " using client label " << ownerLabel);
-    }
-
-    DBCrypto::DBRowOptional DBCrypto::getKeyDBRowJoin(
-        const Name &name,
-        const Label &ownerLabel,
-        const Label &smackLabel)
+    void DBCrypto::listNames(
+        const Label &smackLabel,
+        LabelNameVector& labelNameVector,
+        DBDataType typeRangeStart,
+        DBDataType typeRangeStop)
     {
         Try{
             Transaction transaction(this);
             SqlConnection::DataCommandUniquePtr selectCommand =
-                    m_connection->PrepareDataCommand(select_key_name_cmd_join);
-            selectCommand->BindString(1, name.c_str());
-            selectCommand->BindString(2, ownerLabel.c_str());
+                            m_connection->PrepareDataCommand(select_key_type_cross_cmd);
+            selectCommand->BindInteger(1, static_cast<int>(typeRangeStart));
+            selectCommand->BindInteger(2, static_cast<int>(typeRangeStop));
             selectCommand->BindString(3, smackLabel.c_str());
-            selectCommand->BindInteger(4, static_cast<int>(DBDataType::DB_KEY_FIRST));
-            selectCommand->BindInteger(5, static_cast<int>(DBDataType::DB_KEY_LAST));
-
-            if(selectCommand->Step())
-            {
-                // extract data
-                DBRow current_row = getRow(selectCommand);
-
-                // finalize DB operations
-                transaction.commit();
-
-                // all okay, proceed
-                return DBRowOptional(current_row);
-            } else {
-                return DBRowOptional();
-            }
-        } Catch (SqlConnection::Exception::InvalidColumn) {
-            LogError("Select statement invalid column error");
-        } Catch (SqlConnection::Exception::SyntaxError) {
-            LogError("Couldn't prepare select statement");
-        } Catch (SqlConnection::Exception::InternalError) {
-            LogError("Couldn't execute select statement");
-        }
-        ThrowMsg(DBCrypto::Exception::InternalError,
-                "Couldn't get Key for name " << name
-                << " using client label " << smackLabel);
-    }
-
-    void DBCrypto::getSingleType(
-            const Label &clnt_label,
-            DBDataType type,
-            LabelNameVector& labelNameVector) const
-    {
-        Try{
-            SqlConnection::DataCommandUniquePtr selectCommand =
-                            m_connection->PrepareDataCommand(select_type_cross_cmd);
-            selectCommand->BindInteger(1, static_cast<int>(type));
-            selectCommand->BindString(2, clnt_label.c_str());
 
             while(selectCommand->Step()) {
-                Label label = selectCommand->GetColumnString(0);
+                Label ownerLabel = selectCommand->GetColumnString(0);
                 Name name = selectCommand->GetColumnString(1);
-                labelNameVector.push_back(std::make_pair(label, name));
+                labelNameVector.push_back(std::make_pair(ownerLabel, name));
             }
             return;
         } Catch (SqlConnection::Exception::InvalidColumn) {
@@ -563,56 +378,15 @@ using namespace DB;
             LogError("Couldn't execute select statement");
         }
         ThrowMsg(DBCrypto::Exception::InternalError,
-                "Couldn't get type " << static_cast<int>(type));
+                "Couldn't list names of type <" <<
+                static_cast<int>(typeRangeStart) << "," <<
+                static_cast<int>(typeRangeStop)  << ">" <<
+                " accessible to client label " << smackLabel);
     }
 
-    void DBCrypto::getNames(
-        const Label &clnt_label,
-        DBDataType type,
-        LabelNameVector& labelNameVector)
-    {
-        getSingleType(clnt_label, type, labelNameVector);
-    }
-
-
-    void DBCrypto::getKeyNames(const Label &clnt_label, LabelNameVector &labelNameVector)
-    {
-        Try{
-            Transaction transaction(this);
-            SqlConnection::DataCommandUniquePtr selectCommand =
-                            m_connection->PrepareDataCommand(select_key_type_cross_cmd);
-            selectCommand->BindInteger(1, static_cast<int>(DBDataType::DB_KEY_FIRST));
-            selectCommand->BindInteger(2, static_cast<int>(DBDataType::DB_KEY_LAST));
-            selectCommand->BindString(3, clnt_label.c_str());
-
-            while(selectCommand->Step()) {
-                Label label = selectCommand->GetColumnString(0);
-                Name name = selectCommand->GetColumnString(1);
-                labelNameVector.push_back(std::make_pair(label, name));
-            }
-            transaction.commit();
-            return;
-        } Catch (SqlConnection::Exception::InvalidColumn) {
-            LogError("Select statement invalid column error");
-        } Catch (SqlConnection::Exception::SyntaxError) {
-            LogError("Couldn't prepare select statement");
-        } Catch (SqlConnection::Exception::InternalError) {
-            LogError("Couldn't execute select statement");
-        }
-        ThrowMsg(DBCrypto::Exception::InternalError, "Couldn't get key names");
-    }
-
-    bool DBCrypto::deleteDBRow(const Name &name, const Label &ownerLabel, const Label &credLabel) {
-        if (ownerLabel == credLabel)
-            return deleteDBRowSimple(name, ownerLabel);
-        return deleteDBRowJoin(name, ownerLabel, credLabel);
-    }
-
-    bool DBCrypto::deleteDBRowSimple(const Name &name, const Label &ownerLabel)
+    bool DBCrypto::deleteDBRow(const Name &name, const Label &ownerLabel)
     {
         Try {
-            Transaction transaction(this);
-
             if(countRows(name, ownerLabel) > 0)
             {
                 SqlConnection::DataCommandUniquePtr deleteCommand =
@@ -623,7 +397,6 @@ using namespace DB;
                 // Step() result code does not provide information whether
                 // anything was removed.
                 deleteCommand->Step();
-                transaction.commit();
 
                 return true;
             }
@@ -637,46 +410,8 @@ using namespace DB;
                 "Couldn't delete DBRow for name " << name << " using client label " << ownerLabel);
     }
 
-    bool DBCrypto::deleteDBRowJoin(const Name &name, const Label &ownerLabel, const Label &smackLabel)
+    int DBCrypto::countRows(const Name &name, const Label &ownerLabel) const
     {
-        Try {
-            Transaction transaction(this);
-
-            if (!checkNameExist(name, ownerLabel))
-                return false;
-
-            std::string permissions = DBCrypto::getPermissions(name, ownerLabel, smackLabel);
-            if(permissions.empty() == false)
-            {
-                // entry present, check if for reading or read/remove
-                if(permissions.find(toDBAccessRight(AccessRight::AR_READ_REMOVE)) == std::string::npos)
-                    ThrowMsg(DBCrypto::Exception::PermissionDenied, "Client " << smackLabel << " can only read " <<
-                             ownerLabel << CKM::LABEL_NAME_SEPARATOR << name << ", remove forbidden");
-
-                SqlConnection::DataCommandUniquePtr deleteCommand =
-                    m_connection->PrepareDataCommand(delete_name_cmd_join);
-                deleteCommand->BindString(1, name.c_str());
-                deleteCommand->BindString(2, ownerLabel.c_str());
-                deleteCommand->BindString(3, smackLabel.c_str());
-
-                // Step() result code does not provide information whether
-                // anything was removed.
-                deleteCommand->Step();
-                transaction.commit();
-
-                return true;
-            }
-            return false;
-        } Catch (SqlConnection::Exception::SyntaxError) {
-            LogError("Couldn't prepare delete statement");
-        } Catch (SqlConnection::Exception::InternalError) {
-            LogError("Couldn't execute delete statement");
-        }
-        ThrowMsg(DBCrypto::Exception::InternalError,
-                "Couldn't delete DBRow for name " << name << " using client label " << ownerLabel);
-    }
-
-    int DBCrypto::countRows(const Name &name, const Label &ownerLabel) {
         SqlConnection::DataCommandUniquePtr checkCmd =
                     m_connection->PrepareDataCommand(select_count_rows_cmd);
         checkCmd->BindString(1, name.c_str());
@@ -694,13 +429,11 @@ using namespace DB;
             const RawBuffer &key)
     {
         Try {
-            Transaction transaction(this);
             SqlConnection::DataCommandUniquePtr insertCommand =
                     m_connection->PrepareDataCommand(insert_key_cmd);
             insertCommand->BindString(1, label.c_str());
             insertCommand->BindBlob(2, key);
             insertCommand->Step();
-            transaction.commit();
             return;
         } Catch (SqlConnection::Exception::SyntaxError) {
             LogError("Couldn't prepare insert key statement");
@@ -714,17 +447,14 @@ using namespace DB;
     DBCrypto::RawBufferOptional DBCrypto::getKey(const Label& label)
     {
         Try {
-            Transaction transaction(this);
             SqlConnection::DataCommandUniquePtr selectCommand =
                     m_connection->PrepareDataCommand(select_key_cmd);
             selectCommand->BindString(1, label.c_str());
 
             if (selectCommand->Step()) {
-                transaction.commit();
                 return RawBufferOptional(
                         selectCommand->GetColumnBlob(0));
             } else {
-                transaction.commit();
                 return RawBufferOptional();
             }
 
@@ -764,30 +494,34 @@ using namespace DB;
                 "Couldn't delete key for label " << label);
     }
 
-    int DBCrypto::setAccessRights(
+    int DBCrypto::setPermission(
             const Name &name,
             const Label& ownerLabel,
             const Label& accessorLabel,
-            const AccessRight accessRights)
+            const Permission permissions)
     {
         Try {
-            Transaction transaction(this);
-
-            // owner can not add permissions to itself
-            if(ownerLabel.compare(accessorLabel) == 0)
-                return CKM_API_ERROR_INPUT_PARAM;
-
-            if (!checkNameExist(name, ownerLabel))
-                return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
-
-            SqlConnection::DataCommandUniquePtr setPermissionCommand =
-                m_connection->PrepareDataCommand(set_permission_name_cmd);
-            setPermissionCommand->BindString(1, accessorLabel.c_str());
-            setPermissionCommand->BindString(2, toDBAccessRight(accessRights));
-            setPermissionCommand->BindString(3, name.c_str());
-            setPermissionCommand->BindString(4, ownerLabel.c_str());
-            setPermissionCommand->Step();
-            transaction.commit();
+            if(permissions == Permission::NONE)
+            {
+                // clear access rights
+                SqlConnection::DataCommandUniquePtr deletePermissionCommand =
+                    m_connection->PrepareDataCommand(delete_permission_cmd);
+                deletePermissionCommand->BindString(1, name.c_str());
+                deletePermissionCommand->BindString(2, ownerLabel.c_str());
+                deletePermissionCommand->BindString(3, accessorLabel.c_str());
+                deletePermissionCommand->Step();
+            }
+            else
+            {
+                // add new rights
+                SqlConnection::DataCommandUniquePtr setPermissionCommand =
+                    m_connection->PrepareDataCommand(set_permission_name_cmd);
+                setPermissionCommand->BindString(1, accessorLabel.c_str());
+                setPermissionCommand->BindString(2, toDBPermission(permissions));
+                setPermissionCommand->BindString(3, name.c_str());
+                setPermissionCommand->BindString(4, ownerLabel.c_str());
+                setPermissionCommand->Step();
+            }
             return CKM_API_SUCCESS;
         } Catch (SqlConnection::Exception::SyntaxError) {
             LogError("Couldn't prepare set statement");
@@ -798,45 +532,6 @@ using namespace DB;
                 "Couldn't set permissions for name " << name );
     }
 
-    int DBCrypto::clearAccessRights(
-            const Name &name,
-            const Label &ownerLabel,
-            const Label &accessorLabel)
-    {
-        Try {
-            Transaction transaction(this);
-
-            // owner can not add permissions to itself
-            if(ownerLabel.compare(accessorLabel) == 0)
-                return CKM_API_ERROR_INPUT_PARAM;
-
-            // check if CKM entry present
-            if (!checkNameExist(name, ownerLabel)) {
-                transaction.commit();
-                return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
-            }
-
-            // check if permission entry present
-            if( DBCrypto::getPermissions(name, ownerLabel, accessorLabel).empty() )
-                return CKM_API_ERROR_INPUT_PARAM;
-
-            SqlConnection::DataCommandUniquePtr deletePermissionCommand =
-                m_connection->PrepareDataCommand(delete_permission_cmd);
-            deletePermissionCommand->BindString(1, name.c_str());
-            deletePermissionCommand->BindString(2, ownerLabel.c_str());
-            deletePermissionCommand->BindString(3, accessorLabel.c_str());
-            deletePermissionCommand->Step();
-            transaction.commit();
-            return CKM_API_SUCCESS;
-        } Catch (SqlConnection::Exception::SyntaxError) {
-            LogError("Couldn't prepare delete statement");
-        } Catch (SqlConnection::Exception::InternalError) {
-            LogError("Couldn't execute delete statement");
-        }
-        ThrowMsg(DBCrypto::Exception::InternalError,
-                "Couldn't delete permissions for name " << name);
-    }
-
 } // namespace CKM
 
 #pragma GCC diagnostic pop
index 714afd2..adb4e6f 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <ckm/ckm-type.h>
 #include <db-row.h>
+#include <permission.h>
 #include <protocols.h>
 
 #pragma GCC diagnostic push
@@ -44,10 +45,8 @@ namespace CKM {
             {
               public:
                 DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
-                DECLARE_EXCEPTION_TYPE(Base, NameExists)
                 DECLARE_EXCEPTION_TYPE(Base, InternalError)
                 DECLARE_EXCEPTION_TYPE(Base, TransactionError)
-                DECLARE_EXCEPTION_TYPE(Base, PermissionDenied)
                 DECLARE_EXCEPTION_TYPE(Base, InvalidArgs)
             };
             DBCrypto() :
@@ -65,43 +64,58 @@ namespace CKM {
             virtual ~DBCrypto();
 
             void saveDBRow(const DBRow &row);
+
             DBRowOptional getDBRow(
                     const Name &name,
                     const Label &ownerLabel,
-                    const Label &smackLabel,
                     DBDataType type);
-            DBRowOptional getKeyDBRow(
+
+            DBRowOptional getDBRow(
                     const Name &name,
                     const Label &ownerLabel,
-                    const Label &smackLabel);
-            void getNames(
-                    const Label &clnt_label,
-                    DBDataType dataType,
-                    LabelNameVector &labelNameVector);
-            void getKeyNames(
-                    const Label &clnt_label,
-                    LabelNameVector &labelNameVector);
+                    DBDataType typeRangeStart,
+                    DBDataType typeRangeStop);
+
+            void listNames(
+                    const Label &smackLabel,
+                    LabelNameVector& labelNameVector,
+                    DBDataType type);
+
+            void listNames(
+                    const Label &smackLabel,
+                    LabelNameVector& labelNameVector,
+                    DBDataType typeRangeStart,
+                    DBDataType typeRangeStop);
+
             bool deleteDBRow(
                     const Name &name,
-                    const Label &ownerLabel,
-                    const Label &smackLabel);
+                    const Label &ownerLabel);
+
 
             // keys
             void saveKey(const Label& label, const RawBuffer &key);
             RawBufferOptional getKey(const Label& label);
             void deleteKey(const Label& label);
 
+
             // permissions
-            int setAccessRights(
+            bool isNameLabelPresent(
+                    const Name &name,
+                    const Label &owner) const;
+
+            int setPermission(
                     const Name &name,
                     const Label &ownerLabel,
                     const Label &accessorLabel,
-                    const AccessRight rights);
-            int clearAccessRights(
+                    const Permission permissions);
+
+            PermissionOptional getPermissionRow(
                     const Name &name,
                     const Label &ownerLabel,
-                    const Label &accessorLabel);
+                    const Label &accessorLabel) const;
+
 
+            // transactions
             int beginTransaction();
             int commitTransaction();
             int rollbackTransaction();
@@ -180,62 +194,13 @@ namespace CKM {
             void initDatabase();
             DBRow getRow(const DB::SqlConnection::DataCommandUniquePtr &selectCommand);
 
-            enum DBOperationType : char {
-                DB_OPERATION_READ       = 'R',            ///< read DB row
-                DB_OPERATION_WRITE      = 'W',            ///< modify DB row
-                DB_OPERATION_REMOVE     = 'D'             ///< delete DB row
-            };
-
-            /**
-             * read PERMISSION_TABLE entry for client smackLabel to access CKM entry <name, ownerLabel>
-             *
-             * @return permission string (consisting with DBOperationType chars), may be empty
-             */
-            std::string getPermissions(
-                    const Name &name,
-                    const Label &ownerLabel,
-                    const Label &smackLabel) const;
-
             void createTable(
                     const char *create_cmd,
                     const char *table_name);
-            bool checkNameExist(const Name &name, const Label &owner) const;
-//            void getLabelForName(const Name &name, Label & label) const;
-//            void getLabelForName(const Name &name, Label & label, int & index) const;
-            bool checkGlobalNameExist(const Name &name, const Label &ownerLabel) const;
-            void getSingleType(const Label &clnt_label, DBDataType type, LabelNameVector& labelNameVector) const;
-            DBRowOptional getDBRowSimple(
-                    const Name &name,
-                    const Label &ownerLabel,
-                    DBDataType type);
-
-            DBRowOptional getDBRowJoin(
-                    const Name &name,
-                    const Label &ownerLabel,
-                    const Label &smackLabel,
-                    DBDataType type);
-
-            DBRowOptional getKeyDBRowSimple(
-                    const Name &name,
-                    const Label &onwerLabel);
-
-            DBRowOptional getKeyDBRowJoin(
-                    const Name &name,
-                    const Label &onwerLabel,
-                    const Label &smackLabel);
 
             int countRows(
                     const Name &name,
-                    const Label &label);
-
-            bool deleteDBRowSimple(
-                    const Name &name,
-                    const Label &ownerLabel);
-
-            bool deleteDBRowJoin(
-                    const Name &name,
-                    const Label &ownerLabel,
-                    const Label &smackLabel);
+                    const Label &label) const;
     };
 } // namespace CKM
 
index 56baead..6f3189b 100644 (file)
@@ -1,3 +1,24 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        db-row.h
+ * @author      Zofia Abramowska (z.abramowska@samsung.com)
+ * @version     1.0
+ * @brief       OBJECT_TABLE entry enhanced with corresponding NAME_TABLE identifier
+ */
 #pragma once
 
 #include <ckm/ckm-type.h>
@@ -6,7 +27,7 @@
 namespace CKM {
     struct DBRow {
         Name name;
-        Label smackLabel;
+        Label ownerLabel;
         int exportable;
         DBDataType dataType;        // cert/key/data
         DBCMAlgType algorithmType;  // Algorithm type used for row data encryption
diff --git a/src/manager/service/permission.h b/src/manager/service/permission.h
new file mode 100644 (file)
index 0000000..b7a3855
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        permission.h
+ * @author      Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @version     1.0
+ * @brief       PermissionForLabel - helper to bind permissions with accessor label.
+ */
+#pragma once
+
+#include <ckm/ckm-type.h>
+#include <boost/optional.hpp>
+
+namespace CKM {
+typedef boost::optional<Permission> PermissionOptional;
+struct PermissionForLabel {
+    Label accessorLabel;        // who is accessing the item
+    Permission permissions;
+
+    PermissionForLabel(const Label & accessor, const PermissionOptional & permOpt)
+    {
+        accessorLabel = accessor;
+        if(permOpt)
+            permissions = *permOpt;
+        else
+            permissions = Permission::NONE;
+    }
+};
+} // namespace CKM
index 9581a53..db6c46f 100644 (file)
@@ -62,7 +62,7 @@ void DBFixture::generate_perf_DB(unsigned int num_name, unsigned int num_label)
     for(unsigned int i=0; i<num_name; i++)
     {
         generate_name(i, rowPattern.name);
-        generate_label(i/num_label, rowPattern.smackLabel);
+        generate_label(i/num_label, rowPattern.ownerLabel);
 
         BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
     }
@@ -105,7 +105,7 @@ DBRow DBFixture::create_default_row(const Name &name,
 {
     DBRow row;
     row.name = name;
-    row.smackLabel = label;
+    row.ownerLabel = label;
     row.exportable = 1;
     row.algorithmType = DBCMAlgType::AES_GCM_256;
     row.dataType = type;
@@ -122,9 +122,9 @@ void DBFixture::compare_row(const DBRow &lhs, const DBRow &rhs)
             "namees didn't match! Got: " << rhs.name
                 << " , expected : " << lhs.name);
 
-    BOOST_CHECK_MESSAGE(lhs.smackLabel == rhs.smackLabel,
-            "smackLabel didn't match! Got: " << rhs.smackLabel
-                << " , expected : " << lhs.smackLabel);
+    BOOST_CHECK_MESSAGE(lhs.ownerLabel == rhs.ownerLabel,
+            "smackLabel didn't match! Got: " << rhs.ownerLabel
+                << " , expected : " << lhs.ownerLabel);
 
     BOOST_CHECK_MESSAGE(lhs.exportable == rhs.exportable,
             "exportable didn't match! Got: " << rhs.exportable
@@ -145,7 +145,7 @@ void DBFixture::check_DB_integrity(const DBRow &rowPattern)
     DBRow selectRow = rowPattern;
 
     DBCrypto::DBRowOptional optional_row;
-    BOOST_REQUIRE_NO_THROW(optional_row = m_db.getDBRow("name", "label", "label", DBDataType::BINARY_DATA));
+    BOOST_REQUIRE_NO_THROW(optional_row = m_db.getDBRow("name", "label", DBDataType::BINARY_DATA));
     BOOST_REQUIRE_MESSAGE(optional_row, "Select didn't return any row");
 
     compare_row(selectRow, rowPattern);
@@ -153,13 +153,12 @@ void DBFixture::check_DB_integrity(const DBRow &rowPattern)
     name_duplicate.data = createDefaultPass();
     name_duplicate.dataSize = name_duplicate.data.size();
 
-    BOOST_REQUIRE_THROW(m_db.saveDBRow(name_duplicate), DBCrypto::Exception::NameExists);
     unsigned int erased;
-    BOOST_REQUIRE_NO_THROW(erased = m_db.deleteDBRow("name", "label", "label"));
+    BOOST_REQUIRE_NO_THROW(erased = m_db.deleteDBRow("name", "label"));
     BOOST_REQUIRE_MESSAGE(erased > 0, "Inserted row didn't exist in db");
 
     DBCrypto::DBRowOptional row_optional;
-    BOOST_REQUIRE_NO_THROW(row_optional = m_db.getDBRow("name", "label", "label", DBDataType::BINARY_DATA));
+    BOOST_REQUIRE_NO_THROW(row_optional = m_db.getDBRow("name", "label", DBDataType::BINARY_DATA));
     BOOST_REQUIRE_MESSAGE(!row_optional, "Select should not return row after deletion");
 }
 
@@ -177,34 +176,27 @@ void DBFixture::insert_row(const Name &name, const Label &owner_label)
     BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
 }
 
-void DBFixture::delete_row(const Name &name, const Label &owner_label, const Label &accessor_label)
+void DBFixture::delete_row(const Name &name, const Label &owner_label)
 {
     bool exit_flag;
-    BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteDBRow(name, owner_label, accessor_label));
+    BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteDBRow(name, owner_label));
     BOOST_REQUIRE_MESSAGE(true == exit_flag, "remove name failed: no rows removed");
 }
 
 void DBFixture::add_permission(const Name &name, const Label &owner_label, const Label &accessor_label)
 {
     int ec;
-    BOOST_REQUIRE_NO_THROW(ec = m_db.setAccessRights(name,
+    BOOST_REQUIRE_NO_THROW(ec = m_db.setPermission(name,
                                                      owner_label,
                                                      accessor_label,
-                                                     CKM::AccessRight::AR_READ_REMOVE));
+                                                     CKM::Permission::READ_REMOVE));
     BOOST_REQUIRE_MESSAGE(CKM_API_SUCCESS == ec, "add permission failed: " << ec);
 }
 
-void DBFixture::read_row_expect_fail(const Name &name, const Label &owner_label, const Label &accessor_label)
+void DBFixture::read_row_expect_success(const Name &name, const Label &owner_label)
 {
     DBCrypto::DBRowOptional row;
-    BOOST_REQUIRE_NO_THROW(row = m_db.getDBRow(name, owner_label, accessor_label, DBDataType::BINARY_DATA));
-    BOOST_REQUIRE(!row);
-}
-
-void DBFixture::read_row_expect_success(const Name &name, const Label &owner_label, const Label &accessor_label)
-{
-    DBCrypto::DBRowOptional row;
-    BOOST_REQUIRE_NO_THROW(row = m_db.getDBRow(name, owner_label, accessor_label, DBDataType::BINARY_DATA));
+    BOOST_REQUIRE_NO_THROW(row = m_db.getDBRow(name, owner_label, DBDataType::BINARY_DATA));
     BOOST_REQUIRE_MESSAGE(row, "row is empty");
     BOOST_REQUIRE_MESSAGE(row->name == name, "name is not valid");
 }
index e4047c5..deacabf 100644 (file)
@@ -32,10 +32,9 @@ class DBFixture
         void check_DB_integrity(const CKM::DBRow &rowPattern);
         void insert_row();
         void insert_row(const CKM::Name &name, const CKM::Label &owner_label);
-        void delete_row(const CKM::Name &name, const CKM::Label &owner_label, const CKM::Label &accessor_label);
+        void delete_row(const CKM::Name &name, const CKM::Label &owner_label);
         void add_permission(const CKM::Name &name, const CKM::Label &owner_label, const CKM::Label &accessor_label);
-        void read_row_expect_fail(const CKM::Name &name, const CKM::Label &owner_label, const CKM::Label &accessor_label);
-        void read_row_expect_success(const CKM::Name &name, const CKM::Label &owner_label, const CKM::Label &accessor_label);
+        void read_row_expect_success(const CKM::Name &name, const CKM::Label &owner_label);
 
         CKM::DBCrypto    m_db;
     private:
index db1db79..69f697b 100644 (file)
@@ -51,10 +51,7 @@ BOOST_AUTO_TEST_CASE(DBtestGlobal) {
     BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
 
     DBRow name_duplicate = rowPattern;
-    rowPattern.smackLabel = rowPattern.smackLabel + "1";
-
-    BOOST_REQUIRE_THROW(m_db.saveDBRow(name_duplicate),
-            DBCrypto::Exception::NameExists);
+    rowPattern.ownerLabel = rowPattern.ownerLabel + "1";
 }
 BOOST_AUTO_TEST_CASE(DBtestTransaction) {
     DBRow rowPattern = create_default_row();
@@ -68,96 +65,10 @@ BOOST_AUTO_TEST_CASE(DBtestTransaction) {
 
     DBCrypto::DBRowOptional row_optional;
     BOOST_REQUIRE_NO_THROW(row_optional = m_db.getDBRow(m_default_name, m_default_label,
-                                                   m_default_label, DBDataType::BINARY_DATA));
+                                                        DBDataType::BINARY_DATA));
     BOOST_CHECK_MESSAGE(!row_optional, "Row still present after rollback");
-
 }
 
-BOOST_AUTO_TEST_CASE(DBaddDataCheckIfPermissionIsAdded)
-{
-    Name row_A_name, row_B_name;
-    Label row_A_label, row_B_label;
-    generate_name(0, row_A_name); generate_label(0, row_A_label);
-    generate_name(1, row_B_name); generate_label(1, row_B_label);
-
-    // insert initial data set
-    insert_row(row_A_name, row_A_label);
-    insert_row(row_B_name, row_B_label);
-    read_row_expect_success(row_A_name, row_A_label, row_A_label);
-    read_row_expect_success(row_B_name, row_B_label, row_B_label);
-
-    // verify that no entries present in the permission table
-    // read row A from label B and vice versa
-    read_row_expect_fail(row_A_name, row_A_label, row_B_label);
-    read_row_expect_fail(row_B_name, row_B_label, row_A_label);
-
-    // add appropriate permissions for label B
-    add_permission(row_A_name, row_A_label, row_B_label);
-
-    // B should have access to A, while A should not to B
-    // read row A from label B and vice versa
-    read_row_expect_success(row_A_name, row_A_label, row_B_label);
-    read_row_expect_fail(row_B_name, row_B_label, row_A_label);
-
-    // add appropriate permissions for label A
-    add_permission(row_B_name, row_B_label, row_A_label);
-
-    // B should have access to A, same as A have access to B
-    // read row A from label B and vice versa
-    read_row_expect_success(row_A_name, row_A_label, row_B_label);
-    read_row_expect_success(row_B_name, row_B_label, row_A_label);
-}
-
-
-BOOST_AUTO_TEST_CASE(DBremoveDataCheckIfPermissionIsRemoved)
-{
-    Name row_A_name, row_B_name, row_C_name;
-    Label row_A_label, row_B_label, row_C_label;
-    generate_name(0, row_A_name); generate_label(0, row_A_label);
-    generate_name(1, row_B_name); generate_label(1, row_B_label);
-    generate_name(2, row_C_name); generate_label(2, row_C_label);
-
-    // insert initial data set
-    insert_row(row_A_name, row_A_label);
-    insert_row(row_B_name, row_B_label);
-    insert_row(row_C_name, row_C_label);
-    add_permission(row_A_name, row_A_label, row_B_label);
-    add_permission(row_B_name, row_B_label, row_A_label);
-    // to test multiple permissions removal
-    // put intentionally after row_B_name permission entry
-    add_permission(row_A_name, row_A_label, row_C_label);
-
-    // B should have access to A, same as A have access to B
-    // read row A from label B and vice versa
-    read_row_expect_success(row_A_name, row_A_label, row_B_label);
-    read_row_expect_success(row_A_name, row_A_label, row_C_label);
-    read_row_expect_success(row_B_name, row_B_label, row_A_label);
-    read_row_expect_fail(row_B_name, row_B_label, row_C_label);
-
-    // remove data A - expect permissions for B and C to be removed as well
-    delete_row(row_A_name, row_A_label, row_A_label);
-    // insert it again - expect permissions for label B and C not to be there anymore
-    insert_row(row_A_name, row_A_label);
-
-    // read row A from label B and vice versa
-    read_row_expect_fail(row_A_name, row_A_label, row_B_label);
-    read_row_expect_fail(row_A_name, row_A_label, row_C_label);
-    read_row_expect_success(row_B_name, row_B_label, row_A_label);
-
-    // remove data B - expect permission to be removed as well
-    delete_row(row_B_name, row_B_label, row_B_label);
-    // insert it again - expect permissions for label A not to be there anymore
-    insert_row(row_B_name, row_B_label);
-
-    // read row A from label B and vice versa
-    read_row_expect_fail(row_A_name, row_A_label, row_B_label);
-    read_row_expect_fail(row_A_name, row_A_label, row_C_label);
-    read_row_expect_fail(row_B_name, row_B_label, row_A_label);
-
-    // sanity check: data exists
-    read_row_expect_success(row_A_name, row_A_label, row_A_label);
-    read_row_expect_success(row_B_name, row_B_label, row_B_label);
-}
 BOOST_AUTO_TEST_SUITE_END()
 
 
@@ -194,36 +105,12 @@ BOOST_AUTO_TEST_CASE(DBperfLookupAliasByOwner)
         for(unsigned int name_num=start_name; name_num<(start_name+c_names_per_label); name_num++)
         {
             generate_name(name_num, name);
-            read_row_expect_success(name, label, label);
+            read_row_expect_success(name, label);
         }
     }
     performance_stop(c_test_retries * c_num_names);
 }
 
-BOOST_AUTO_TEST_CASE(DBperfLookupAliasByNotAllowed)
-{
-    // prepare data
-    generate_perf_DB(c_num_names, c_names_per_label);
-
-    Name name;
-    Label owner_label;
-    Label smack_label;
-    const unsigned int unavailable_label_idx = (c_num_names/c_names_per_label) + 1;
-    generate_label(unavailable_label_idx, smack_label);
-
-    // actual test - failure lookup
-    performance_start("getDBRow");
-    for(unsigned int t=0; t<c_test_retries; t++)
-    {
-        int name_idx = rand()%c_num_names;
-        generate_name(name_idx, name);
-        generate_label(name_idx/c_names_per_label, owner_label);
-
-        read_row_expect_fail(name, owner_label, smack_label);
-    }
-    performance_stop(c_test_retries * c_num_names);
-}
-
 BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipNoPermissions)
 {
     // prepare data
@@ -244,7 +131,7 @@ BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipNoPermissions)
         generate_label(rand()%num_labels, smack_label);
 
         // do not care of result
-        m_db.getDBRow(name, owner_label, smack_label, DBDataType::BINARY_DATA);
+        m_db.getDBRow(name, owner_label, DBDataType::BINARY_DATA);
     }
     performance_stop(c_test_retries * c_num_names);
 }
@@ -255,36 +142,11 @@ BOOST_AUTO_TEST_CASE(DBperfAddPermissions)
     generate_perf_DB(c_num_names, c_names_per_label);
 
     // actual test - add access rights
-    performance_start("setAccessRights");
+    performance_start("setPermission");
     long iterations = add_full_access_rights(c_num_names, c_names_per_label);
     performance_stop(iterations);
 }
 
-BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipWithPermissions)
-{
-    // prepare data
-    generate_perf_DB(c_num_names, c_names_per_label);
-    add_full_access_rights(c_num_names, c_names_per_label);
-
-    Name name;
-    Label owner_label;
-    Label smack_label;
-    unsigned int num_labels = c_num_names / c_names_per_label;
-
-    // actual test - random lookup
-    performance_start("getDBRow/perm");
-    for(unsigned int t=0; t<c_test_retries; t++)
-    {
-        int name_idx = rand()%c_num_names;
-        generate_name(name_idx, name);
-        generate_label(name_idx/c_names_per_label, owner_label);
-        generate_label(rand()%num_labels, smack_label);
-
-        read_row_expect_success(name, owner_label, smack_label);
-    }
-    performance_stop(c_test_retries * c_num_names);
-}
-
 BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
 {
     // prepare data
@@ -300,7 +162,7 @@ BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
         generate_name(t, name);
         generate_label(t/c_names_per_label, label);
 
-        BOOST_REQUIRE_NO_THROW(m_db.deleteDBRow(name, label, label));
+        BOOST_REQUIRE_NO_THROW(m_db.deleteDBRow(name, label));
     }
     performance_stop(c_num_names);
 
@@ -310,7 +172,7 @@ BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
     {
         generate_label(l, label);
         LabelNameVector expect_no_data;
-        BOOST_REQUIRE_NO_THROW(m_db.getNames(label, DBDataType::BINARY_DATA, expect_no_data));
+        BOOST_REQUIRE_NO_THROW(m_db.listNames(label, expect_no_data, DBDataType::BINARY_DATA));
         BOOST_REQUIRE(0 == expect_no_data.size());
     }
 }
@@ -325,13 +187,13 @@ BOOST_AUTO_TEST_CASE(DBperfGetAliasList)
     Label label;
 
     // actual test - random lookup
-    performance_start("getNames");
+    performance_start("listNames");
     for(unsigned int t=0; t<(c_test_retries/num_labels); t++)
     {
         LabelNameVector ret_list;
         generate_label(rand()%num_labels, label);
 
-        BOOST_REQUIRE_NO_THROW(m_db.getNames(label, DBDataType::BINARY_DATA, ret_list));
+        BOOST_REQUIRE_NO_THROW(m_db.listNames(label, ret_list, DBDataType::BINARY_DATA));
         BOOST_REQUIRE(c_num_names == ret_list.size());
         ret_list.clear();
     }