E2EE: OCF API implementation
[platform/core/test/security-tests.git] / src / e2ee-adaptation-layer / e2ee-adaptation-layer.cpp
index 73d068e..3e86ae0 100644 (file)
 #include "e2ee-adaptation-layer.h"
 
 #include <cstring>
+#include <cstdlib>
+
 #include <memory>
 
 #include <openssl/evp.h>
 
 #include <ckmc/ckmc-manager.h>
+#include <device_certificate_manager.h>
 
 namespace {
 
@@ -31,6 +34,10 @@ const char* const SECRET_ALIAS = "temporary_shared_e2ee_secret";
 constexpr size_t ITERATIONS = 1000;
 
 typedef std::unique_ptr<struct __ckmc_param_list, decltype(&ckmc_param_list_free)> ParamsPtr;
+typedef std::unique_ptr<void, decltype(&dcm_free_key_context)> DcmCtxPtr;
+typedef std::unique_ptr<ckmc_raw_buffer_s, decltype(&ckmc_buffer_free)> BufferPtr;
+typedef std::unique_ptr<ckmc_key_s, decltype(&ckmc_key_free)> KeyPtr;
+typedef std::unique_ptr<dcm_e2ee_bundle_s, decltype(&dcm_e2ee_free_bundle)> BundlePtr;
 
 std::tuple<ParamsPtr, int> makeParams()
 {
@@ -39,8 +46,6 @@ std::tuple<ParamsPtr, int> makeParams()
     return std::make_tuple(ParamsPtr(params, ckmc_param_list_free), ret);
 }
 
-typedef std::unique_ptr<ckmc_raw_buffer_s, decltype(&ckmc_buffer_free)> BufferPtr;
-
 std::tuple<BufferPtr, int> makeBuffer(const unsigned char* data, size_t size)
 {
     ckmc_raw_buffer_s* buffer = nullptr;
@@ -60,6 +65,13 @@ private:
     const char* alias;
 };
 
+std::tuple<DcmCtxPtr, int> getOcfContext()
+{
+    void* ocf_ctx = nullptr;
+    int ret = dcm_create_key_context(nullptr, nullptr, "ECDSA", &ocf_ctx);
+    return std::make_tuple(DcmCtxPtr(ocf_ctx, dcm_free_key_context), ret);
+}
+
 } // anonymous namespace
 
 int ckmew_key_agreement(const char *private_key_alias,
@@ -188,16 +200,65 @@ int ckmew_key_derive_pbkdf2(const char *password,
     return ret;
 }
 
-int ckmew_get_ocf_cert_chain(char ** /*cert_chain*/, size_t * /*cert_chain_len*/)
+int ckmew_get_ocf_cert_chain(char **cert_chain, size_t *cert_chain_len)
 {
-    // TODO
-    return 0;
+    auto [ocf, ret] = getOcfContext();
+    if (ret != DCM_ERROR_NONE)
+        return ret;
+
+    return dcm_get_certificate_chain(ocf.get(), cert_chain, cert_chain_len);
 }
 
-int ckmew_sign_with_ocf(const char * /*public_key_alias*/,
-                        ckmc_raw_buffer_s** /*message_buf*/,
-                        ckmc_raw_buffer_s** /*signature_buf*/)
+int ckmew_sign_with_ocf(const char *public_key_alias,
+                        ckmc_raw_buffer_s **message_buf,
+                        ckmc_raw_buffer_s **signature_buf)
 {
-    // TODO
-    return 0;
+    if (public_key_alias == nullptr || message_buf == nullptr || signature_buf == nullptr)
+        return DCM_ERROR_INVALID_PARAMETER;
+
+    // get ocf context
+    auto [ocf, ret] = getOcfContext();
+    if (ret != DCM_ERROR_NONE)
+        return ret;
+
+    // get device public key
+    ckmc_key_s* device_pub_key = nullptr;
+    ret = ckmc_get_key(public_key_alias, nullptr, &device_pub_key);
+    if (ret != CKMC_ERROR_NONE)
+        return ret; // This is a CKM error!
+
+    KeyPtr device_pub_key_ptr(device_pub_key, ckmc_key_free);
+
+    // pack & sign device public key
+    dcm_e2ee_bundle_h bundle = nullptr;
+    unsigned char* signature = nullptr;
+    size_t signature_len = 0;
+    ret = dcm_e2ee_create_signed_bundle(ocf.get(),
+                                        DCM_DIGEST_SHA256,
+                                        device_pub_key->raw_key,
+                                        device_pub_key->key_size,
+                                        &bundle,
+                                        reinterpret_cast<char**>(&signature),
+                                        &signature_len);
+    if (ret != DCM_ERROR_NONE)
+        return ret;
+
+    BundlePtr bundle_ptr(bundle, dcm_e2ee_free_bundle);
+    auto [signature_ptr, ret2] = makeBuffer(signature, signature_len);
+    if (ret2 != CKMC_ERROR_NONE)
+        return ret2; // This is a CKM error!
+
+    const unsigned char* message = nullptr;
+    size_t message_len = 0;
+    ret = dcm_e2ee_get_bundle_message(bundle, &message, &message_len);
+    if (ret != DCM_ERROR_NONE)
+        return ret;
+
+    ret = ckmc_buffer_new(const_cast<unsigned char*>(message), message_len, message_buf);
+    if (ret != CKMC_ERROR_NONE)
+        return ret; // This is a CKM error!
+
+    *signature_buf = signature_ptr.release();
+
+    return DCM_ERROR_NONE;
 }