E2EE API draft
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 17 Jan 2023 09:54:54 +0000 (10:54 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 6 Mar 2023 10:20:24 +0000 (11:20 +0100)
- E2EE bundle concept
- E2EE signatures

Change-Id: I5caf98d6d976752d009f56c090d442e2f9aecbf2

CMakeLists.txt
packaging/device-certificate-manager.spec
src/dcm-client/device_certificate_manager.cpp
src/dcm-client/device_certificate_manager.h
src/dcm-client/version_script.lds

index a39b589..ebfb43a 100644 (file)
@@ -17,7 +17,7 @@
 # @author      Jaroslaw Pelczar <j.pelczar@samsung.com>
 
 CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
-PROJECT(device-certificate-manager VERSION 2.0 LANGUAGES C CXX)
+PROJECT(device-certificate-manager VERSION 2.1 LANGUAGES C CXX)
 
 INCLUDE(GNUInstallDirs)
 INCLUDE(FindPkgConfig)
index 57a61a2..e5a9d9c 100644 (file)
@@ -2,8 +2,8 @@
 
 Name: device-certificate-manager
 Summary: Device Certificate Manager daemon and libraries
-Version: 2.0
-Release: 2
+Version: 2.1
+Release: 1
 Group: Security/Secure Storage
 License: Apache-2.0
 Source0: %{name}-%{version}.tar.gz
index d943bd5..18b429d 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <vector>
 #include <cstring>
+#include <cstdlib>
+#include <cassert>
 
 #include "device_certificate_manager.h"
 #include "dcm_client.h"
@@ -151,3 +153,140 @@ int dcm_create_signature(const void *key_ctx, dcm_digest_algorithm_e md,
 
        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 7.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)
+{
+       if (message == NULL || bundle == NULL)
+               return DCM_ERROR_INVALID_PARAMETER;
+
+       const char* message_str = reinterpret_cast<const char*>(message);
+
+       struct dcm_e2ee_bundle_s *tmp = new dcm_e2ee_bundle_s;
+
+       tmp->message_len = message_len;
+       tmp->pkg_id_offset = strnlen(message_str, message_len);
+       if (tmp->pkg_id_offset == message_len) {
+               delete tmp;
+               return DCM_ERROR_INVALID_PARAMETER; // wrong format
+       }
+
+       if (strcmp(message_str, "Tizen") != 0) { // TODO specify platform format
+               delete tmp;
+               return DCM_ERROR_NOT_SUPPORTED; // not a Tizen bundle
+       }
+
+       tmp->pkg_id_offset++; // skip \0
+       message_str += tmp->pkg_id_offset;
+       message_len -= tmp->pkg_id_offset;
+
+       tmp->payload_offset = strnlen(message_str, message_len);
+       if (tmp->payload_offset == message_len) {
+               delete tmp;
+               return DCM_ERROR_INVALID_PARAMETER; // wrong format
+       }
+       tmp->payload_offset += tmp->pkg_id_offset; // skip pkg_id
+       tmp->payload_offset++; // skip \0
+
+       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);
+       delete 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)
+{
+       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)
+{
+       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)
+{
+       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)
+{
+       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*/,
+       unsigned char **/*signature*/,
+       size_t */*signature_len*/)
+{
+       /* TODO:
+        * 1. Get client pkg_id from socket
+        * 2. Construct a message (platform="Tizen" + pkg_id + payload) and put it into bundle
+        * 3. Sign the message with OCF
+        * 4. Return bundle and signature
+        */
+
+       return DCM_ERROR_NONE;
+}
index 9e53a83..b3c234e 100644 (file)
@@ -230,6 +230,194 @@ int dcm_create_signature(const void *key_ctx, dcm_digest_algorithm_e md,
                          char **signature, size_t *signature_len);
 
 /**
+ * @brief Handle to a struct containing E2EE message bundle
+ * @since_tizen 7.5
+ */
+typedef struct dcm_e2ee_bundle_s* dcm_e2ee_bundle_h;
+
+/**
+ * @platform
+ * @brief Creates an E2EE message bundle from a binary message.
+ * @since_tizen 7.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_INVALID_PARAMETER Input parameter is invalid (message = NULL or bundle = NULL)
+ *                                      or the message format is invalid.
+ * @retval #DCM_ERROR_NOT_SUPPORTED The message is not in Tizen platform format.
+ *
+ * @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);
+
+/**
+ * @platform
+ * @brief Releases the memory associated with E2EE message bundle.
+ * @since_tizen 7.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);
+
+/**
+ * @platform
+ * @brief Retrieves a pointer to the whole binary message contained in the E2EE bundle.
+ * @since_tizen 7.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_INVALID_PARAMETER @a bundle, @a message or @a message_len is NULL.
+ *
+ * @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);
+
+/**
+ * @platform
+ * @brief Retrieves a pointer to the platform string contained in the E2EE bundle.
+ * @since_tizen 7.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_INVALID_PARAMETER @a bundle or @a platform is NULL.
+ *
+ * @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);
+
+/**
+ * @platform
+ * @brief Retrieves a pointer to the package id string contained in the E2EE bundle.
+ * @since_tizen 7.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_INVALID_PARAMETER @a bundle or @a pkg_id is NULL.
+ *
+ * @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);
+
+/**
+ * @platform
+ * @brief Retrieves a pointer to the payload byte sequence contained in the E2EE bundle.
+ * @since_tizen 7.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_INVALID_PARAMETER @a bundle, @a payload or @a payload_len is NULL.
+ *
+ * @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 7.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_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_PERMISSION_DENIED Failed to access device certificate manager
+ * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
+ * @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,
+                                  unsigned char **signature,
+                                  size_t *signature_len);
+
+/**
  * @}
  */
 
index 9b724fc..2926bef 100644 (file)
@@ -9,3 +9,14 @@ DCMCLIENT_2.0 {
        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;