Simplify CryptoAlgorithm interface 01/39501/4
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 15 May 2015 17:40:29 +0000 (19:40 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Tue, 19 May 2015 08:27:06 +0000 (01:27 -0700)
[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

src/include/ckm/ckm-type.h
src/manager/common/algo-param.cpp
src/manager/common/protocols.cpp
tests/test_serialization.cpp

index 95233d8..9d93421 100644 (file)
@@ -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 <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
 
index e0a72c9..7585d96 100644 (file)
  */
 
 #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
index 92c24b0..7bd6eac 100644 (file)
@@ -119,9 +119,7 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(CryptoAlgorithm &&algo)
 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;
@@ -135,9 +133,10 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream)
         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:
@@ -145,7 +144,7 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream)
         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:
@@ -157,14 +156,14 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream)
 
 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");
index 6181102..4c6e5b5 100644 (file)
@@ -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<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;
@@ -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<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;