Service denies attempt to add data using different label.
authorMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Fri, 28 Nov 2014 16:17:20 +0000 (17:17 +0100)
committerMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Tue, 17 Feb 2015 10:18:55 +0000 (11:18 +0100)
The same applies to attempt to modify another label's permissions.

Change-Id: Ib167de4b4ccb59271f2dcfdbf7ce049f3d3dc819

src/manager/client-async/client-manager-async-impl.cpp
src/manager/client/client-control.cpp
src/manager/client/client-manager-impl.cpp
src/manager/service/access-control.cpp
src/manager/service/access-control.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp

index 79df43d..38b2681 100644 (file)
@@ -85,11 +85,13 @@ void ManagerAsync::Impl::saveBinaryData(const ManagerAsync::ObserverPtr& observe
                                         const Policy& policy)
 {
     try_catch_async([&] {
+        AliasSupport helper(alias);
         sendToStorage(observer,
                       static_cast<int>(LogicCommand::SAVE),
                       m_counter,
                       static_cast<int>(dataType),
-                      alias,
+                      helper.getName(),
+                      helper.getLabel(),
                       rawData,
                       PolicySerializable(policy));
     }, [&observer](int error){ observer->ReceivedError(error); } );
@@ -226,10 +228,12 @@ void ManagerAsync::Impl::setPermission(const ObserverPtr& observer,
         return;
     }
     try_catch_async([&] {
+        AliasSupport helper(alias);
         sendToStorage(observer,
                       static_cast<int>(LogicCommand::SET_PERMISSION),
                       m_counter,
-                      alias,
+                      helper.getName(),
+                      helper.getLabel(),
                       accessor,
                       static_cast<int>(newPermission));
     }, [&observer](int error){ observer->ReceivedError(error); } );
@@ -285,14 +289,18 @@ void ManagerAsync::Impl::createKeyPair(const ManagerAsync::ObserverPtr& observer
     }
 
     try_catch_async([&] {
+        AliasSupport prvHelper(privateKeyAlias);
+        AliasSupport pubHelper(publicKeyAlias);
         sendToStorage(observer,
                       static_cast<int>(cmd_type),
                       m_counter,
                       static_cast<int>(additional_param),
                       PolicySerializable(policyPrivateKey),
                       PolicySerializable(policyPublicKey),
-                      privateKeyAlias,
-                      publicKeyAlias);
+                      prvHelper.getName(),
+                      prvHelper.getLabel(),
+                      pubHelper.getName(),
+                      pubHelper.getLabel());
     }, [&observer](int error){ observer->ReceivedError(error); } );
 }
 
index 6c0675d..dbaa78f 100644 (file)
@@ -184,10 +184,14 @@ public:
     {
         return try_catch([&] {
             MessageBuffer recv;
+            AliasSupport helper(alias);
+            if( /* label defined */ !helper.getLabel().empty() &&
+                /* two different labels given */ (helper.getLabel() != owner))
+                return CKM_API_ERROR_INPUT_PARAM;
             auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::SET_PERMISSION),
                                                  static_cast<int>(user),
+                                                 helper.getName(),
                                                  owner,
-                                                 alias,
                                                  accessor,
                                                  static_cast<int>(newPermission));
 
index 471881e..95b4dc6 100644 (file)
@@ -381,13 +381,17 @@ int ManagerImpl::createKeyPair(
     return try_catch([&] {
 
         MessageBuffer recv;
+        AliasSupport privateHelper(privateKeyAlias);
+        AliasSupport publicHelper(publicKeyAlias);
         auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
                                              my_counter,
                                              static_cast<int>(additional_param),
                                              PolicySerializable(policyPrivateKey),
                                              PolicySerializable(policyPublicKey),
-                                             privateKeyAlias,
-                                             publicKeyAlias);
+                                             privateHelper.getName(),
+                                             privateHelper.getLabel(),
+                                             publicHelper.getName(),
+                                             publicHelper.getLabel());
 
         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
         if (CKM_API_SUCCESS != retCode)
@@ -610,9 +614,11 @@ int ManagerImpl::setPermission(const Alias &alias,
     int my_counter = m_counter;
     return try_catch([&] {
         MessageBuffer recv;
+        AliasSupport helper(alias);
         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
                                              my_counter,
-                                             alias,
+                                             helper.getName(),
+                                             helper.getLabel(),
                                              accessor,
                                              static_cast<int>(newPermission));
 
index c007edc..7cf0e6c 100644 (file)
@@ -76,6 +76,22 @@ bool AccessControl::isCCMode() const
     return m_ccMode;
 }
 
+int AccessControl::canSave(
+        const Label & ownerLabel,
+        const Label & accessorLabel) const
+{
+    if(ownerLabel != accessorLabel)
+        return CKM_API_ERROR_ACCESS_DENIED;
+
+    return CKM_API_SUCCESS;
+}
+
+int AccessControl::canModify(
+        const Label & ownerLabel,
+        const Label & accessorLabel) const
+{
+    return canSave(ownerLabel, accessorLabel);
+}
 
 int AccessControl::canRead(
         const DBRow & row,
index 169be68..b7c2873 100644 (file)
@@ -34,6 +34,20 @@ class AccessControl
 {
 public:
     /**
+     * check if given data can be saved under given label by accessorLabel
+     * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code
+     */
+    int canSave(const Label & ownerLabel,
+                const Label & accessorLabel) const;
+
+    /**
+     * check if given label can be modified by accessorLabel
+     * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code
+     */
+    int canModify(const Label & ownerLabel,
+                  const Label & accessorLabel) const;
+
+    /**
      * check if given row can be read (for internal use)
      * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code
      */
index 9501a9d..b839872 100644 (file)
@@ -210,17 +210,33 @@ int CKMLogic::saveDataHelper(
     const Credentials &cred,
     DBDataType dataType,
     const Name &name,
+    const Label &label,
     const RawBuffer &key,
     const PolicySerializable &policy)
 {
-    if (0 == m_userDataMap.count(cred.uid))
-        return CKM_API_ERROR_DB_LOCKED;
+    // use client label if not explicitly provided
+    const Label ownerLabel = label.empty() ? cred.smackLabel : label;
+
+    // verify name and label are correct
+    if ( !checkNameAndLabelValid(name, ownerLabel) )
+        return CKM_API_ERROR_INPUT_PARAM;
+
+    // check if allowed to save using ownerLabel
+    int access_ec = m_accessControl.canSave(ownerLabel, cred.smackLabel);
+    if(access_ec != CKM_API_SUCCESS)
+    {
+        LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
+        return access_ec;
+    }
 
     // proceed to data save
     DBRow row = { name, cred.smackLabel,
          policy.extractable, dataType, DBCMAlgType::NONE,
          0, RawBuffer(), static_cast<int>(key.size()), key, RawBuffer() };
 
+    if (0 == m_userDataMap.count(cred.uid))
+        return CKM_API_ERROR_DB_LOCKED;
+
     auto &handler = m_userDataMap[cred.uid];
     DBCrypto::Transaction transaction(&handler.database);
 
@@ -302,12 +318,9 @@ RawBuffer CKMLogic::saveData(
 {
     int retCode = CKM_API_SUCCESS;
     try {
-        if (!label.empty() && label.compare(cred.smackLabel))
-            ThrowMsg(CKMLogic::Exception::InputDataInvalid, "smack label in param is not your label");
-
         verifyBinaryData(dataType, key);
 
-        retCode = saveDataHelper(cred, dataType, name, key, policy);
+        retCode = saveDataHelper(cred, dataType, name, label, key, policy);
         LogDebug("SaveDataHelper returned: " << retCode);
     } catch (const CKMLogic::Exception::InputDataInvalid &e) {
         LogError("Provided data invalid: " << e.GetMessage());
@@ -613,7 +626,9 @@ int CKMLogic::createKeyPairHelper(
     const KeyType key_type,
     const int additional_param,
     const Name &namePrivate,
+    const Label &labelPrivate,
     const Name &namePublic,
+    const Label &labelPublic,
     const PolicySerializable &policyPrivate,
     const PolicySerializable &policyPublic)
 {
@@ -654,6 +669,7 @@ int CKMLogic::createKeyPairHelper(
     retCode = saveDataHelper(cred,
                             toDBDataType(prv.getType()),
                             namePrivate,
+                            labelPrivate,
                             prv.getDER(),
                             policyPrivate);
 
@@ -663,6 +679,7 @@ int CKMLogic::createKeyPairHelper(
     retCode = saveDataHelper(cred,
                             toDBDataType(pub.getType()),
                             namePublic,
+                            labelPublic,
                             pub.getDER(),
                             policyPublic);
 
@@ -680,7 +697,9 @@ RawBuffer CKMLogic::createKeyPair(
     int commandId,
     const int additional_param,
     const Name &namePrivate,
+    const Label &labelPrivate,
     const Name &namePublic,
+    const Label &labelPublic,
     const PolicySerializable &policyPrivate,
     const PolicySerializable &policyPublic)
 {
@@ -708,7 +727,9 @@ RawBuffer CKMLogic::createKeyPair(
                         key_type,
                         additional_param,
                         namePrivate,
+                        labelPrivate,
                         namePublic,
+                        labelPublic,
                         policyPrivate,
                         policyPublic);
     } catch (DBCrypto::Exception::TransactionError &e) {
@@ -933,6 +954,7 @@ RawBuffer CKMLogic::verifySignature(
 int CKMLogic::setPermissionHelper(
         const Credentials &cred,
         const Name &name,
+        const Label &label,
         const Label &accessorLabel,
         const Permission reqRights)
 {
@@ -940,25 +962,38 @@ int CKMLogic::setPermissionHelper(
     if(cred.smackLabel.empty() || cred.smackLabel==accessorLabel)
         return CKM_API_ERROR_INPUT_PARAM;
 
+    // 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))
+        return CKM_API_ERROR_INPUT_PARAM;
+
+    // check if allowed to modify
+    int access_ec = m_accessControl.canModify(ownerLabel, cred.smackLabel);
+    if(access_ec != CKM_API_SUCCESS)
+        return access_ec;
+
     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) )
+    if( ! database.isNameLabelPresent(name, ownerLabel) )
         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
 
     // removing non-existing permissions: fail
     if(reqRights == Permission::NONE)
     {
-        if( !database.getPermissionRow(name, cred.smackLabel, accessorLabel) )
+        if( !database.getPermissionRow(name, ownerLabel, accessorLabel) )
             return CKM_API_ERROR_INPUT_PARAM;
     }
 
     retCode = database.setPermission(name,
-                                       cred.smackLabel,
-                                       accessorLabel,
-                                       reqRights);
+                                     ownerLabel,
+                                     accessorLabel,
+                                     reqRights);
 
     transaction.commit();
 
@@ -970,12 +1005,13 @@ RawBuffer CKMLogic::setPermission(
         int command,
         int msgID,
         const Name &name,
+        const Label &label,
         const Label &accessorLabel,
         const Permission reqRights)
 {
     int retCode;
     Try {
-        retCode = setPermissionHelper(cred, name, accessorLabel, reqRights);
+        retCode = setPermissionHelper(cred, name, label, accessorLabel, reqRights);
     } Catch (CKM::Exception) {
         LogError("Error in set row!");
         retCode = CKM_API_ERROR_DB_ERROR;
index b8d44eb..8b399fb 100644 (file)
@@ -112,7 +112,9 @@ public:
         int commandId,
         const int additional_param,
         const Name &namePrivate,
+        const Label &labelPrivate,
         const Name &namePublic,
+        const Label &labelPublic,
         const PolicySerializable &policyPrivate,
         const PolicySerializable &policyPublic);
 
@@ -142,7 +144,7 @@ public:
         const Credentials &cred,
         int commandId,
         const Name &publicKeyOrCertName,
-        const Label & ownerLabel,
+        const Label &label,
         const Password &password,           // password for public_key (optional)
         const RawBuffer &message,
         const RawBuffer &signature,
@@ -156,6 +158,7 @@ public:
         int command,
         int msgID,
         const Name &name,
+        const Label &label,
         const Label &accessor_label,
         const Permission req_rights);
 
@@ -169,6 +172,7 @@ private:
         const Credentials &cred,
         DBDataType dataType,
         const Name &name,
+        const Label &label,
         const RawBuffer &key,
         const PolicySerializable &policy);
 
@@ -206,7 +210,9 @@ private:
         const KeyType key_type,
         const int additional_param,
         const Name &namePrivate,
+        const Label &labelPrivate,
         const Name &namePublic,
+        const Label &labelPublic,
         const PolicySerializable &policyPrivate,
         const PolicySerializable &policyPublic);
 
@@ -219,6 +225,7 @@ private:
     int setPermissionHelper(
         const Credentials &cred,
         const Name &name,
+        const Label &ownerLabel,
         const Label &accessorLabel,
         const Permission reqRights);
 
index c44c397..7ca93e5 100644 (file)
@@ -142,17 +142,18 @@ RawBuffer CKMService::processControl(MessageBuffer &buffer) {
     case ControlCommand::SET_PERMISSION:
     {
         Name name;
-        Label ownerLabel;
+        Label label;
         Label accessorLabel;
         int accessorPermissions = 0;
 
-        buffer.Deserialize(user, ownerLabel, name, accessorLabel, accessorPermissions);
-        Credentials cred = { user, ownerLabel };
+        buffer.Deserialize(user, name, label, accessorLabel, accessorPermissions);
+        Credentials cred = { user, label };
         return m_logic->setPermission(
             cred,
             command,
             0, // dummy
             name,
+            label,
             accessorLabel,
             static_cast<Permission>(accessorPermissions));
     }
@@ -167,7 +168,7 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
     int msgID = 0;
     int tmpDataType = 0;
     Name name;
-    Label label;
+    Label label, accessorLabel;
     std::string user;
 
     buffer.Deserialize(command);
@@ -234,21 +235,27 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
         {
             int additional_param = 0;
             Name privateKeyName;
+            Label privateKeyLabel;
             Name publicKeyName;
+            Label publicKeyLabel;
             PolicySerializable policyPrivateKey;
             PolicySerializable policyPublicKey;
             buffer.Deserialize(additional_param,
                                policyPrivateKey,
                                policyPublicKey,
                                privateKeyName,
-                               publicKeyName);
+                               privateKeyLabel,
+                               publicKeyName,
+                               publicKeyLabel);
             return m_logic->createKeyPair(
                 cred,
                 static_cast<LogicCommand>(command),
                 msgID,
                 additional_param,
                 privateKeyName,
+                privateKeyLabel,
                 publicKeyName,
+                publicKeyLabel,
                 policyPrivateKey,
                 policyPublicKey);
         }
@@ -319,13 +326,14 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
         case LogicCommand::SET_PERMISSION:
         {
             int accessorPermissions = 0;
-            buffer.Deserialize(name, label, accessorPermissions);
+            buffer.Deserialize(name, label, accessorLabel, accessorPermissions);
             return m_logic->setPermission(
                 cred,
                 command,
                 msgID,
                 name,
                 label,
+                accessorLabel,
                 static_cast<Permission>(accessorPermissions));
         }
         default: