Key/password management API implementation 60/156860/18
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 19 Oct 2017 15:17:39 +0000 (17:17 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 24 Nov 2017 09:51:24 +0000 (10:51 +0100)
Change-Id: Ib74cc6e9212a948a043b483f08159024b642eb77

lib/CMakeLists.txt
lib/key-client.cpp [new file with mode: 0644]
lib/key-client.h [new file with mode: 0644]
lib/ode/keys.cpp [new file with mode: 0644]
rmi/key.h [new file with mode: 0644]
server/CMakeLists.txt
server/key-server.cpp [new file with mode: 0644]
server/key-server.h [new file with mode: 0644]
server/server.cpp
server/server.h

index 6f4a10c..fba59e4 100755 (executable)
@@ -23,10 +23,12 @@ SET(SOURCES client.cpp
                        internal-encryption.cpp
                        external-encryption.cpp
                        luks.cpp
+                       key-client.cpp
                        ode/secure-erase.cpp
                        ode/internal-encryption.cpp
                        ode/external-encryption.cpp
                        ode/luks.cpp
+                       ode/keys.cpp
                        ode/error-translation.cpp
 )
 
diff --git a/lib/key-client.cpp b/lib/key-client.cpp
new file mode 100644 (file)
index 0000000..6bb30ad
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (c) 2017 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
+ */
+#include "key-client.h"
+#include "rmi/common.h"
+
+namespace ode {
+
+KeyClient::KeyClient(RmiClientPtr& ctx) :
+       context(ctx)
+{
+}
+
+KeyClient::~KeyClient()
+{
+}
+
+int KeyClient::isInitialized(const std::string& device)
+{
+       try {
+               return context->methodCall<int>("KeyServer::isInitialized", device);
+       } catch (runtime::Exception& e) {
+               return error::Unknown;
+       }
+}
+
+int KeyClient::init(const std::string& device,
+                                       const std::string& password,
+                                       int params)
+{
+       try {
+               return context->methodCall<int>("KeyServer::init",
+                                                                               device,
+                                                                               password,
+                                                                               params);
+       } catch (runtime::Exception& e) {
+               return error::Unknown;
+       }
+}
+
+int KeyClient::remove(const std::string& device, const std::string& password)
+{
+       try {
+               return context->methodCall<int>("KeyServer::remove", device, password);
+       } catch (runtime::Exception& e) {
+               return error::Unknown;
+       }
+}
+
+int KeyClient::changePassword(const std::string& device,
+                                                         const std::string& curPassword,
+                                                         const std::string& newPassword)
+{
+       try {
+               return context->methodCall<int>("KeyServer::changePassword",
+                                                                               device,
+                                                                               curPassword,
+                                                                               newPassword);
+       } catch (runtime::Exception& e) {
+               return error::Unknown;
+       }
+}
+
+int KeyClient::verifyPassword(const std::string& device,
+                                                         const std::string& password)
+{
+       try {
+               return context->methodCall<int>("KeyServer::verifyPassword",
+                                                                               device,
+                                                                               password);
+       } catch (runtime::Exception& e) {
+               return error::Unknown;
+       }
+}
+
+} // namespace ode
diff --git a/lib/key-client.h b/lib/key-client.h
new file mode 100644 (file)
index 0000000..aeff433
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2017 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
+ */
+
+#ifndef __KEY_CLIENT_H__
+#define __KEY_CLIENT_H__
+
+#include <string>
+
+#include "rmi/key.h"
+#include "client.h"
+
+namespace ode {
+
+class KeyClient final: public Key {
+public:
+       explicit KeyClient(RmiClientPtr& ctxt);
+       ~KeyClient();
+
+       int isInitialized(const std::string& dev);
+       int init(const std::string& dev, const std::string& password, int params);
+       int remove(const std::string& dev, const std::string& password);
+       int changePassword(const std::string& dev,
+                                          const std::string& curPW,
+                                          const std::string& newPW);
+       int verifyPassword(const std::string& dev, const std::string& password);
+
+private:
+       RmiClientPtr& context;
+};
+
+} // namespace ode
+
+#endif // __KEY_CLIENT_H__
diff --git a/lib/ode/keys.cpp b/lib/ode/keys.cpp
new file mode 100644 (file)
index 0000000..c982700
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  Copyright (c) 2017 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
+ */
+
+#include "debug.h"
+#include "keys.h"
+
+#include "client.h"
+#include "lib/key-client.h"
+#include "error-translation.h"
+#include "rmi/common.h"
+
+using namespace ode;
+
+int ode_key_is_initialized(const char* device, bool* result)
+{
+       RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(result, ODE_ERROR_INVALID_PARAMETER);
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       KeyClient key = client.createInterface<KeyClient>();
+       int ret = key.isInitialized(device);
+
+       if (ret == error::None)
+               *result = true;
+       else if (ret == error::NoSuchFile)
+               *result = false;
+       else
+               return toApiError(ret);
+
+       return ODE_ERROR_NONE;
+}
+
+int ode_key_init(const char* device,
+                                const char* password,
+                                ode_key_gen_params_e params)
+{
+       RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(password, ODE_ERROR_INVALID_PARAMETER);
+
+       if (params < ODE_KEY_DEFAULT_256BIT || params > ODE_KEY_DEFAULT_512BIT)
+               return ODE_ERROR_INVALID_PARAMETER;
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       KeyClient key = client.createInterface<KeyClient>();
+       return toApiError(key.init(device, password, params));
+}
+
+int ode_key_clean(const char* device, const char* password)
+{
+       RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(password, ODE_ERROR_INVALID_PARAMETER);
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       KeyClient key = client.createInterface<KeyClient>();
+       return toApiError(key.remove(device, password));
+}
+
+int ode_key_change(const char* device,
+                                  const char* cur_password,
+                                  const char* new_password)
+{
+       RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(cur_password, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(new_password, ODE_ERROR_INVALID_PARAMETER);
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       KeyClient key = client.createInterface<KeyClient>();
+       return toApiError(key.changePassword(device, cur_password, new_password));
+}
+
+int ode_key_verify(const char* device, const char* password, bool* result)
+{
+       RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(password, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(result, ODE_ERROR_INVALID_PARAMETER);
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       KeyClient key = client.createInterface<KeyClient>();
+       int ret = key.verifyPassword(device, password);
+
+       if (ret == error::None)
+               *result = true;
+       else if (ret == error::WrongPassword)
+               *result = false;
+       else
+               return toApiError(ret);
+
+       return ODE_ERROR_NONE;
+}
diff --git a/rmi/key.h b/rmi/key.h
new file mode 100644 (file)
index 0000000..ceff714
--- /dev/null
+++ b/rmi/key.h
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2017 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
+ */
+
+#ifndef __ODE_KEY_H__
+#define __ODE_KEY_H__
+
+#include <string>
+
+namespace ode {
+
+/**
+ * This class provides APIs to manage device keys and passwords.
+ */
+
+class Key {
+public:
+       enum InitMethod {
+           DEFAULT_256BIT = 1,
+           DEFAULT_512BIT = 2,
+       };
+
+       virtual ~Key() {}
+
+       virtual int isInitialized(const std::string& dev) = 0;
+       virtual int init(const std::string& dev,
+                                        const std::string& password,
+                                        int params) = 0;
+       virtual int remove(const std::string& dev, const std::string& password) = 0;
+       virtual int changePassword(const std::string& dev,
+                                                          const std::string& curPW,
+                                                          const std::string& newPW) = 0;
+       virtual int verifyPassword(const std::string& dev,
+                                                          const std::string& password) = 0;
+};
+
+} // namespace ode
+
+#endif // __ODE_KEY_H__
index ab88ad6..efbc4f8 100644 (file)
@@ -26,6 +26,7 @@ SET(SERVER_SRCS       main.cpp
                                internal-encryption.cpp
                                external-encryption.cpp
                                luks.cpp
+                               key-server.cpp
                                engine/encryption/ext4-engine.cpp
                                engine/encryption/dmcrypt-engine.cpp
                                engine/encryption/ecryptfs-engine.cpp
diff --git a/server/key-server.cpp b/server/key-server.cpp
new file mode 100644 (file)
index 0000000..a7d4a69
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *  Copyright (c) 2015-2017 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
+ */
+
+#include <stdlib.h>
+
+#include <string>
+#include <algorithm>
+#include <map>
+
+#include "key-server.h"
+#include "file-footer.h"
+#include "logger.h"
+#include "key-manager/key-manager.h"
+#include "misc.h"
+#include "rmi/common.h"
+
+namespace ode {
+
+namespace {
+
+const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
+
+const std::map<int, size_t> KEY_SIZE = {
+       { Key::DEFAULT_256BIT, 32 },
+       { Key::DEFAULT_512BIT, 64 }
+};
+
+} // anonymous namespace
+
+KeyServer::KeyServer(ServerContext& srv) :
+       server(srv)
+{
+       server.expose(this, "",                                 (int)(KeyServer::isInitialized)(std::string));
+       server.expose(this, PRIVILEGE_PLATFORM, (int)(KeyServer::init)(std::string, std::string, int));
+       server.expose(this, PRIVILEGE_PLATFORM, (int)(KeyServer::remove)(std::string, std::string));
+       server.expose(this, PRIVILEGE_PLATFORM, (int)(KeyServer::changePassword)(std::string, std::string, std::string));
+       server.expose(this, PRIVILEGE_PLATFORM, (int)(KeyServer::verifyPassword)(std::string, std::string));
+}
+
+KeyServer::~KeyServer()
+{
+}
+
+int KeyServer::isInitialized(const std::string& dev)
+{
+       if (dev.empty())
+               return error::InvalidParameter;
+
+       return FileFooter::exist(dev) ? error::None : error::NoSuchFile;
+}
+
+int KeyServer::init(const std::string& dev,
+                                       const std::string& password,
+                                       int params)
+{
+       if (dev.empty() || password.empty() || KEY_SIZE.find(params) == KEY_SIZE.end())
+               return error::InvalidParameter;
+
+       KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager;
+
+       keyManager.initPassword(pwData, KEY_SIZE.at(params));
+
+       FileFooter::write(dev, keyManager.serialize());
+       return error::None;
+}
+
+int KeyServer::remove(const std::string& dev, const std::string& password)
+{
+       if (dev.empty() || password.empty())
+               return error::InvalidParameter;
+
+       KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager(FileFooter::read(dev));
+
+       if (!keyManager.verifyPassword(pwData)) {
+               ERROR(SINK, "Wrong password passed.");
+               return error::WrongPassword;
+       }
+
+       FileFooter::clear(dev);
+       return error::None;
+}
+
+int KeyServer::changePassword(const std::string& dev,
+                                                         const std::string& curPassword,
+                                                         const std::string& newPassword)
+{
+       if (dev.empty() || curPassword.empty() || newPassword.empty())
+               return error::InvalidParameter;
+
+       KeyManager::data curPwData(curPassword.begin(), curPassword.end());
+       KeyManager::data newPwData(newPassword.begin(), newPassword.end());
+       KeyManager keyManager(FileFooter::read(dev));
+
+       if (!keyManager.verifyPassword(curPwData)) {
+               ERROR(SINK, "Wrong password passed.");
+               return error::WrongPassword;
+       }
+
+       keyManager.changePassword(curPwData, newPwData);
+       FileFooter::write(dev, keyManager.serialize());
+       return error::None;
+}
+
+int KeyServer::verifyPassword(const std::string& dev,
+                                                         const std::string& password)
+{
+       if (dev.empty() || password.empty())
+               return error::InvalidParameter;
+
+       KeyManager::data pwData(password.begin(), password.end());
+       KeyManager keyManager(FileFooter::read(dev));
+
+       return keyManager.verifyPassword(pwData) ? error::None : error::WrongPassword;
+}
+
+} // namespace ode
diff --git a/server/key-server.h b/server/key-server.h
new file mode 100644 (file)
index 0000000..e44eebb
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2017 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
+ */
+
+#ifndef __KEY_SERVER_H__
+#define __KEY_SERVER_H__
+
+#include <string>
+
+#include "rmi/key.h"
+#include "server.h"
+
+namespace ode {
+
+class KeyServer final: public Key {
+public:
+       explicit KeyServer(ServerContext& srv);
+       ~KeyServer();
+
+       int isInitialized(const std::string& dev);
+       int init(const std::string& dev, const std::string& password, int params);
+       int remove(const std::string& dev, const std::string& password);
+       int changePassword(const std::string& dev,
+                                          const std::string& curPW,
+                                          const std::string& newPW);
+       int verifyPassword(const std::string& dev, const std::string& password);
+
+private:
+       ServerContext& server;
+};
+
+} // namespace ode
+
+#endif // __KEY_SERVER_H__
index 90ab266..64bc609 100644 (file)
@@ -24,6 +24,7 @@
 #include "internal-encryption.h"
 #include "external-encryption.h"
 #include "luks.h"
+#include "key-server.h"
 #include "key-manager/key-generator.h"
 #include "server.h"
 
@@ -56,6 +57,7 @@ ServerContext::ServerContext() : rmi::Service(ODE_MANAGER_ADDRESS)
        internalEncryption.reset(new InternalEncryptionServer(*this));
        externalEncryption.reset(new ExternalEncryptionServer(*this));
        luks.reset(new LuksServer(*this));
+       keys.reset(new KeyServer(*this));
 
        KeyGenerator::init();
 }
index 18b5870..9b38f70 100644 (file)
@@ -29,6 +29,7 @@ class SecureEraseServer;
 class InternalEncryptionServer;
 class ExternalEncryptionServer;
 class LuksServer;
+class KeyServer;
 
 class ServerContext final: public rmi::Service {
 public:
@@ -45,6 +46,7 @@ private:
        std::unique_ptr<InternalEncryptionServer> internalEncryption;
        std::unique_ptr<ExternalEncryptionServer> externalEncryption;
        std::unique_ptr<LuksServer> luks;
+       std::unique_ptr<KeyServer> keys;
 };
 
 } // namespace ode