From: Maciej J. Karpiuk Date: Mon, 20 Jul 2015 09:31:29 +0000 (+0200) Subject: Encrypted Initial Values: parsing key values. X-Git-Tag: accepted/tizen/mobile/20151230.112505~14 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d4505025de280c090bb54264da5597e311d94af3;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git Encrypted Initial Values: parsing key values. Change-Id: Iecebe5cba1ce716e43fff09ddc442a57dcfdf976 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa31106..ceb976e 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 e1ca362..d59cea1 100644 --- a/src/manager/crypto/sw-backend/store.cpp +++ b/src/manager/crypto/sw-backend/store.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include @@ -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 03d69ff..860e393 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 bc5fbec..166f158 100644 --- a/src/manager/initial-values/InitialValuesFile.cpp +++ b/src/manager/initial-values/InitialValuesFile.cpp @@ -29,11 +29,13 @@ #include #include #include +#include #include 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(*this)) + m_header(std::make_shared(*this)), + m_encryptionKeyHandler(std::make_shared(*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 8226822..1572e2f 100644 --- a/src/manager/initial-values/InitialValuesFile.h +++ b/src/manager/initial-values/InitialValuesFile.h @@ -26,10 +26,16 @@ #include #include #include +#include +#include +#include +#include +#include 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 HeaderHandlerPtr; + typedef std::shared_ptr 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 0000000..f614185 --- /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 +#include +#include +#include +#include +#include + +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(*this)), + m_RSAKeyHandler(std::make_shared(*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(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 0000000..887c0a9 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +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 HeaderHandlerPtr; + typedef std::shared_ptr 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 8b1abdb..0553c01 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 +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 c385598..8ef94fd 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 +#include 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 c040cad..9513b80 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