Protect file footer from concurrent access 83/160883/20
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 24 Nov 2017 10:03:45 +0000 (11:03 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 29 Nov 2017 11:20:09 +0000 (12:20 +0100)
Add mutex synchronisation.

Can't use runtime::File locks because it's not possible to truncate a file
during writing without closing the descriptor (and unlocking the lock).
Derivation won't help either as the descriptor is private.

Change-Id: I5e22b21dca48b1b3d17ae6b2e4084c1029f84089

server/key-server.cpp
server/key-server.h

index a0b00dd..4ab6541 100644 (file)
@@ -88,6 +88,8 @@ int KeyServer::initAndGet(const std::string& dev,
        masterKey = KeyGenerator::RNG(KEY_SIZE.at(params));
 
        EncryptedKey ek(masterKey, password);
+
+       std::lock_guard<std::mutex> lock(footerLock);
        FileFooter::write(dev, ek.serialize());
 
        return error::None;
@@ -95,12 +97,14 @@ int KeyServer::initAndGet(const std::string& dev,
 
 int KeyServer::remove(const std::string& dev, const std::string& password)
 {
-       int ret = verifyPassword(dev, password);
-       if (ret != error::None) {
-               if (ret == error::WrongPassword)
-                       ERROR(SINK, "Wrong password passed.");
+       if (dev.empty() || password.empty())
+               return error::InvalidParameter;
+
+       std::lock_guard<std::mutex> lock(footerLock);
+       BinaryData key;
+       int ret = internalGet(dev, password, key);
+       if (ret != error::None)
                return ret;
-       }
 
        FileFooter::clear(dev);
        return error::None;
@@ -113,8 +117,9 @@ int KeyServer::changePassword(const std::string& dev,
        if (dev.empty() || curPassword.empty() || newPassword.empty())
                return error::InvalidParameter;
 
+       std::lock_guard<std::mutex> lock(footerLock);
        if (!FileFooter::exist(dev)) {
-               ERROR(SINK, "Given device has no master key");
+               ERROR(SINK, "Given device has no master key.");
                return error::NoSuchFile;
        }
 
@@ -122,9 +127,10 @@ int KeyServer::changePassword(const std::string& dev,
 
        auto key = ek.decrypt(curPassword);
        if (key.empty()) {
-               ERROR(SINK, "Wrong password passed");
+               ERROR(SINK, "Wrong password passed.");
                return error::WrongPassword;
        }
+
        ek.encrypt(key, newPassword);
 
        FileFooter::write(dev, ek.serialize());
@@ -137,18 +143,9 @@ int KeyServer::verifyPassword(const std::string& dev,
        if (dev.empty() || password.empty())
                return error::InvalidParameter;
 
-       if (!FileFooter::exist(dev)) {
-               ERROR(SINK, "Given device has no master key");
-               return error::NoSuchFile;
-       }
-
-       EncryptedKey ek(FileFooter::read(dev));
-
-       auto key = ek.decrypt(password);
-       if (key.empty())
-               return error::WrongPassword;
-
-       return error::None;
+       BinaryData dummy;
+       std::lock_guard<std::mutex> lock(footerLock);
+       return internalGet(dev, password, dummy);
 }
 
 int KeyServer::get(const std::string& dev,
@@ -158,19 +155,8 @@ int KeyServer::get(const std::string& dev,
        if (dev.empty() || password.empty())
                return error::InvalidParameter;
 
-       if (!FileFooter::exist(dev)) {
-               ERROR(SINK, "Given device has no master key");
-               return error::NoSuchFile;
-       }
-
-       EncryptedKey ek(FileFooter::read(dev));
-
-       masterKey = ek.decrypt(password);
-       if (masterKey.empty()) {
-               ERROR(SINK, "Wrong password passed");
-               return error::WrongPassword;
-       }
-       return error::None;
+       std::lock_guard<std::mutex> lock(footerLock);
+       return internalGet(dev, password, masterKey);
 }
 
 void KeyServer::removePassword(const std::string& dev)
@@ -178,6 +164,7 @@ void KeyServer::removePassword(const std::string& dev)
        if (dev.empty())
                return;
 
+       std::lock_guard<std::mutex> lock(footerLock);
        FileFooter::clear(dev);
 }
 
@@ -187,18 +174,13 @@ int KeyServer::storeMasterKey(const std::string& dev,
        if (dev.empty() || password.empty())
                return error::InvalidParameter;
 
-       if (!FileFooter::exist(dev)) {
-               ERROR(SINK, "Given device has no master key");
-               return error::NoSuchFile;
-       }
-
-       EncryptedKey ek(FileFooter::read(dev));
+       std::unique_lock<std::mutex> lock(footerLock);
+       BinaryData masterKey;
+       int ret = internalGet(dev, password, masterKey);
+       if (ret != error::None)
+               return ret;
 
-       auto masterKey = ek.decrypt(password);
-       if (masterKey.empty()) {
-               ERROR(SINK, "Wrong password passed");
-               return error::WrongPassword;
-       }
+       lock.unlock();
 
        try {
                UpgradeSupport::storeMasterKey(dev, masterKey);
@@ -223,4 +205,23 @@ int KeyServer::removeMasterKey(const std::string& dev)
        return error::None;
 }
 
+int KeyServer::internalGet(const std::string& dev,
+                                                  const std::string& password,
+                                                  BinaryData& key) const
+{
+       if (!FileFooter::exist(dev)) {
+               ERROR(SINK, "Given device has no master key.");
+               return error::NoSuchFile;
+       }
+
+       EncryptedKey ek(FileFooter::read(dev));
+
+       key = ek.decrypt(password);
+       if (key.empty()) {
+               ERROR(SINK, "Wrong password passed.");
+               return error::WrongPassword;
+       }
+       return error::None;
+}
+
 } // namespace ode
index 244719b..a37f442 100644 (file)
@@ -18,6 +18,7 @@
 #define __KEY_SERVER_H__
 
 #include <string>
+#include <mutex>
 
 #include "rmi/key.h"
 #include "server.h"
@@ -48,7 +49,12 @@ public:
        int removeMasterKey(const std::string& dev);
 
 private:
+       int internalGet(const std::string& dev,
+                                       const std::string& password,
+                                       BinaryData& key) const;
+
        ServerContext& server;
+       mutable std::mutex footerLock;
 };
 
 } // namespace ode