diff options
author | Maciej J. Karpiuk <m.karpiuk2@samsung.com> | 2015-07-20 11:31:29 +0200 |
---|---|---|
committer | Bartlomiej Grzelewski <b.grzelewski@samsung.com> | 2015-11-24 09:38:34 -0800 |
commit | d4505025de280c090bb54264da5597e311d94af3 (patch) | |
tree | 9377ac4af0f6265e02cfc5a2ab1b1204e1dda02f | |
parent | d3e24f2ecde5aa23aa7b2aed806725350f490629 (diff) | |
download | key-manager-d4505025de280c090bb54264da5597e311d94af3.tar.gz key-manager-d4505025de280c090bb54264da5597e311d94af3.tar.bz2 key-manager-d4505025de280c090bb54264da5597e311d94af3.zip |
Encrypted Initial Values: parsing key values.
Change-Id: Iecebe5cba1ce716e43fff09ddc442a57dcfdf976
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/manager/crypto/sw-backend/store.cpp | 41 | ||||
-rw-r--r-- | src/manager/crypto/sw-backend/store.h | 3 | ||||
-rw-r--r-- | src/manager/initial-values/InitialValuesFile.cpp | 35 | ||||
-rw-r--r-- | src/manager/initial-values/InitialValuesFile.h | 24 | ||||
-rw-r--r-- | src/manager/initial-values/SWKeyFile.cpp | 146 | ||||
-rw-r--r-- | src/manager/initial-values/SWKeyFile.h | 98 | ||||
-rw-r--r-- | src/manager/initial-values/xml-utils.cpp | 54 | ||||
-rw-r--r-- | src/manager/initial-values/xml-utils.h | 2 | ||||
-rw-r--r-- | tools/ckm_db_tool/CMakeLists.txt | 1 |
10 files changed, 386 insertions, 19 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa31106a..ceb976ea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,6 +61,7 @@ SET(KEY_MANAGER_SOURCES ${KEY_MANAGER_PATH}/initial-values/InitialValueHandler.cpp ${KEY_MANAGER_PATH}/initial-values/InitialValuesFile.cpp ${KEY_MANAGER_PATH}/initial-values/NoCharactersHandler.cpp + ${KEY_MANAGER_PATH}/initial-values/SWKeyFile.cpp ${KEY_MANAGER_PATH}/initial-values/xml-utils.cpp ${KEY_MANAGER_PATH}/initial-values/initial-value-loader.cpp ${KEY_MANAGER_PATH}/dpl/core/src/assert.cpp diff --git a/src/manager/crypto/sw-backend/store.cpp b/src/manager/crypto/sw-backend/store.cpp index e1ca3620..d59cea1b 100644 --- a/src/manager/crypto/sw-backend/store.cpp +++ b/src/manager/crypto/sw-backend/store.cpp @@ -27,6 +27,8 @@ #include <sw-backend/obj.h> #include <sw-backend/store.h> #include <sw-backend/internals.h> +#include <SWKeyFile.h> +#include <dpl/log/log.h> #include <message-buffer.h> @@ -142,9 +144,31 @@ RawBuffer pack(const RawBuffer& data, const Password& pass) } // namespace anonymous +namespace +{ +const char * const DEVICE_KEY_XSD = "/usr/share/ckm/sw_key.xsd"; +const char * const DEVICE_KEY_SW_FILE = "/opt/data/ckm/device_key.xml"; +} + Store::Store(CryptoBackend backendId) : GStore(backendId) { + // get the device key if present + InitialValues::SWKeyFile keyFile(DEVICE_KEY_SW_FILE); + int rc = keyFile.Validate(DEVICE_KEY_XSD); + if(rc == XML::Parser::PARSE_SUCCESS) + { + rc = keyFile.Parse(); + if(rc == XML::Parser::PARSE_SUCCESS) + m_deviceKey = keyFile.getPrivKey(); + else + { + // do nothing, bypass encrypted elements + LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", parsing code: " << rc); + } + } + else + LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", validation code: " << rc); } GObjUPtr Store::getObject(const Token &token, const Password &pass) { @@ -194,8 +218,21 @@ Token Store::import(const Data &data, const Password &pass) { return Token(m_backendId, data.type, pack(data.data, pass)); } -Token Store::importEncrypted(const Data &, const Password &, const DataEncryption &) { - ThrowErr(Exc::Crypto::OperationNotSupported, "Importing encrypted data not yet implemented!"); +Token Store::importEncrypted(const Data &data, const Password &pass, const DataEncryption &enc) { + if(!m_deviceKey) + ThrowErr(Exc::Crypto::InternalError, "No device key present"); + + // decrypt the AES key using device key + CryptoAlgorithm algorithmRSAOAEP; + algorithmRSAOAEP.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP); + Crypto::SW::SKey aesKey(m_deviceKey->decrypt(algorithmRSAOAEP, enc.encryptedKey), DataType::KEY_AES); + + // decrypt the buffer using AES key + CryptoAlgorithm algorithmAESCBC; + algorithmAESCBC.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC); + algorithmAESCBC.setParam(ParamName::ED_IV, enc.iv); + RawBuffer rawData = aesKey.decrypt(algorithmAESCBC, data.data); + return Token(m_backendId, data.type, pack(rawData, pass)); } } // namespace SW diff --git a/src/manager/crypto/sw-backend/store.h b/src/manager/crypto/sw-backend/store.h index 03d69ff4..860e3938 100644 --- a/src/manager/crypto/sw-backend/store.h +++ b/src/manager/crypto/sw-backend/store.h @@ -37,6 +37,9 @@ public: virtual Token import(const Data &data, const Password &); virtual Token importEncrypted(const Data &, const Password &, const DataEncryption &); virtual void destroy(const Token &){} + +private: + Crypto::GObjShPtr m_deviceKey; }; } // namespace SW diff --git a/src/manager/initial-values/InitialValuesFile.cpp b/src/manager/initial-values/InitialValuesFile.cpp index bc5fbec5..166f158f 100644 --- a/src/manager/initial-values/InitialValuesFile.cpp +++ b/src/manager/initial-values/InitialValuesFile.cpp @@ -29,11 +29,13 @@ #include <CertHandler.h> #include <DataHandler.h> #include <EncodingType.h> +#include <sw-backend/obj.h> #include <dpl/log/log.h> namespace { const int XML_CURRENT_VERSION = 1; const char * const XML_TAG_INITIAL_VALUES = "InitialValues"; +const char * const XML_TAG_ENCRYPTION_KEY = "EncryptionKey"; const char * const XML_TAG_KEY = "Key"; const char * const XML_TAG_DATA = "Data"; const char * const XML_TAG_CERT = "Cert"; @@ -48,9 +50,11 @@ const char * const XML_ATTR_VERSION = "version"; namespace CKM { namespace InitialValues { -InitialValuesFile::InitialValuesFile(const std::string &XML_filename, CKMLogic & db_logic) +InitialValuesFile::InitialValuesFile(const std::string &XML_filename, + CKMLogic & db_logic) : m_parser(XML_filename), m_db_logic(db_logic), - m_header(std::make_shared<HeaderHandler>(*this)) + m_header(std::make_shared<HeaderHandler>(*this)), + m_encryptionKeyHandler(std::make_shared<EncryptionKeyHandler>(*this)) { m_parser.RegisterErrorCb(InitialValuesFile::Error); m_parser.RegisterElementCb(XML_TAG_INITIAL_VALUES, @@ -59,6 +63,15 @@ InitialValuesFile::InitialValuesFile(const std::string &XML_filename, CKMLogic & return m_header; }, [this](const XML::Parser::ElementHandlerPtr &) {}); + m_parser.RegisterElementCb(XML_TAG_ENCRYPTION_KEY, + [this]() -> XML::Parser::ElementHandlerPtr + { + return m_encryptionKeyHandler; + }, + [this](const XML::Parser::ElementHandlerPtr &) + { + m_encryptedAESkey = m_encryptionKeyHandler->getEncryptedKey(); + }); } void InitialValuesFile::registerElementListeners() @@ -226,6 +239,24 @@ void InitialValuesFile::ReleasePermissionHandler() } +InitialValuesFile::EncryptionKeyHandler::EncryptionKeyHandler(InitialValuesFile & parent) : m_parent(parent) {} +void InitialValuesFile::EncryptionKeyHandler::Characters(const std::string &data) { + m_encryptedKey.reserve(m_encryptedKey.size() + data.size()); + m_encryptedKey.insert(m_encryptedKey.end(), data.begin(), data.end()); +}; +void InitialValuesFile::EncryptionKeyHandler::End() { + std::string trimmed = XML::trimEachLine(std::string(m_encryptedKey.begin(), m_encryptedKey.end())); + Base64Decoder base64; + base64.reset(); + base64.append(RawBuffer(trimmed.begin(), trimmed.end())); + base64.finalize(); + m_encryptedKey = base64.get(); +}; + +CKM::RawBuffer InitialValuesFile::EncryptionKeyHandler::getEncryptedKey() const { + return m_encryptedKey; +} + InitialValuesFile::HeaderHandler::HeaderHandler(InitialValuesFile & parent) : m_version(-1), m_parent(parent) {} void InitialValuesFile::HeaderHandler::Start(const XML::Parser::Attributes & attr) diff --git a/src/manager/initial-values/InitialValuesFile.h b/src/manager/initial-values/InitialValuesFile.h index 82268223..1572e2f6 100644 --- a/src/manager/initial-values/InitialValuesFile.h +++ b/src/manager/initial-values/InitialValuesFile.h @@ -26,10 +26,16 @@ #include <parser.h> #include <InitialValueHandler.h> #include <ckm-logic.h> +#include <string> +#include <algorithm> +#include <cctype> +#include <xml-utils.h> +#include <base64.h> namespace CKM { namespace InitialValues { + class InitialValuesFile { public: @@ -74,8 +80,26 @@ private: int m_version; InitialValuesFile & m_parent; }; + + class EncryptionKeyHandler : public XML::Parser::ElementHandler + { + public: + explicit EncryptionKeyHandler(InitialValuesFile & parent); + virtual void Start(const XML::Parser::Attributes &) {}; + virtual void Characters(const std::string &data); + virtual void End(); + + CKM::RawBuffer getEncryptedKey() const; + private: + CKM::RawBuffer m_encryptedKey; + InitialValuesFile & m_parent; + }; + typedef std::shared_ptr<HeaderHandler> HeaderHandlerPtr; + typedef std::shared_ptr<EncryptionKeyHandler> EncryptionKeyHandlerPtr; HeaderHandlerPtr m_header; + EncryptionKeyHandlerPtr m_encryptionKeyHandler; + CKM::RawBuffer m_encryptedAESkey; void registerElementListeners(); static void Error(const XML::Parser::ErrorType errorType, diff --git a/src/manager/initial-values/SWKeyFile.cpp b/src/manager/initial-values/SWKeyFile.cpp new file mode 100644 index 00000000..f6141852 --- /dev/null +++ b/src/manager/initial-values/SWKeyFile.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2000 - 2015 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 SWKeyFile.cpp + * @author Maciej Karpiuk (m.karpiuk2@samsung.com) + * @version 1.0 + * @brief SWKeyFile class implementation. + */ + +#include <iostream> +#include <SWKeyFile.h> +#include <BufferHandler.h> +#include <EncodingType.h> +#include <sw-backend/obj.h> +#include <dpl/log/log.h> + +namespace { +const int XML_SW_KEY_CURRENT_VERSION = 1; +const char * const XML_TAG_DEVICE_KEY = "DeviceKey"; +const char * const XML_TAG_RSA_KEY = "RSAPrivateKey"; +const char * const XML_TAG_PEM = "PEM"; +const char * const XML_TAG_DER = "DERBase64"; +const char * const XML_TAG_BASE64 = "Base64"; +const char * const XML_ATTR_VERSION = "version"; +} + +namespace CKM { +namespace InitialValues { + +SWKeyFile::SWKeyFile(const std::string &XML_filename) + : m_parser(XML_filename), + m_header(std::make_shared<HeaderHandler>(*this)), + m_RSAKeyHandler(std::make_shared<RSAKeyHandler>(*this)) +{ + m_parser.RegisterErrorCb(SWKeyFile::Error); + m_parser.RegisterElementCb(XML_TAG_DEVICE_KEY, + [this]() -> XML::Parser::ElementHandlerPtr + { + return m_header; + }, + [this](const XML::Parser::ElementHandlerPtr &) {}); +} + +void SWKeyFile::registerElementListeners() +{ + m_parser.RegisterElementCb(XML_TAG_RSA_KEY, + [this]() -> XML::Parser::ElementHandlerPtr + { + return m_RSAKeyHandler; + }, + [this](const XML::Parser::ElementHandlerPtr &) + { + m_deviceKey = m_RSAKeyHandler->getPrivKey(); + }); +} + +void SWKeyFile::Error(const XML::Parser::ErrorType errorType, + const std::string & log_msg) +{ + switch(errorType) + { + case XML::Parser::VALIDATION_ERROR: + LogWarning("validating error: " << log_msg); + break; + case XML::Parser::PARSE_WARNING: + LogWarning("parsing warning: " << log_msg); + break; + case XML::Parser::PARSE_ERROR: + LogWarning("parsing error: " << log_msg); + break; + } +} + +int SWKeyFile::Validate(const std::string &XSD_file) +{ + return m_parser.Validate(XSD_file); +} + +int SWKeyFile::Parse() +{ + int ec = m_parser.Parse(); + if(!m_header || !m_header->isCorrectVersion()) { + LogError("bypassing XML file: " << m_filename << " - wrong file version!"); + ec = XML::Parser::ERROR_INVALID_VERSION; + } + return ec; +} + + + +SWKeyFile::RSAKeyHandler::RSAKeyHandler(SWKeyFile & parent) + : m_parent(parent) +{} + +void SWKeyFile::RSAKeyHandler::Characters(const std::string &data) { + //m_encryptedKey.reserve(m_encryptedKey.size() + data.size()); + //m_encryptedKey.insert(m_encryptedKey.end(), data.begin(), data.end()); + std::copy(data.begin(), data.end(), std::back_inserter(m_encryptedKey)); +} + +void SWKeyFile::RSAKeyHandler::End() { +// std::string trimmed = XML::trimEachLine(std::string(m_encryptedKey.begin(), m_encryptedKey.end())); + + Base64Decoder base64; + base64.reset(); + base64.append(XML::removeWhiteChars(m_encryptedKey)); + base64.finalize(); + m_encryptedKey = base64.get(); +}; + +Crypto::GObjShPtr SWKeyFile::RSAKeyHandler::getPrivKey() { + return std::make_shared<Crypto::SW::AKey>(m_encryptedKey, DataType::KEY_RSA_PRIVATE); +} + +SWKeyFile::HeaderHandler::HeaderHandler(SWKeyFile & parent) + : m_version(-1), m_parent(parent) {} +void SWKeyFile::HeaderHandler::Start(const XML::Parser::Attributes & attr) +{ + // get key type + if(attr.find(XML_ATTR_VERSION) != attr.end()) + { + m_version = atoi(attr.at(XML_ATTR_VERSION).c_str()); + + if(isCorrectVersion()) + m_parent.registerElementListeners(); + } +} +bool SWKeyFile::HeaderHandler::isCorrectVersion() const { + return m_version == XML_SW_KEY_CURRENT_VERSION; +} + +} +} diff --git a/src/manager/initial-values/SWKeyFile.h b/src/manager/initial-values/SWKeyFile.h new file mode 100644 index 00000000..887c0a98 --- /dev/null +++ b/src/manager/initial-values/SWKeyFile.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2000 - 2015 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 SWKeyFile.h + * @author Maciej Karpiuk (m.karpiuk2@samsung.com) + * @version 1.0 + * @brief SWKeyFile class. + */ + +#ifndef SWKEYFILE_H_ +#define SWKEYFILE_H_ + +#include <parser.h> +#include <InitialValueHandler.h> +#include <ckm-logic.h> +#include <string> +#include <algorithm> +#include <cctype> +#include <xml-utils.h> +#include <base64.h> +#include <generic-backend/gobj.h> +#include <dpl/log/log.h> +namespace CKM { +namespace InitialValues { + + +class SWKeyFile +{ +public: + explicit SWKeyFile(const std::string &XML_filename); + + int Validate(const std::string &XSD_file); + int Parse(); + + Crypto::GObjShPtr getPrivKey() { + return m_deviceKey; + } + +private: + class HeaderHandler : public XML::Parser::ElementHandler + { + public: + explicit HeaderHandler(SWKeyFile & parent); + virtual void Start(const XML::Parser::Attributes & attr); + virtual void Characters(const std::string &) {}; + virtual void End() {}; + + bool isCorrectVersion() const; + + private: + int m_version; + SWKeyFile & m_parent; + }; + + class RSAKeyHandler : public XML::Parser::ElementHandler + { + public: + explicit RSAKeyHandler(SWKeyFile & parent); + virtual void Start(const XML::Parser::Attributes &) {}; + virtual void Characters(const std::string &data); + virtual void End(); + + Crypto::GObjShPtr getPrivKey(); + private: + CKM::RawBuffer m_encryptedKey; + SWKeyFile & m_parent; + }; + + std::string m_filename; + XML::Parser m_parser; + typedef std::shared_ptr<HeaderHandler> HeaderHandlerPtr; + typedef std::shared_ptr<RSAKeyHandler> RSAKeyHandlerPtr; + HeaderHandlerPtr m_header; + RSAKeyHandlerPtr m_RSAKeyHandler; + Crypto::GObjShPtr m_deviceKey; + + void registerElementListeners(); + static void Error(const XML::Parser::ErrorType errorType, + const std::string & logMsg); + +}; + +} +} +#endif /* SWKEYFILE_H_ */ diff --git a/src/manager/initial-values/xml-utils.cpp b/src/manager/initial-values/xml-utils.cpp index 8b1abdb0..0553c01f 100644 --- a/src/manager/initial-values/xml-utils.cpp +++ b/src/manager/initial-values/xml-utils.cpp @@ -28,7 +28,7 @@ namespace { const char * const WHITESPACE = " \n\r\t\v"; -const char * const LINE_WHITESPACE = " \t"; +const char * const LINE_WHITESPACE = " \r\t\v"; std::string trim_left(const std::string& s, const char *whitespaces) { @@ -46,27 +46,51 @@ std::string trim(const std::string& s, const char *whitespaces) { return trim_right(trim_left(s, whitespaces), whitespaces); } + } namespace CKM { namespace XML { -std::string trim(const std::string& s) + +template <typename T> +T removeChars(const T& input, const char *what) { - return ::trim(s, WHITESPACE); + T out(input); + auto endit = std::remove_if(out.begin(), out.end(), + [what](char c) + { + for (const char *ptr = what; *ptr; ++ptr) + if (*ptr == c) + return true; + return false; + }); + + out.erase(endit, out.end()); + return out; } -std::string trimEachLine(const std::string& s) -{ - std::istringstream stream(s); - size_t line_cnt = 0; - std::string line, output; - while(std::getline(stream, line)) { - if(line_cnt>0) - output += "\n"; - output += ::trim(line, LINE_WHITESPACE); - line_cnt ++; - } - return output; +RawBuffer removeWhiteChars(const RawBuffer &buffer) { + return removeChars(buffer, WHITESPACE); } + +std::string trimEachLine(const std::string& input) { + std::stringstream ss(input); + std::stringstream output; + std::string line; + + while(std::getline(ss, line, '\n')) { + auto afterTrim = ::trim(line, LINE_WHITESPACE); + if (!afterTrim.empty()) + output << afterTrim << std::endl; + } + + return output.str(); } + +std::string trim(const std::string &s) { + return removeChars(s, WHITESPACE); } + +} // namespace XML +} // namespace CKM + diff --git a/src/manager/initial-values/xml-utils.h b/src/manager/initial-values/xml-utils.h index c3855987..8ef94fd8 100644 --- a/src/manager/initial-values/xml-utils.h +++ b/src/manager/initial-values/xml-utils.h @@ -24,10 +24,12 @@ #define XML_UTILS_H_ #include <string> +#include <ckm/ckm-raw-buffer.h> namespace CKM { namespace XML { +RawBuffer removeWhiteChars(const RawBuffer &buffer); std::string trim(const std::string& s); std::string trimEachLine(const std::string &s); diff --git a/tools/ckm_db_tool/CMakeLists.txt b/tools/ckm_db_tool/CMakeLists.txt index c040cad9..9513b800 100644 --- a/tools/ckm_db_tool/CMakeLists.txt +++ b/tools/ckm_db_tool/CMakeLists.txt @@ -33,6 +33,7 @@ SET(CKM_DB_TOOL_SOURCES ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm_db_tool.cpp ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/db-crypto-ext.cpp ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm-logic-ext.cpp + ${KEY_MANAGER_PATH}/initial-values/SWKeyFile.cpp ${KEY_MANAGER_PATH}/main/cynara.cpp ${KEY_MANAGER_PATH}/main/generic-socket-manager.cpp |