BuildRequires: pkgconfig(cynara-client)
BuildRequires: pkgconfig(cynara-creds-socket)
BuildRequires: pkgconfig(cynara-session)
-BuildRequires: pkgconfig(openssl1.1)
BuildRequires: pkgconfig(capi-system-info)
BuildRequires: boost-devel
%if "%{build_type}" == "COVERAGE"
device_certificate_manager.cpp
../shared/protobuf_asio.cpp
../shared/log.cpp
- ../shared/bundle.cpp
${PROTO_SRCS}
${PROTO_HDRS})
return DCM_ERROR_NONE;
}
-int dcm_client_connection::e2ee_sign_data(
- dcm_digest_algorithm_e md,
- const void* payload, size_t payload_size,
- std::vector<uint8_t>& signed_message,
- std::vector<uint8_t>& digest) noexcept
-{
- std::lock_guard<std::mutex> locker(fLock);
-
- if(!fCookie) {
- LOGE("Trying to request E2EE data signing in object %p but there is no connection", this);
- return DCM_ERROR_SOCKET;
- }
-
- try {
- RequestMessage request;
- ResponseMessage response;
-
- auto* sign_req = request.mutable_e2ee_sign_data();
- sign_req->set_context_cookie(fCookie);
- sign_req->set_data_to_sign(payload, payload_size);
- sign_req->set_digest_type(static_cast<MessageDigestType>(md));
-
- send_receive(request, response);
- if(!response.has_sign_data()) {
- LOGE("Response for E2EE signature has no signature data");
- return DCM_ERROR_NO_DATA;
- }
-
- auto& sign_resp(response.sign_data());
- if(sign_resp.result() != 0) {
- LOGE("E2EE signature request for session %p received error %d", this, sign_resp.result());
- return DCM_ERROR_INVALID_PARAMETER;
- }
-
- const auto& signature = sign_resp.signature();
- if(signature.empty()) {
- LOGE("Received E2EE signature object is empty for session %p", this);
- return DCM_ERROR_NO_DATA;
- }
-
- digest.resize(signature.size());
- memcpy(&digest[0], signature.c_str(), signature.size());
-
- const auto& message = sign_resp.message();
- if(message.empty()) {
- LOGE("Received E2EE message object is empty for session %p", this);
- return DCM_ERROR_NO_DATA;
- }
- signed_message.resize(message.size());
- memcpy(&signed_message[0], message.c_str(), message.size());
- } catch(std::bad_alloc&) {
- LOGE("Out of memory when processing E2EE sign request for session %p", this);
- return DCM_ERROR_OUT_OF_MEMORY;
- } catch(...) {
- LOGE("When processing E2EE signature for session %p got exception : %s", this, "Unknown error");
- return DCM_ERROR_UNKNOWN;
- }
-
- return DCM_ERROR_NONE;
-}
-
void dcm_client_connection::send_receive(RequestMessage& request, ResponseMessage& response)
{
protobuf_sync_message_serialization(*fSocket).encodeMessage(request);
const void* hash_data, size_t hash_size,
std::vector<uint8_t>& digest) noexcept;
- int e2ee_sign_data(
- dcm_digest_algorithm_e md,
- const void* hash_data, size_t hash_size,
- std::vector<uint8_t>& message,
- std::vector<uint8_t>& digest) noexcept;
-
private:
void send_receive(RequestMessage& request, ResponseMessage& response);
{
required int32 result = 1;
optional bytes signature = 2;
- optional bytes message = 3;
}
message ExtCallRequest
RequestCertificateChain request_chain = 2;
SignRequest sign_data = 3;
ExtCallRequest ext_call = 4;
- SignRequest e2ee_sign_data = 5;
}
}
RequestCertificateChainResponse request_chain = 2;
SignResponse sign_data = 3;
ExtCallResponse ext_call = 4;
-
}
}
#include <vector>
#include <cstring>
-#include <cstdlib>
-#include <cassert>
#include <mutex>
#include <system_info.h>
#include "device_certificate_manager.h"
#include "dcm_client.h"
#include "log.h"
-#include "bundle.h"
#ifndef API_DEVICE_CERTIFICATE_MANAGER_EXPORT
#define API_DEVICE_CERTIFICATE_MANAGER_EXPORT __attribute__((visibility("default")))
return result;
}
-
-/**
- * @brief Struct containing E2EE message bundle. Message = platform | pkg_id | payload.
- * @remarks The platform and pkg_id are NULL terminated strings. The payload is a sequence of bytes.
- * @since_tizen 6.5
- */
-struct dcm_e2ee_bundle_s {
- unsigned char *message; /**< Byte array containing whole message */
- size_t message_len; /**< The size of the message */
- size_t pkg_id_offset; /**< Package id offset */
- size_t payload_offset; /**< Payload offset */
-};
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_e2ee_create_bundle(unsigned char *message,
- size_t message_len,
- dcm_e2ee_bundle_h* bundle)
-{
- CHECK_FEATURE_SUPPORTED;
-
- if (message == NULL || bundle == NULL)
- return DCM_ERROR_INVALID_PARAMETER;
-
- struct dcm_e2ee_bundle_s *tmp = static_cast<struct dcm_e2ee_bundle_s*>(
- malloc(sizeof(struct dcm_e2ee_bundle_s)));
-
- if (tmp == NULL)
- return DCM_ERROR_OUT_OF_MEMORY;
-
- int ret = decompose_e2ee_message(message, message_len, tmp->pkg_id_offset, tmp->payload_offset);
- if (ret != DCM_ERROR_NONE) {
- free(tmp);
- return ret;
- }
-
- tmp->message_len = message_len;
- tmp->message = message;
-
- *bundle = tmp;
- return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-void dcm_e2ee_free_bundle(dcm_e2ee_bundle_h bundle)
-{
- if (bundle == NULL)
- return;
-
- free(bundle->message);
- free(bundle);
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_e2ee_get_bundle_message(const dcm_e2ee_bundle_h bundle,
- const unsigned char** message,
- size_t* message_len)
-{
- CHECK_FEATURE_SUPPORTED;
-
- if (bundle == NULL || message == NULL || message_len == NULL)
- return DCM_ERROR_INVALID_PARAMETER;
-
- assert(bundle->message != NULL);
-
- *message = bundle->message;
- *message_len = bundle->message_len;
- return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_e2ee_get_bundle_platform(const dcm_e2ee_bundle_h bundle, const char** platform)
-{
- CHECK_FEATURE_SUPPORTED;
-
- if (bundle == NULL || platform == NULL)
- return DCM_ERROR_INVALID_PARAMETER;
-
- assert(bundle->message != NULL);
-
- *platform = reinterpret_cast<const char*>(bundle->message);
- return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_e2ee_get_bundle_pkg_id(const dcm_e2ee_bundle_h bundle, const char** pkg_id)
-{
- CHECK_FEATURE_SUPPORTED;
-
- if (bundle == NULL || pkg_id == NULL)
- return DCM_ERROR_INVALID_PARAMETER;
-
- assert(bundle->message != NULL);
-
- *pkg_id = reinterpret_cast<const char*>(&bundle->message[bundle->pkg_id_offset]);
- return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_e2ee_get_bundle_payload(const dcm_e2ee_bundle_h bundle,
- const unsigned char** payload,
- size_t* payload_len)
-{
- CHECK_FEATURE_SUPPORTED;
-
- if (bundle == NULL || payload == NULL || payload_len == NULL)
- return DCM_ERROR_INVALID_PARAMETER;
-
- assert(bundle->message != NULL);
-
- *payload = &bundle->message[bundle->payload_offset];
- *payload_len = bundle->message_len - bundle->payload_offset;
- return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_e2ee_create_signed_bundle(const void *key_ctx,
- dcm_digest_algorithm_e md,
- const unsigned char *payload,
- size_t payload_len,
- dcm_e2ee_bundle_h *bundle,
- char **signature,
- size_t *signature_len)
-{
- CHECK_FEATURE_SUPPORTED;
-
- if (key_ctx == NULL || payload == NULL || bundle == NULL || signature == NULL ||
- signature_len == NULL)
- return DCM_ERROR_INVALID_PARAMETER;
-
- const dcm_key_context_internal *context =
- reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
-
- std::vector<uint8_t> digest;
- std::vector<uint8_t> message;
- int result = context->connection->e2ee_sign_data(md, payload, payload_len, message, digest);
- if(result == DCM_ERROR_NONE) {
- *signature = static_cast<char*>(malloc(sizeof(uint8_t) * digest.size()));
- if(*signature == NULL)
- return DCM_ERROR_OUT_OF_MEMORY;
- memcpy(*signature, digest.data(), digest.size());
- *signature_len = digest.size();
-
- auto message_dup = static_cast<unsigned char*>(malloc(sizeof(uint8_t)*message.size()));
- if(message_dup == NULL) {
- free(signature);
- return DCM_ERROR_OUT_OF_MEMORY;
- }
- memcpy(message_dup, message.data(), message.size());
-
- result = dcm_e2ee_create_bundle(message_dup, message.size(), bundle);
- assert(result == DCM_ERROR_NONE);
- }
-
- return result;
-}
local:
*;
};
-
-DCMCLIENT_2.1 {
- global:
- dcm_e2ee_create_bundle;
- dcm_e2ee_free_bundle;
- dcm_e2ee_get_bundle_message;
- dcm_e2ee_get_bundle_platform;
- dcm_e2ee_get_bundle_pkg_id;
- dcm_e2ee_get_bundle_payload;
- dcm_e2ee_create_signed_bundle;
-} DCMCLIENT_2.0;
PKG_CHECK_MODULES(DAEMON_DEPS
REQUIRED
libsystemd
- openssl1.1
cynara-client
cynara-creds-socket
cynara-session
dcm_session.cpp
../shared/protobuf_asio.cpp
../shared/log.cpp
- ../shared/bundle.cpp
soresolver.cpp
${PROTO_SRCS}
${PROTO_HDRS})
#include <iostream>
#include <cassert>
-#include <openssl/evp.h>
#include <cynara-client.h>
#include <cynara-creds-socket.h>
#include "device_certificate_manager_ext_types.h"
#include "device_certificate_manager.h"
#include "log.h"
-#include "bundle.h"
-
-namespace {
-const EVP_MD* get_md(MessageDigestType digest_type)
-{
- switch(digest_type) {
- case MD_MD2:
- return EVP_md2();
- case MD_MD4:
- return EVP_md4();
- case MD_MD5:
- return EVP_md5();
- case MD_SHA1:
- return EVP_sha1();
- case MD_SHA224:
- return EVP_sha224();
- case MD_SHA256:
- return EVP_sha256();
- case MD_SHA384:
- return EVP_sha384();
- case MD_SHA512:
- return EVP_sha512();
- case MD_RIPEMD160:
- return EVP_ripemd160();
- default:
- LOGE("Unknown message digest type: " << static_cast<unsigned>(digest_type));
- return nullptr;
- }
-}
-
-std::string digest_message(const std::string& message, MessageDigestType digest_type)
-{
- if (digest_type == MD_NONE)
- return message;
-
- EVP_MD_CTX* mdctx = nullptr;
- if((mdctx = EVP_MD_CTX_new()) == nullptr)
- return std::string();
-
- std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> mdctxPtr(mdctx, EVP_MD_CTX_free);
-
- auto md = get_md(digest_type);
- if (md == nullptr)
- return std::string();
-
- if(1 != EVP_DigestInit_ex(mdctx, md, nullptr))
- return std::string();
-
- if(1 != EVP_DigestUpdate(
- mdctx,
- reinterpret_cast<const unsigned char*>(message.c_str()),
- message.size()))
- return std::string();
-
- std::string digest(EVP_MD_size(md), '\0');
- unsigned digest_size;
- if(1 != EVP_DigestFinal_ex(
- mdctx,
- reinterpret_cast<unsigned char*>(digest.data()),
- &digest_size))
- return std::string();
-
- digest.resize(digest_size);
- return digest;
-}
-} // namespace
#define DCM_DEFAULT_PRIVILEGE "http://tizen.org/privilege/devicecertificate"
case RequestMessage::kExtCall:
handle_ext_call_request(requestMessage.ext_call());
break;
- case RequestMessage::kE2EeSignData:
- handle_e2ee_sign_request(requestMessage.e2ee_sign_data());
- break;
default:
LOGE("Incorrect request message type");
// This will terminate connection
reply(msg);
}
-void dcm_session::handle_e2ee_sign_request(const SignRequest& message)
-{
- LOGD("Request E2EE data signing");
-
- if(!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
- LOGE("Client privilege check failure. Disconnect");
- return;
- }
-
- int ret;
- ResponseMessage msg;
- auto* signingResponse = msg.mutable_sign_data();
-
- if (!sign_request_check(message)) {
- ret = -EINVAL;
- } else {
- std::unique_ptr<char, string_free_deleter> client;
- char* tmp_str = nullptr;
- ret = cynara_creds_socket_get_client(
- fSocket.native_handle(), CLIENT_METHOD_DEFAULT, &tmp_str);
- assert(ret == CYNARA_API_SUCCESS); // it was checked in verify_privileges already
- client.reset(tmp_str);
-
- std::string composed = compose_e2ee_message(client.get(), message.data_to_sign());
- auto digest = digest_message(composed, message.digest_type());
- if (digest.empty()) {
- LOGE("Digest calculation failed");
- ret = -EINVAL; // TODO validate digest algorithms and return proper error to client
- } else {
- ret = sign(message.digest_type(), digest, *signingResponse->mutable_signature());
- if (ret != 0)
- LOGE("Signing failed");
- signingResponse->set_message(composed);
- }
- }
- signingResponse->set_result(ret);
- reply(msg);
-}
-
void dcm_session::handle_ext_call_request(const ExtCallRequest& message)
{
LOGD("Request EXT API call from backend");
void handle_context_association(const AssociateKeyContext& message);
void handle_cert_chain(const RequestCertificateChain& message);
void handle_sign_request(const SignRequest& message);
- void handle_e2ee_sign_request(const SignRequest& message);
void handle_ext_call_request(const ExtCallRequest& message);
int sign(MessageDigestType digest_type, const std::string& message, std::string& signature);
DCM_ERROR_UNKNOWN = TIZEN_ERROR_UNKNOWN, /**< Unknown error */
DCM_ERROR_SOCKET = TIZEN_ERROR_DEVICE_CERTIFICATE_MANAGER | 0x01, /**< Socket error between client and server */
- DCM_ERROR_MSG_FORMAT = TIZEN_ERROR_DEVICE_CERTIFICATE_MANAGER | 0x02, /**< Message is not in Tizen platform format (Since 6.5) */
} dcm_error_e;
const char *message, size_t message_len,
char **signature, size_t *signature_len);
-/**
- * @brief Handle to a struct containing E2EE message bundle.
- * @since_tizen 6.5
- */
-typedef struct dcm_e2ee_bundle_s* dcm_e2ee_bundle_h;
-
-/**
- * @brief Creates an E2EE message bundle from a binary message.
- * @since_tizen 6.5
- *
- * @param[in] message The binary message. Usually received from another E2EE peer. The @a message
- * must be allocated with malloc(). The bundle takes the ownership of the
- * @a message and will free it automatically using free().
- * @param[in] message_len Length of the @a message
- * @param[out] bundle Bundle allowing deserialization of the E2EE message. Must be freed with
- * dcm_e2ee_free_bundle() when no longer needed.
- *
- * @return #DCM_ERROR_NONE on success, otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid (message = NULL or bundle = NULL)
- * or the message format is invalid.
- * @retval #DCM_ERROR_MSG_FORMAT The message is not in Tizen platform format.
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_e2ee_free_bundle()
- * @see #dcm_e2ee_bundle_h
- */
-int dcm_e2ee_create_bundle(unsigned char *message, size_t message_len, dcm_e2ee_bundle_h* bundle);
-
-/**
- * @brief Releases the memory associated with E2EE message bundle.
- * @since_tizen 6.5
- *
- * @remarks It will free the underlying binary message.
- *
- * @param[in] bundle Bundle to be freed
- *
- * @see dcm_e2ee_create_bundle()
- * @see #dcm_e2ee_bundle_h
- */
-void dcm_e2ee_free_bundle(dcm_e2ee_bundle_h bundle);
-
-/**
- * @brief Retrieves a pointer to the whole binary message contained in the E2EE bundle.
- * @since_tizen 6.5
- *
- * @remarks The typical use is to retrieve the message from a bundle created and signed with
- * dcm_e2ee_create_signed_bundle()
- *
- * @param[in] bundle The bundle to retrieve from
- * @param[out] message The pointer to the binary message contained in the @a bundle. The pointer
- * must not be freed. The pointer becomes invalid after the @a bundle is freed
- * @param[out] message_len The length of the @a message
- *
- * @return #DCM_ERROR_NONE on success, otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_INVALID_PARAMETER @a bundle, @a message or @a message_len is NULL.
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_e2ee_create_signed_bundle()
- * @see dcm_e2ee_free_bundle()
- * @see #dcm_e2ee_bundle_h
- */
-int dcm_e2ee_get_bundle_message(const dcm_e2ee_bundle_h bundle,
- const unsigned char** message,
- size_t* message_len);
-
-/**
- * @brief Retrieves a pointer to the platform string contained in the E2EE bundle.
- * @since_tizen 6.5
- *
- * @remarks The typical use is to retrieve the platform string from a bundle created with
- * dcm_e2ee_create_bundle() from received binary message.
- *
- * @param[in] bundle The bundle to retrieve from
- * @param[out] platform The pointer to the platform string contained in the @a bundle. The pointer
- * must not be freed. The pointer becomes invalid after the @a bundle is freed
- *
- * @return #DCM_ERROR_NONE on success, otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_INVALID_PARAMETER @a bundle or @a platform is NULL.
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_e2ee_create_bundle()
- * @see dcm_e2ee_free_bundle()
- * @see #dcm_e2ee_bundle_h
- */
-int dcm_e2ee_get_bundle_platform(const dcm_e2ee_bundle_h bundle, const char** platform);
-
-/**
- * @brief Retrieves a pointer to the package id string contained in the E2EE bundle.
- * @since_tizen 6.5
- *
- * @remarks The typical use is to retrieve the package id from a bundle created with
- * dcm_e2ee_create_bundle() from received binary message.
- *
- * @param[in] bundle The bundle to retrieve from
- * @param[out] pkg_id The pointer to the package id string contained in the @a bundle. The pointer
- * must not be freed. The pointer becomes invalid after the @a bundle is freed
- *
- * @return #DCM_ERROR_NONE on success, otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_INVALID_PARAMETER @a bundle or @a pkg_id is NULL.
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_e2ee_create_bundle()
- * @see dcm_e2ee_free_bundle()
- * @see #dcm_e2ee_bundle_h
- */
-int dcm_e2ee_get_bundle_pkg_id(const dcm_e2ee_bundle_h bundle, const char** pkg_id);
-
-/**
- * @brief Retrieves a pointer to the payload byte sequence contained in the E2EE bundle.
- * @since_tizen 6.5
- *
- * @remarks The typical use is to retrieve the binary payload from a bundle created with
- * dcm_e2ee_create_bundle() from received binary message.
- *
- * @param[in] bundle The bundle to retrieve from
- * @param[out] payload The pointer to the payload byte sequence contained in the @a bundle. The
- * pointer must not be freed. The pointer becomes invalid after the @a bundle
- * is freed
- * @param[out] payload_len The length of the @a payload
- *
- * @return #DCM_ERROR_NONE on success, otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_INVALID_PARAMETER @a bundle, @a payload or @a payload_len is NULL.
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_e2ee_create_bundle()
- * @see dcm_e2ee_free_bundle()
- * @see #dcm_e2ee_bundle_h
- */
-int dcm_e2ee_get_bundle_payload(const dcm_e2ee_bundle_h bundle,
- const unsigned char** payload,
- size_t* payload_len);
-
-/**
- * @platform
- * @brief Creates an E2EE message bundle from a payload and signs it using given private key.
- * @since_tizen 6.5
- * @privlevel platform
- * @privilege %http://tizen.org/privilege/devicecertificate
- *
- * @remarks The private key is identified by @a key_ctx.
- * @remarks The @a payload can be NULL but then @a payload_len must be 0.
- * @remarks The @a signature should be freed using free().
- *
- * @param[in] key_ctx Key context object that identifies a proper private key for signing
- * @param[in] md Message digest algorithm used in creating signature
- * @param[in] payload Byte sequence used to construct the E2EE message that will be signed
- * @param[in] payload_len Length of the @a payload
- * @param[out] bundle Newly created bundle containing the signed E2EE message. Must be freed with
- * dcm_e2ee_free_bundle() when no longer needed
- * @param[out] signature Newly created signature, will be allocated by the library. Must be freed
- * using free() when no longer needed
- * @param[out] signature_len Length of a newly created @a signature
- *
- * @return #DCM_ERROR_NONE on success,
- * otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid (@a key_ctx = NULL, @a payload =
- * NULL but @a payload_len > 0, @a bundle = NULL, @a signature
- * = NULL or @a signature_len = NULL)
- * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
- * @retval #DCM_ERROR_SOCKET Socket error between client and server
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_e2ee_free_bundle()
- * @see #dcm_e2ee_bundle_h
- */
-int dcm_e2ee_create_signed_bundle(const void *key_ctx,
- dcm_digest_algorithm_e md,
- const unsigned char *payload,
- size_t payload_len,
- dcm_e2ee_bundle_h* bundle,
- char **signature,
- size_t *signature_len);
-
/**
* @}
*/
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2023 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-#include <cerrno>
-#include <cassert>
-#include <cstring>
-
-#include "bundle.h"
-#include "device_certificate_manager.h"
-
-namespace {
-constexpr char PLATFORM[] = "Tizen";
-}
-
-std::string compose_e2ee_message(const char* pkg_id, const std::string& payload)
-{
- assert(pkg_id);
-
- size_t platform_len = strlen(PLATFORM) + 1;
- size_t pkg_id_len = strlen(pkg_id) + 1;
- size_t size = platform_len + pkg_id_len + payload.size();
-
- std::string message(size, ' ');
-
- auto tmp = message.data();
-
- memcpy(tmp, PLATFORM, platform_len);
- tmp += platform_len;
- memcpy(tmp, pkg_id, pkg_id_len);
- tmp += pkg_id_len;
- memcpy(tmp, payload.c_str(), payload.size());
-
- return message;
-}
-
-int decompose_e2ee_message(
- const unsigned char* message,
- size_t message_len,
- size_t& pkg_id_offset,
- size_t& payload_offset)
-{
- if (message == NULL)
- return DCM_ERROR_INVALID_PARAMETER;
-
- const char* message_str = reinterpret_cast<const char*>(message);
- pkg_id_offset = strnlen(message_str, message_len);
- if (pkg_id_offset == message_len)
- return DCM_ERROR_INVALID_PARAMETER; // wrong format
-
- if (strcmp(message_str, PLATFORM) != 0)
- return DCM_ERROR_MSG_FORMAT; // not a Tizen bundle
-
- pkg_id_offset++; // skip \0
- message_str += pkg_id_offset;
- message_len -= pkg_id_offset;
-
- payload_offset = strnlen(message_str, message_len);
- if (payload_offset == message_len)
- return DCM_ERROR_INVALID_PARAMETER; // wrong format
-
- payload_offset += pkg_id_offset; // skip pkg_id
- payload_offset++; // skip \0
-
- return DCM_ERROR_NONE;
-}
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2023 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-#pragma once
-
-#include <cstddef>
-#include <string>
-
-std::string compose_e2ee_message(const char* pkg_id, const std::string& payload);
-int decompose_e2ee_message(
- const unsigned char* message,
- size_t message_len,
- size_t& pkg_id_offset,
- size_t& payload_offset);
../src/dcm-client/device_certificate_manager_ext.cpp
../src/shared/log.cpp
../src/shared/protobuf_asio.cpp
- ../src/shared/bundle.cpp
${PROTO_SRCS}
${PROTO_HDRS})
#include <boost/algorithm/hex.hpp>
#include <cstring>
-#include <memory>
#include <iomanip>
#include <iostream>
#include <sys/smack.h> // SMACK_LABEL_LEN
}
};
-template <typename F, typename... Args>
-void assert_result(int expected, F&& func, Args... args)
-{
- BOOST_REQUIRE_EQUAL(func(args...), expected);
-}
-
-template <typename F, typename... Args>
-void assert_positive(F&& func, Args... args)
-{
- assert_result(DCM_ERROR_NONE, std::move(func), args...);
-}
-
-template <typename F, typename... Args>
-void assert_invalid_param(F&& func, Args... args)
-{
- assert_result(DCM_ERROR_INVALID_PARAMETER, std::move(func), args...);
-}
-
-template <size_t N>
-std::pair<unsigned char*, size_t> makeMessage(const char* platform,
- const char* pkgId,
- const unsigned char (&payload)[N])
-{
- const size_t platformSize = strlen(platform) + 1;
- const size_t pkgIdSize = strlen(pkgId) + 1;
- const size_t size = platformSize + pkgIdSize + N;
-
- unsigned char* message = static_cast<unsigned char*>(malloc(size));
- BOOST_REQUIRE(message != nullptr);
-
- memcpy(message, platform, platformSize);
- memcpy(message + platformSize, pkgId, pkgIdSize);
- memcpy(message + platformSize + pkgIdSize, payload, N);
- return std::make_pair(message, size);
-}
-
-template <typename T, void (*Fn)(T*)>
-struct Free {
- explicit Free(T* ptr) : ptr(ptr) {}
- ~Free() {
- Fn(ptr);
- }
- Free(const Free&) = delete;
- Free& operator=(const Free&) = delete;
- T* operator*() { return ptr; }
-private:
- T* ptr;
-};
-
-void freeKey(void* ptr)
-{
- dcm_free_key_context(ptr);
-}
-
-typedef Free<dcm_e2ee_bundle_s, dcm_e2ee_free_bundle> FreeBundle;
-typedef Free<void, freeKey> FreeKey;
-typedef std::unique_ptr<unsigned char, decltype(&free)> BytesPtr;
-typedef std::unique_ptr<char, decltype(&free)> CharPtr;
-
} // namespace
BOOST_AUTO_TEST_SUITE(API_TEST)
nullptr, nullptr, nullptr, &ctx) == DCM_ERROR_UNKNOWN);
}
-POSITIVE_TEST_CASE(test20_dcm_e2ee_bundle_api) {
- BOOST_REQUIRE_NO_THROW(dcm_e2ee_free_bundle(NULL));
-
- unsigned char payload[] = {1,2,3,4};
- auto [msg, size] = makeMessage("Tizen", "User::Pkg::test", payload);
-
- dcm_e2ee_bundle_h bundle;
- assert_positive(dcm_e2ee_create_bundle, msg, size, &bundle);
- FreeBundle freeBundle(bundle);
-
- const unsigned char* cMsg;
- size_t cMsgSize;
- assert_positive(dcm_e2ee_get_bundle_message, bundle, &cMsg, &cMsgSize);
- BOOST_REQUIRE_EQUAL(cMsgSize, size);
- BOOST_REQUIRE_EQUAL(memcmp(msg, cMsg, cMsgSize), 0);
-
- const char* cPlatform;
- assert_positive(dcm_e2ee_get_bundle_platform, bundle, &cPlatform);
- BOOST_REQUIRE_EQUAL(strcmp(cPlatform, "Tizen"), 0);
-
- const char* cPkgId;
- assert_positive(dcm_e2ee_get_bundle_pkg_id, bundle, &cPkgId);
- BOOST_REQUIRE_EQUAL(strcmp(cPkgId, "User::Pkg::test"), 0);
-
- const unsigned char* cPayload;
- size_t cPayloadSize;
- assert_positive(dcm_e2ee_get_bundle_payload, bundle, &cPayload, &cPayloadSize);
- BOOST_REQUIRE_EQUAL(cPayloadSize, sizeof(payload));
- BOOST_REQUIRE_EQUAL(memcmp(payload, cPayload, cPayloadSize), 0);
-}
-
-NEGATIVE_TEST_CASE(test21_dcm_e2ee_bundle_api) {
- unsigned char payload[] = {1,2,3,4};
- unsigned char payload2[] = {'T', 'i', 'z', 'e', 'n', 0, 1, 2, 3, 4};
- auto [msg, size] = makeMessage("Tizen", "User::Pkg::test", payload);
- auto [msg2, size2] = makeMessage("Tauzen", "User::Pkg::test", payload);
- BytesPtr msgPtr(msg, free);
- BytesPtr msg2Ptr(msg2, free);
-
- dcm_e2ee_bundle_h bundle;
-
- assert_invalid_param(dcm_e2ee_create_bundle, nullptr, size, &bundle);
- assert_invalid_param(dcm_e2ee_create_bundle, msg, size, nullptr);
- assert_invalid_param(dcm_e2ee_create_bundle, payload, sizeof(payload), &bundle);
- assert_invalid_param(dcm_e2ee_create_bundle, payload2, sizeof(payload2), &bundle);
-
- BOOST_REQUIRE_EQUAL(dcm_e2ee_create_bundle(msg2, size2, &bundle), DCM_ERROR_MSG_FORMAT);
-
- assert_positive(dcm_e2ee_create_bundle, msg, size, &bundle);
- msgPtr.release();
- FreeBundle freeBundle(bundle);
-
- const unsigned char* cMsg;
- size_t cMsgSize;
- assert_invalid_param(dcm_e2ee_get_bundle_message, nullptr, &cMsg, &cMsgSize);
- assert_invalid_param(dcm_e2ee_get_bundle_message, bundle, nullptr, &cMsgSize);
- assert_invalid_param(dcm_e2ee_get_bundle_message, bundle, &cMsg, nullptr);
-
- const char* cPlatform;
- assert_invalid_param(dcm_e2ee_get_bundle_platform, nullptr, &cPlatform);
- assert_invalid_param(dcm_e2ee_get_bundle_platform, bundle, nullptr);
-
- const char* cPkgId;
- assert_invalid_param(dcm_e2ee_get_bundle_pkg_id, nullptr, &cPkgId);
- assert_invalid_param(dcm_e2ee_get_bundle_pkg_id, bundle, nullptr);
-
- const unsigned char* cPayload;
- size_t cPayloadSize;
- assert_invalid_param(dcm_e2ee_get_bundle_payload, nullptr, &cPayload, &cPayloadSize);
- assert_invalid_param(dcm_e2ee_get_bundle_payload, bundle, nullptr, &cPayloadSize);
- assert_invalid_param(dcm_e2ee_get_bundle_payload, bundle, &cPayload, nullptr);
-}
-
-POSITIVE_TEST_CASE(test22_dcm_e2ee_sign_api) {
- unsigned char payload[] = {1,2,3,4};
- void* ocfCtx = nullptr;
-
- assert_positive(dcm_create_key_context, nullptr, nullptr, "ECDSA", &ocfCtx);
- FreeKey freeOcfCtx(ocfCtx);
-
- dcm_e2ee_bundle_h bundle = nullptr;
- char* sig = nullptr;
- size_t sigSize;
- assert_positive(dcm_e2ee_create_signed_bundle,
- ocfCtx,
- DCM_DIGEST_SHA256,
- payload,
- sizeof(payload),
- &bundle,
- &sig,
- &sigSize);
- FreeBundle freeBundle(bundle);
- CharPtr signaturePtr(sig, free);
- BOOST_REQUIRE(sig != nullptr);
- BOOST_REQUIRE(sigSize > 0);
- BOOST_REQUIRE(bundle != nullptr);
-
- const unsigned char* cMsg;
- size_t cMsgSize;
- const char* cPlatform;
- const char* cPkgId;
- const unsigned char* cPayload;
- size_t cPayloadSize;
- assert_positive(dcm_e2ee_get_bundle_message, bundle, &cMsg, &cMsgSize);
- assert_positive(dcm_e2ee_get_bundle_platform, bundle, &cPlatform);
- assert_positive(dcm_e2ee_get_bundle_pkg_id, bundle, &cPkgId);
- assert_positive(dcm_e2ee_get_bundle_payload, bundle, &cPayload, &cPayloadSize);
-
- BOOST_REQUIRE(cPlatform != nullptr);
- BOOST_REQUIRE(cPkgId != nullptr);
-
- size_t cPlatformSize = strlen(cPlatform) + 1;
- size_t cPkgIdSize = strlen(cPkgId) + 1;
-
- BOOST_REQUIRE(cMsgSize > 0);
- BOOST_REQUIRE(cPayloadSize > 0);
- BOOST_REQUIRE(cPlatformSize + cPkgIdSize + cPayloadSize == cMsgSize);
-
- char* label = nullptr;
- BOOST_REQUIRE(smack_new_label_from_self(&label) >= 0);
- BOOST_REQUIRE(label != nullptr);
- std::string labelStr(label);
- free(label);
-
- BOOST_REQUIRE(strcmp(cPlatform, "Tizen") == 0);
- BOOST_REQUIRE(labelStr == cPkgId);
- BOOST_REQUIRE(memcmp(payload, cPayload, cPayloadSize) == 0);
-}
-
-NEGATIVE_TEST_CASE(test23_dcm_e2ee_sign_api) {
- unsigned char payload[] = {1,2,3,4};
- void* ocfCtx = nullptr;
- assert_positive(dcm_create_key_context, nullptr, nullptr, "ECDSA", &ocfCtx);
- FreeKey freeOcfCtx(ocfCtx);
- dcm_e2ee_bundle_h bundle;
-
- char* sig;
- size_t sigSize;
-
- auto invalid = [](const void *key_ctx,
- dcm_digest_algorithm_e md,
- const unsigned char *payload,
- size_t payload_len,
- dcm_e2ee_bundle_h *bundle,
- char **signature,
- size_t *signature_len){
- assert_invalid_param(dcm_e2ee_create_signed_bundle,
- key_ctx,
- md,
- payload,
- payload_len,
- bundle,
- signature,
- signature_len);
- };
-
- invalid(nullptr, DCM_DIGEST_SHA256, payload, sizeof(payload), &bundle, &sig, &sigSize);
-
- // unsupported md
- invalid(ocfCtx, DCM_DIGEST_NONE, payload, sizeof(payload), &bundle, &sig, &sigSize);
- invalid(ocfCtx, DCM_DIGEST_MD2, payload, sizeof(payload), &bundle, &sig, &sigSize);
- invalid(ocfCtx, DCM_DIGEST_MD4, payload, sizeof(payload), &bundle, &sig, &sigSize);
- invalid(ocfCtx, DCM_DIGEST_MD5, payload, sizeof(payload), &bundle, &sig, &sigSize);
- invalid(ocfCtx, DCM_DIGEST_RIPEMD160, payload, sizeof(payload), &bundle, &sig, &sigSize);
-
- // dcm client will abort for values outside dcm_digest_algorithm_e range
-
- invalid(ocfCtx, DCM_DIGEST_SHA256, nullptr, sizeof(payload), &bundle, &sig, &sigSize);
- invalid(ocfCtx, DCM_DIGEST_SHA256, payload, sizeof(payload), nullptr, &sig, &sigSize);
- invalid(ocfCtx, DCM_DIGEST_SHA256, payload, sizeof(payload), &bundle, nullptr, &sigSize);
- invalid(ocfCtx, DCM_DIGEST_SHA256, payload, sizeof(payload), &bundle, &sig, nullptr);
-}
-
BOOST_AUTO_TEST_SUITE_END()