From: Krzysztof Jackiewicz Date: Thu, 19 Oct 2017 15:17:39 +0000 (+0200) Subject: Key/password management API implementation X-Git-Tag: submit/tizen/20171201.152910~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=13cbf4050ece3e5595eed1622f9e1743ae6c6f93;p=platform%2Fcore%2Fsecurity%2Fode.git Key/password management API implementation Change-Id: Ib74cc6e9212a948a043b483f08159024b642eb77 --- diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 6f4a10c..fba59e4 100755 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -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 index 0000000..6bb30ad --- /dev/null +++ b/lib/key-client.cpp @@ -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("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("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("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("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("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 index 0000000..aeff433 --- /dev/null +++ b/lib/key-client.h @@ -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 + +#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 index 0000000..c982700 --- /dev/null +++ b/lib/ode/keys.cpp @@ -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(); + 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(); + 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(); + 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(); + 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(); + 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 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 + +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__ diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index ab88ad6..efbc4f8 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -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 index 0000000..a7d4a69 --- /dev/null +++ b/server/key-server.cpp @@ -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 + +#include +#include +#include + +#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 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 index 0000000..e44eebb --- /dev/null +++ b/server/key-server.h @@ -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 + +#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__ diff --git a/server/server.cpp b/server/server.cpp index 90ab266..64bc609 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -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(); } diff --git a/server/server.h b/server/server.h index 18b5870..9b38f70 100644 --- a/server/server.h +++ b/server/server.h @@ -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 internalEncryption; std::unique_ptr externalEncryption; std::unique_ptr luks; + std::unique_ptr keys; }; } // namespace ode