From e964ec6f2a5b0cf0deda4e1a0ad4977980d9240b Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 11 Aug 2021 10:44:31 +0200 Subject: [PATCH] add PEPMessage codec functions --- src/message_codec.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ src/message_codec.h | 103 ++++++++++++++++++++++++++++++++ src/pEpEngine.h | 1 + 3 files changed, 245 insertions(+) create mode 100644 src/message_codec.c create mode 100644 src/message_codec.h diff --git a/src/message_codec.c b/src/message_codec.c new file mode 100644 index 000000000..d2da16889 --- /dev/null +++ b/src/message_codec.c @@ -0,0 +1,141 @@ +/** + * @file PEPMessage_codec.c + * @brief Implementation for PEPMessage encode and decode functions which transform message payloads to + * and from PER-encoded data, and XER text to and from PER + * + * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx + * + * @license GNU General Public License 3.0 - see LICENSE.txt + */ + +#include "platform.h" + +#include "distribution_codec.h" +#include "../asn.1/PEPMessage.h" +#include "pEp_internal.h" +#include "growing_buf.h" + +DYNAMIC_API PEP_STATUS decode_PEPMessage_message( + const char *data, + size_t size, + PEPMessage_t **msg + ) +{ + assert(data && msg); + if (!(data && msg)) + return PEP_ILLEGAL_VALUE; + + *msg = NULL; + PEPMessage_t *_msg = NULL; + uper_decode_complete(NULL, &asn_DEF_PEPMessage, (void **) &_msg, data, size); + if (!_msg) + return PEP_PEPMESSAGE_ILLEGAL_MESSAGE; + + *msg = _msg; + return PEP_STATUS_OK; +} + +PEP_STATUS encode_PEPMessage_message( + PEPMessage_t *msg, + char **data, + size_t *size + ) +{ + assert(data && msg); + if (!(data && msg)) + return PEP_ILLEGAL_VALUE; + + *data = NULL; + *size = 0; + + char *_data = NULL; + ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_PEPMessage, NULL, msg, + (void **) &_data); + if (_size == -1) + return PEP_CANNOT_ENCODE; + + *data = _data; + *size = (size_t) _size; + + return PEP_STATUS_OK; +} + +PEP_STATUS PER_to_XER_PEPMessage_msg( + const char *data, + size_t size, + char **text + ) +{ + PEP_STATUS status = PEP_STATUS_OK; + growing_buf_t *dst = NULL; + + assert(data && text); + if (!(data && text)) + return PEP_ILLEGAL_VALUE; + + *text = NULL; + + PEPMessage_t *msg = NULL; + status = decode_PEPMessage_message(data, size, &msg); + if (status) + goto the_end; + + dst = new_growing_buf(); + if (!dst) { + status = PEP_OUT_OF_MEMORY; + goto the_end; + } + + asn_enc_rval_t er = xer_encode(&asn_DEF_PEPMessage, msg, XER_F_BASIC, + (asn_app_consume_bytes_f *) growing_buf_consume, (void *) dst); + if (er.encoded == -1) { + status = PEP_CANNOT_ENCODE; + goto the_end; + } + + *text = dst->data; + dst->data = NULL; + +the_end: + free_growing_buf(dst); + ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + return status; +} + +PEP_STATUS XER_to_PER_PEPMessage_msg( + const char *text, + char **data, + size_t *size + ) +{ + PEP_STATUS status = PEP_STATUS_OK; + + assert(text && data && size); + if (!(text && data && size)) + return PEP_ILLEGAL_VALUE; + + *data = NULL; + *size = 0; + + PEPMessage_t *msg = NULL; + asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_PEPMessage, (void **) &msg, + (const void *) text, strlen(text)); + if (dr.code != RC_OK) { + status = PEP_PEPMESSAGE_ILLEGAL_MESSAGE; + goto the_end; + } + + char *_data = NULL; + size_t _size = 0; + status = encode_PEPMessage_message(msg, &_data, &_size); + if (status) + goto the_end; + + *data = _data; + *size = (size_t) _size; + +the_end: + ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + return status; +} + diff --git a/src/message_codec.h b/src/message_codec.h new file mode 100644 index 000000000..6a451104b --- /dev/null +++ b/src/message_codec.h @@ -0,0 +1,103 @@ +/** + * @file PEPMessage_codec.h + * @brief Definitions for PEPMessage encode and decode functions which transform message payloads to + * and from PER-encoded data, and XER text to and from PER + * + * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx + * + * @license GNU General Public License 3.0 - see LICENSE.txt + */ + + +#ifndef PEPMESSAGE_CODEC_H +#define PEPMESSAGE_CODEC_H + +#include "pEpEngine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct PEPMessage; + +/** + * + * + * @brief decode PER encoded PEPMessage message + * + * @param[in] data PER encoded data + * @param[in] size size of PER encoded data + * @param[out] msg decoded PEPMessage message + * + * @retval status + * + * @ownership msg goes into the ownership of the caller + */ +DYNAMIC_API PEP_STATUS decode_PEPMessage_message( + const char *data, + size_t size, + struct PEPMessage **msg + ); + +/** + * + * + * @brief decode PER encoded PEPMessage message + * + * @param[in] msg PEPMessage message to encode + * @param[out] data PER encoded data + * @param[out] size size of PER encoded data + * + * @retval status + * + * @ownership msg goes into the ownership of the caller + */ +DYNAMIC_API PEP_STATUS encode_PEPMessage_message( + struct PEPMessage *msg, + char **data, + size_t *size + ); + + +/** + * + * + * @brief decode PEPMessage message from PER into XER + * + * @param[in] data PER encoded data + * @param[in] size size of PER encoded data + * @param[out] text XER text of the same PEPMessage message + * + * @retval status + */ +DYNAMIC_API PEP_STATUS PER_to_XER_PEPMessage_msg( + const char *data, + size_t size, + char **text + ); + +/** + * + * + * @brief encode PEPMessage message from XER into PER + * + * @param[in] text string text with XER text of the PEPMessage message + * @param[out] data PER encoded data + * @param[out] size size of PER encoded data + * + * @retval status + */ +DYNAMIC_API PEP_STATUS XER_to_PER_PEPMessage_msg( + const char *text, + char **data, + size_t *size + ); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 0ea84d0bf..f49061608 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -160,6 +160,7 @@ typedef enum { PEP_DISTRIBUTION_ILLEGAL_MESSAGE = 0x1002, PEP_STORAGE_ILLEGAL_MESSAGE = 0x1102, + PEP_PEPMESSAGE_ILLEGAL_MESSAGE = 0x1202, PEP_COMMIT_FAILED = 0xff01, PEP_MESSAGE_CONSUME = 0xff02,