// 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,
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,
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 <typename T>
+ bool getParam(ParamName name, T& value) const;
-protected:
- BaseParam() {}
-};
-typedef std::unique_ptr<BaseParam> BaseParamPtr;
+ // returns false if param 'name' already exists
+ template <typename T>
+ 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<BaseParam> 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<ParamName, BaseParamPtr> 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<ParamName, BaseParamPtr> m_params;
-};
} // namespace CKM
*/
#include <ckm/ckm-type.h>
-#include <ckm/ckm-error.h>
+#include <cassert>
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<uint64_t>(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<RawBuffer>(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<uint64_t>(ParamName name, const uint64_t& value)
+{
+ return m_params.emplace(name, IntParam::create(value)).second;
+}
+
+template <>
+bool CryptoAlgorithm::addParam<int>(ParamName name, const int& value)
+{
+ return m_params.emplace(name, IntParam::create(value)).second;
}
-BaseParamPtr IntParam::create(uint64_t value)
+template <>
+bool CryptoAlgorithm::addParam<RawBuffer>(ParamName name, const RawBuffer& value)
{
- return BaseParamPtr(new IntParam(value));
+ return m_params.emplace(name, BufferParam::create(value)).second;
}
} // namespace CKM
CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream)
{
size_t plen = 0;
- int type;
- Deserializer<int,size_t>::Deserialize(stream, type, plen);
- m_type = static_cast<AlgoType>(type);
+ Deserializer<size_t>::Deserialize(stream, plen);
while(plen) {
ParamName name;
uint64_t integer;
case ParamName::ED_AAD:
case ParamName::ED_LABEL:
Deserializer<RawBuffer>::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:
case ParamName::SV_HASH_ALGO:
case ParamName::SV_RSA_PADDING:
Deserializer<uint64_t>::Deserialize(stream, integer);
- m_params.emplace(name, IntParam::create(integer));
+ addParam(name, integer);
break;
default:
void CryptoAlgorithmSerializable::Serialize(IStream &stream) const
{
- Serializer<int,size_t>::Serialize(stream, static_cast<int>(m_type), m_params.size());
+ Serializer<size_t>::Serialize(stream, m_params.size());
for(const auto& it : m_params) {
Serializer<int>::Serialize(stream, static_cast<int>(it.first));
uint64_t integer;
RawBuffer buffer;
- if (CKM_API_SUCCESS == it.second->getInt(integer))
+ if (it.second->getInt(integer))
Serializer<uint64_t>::Serialize(stream, integer);
- else if (CKM_API_SUCCESS == it.second->getBuffer(buffer))
+ else if (it.second->getBuffer(buffer))
Serializer<RawBuffer>::Serialize(stream, buffer);
else
ThrowMsg(UnsupportedParam, "Unsupported param type");
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<int>(name));
+ BOOST_REQUIRE_MESSAGE(
+ integer == expected,
+ "Parameter " << static_cast<int>(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<int>(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<int>(name));
+ BOOST_REQUIRE_MESSAGE(buffer == expected,
+ "Parameter " << static_cast<int>(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<int>(name) << " should fail");
+}
+
+template <typename T>
+void addParam(CryptoAlgorithm& algo, ParamName name, const T& value, bool success)
+{
+ BOOST_REQUIRE_MESSAGE(success == algo.addParam(name, value),
+ "Adding param " << static_cast<int>(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<uint64_t>(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;
resp.Push(buffer);
resp.Deserialize(output);
- BOOST_REQUIRE_MESSAGE(input.m_type == output.m_type,
- "Algorithm types don't match: " << static_cast<int>(input.m_type) << "!="
- << static_cast<int>(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<int>(iit->first) << "!="
- << static_cast<int>(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<uint64_t>(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<ParamName>(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<ParamName>(666), IntParam::create(666));
+ addParam(ca, static_cast<ParamName>(666), 666, true);
CryptoAlgorithmSerializable input(std::move(ca));
CryptoAlgorithmSerializable output;