internal-encryption.cpp
external-encryption.cpp
extension-encryption.cpp
+ luks.cpp
ode/secure-erase.cpp
ode/internal-encryption.cpp
ode/external-encryption.cpp
ode/extension-encryption.cpp
+ ode/luks.cpp
)
SET(CAPI_INCLUDE_FILES ode/common.h
ode/secure-erase.h
ode/internal-encryption.h
ode/external-encryption.h
+ ode/luks.h
)
namespace {
-const std::string SUBSCRIBER_REGISTER = "ServerContext::registerNotificationSubscriber";
-const std::string SUBSCRIBER_UNREGISTER = "ServerContext::unregisterNotificationSubscriber";
-
-
const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
} // namespace
typedef std::unique_ptr<rmi::Client> RmiClientPtr;
class ClientContext final {
+ const char* SUBSCRIBER_REGISTER = "ServerContext::registerNotificationSubscriber";
+ const char* SUBSCRIBER_UNREGISTER = "ServerContext::unregisterNotificationSubscriber";
+
public:
ClientContext() noexcept;
~ClientContext() noexcept;
int connect(const std::string& address) noexcept;
void disconnect() noexcept;
+ /*
+ * TODO use more generic subscription method below in internal/external
+ * encryption and remove this one.
+ */
int subscribeSignal(const std::string& name, const SignalListener& listener, void* data);
int unsubscribeSignal(int subscriberId);
+ template<typename ...Args>
+ int subscribeSignal(const std::string& name, const std::function<void(Args...)>& listener)
+ {
+ try {
+ return client->subscribe<Args...>(SUBSCRIBER_REGISTER, name, listener);
+ } catch (runtime::Exception& e) {
+ std::cout << e.what() << std::endl;
+ return -1;
+ }
+ }
+
template<typename Interface, typename... Args>
Interface createInterface(Args&&... args) noexcept
{
--- /dev/null
+/*
+ * 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 "luks.h"
+
+namespace ode {
+
+LuksClient::LuksClient(RmiClientPtr& ctx) : context(ctx)
+{
+}
+
+LuksClient::~LuksClient()
+{
+}
+
+int LuksClient::format(const std::string& device, const std::string& password)
+{
+ try {
+ return context->methodCall<int>("LuksServer::format", device, password);
+ } catch (runtime::Exception& e) {
+ return -1;
+ }
+}
+
+int LuksClient::open(const std::string& device,
+ const std::string& password,
+ const std::string& mapping)
+{
+ try {
+ return context->methodCall<int>("LuksServer::open", device, password, mapping);
+ } catch (runtime::Exception& e) {
+ return -1;
+ }
+}
+
+int LuksClient::close(const std::string& mapping)
+{
+ try {
+ return context->methodCall<int>("LuksServer::close", mapping);
+ } catch (runtime::Exception& e) {
+ return -1;
+ }
+}
+
+} // namespace ode
--- /dev/null
+/*
+ * 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_LUKS_CLIENT_H__
+#define __ODE_LUKS_CLIENT_H__
+
+#include "rmi/luks.h"
+#include "client.h"
+
+namespace ode {
+
+class LuksClient final: public Luks {
+public:
+ explicit LuksClient(RmiClientPtr& ctxt);
+ ~LuksClient();
+
+ int format(const std::string& device, const std::string& password);
+
+ int open(const std::string& device,
+ const std::string& password,
+ const std::string& mapping);
+
+ int close(const std::string& mapping);
+
+private:
+ RmiClientPtr& context;
+};
+
+} // namespace ode
+
+#endif // __ODE_LUKS_CLIENT_H__
--- /dev/null
+/*
+ * 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 <map>
+
+#include "debug.h"
+#include "luks.h"
+#include "client.h"
+#include "lib/luks.h"
+#include "rmi/common.h"
+
+using namespace ode;
+
+namespace {
+std::unique_ptr<ClientContext> luksEventCallbackContext;
+
+// TODO Extend it and make it common for whole API
+std::map<OdeError, int> ODE_ERROR_TO_API_ERROR = {
+ { OdeError::None, ODE_ERROR_NONE },
+ { OdeError::InvalidParameter, ODE_ERROR_INVALID_PARAMETER },
+ { OdeError::WrongPassword, ODE_ERROR_KEY_REJECTED },
+ { OdeError::OutOfMemory, ODE_ERROR_OUT_OF_MEMORY },
+ { OdeError::NoSuchFile, ODE_ERROR_NO_SUCH_FILE },
+ { OdeError::DeviceBusy, ODE_ERROR_RESOURCE_BUSY },
+ { OdeError::Unknown, ODE_ERROR_UNKNOWN }
+};
+} // anonymous namespace
+
+int ode_luks_format(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);
+ LuksClient luks = client.createInterface<LuksClient>();
+
+ return luks.format(device, password);
+}
+
+int ode_luks_open(const char* device, const char* password, const char* mapping)
+{
+ RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER);
+ RET_ON_FAILURE(password, ODE_ERROR_INVALID_PARAMETER);
+ RET_ON_FAILURE(mapping, ODE_ERROR_INVALID_PARAMETER);
+
+ ClientContext client;
+ RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+ LuksClient luks = client.createInterface<LuksClient>();
+
+ return luks.open(device, password, mapping);
+}
+
+int ode_luks_close(const char* mapping)
+{
+ RET_ON_FAILURE(mapping, ODE_ERROR_INVALID_PARAMETER);
+
+ ClientContext client;
+ RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+ LuksClient luks = client.createInterface<LuksClient>();
+
+ return luks.close(mapping);
+}
+
+int ode_luks_set_event_cb(ode_luks_event_cb callback, void *user_data)
+{
+ int ret;
+
+ RET_ON_FAILURE(callback, ODE_ERROR_INVALID_PARAMETER);
+
+ luksEventCallbackContext.reset(new ClientContext);
+ RET_ON_FAILURE(luksEventCallbackContext->connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+
+ std::function<void(std::string, int, int)>cb = [callback, user_data](std::string, int op, int res) {
+ int ret = ODE_ERROR_UNKNOWN;
+ auto it = ODE_ERROR_TO_API_ERROR.find(static_cast<OdeError>(res));
+ if (it != ODE_ERROR_TO_API_ERROR.end())
+ ret = it->second;
+
+ callback(static_cast<ode_luks_operation_e>(op), ret, user_data);
+ };
+
+ ret = luksEventCallbackContext->subscribeSignal(Luks::NOTIFICATION, cb);
+ RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER);
+
+ return ODE_ERROR_NONE;
+}
+
+void ode_luks_unset_event_cb()
+{
+ luksEventCallbackContext.reset();
+}
+
--- /dev/null
+/*
+ * 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
+ */
+/*
+ * @file common.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ */
+
+#ifndef __ODE_COMMON_H__
+#define __ODE_COMMON_H__
+
+namespace ode {
+
+enum class OdeError {
+ None = 0,
+ InvalidParameter,
+ WrongPassword,
+ OutOfMemory,
+ NoSuchFile,
+ DeviceBusy,
+ Unknown
+};
+
+} // namespace ode
+
+#endif // __ODE_COMMON_H__
--- /dev/null
+/*
+ * 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_LUKS_H__
+#define __ODE_LUKS_H__
+
+#include <string>
+
+namespace ode {
+
+/**
+ * This class provides APIs to perform luks operations.
+ */
+
+class Luks {
+public:
+ virtual int format(const std::string& device,
+ const std::string& password) = 0;
+
+ virtual int open(const std::string& device,
+ const std::string& password,
+ const std::string& mapping) = 0;
+
+ virtual int close(const std::string& mapping) = 0;
+
+ enum Operation {
+ Format = 1,
+ Open = 2,
+ Close = 3
+ };
+
+ static constexpr char* const NOTIFICATION = "LUKS_NOTIFICATION";
+};
+
+} // namespace ode
+
+#endif // __ODE_LUKS_H__
internal-encryption.cpp
external-encryption.cpp
extension-encryption.cpp
+ luks.cpp
engine/encryption/ext4-engine.cpp
engine/encryption/dmcrypt-engine.cpp
engine/encryption/ecryptfs-engine.cpp
#include <cctype>
#include <algorithm>
-#include <klay/exception.h>
-
namespace ode {
namespace {
}
int ret = WEXITSTATUS(status);
if (ret != 0) {
- throw runtime::Exception(std::string(argv[0]) + " failed with: " + std::to_string(ret));
+ throw CryptsetupEngine::Exception(
+ std::string(argv[0]) + " failed with: " + std::to_string(ret),
+ ret);
}
}
#include <string>
#include <vector>
+#include <klay/exception.h>
+
namespace ode {
class CryptsetupEngine final {
LUKS,
};
+ enum class ReturnCode {
+ SUCCESS = 0,
+ WRONG_PARAMS = 1,
+ NO_PERMISSION = 2,
+ OUT_OF_MEMORY = 3,
+ WRONG_DEVICE = 4,
+ DEVICE_BUSY = 5
+ };
+
+ class Exception : public runtime::Exception {
+ public:
+ Exception(const std::string& what, int r) :
+ runtime::Exception(what),
+ ret(static_cast<ReturnCode>(r))
+ {}
+
+ ReturnCode retCode() const { return ret; }
+ private:
+ ReturnCode ret;
+ };
+
CryptsetupEngine(const std::string &devicePath);
CryptsetupEngine(const CryptsetupEngine &) = delete;
CryptsetupEngine(CryptsetupEngine &&) = delete;
--- /dev/null
+/*
+ * 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 <unistd.h>
+#include <thread>
+#include <klay/dbus/connection.h>
+#include <map>
+
+#include "logger.h"
+#include "luks.h"
+#include "key-manager/key-manager.h"
+#include "engine/encryption/cryptsetup-engine.h"
+#include "rmi/common.h"
+
+namespace ode {
+
+namespace {
+const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
+const size_t DEFAULT_KEY_SIZE = 64;
+
+std::map<Luks::Operation, std::string> OPERATION_NAME = {
+ { Luks::Format, "Formatting" },
+ { Luks::Open, "Opening" },
+ { Luks::Close, "Closing" },
+};
+
+std::map<CryptsetupEngine::ReturnCode, OdeError> CRYPTSETUP_ERROR_2_ODE_ERROR = {
+ { CryptsetupEngine::ReturnCode::SUCCESS, OdeError::None },
+ { CryptsetupEngine::ReturnCode::WRONG_PARAMS, OdeError::InvalidParameter },
+ { CryptsetupEngine::ReturnCode::NO_PERMISSION, OdeError::WrongPassword },
+ { CryptsetupEngine::ReturnCode::OUT_OF_MEMORY, OdeError::OutOfMemory },
+ { CryptsetupEngine::ReturnCode::WRONG_DEVICE, OdeError::NoSuchFile },
+ { CryptsetupEngine::ReturnCode::DEVICE_BUSY, OdeError::DeviceBusy }
+};
+
+} // anonymous namespace
+
+LuksServer::LuksServer(ServerContext &srv) : server(srv)
+{
+ server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::format)(std::string, std::string));
+ server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::open)(std::string, std::string, std::string));
+ server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::close)(std::string));
+
+ server.createNotification(NOTIFICATION);
+}
+
+LuksServer::~LuksServer()
+{
+}
+
+template <typename F>
+int LuksServer::asyncJob(Luks::Operation op, const F& job)
+{
+ auto worker = [=]() {
+ OdeError ret = OdeError::Unknown;
+ try {
+ std::lock_guard<std::mutex> guardLock(opGuard);
+ ret = job();
+ } catch (const CryptsetupEngine::Exception& e) {
+ ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
+ std::string(e.what()));
+ auto it = CRYPTSETUP_ERROR_2_ODE_ERROR.find(e.retCode());
+ if (it != CRYPTSETUP_ERROR_2_ODE_ERROR.end())
+ ret = it->second;
+ } catch (const std::exception& e) {
+ ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
+ std::string(e.what()));
+ ret = OdeError::Unknown;
+ } catch (...) {
+ ERROR(SINK, OPERATION_NAME.at(op) +
+ " thread failed: unknown exception.");
+ ret = OdeError::Unknown;
+ }
+ server.notify(NOTIFICATION, static_cast<int>(op), static_cast<int>(ret));
+ };
+
+ std::thread work(worker);
+ work.detach();
+ return 0;
+}
+
+int LuksServer::format(const std::string& device, const std::string& password)
+{
+ return asyncJob(Luks::Format, [=](){
+ KeyManager::data pwData(password.begin(), password.end());
+ KeyManager keyManager;
+ keyManager.initPassword(pwData, DEFAULT_KEY_SIZE);
+
+ CryptsetupEngine engine(device);
+ engine.setKeyMeta(keyManager.serialize());
+
+ engine.format(CryptsetupEngine::DeviceType::LUKS,
+ keyManager.getMasterKey(pwData));
+ return OdeError::None;
+ });
+}
+
+int LuksServer::open(const std::string& device,
+ const std::string& password,
+ const std::string& mapping)
+{
+ return asyncJob(Luks::Open, [=](){
+ CryptsetupEngine engine(device);
+
+ KeyManager::data pwData(password.begin(), password.end());
+ KeyManager keyManager(engine.getKeyMeta());
+
+ if (!keyManager.verifyPassword(pwData)) {
+ ERROR(SINK, "Wrong password passed.");
+ return OdeError::WrongPassword;
+ }
+
+ KeyManager::data masterKey = keyManager.getMasterKey(pwData);
+ engine.open(CryptsetupEngine::DeviceType::LUKS, mapping, masterKey);
+ return OdeError::None;
+ });
+}
+
+int LuksServer::close(const std::string& mapping)
+{
+ return asyncJob(Luks::Close, [=](){
+ CryptsetupEngine::close(mapping);
+ return OdeError::None;
+ });
+}
+
+} // namespace ode
--- /dev/null
+/*
+ * 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_LUKS_SERVER_H__
+#define __ODE_LUKS_SERVER_H__
+
+#include <string>
+#include <mutex>
+
+#include "rmi/luks.h"
+#include "server.h"
+
+namespace ode {
+
+class LuksServer final: public Luks {
+public:
+ explicit LuksServer(ServerContext& srv);
+ ~LuksServer();
+
+ int format(const std::string& device, const std::string& password);
+ int open(const std::string& device,
+ const std::string& password,
+ const std::string& mapping);
+ int close(const std::string& mapping);
+
+private:
+ template <typename F>
+ int asyncJob(Luks::Operation op, const F& job);
+
+ ServerContext& server;
+
+ std::mutex opGuard;
+};
+
+} // namespace ode
+
+#endif // __ODE_LUKS_SERVER_H__
#include "internal-encryption.h"
#include "external-encryption.h"
#include "extension-encryption.h"
+#include "luks.h"
#include "key-manager/key-generator.h"
#include "server.h"
internalEncryption.reset(new InternalEncryptionServer(*this));
externalEncryption.reset(new ExternalEncryptionServer(*this));
extensionEncryption.reset(new ExtensionEncryptionServer(*this));
+ luks.reset(new LuksServer(*this));
KeyGenerator::init();
}
class InternalEncryptionServer;
class ExternalEncryptionServer;
class ExtensionEncryptionServer;
+class LuksServer;
class ServerContext final: public rmi::Service {
public:
std::unique_ptr<InternalEncryptionServer> internalEncryption;
std::unique_ptr<ExternalEncryptionServer> externalEncryption;
std::unique_ptr<ExtensionEncryptionServer> extensionEncryption;
+ std::unique_ptr<LuksServer> luks;
};
} // namespace ode