#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 {
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()
{
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;
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,
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;
}