From: Krzysztof Jackiewicz Date: Fri, 15 May 2015 17:40:29 +0000 (+0200) Subject: Simplify CryptoAlgorithm interface X-Git-Tag: accepted/tizen/mobile/20150629.000431~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ce7f15771b437cc86d6ed005433e818d5616606;hp=94cd4b238acc09261439071cf5e7a9be114eee93;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git Simplify CryptoAlgorithm interface [Issue#] N/A [Feature/Bug] N/A [Problem] N/A [Cause] CryptoAlgorithm interface was too complicated [Solution] Add high level interface [Verification] Run: ckm-tests-internal --run_test=SERIALIZATION_TEST Change-Id: I9f02d6ea6f3cc37d46585e1460f2a02bdc107f3c --- diff --git a/src/include/ckm/ckm-type.h b/src/include/ckm/ckm-type.h index 95233d8..9d93421 100644 --- a/src/include/ckm/ckm-type.h +++ b/src/include/ckm/ckm-type.h @@ -111,8 +111,11 @@ const char * ErrorToString(int error); // algorithm parameters enum class ParamName : int { + ALGO_TYPE = 1, // If there's no such param, the service will try to deduce the algorithm + // type from the key. + // encryption & decryption - ED_IV = 1, + ED_IV = 101, ED_CTR, ED_CTR_LEN, ED_AAD, @@ -120,15 +123,15 @@ enum class ParamName : int { ED_LABEL, // key generation - GEN_KEY_LEN = 101, + GEN_KEY_LEN = 201, GEN_EC, // elliptic curve (ElipticCurve) // sign & verify - SV_HASH_ALGO = 201, // hash algorithm (HashAlgorithm) + SV_HASH_ALGO = 301, // hash algorithm (HashAlgorithm) SV_RSA_PADDING, // RSA padding (RSAPaddingAlgorithm) }; -// algorithm types +// algorithm types (ALGO_TYPE param) enum class AlgoType : int { AES_CTR = 1, AES_CBC, @@ -140,42 +143,52 @@ enum class AlgoType : int { ECDSA, }; -class KEY_MANAGER_API BaseParam { +// cryptographic algorithm description +class KEY_MANAGER_API CryptoAlgorithm { public: - virtual int getBuffer(RawBuffer&) const; - virtual int getInt(uint64_t&) const; - virtual ~BaseParam() {} + template + bool getParam(ParamName name, T& value) const; -protected: - BaseParam() {} -}; -typedef std::unique_ptr BaseParamPtr; + // returns false if param 'name' already exists + template + bool addParam(ParamName name, const T& value); -class KEY_MANAGER_API BufferParam : public BaseParam { -public: - int getBuffer(RawBuffer& buffer) const; - static BaseParamPtr create(const RawBuffer& buffer); -private: - explicit BufferParam(const RawBuffer& value) : m_buffer(value) {} +protected: + class BaseParam { + public: + virtual bool getBuffer(RawBuffer&) const { return false; } + virtual bool getInt(uint64_t&) const { return false; } + virtual ~BaseParam() {} + + protected: + BaseParam() {} + }; + typedef std::unique_ptr BaseParamPtr; + + class BufferParam : public BaseParam { + public: + bool getBuffer(RawBuffer& buffer) const; + static BaseParamPtr create(const RawBuffer& buffer); + private: + explicit BufferParam(const RawBuffer& value) : m_buffer(value) {} + + RawBuffer m_buffer; + }; + + class IntParam : public BaseParam { + public: + static BaseParamPtr create(uint64_t value); + bool getInt(uint64_t& value) const; + private: + explicit IntParam(uint64_t value) : m_int(value) {} + + uint64_t m_int; + }; - RawBuffer m_buffer; + std::map m_params; }; -class KEY_MANAGER_API IntParam : public BaseParam { -public: - static BaseParamPtr create(uint64_t value); - int getInt(uint64_t& value) const; -private: - explicit IntParam(uint64_t value) : m_int(value) {} - - uint64_t m_int; -}; -// cryptographic algorithm description -struct CryptoAlgorithm { - AlgoType m_type; - std::map m_params; -}; } // namespace CKM diff --git a/src/manager/common/algo-param.cpp b/src/manager/common/algo-param.cpp index e0a72c9..7585d96 100644 --- a/src/manager/common/algo-param.cpp +++ b/src/manager/common/algo-param.cpp @@ -20,41 +20,71 @@ */ #include -#include +#include namespace CKM { -int BaseParam::getBuffer(RawBuffer&) const +bool CryptoAlgorithm::BufferParam::getBuffer(RawBuffer& buffer) const { - return CKM_API_ERROR_INVALID_FORMAT; + buffer = m_buffer; + return true; } -int BaseParam::getInt(uint64_t&) const +CryptoAlgorithm::BaseParamPtr CryptoAlgorithm::BufferParam::create(const RawBuffer& buffer) { - return CKM_API_ERROR_INVALID_FORMAT; + return BaseParamPtr(new CryptoAlgorithm::BufferParam(buffer)); } -int BufferParam::getBuffer(RawBuffer& buffer) const +bool CryptoAlgorithm::IntParam::getInt(uint64_t& value) const { - buffer = m_buffer; - return CKM_API_SUCCESS; + value = m_int; + return true; } -BaseParamPtr BufferParam::create(const RawBuffer& buffer) +CryptoAlgorithm::BaseParamPtr CryptoAlgorithm::IntParam::create(uint64_t value) { - return BaseParamPtr(new BufferParam(buffer)); + return BaseParamPtr(new CryptoAlgorithm::IntParam(value)); } -int IntParam::getInt(uint64_t& value) const +template <> +bool CryptoAlgorithm::getParam(ParamName name, uint64_t& value) const { - value = m_int; - return CKM_API_SUCCESS; + auto param = m_params.find(name); + if (param == m_params.end()) + return false; + + assert(param->second); + return param->second->getInt(value); +} + +template <> +bool CryptoAlgorithm::getParam(ParamName name, RawBuffer& value) const +{ + auto param = m_params.find(name); + if (param == m_params.end()) + return false; + + assert(param->second); + return param->second->getBuffer(value); +} + +template <> +bool CryptoAlgorithm::addParam(ParamName name, const uint64_t& value) +{ + return m_params.emplace(name, IntParam::create(value)).second; +} + +template <> +bool CryptoAlgorithm::addParam(ParamName name, const int& value) +{ + return m_params.emplace(name, IntParam::create(value)).second; } -BaseParamPtr IntParam::create(uint64_t value) +template <> +bool CryptoAlgorithm::addParam(ParamName name, const RawBuffer& value) { - return BaseParamPtr(new IntParam(value)); + return m_params.emplace(name, BufferParam::create(value)).second; } } // namespace CKM diff --git a/src/manager/common/protocols.cpp b/src/manager/common/protocols.cpp index 92c24b0..7bd6eac 100644 --- a/src/manager/common/protocols.cpp +++ b/src/manager/common/protocols.cpp @@ -119,9 +119,7 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(CryptoAlgorithm &&algo) CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream) { size_t plen = 0; - int type; - Deserializer::Deserialize(stream, type, plen); - m_type = static_cast(type); + Deserializer::Deserialize(stream, plen); while(plen) { ParamName name; uint64_t integer; @@ -135,9 +133,10 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream) case ParamName::ED_AAD: case ParamName::ED_LABEL: Deserializer::Deserialize(stream, buffer); - m_params.emplace(name, BufferParam::create(buffer)); + addParam(name, buffer); break; + case ParamName::ALGO_TYPE: case ParamName::ED_CTR_LEN: case ParamName::ED_TAG_LEN: case ParamName::GEN_KEY_LEN: @@ -145,7 +144,7 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream) case ParamName::SV_HASH_ALGO: case ParamName::SV_RSA_PADDING: Deserializer::Deserialize(stream, integer); - m_params.emplace(name, IntParam::create(integer)); + addParam(name, integer); break; default: @@ -157,14 +156,14 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream) void CryptoAlgorithmSerializable::Serialize(IStream &stream) const { - Serializer::Serialize(stream, static_cast(m_type), m_params.size()); + Serializer::Serialize(stream, m_params.size()); for(const auto& it : m_params) { Serializer::Serialize(stream, static_cast(it.first)); uint64_t integer; RawBuffer buffer; - if (CKM_API_SUCCESS == it.second->getInt(integer)) + if (it.second->getInt(integer)) Serializer::Serialize(stream, integer); - else if (CKM_API_SUCCESS == it.second->getBuffer(buffer)) + else if (it.second->getBuffer(buffer)) Serializer::Serialize(stream, buffer); else ThrowMsg(UnsupportedParam, "Unsupported param type"); diff --git a/tests/test_serialization.cpp b/tests/test_serialization.cpp index 6181102..4c6e5b5 100644 --- a/tests/test_serialization.cpp +++ b/tests/test_serialization.cpp @@ -36,20 +36,60 @@ std::string AAD_STR("sdfdsgsghrtkghwiuho3irhfoewituhre"); RawBuffer IV(IV_STR.begin(), IV_STR.end()); RawBuffer AAD(AAD_STR.begin(), AAD_STR.end()); -struct BrokenParam : public BaseParam { - static BaseParamPtr create() { return BaseParamPtr(new BrokenParam()); } -}; +void checkIntParam(const CryptoAlgorithm& algo, ParamName name, uint64_t expected) +{ + uint64_t integer; + BOOST_REQUIRE_MESSAGE(algo.getParam(name, integer), + "Failed to get parameter " << static_cast(name)); + BOOST_REQUIRE_MESSAGE( + integer == expected, + "Parameter " << static_cast(name) << + " expected value: " << expected << + " got: " << integer); +} + +void checkIntParamNegative(const CryptoAlgorithm& algo, ParamName name) +{ + uint64_t integer; + BOOST_REQUIRE_MESSAGE(!algo.getParam(name, integer), + "Getting int parameter " << static_cast(name) << " should fail"); +} + +void checkBufferParam(const CryptoAlgorithm& algo, ParamName name, RawBuffer expected) +{ + RawBuffer buffer; + BOOST_REQUIRE_MESSAGE(algo.getParam(name, buffer), + "Failed to get buffer parameter " << static_cast(name)); + BOOST_REQUIRE_MESSAGE(buffer == expected, + "Parameter " << static_cast(name) << " different than expected"); +} + +void checkBufferParamNegative(const CryptoAlgorithm& algo, ParamName name) +{ + RawBuffer buffer; + BOOST_REQUIRE_MESSAGE(!algo.getParam(name, buffer), + "Getting buffer parameter " << static_cast(name) << " should fail"); +} + +template +void addParam(CryptoAlgorithm& algo, ParamName name, const T& value, bool success) +{ + BOOST_REQUIRE_MESSAGE(success == algo.addParam(name, value), + "Adding param " << static_cast(name) << + " should " << (success ? "succeed":"fail")); +} } // namespace anonymous BOOST_AUTO_TEST_SUITE(SERIALIZATION_TEST) -BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm_positive) { +BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm) { CryptoAlgorithm ca; - ca.m_type = AlgoType::AES_GCM; - ca.m_params.emplace(ParamName::ED_IV, BufferParam::create(IV)); - ca.m_params.emplace(ParamName::ED_TAG_LEN, IntParam::create(128)); - ca.m_params.emplace(ParamName::ED_AAD, BufferParam::create(AAD)); + addParam(ca,ParamName::ALGO_TYPE, static_cast(AlgoType::AES_GCM), true); + addParam(ca,ParamName::ED_IV, IV, true); + addParam(ca,ParamName::ED_IV, AAD, false); // try to overwrite + addParam(ca,ParamName::ED_TAG_LEN, 128, true); + addParam(ca,ParamName::ED_AAD, AAD, true); CryptoAlgorithmSerializable input(std::move(ca)); CryptoAlgorithmSerializable output; @@ -59,53 +99,31 @@ BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm_positive) { resp.Push(buffer); resp.Deserialize(output); - BOOST_REQUIRE_MESSAGE(input.m_type == output.m_type, - "Algorithm types don't match: " << static_cast(input.m_type) << "!=" - << static_cast(output.m_type)); - - // compare params - auto iit = input.m_params.cbegin(); - auto oit = output.m_params.cbegin(); - for(;iit != input.m_params.cend() && oit != output.m_params.cend(); iit++, oit++ ) - { - BOOST_REQUIRE_MESSAGE(iit->first == oit->first, - "Param names do not match :" << static_cast(iit->first) << "!=" - << static_cast(oit->first)); - uint64_t integer[2]; - RawBuffer buffer[2]; - if(CKM_API_SUCCESS == iit->second->getInt(integer[0])) - { - BOOST_REQUIRE_MESSAGE(CKM_API_SUCCESS == oit->second->getInt(integer[1]), - "Param types do not match"); - BOOST_REQUIRE_MESSAGE(integer[0] == integer[1], "Integer params do not match"); - } - else if(CKM_API_SUCCESS == iit->second->getBuffer(buffer[0])) - { - BOOST_REQUIRE_MESSAGE(CKM_API_SUCCESS == oit->second->getBuffer(buffer[1]), - "Param types do not match"); - BOOST_REQUIRE_MESSAGE(buffer[0] == buffer[1], "Integer params do not match"); - } - else - BOOST_FAIL("Wrong param type"); - } -} - -BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm_broken_param) { - CryptoAlgorithm ca; - ca.m_type = AlgoType::AES_GCM; - // unuspported param type - ca.m_params.emplace(ParamName::ED_IV, BrokenParam::create()); - - CryptoAlgorithmSerializable input(std::move(ca)); - BOOST_REQUIRE_THROW(auto buffer = MessageBuffer::Serialize(input), - CryptoAlgorithmSerializable::UnsupportedParam); + checkIntParam(output, ParamName::ALGO_TYPE, static_cast(AlgoType::AES_GCM)); + checkBufferParam(output, ParamName::ED_IV, IV); + checkIntParam(output, ParamName::ED_TAG_LEN, 128); + checkBufferParam(output, ParamName::ED_AAD, AAD); + + // wrong type + checkBufferParamNegative(output, ParamName::ALGO_TYPE); + checkIntParamNegative(output, ParamName::ED_IV); + + // non-existing + checkBufferParamNegative(output, ParamName::ED_CTR); + checkIntParamNegative(output, ParamName::ED_CTR_LEN); + checkBufferParamNegative(output, ParamName::ED_LABEL); + checkIntParamNegative(output, ParamName::GEN_KEY_LEN); + checkIntParamNegative(output, ParamName::GEN_EC); + checkIntParamNegative(output, ParamName::SV_HASH_ALGO); + checkIntParamNegative(output, ParamName::SV_RSA_PADDING); + + checkIntParamNegative(output, static_cast(666)); } BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm_wrong_name) { CryptoAlgorithm ca; - ca.m_type = AlgoType::AES_GCM; // unuspported param name - ca.m_params.emplace(static_cast(666), IntParam::create(666)); + addParam(ca, static_cast(666), 666, true); CryptoAlgorithmSerializable input(std::move(ca)); CryptoAlgorithmSerializable output;