summaryrefslogtreecommitdiff
path: root/src/messenger/messenger_api_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/messenger_api_message.c')
-rw-r--r--src/messenger/messenger_api_message.c602
1 files changed, 0 insertions, 602 deletions
diff --git a/src/messenger/messenger_api_message.c b/src/messenger/messenger_api_message.c
deleted file mode 100644
index fdab60eef..000000000
--- a/src/messenger/messenger_api_message.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2020 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-/**
- * @author Tobias Frisch
- * @file src/messenger/messenger_api_message.c
- * @brief messenger api: client and service implementation of GNUnet MESSENGER service
- */
-
-#include "messenger_api_message.h"
-
-struct GNUNET_MESSENGER_MessageSignature
-{
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
- struct GNUNET_HashCode hash;
-};
-
-struct GNUNET_MESSENGER_ShortMessage
-{
- enum GNUNET_MESSENGER_MessageKind kind;
- struct GNUNET_MESSENGER_MessageBody body;
-};
-
-struct GNUNET_MESSENGER_Message*
-create_message (enum GNUNET_MESSENGER_MessageKind kind)
-{
- struct GNUNET_MESSENGER_Message *message = GNUNET_new(struct GNUNET_MESSENGER_Message);
-
- message->header.kind = kind;
-
- switch (message->header.kind)
- {
- case GNUNET_MESSENGER_KIND_NAME:
- message->body.name.name = NULL;
- break;
- case GNUNET_MESSENGER_KIND_TEXT:
- message->body.text.text = NULL;
- break;
- case GNUNET_MESSENGER_KIND_FILE:
- message->body.file.uri = NULL;
- break;
- case GNUNET_MESSENGER_KIND_PRIVATE:
- message->body.private.length = 0;
- message->body.private.data = NULL;
- break;
- default:
- break;
- }
-
- return message;
-}
-
-struct GNUNET_MESSENGER_Message*
-copy_message (const struct GNUNET_MESSENGER_Message *message)
-{
- struct GNUNET_MESSENGER_Message *copy = GNUNET_new(struct GNUNET_MESSENGER_Message);
-
- GNUNET_memcpy(copy, message, sizeof(struct GNUNET_MESSENGER_Message));
-
- switch (message->header.kind)
- {
- case GNUNET_MESSENGER_KIND_NAME:
- copy->body.name.name = GNUNET_strdup(message->body.name.name);
- break;
- case GNUNET_MESSENGER_KIND_TEXT:
- copy->body.text.text = GNUNET_strdup(message->body.text.text);
- break;
- case GNUNET_MESSENGER_KIND_FILE:
- copy->body.file.uri = GNUNET_strdup(message->body.file.uri);
- break;
- case GNUNET_MESSENGER_KIND_PRIVATE:
- copy->body.private.data = copy->body.private.length ? GNUNET_malloc(copy->body.private.length) : NULL;
-
- if (copy->body.private.data)
- {
- GNUNET_memcpy(copy->body.private.data, message->body.private.data, copy->body.private.length);
- }
-
- break;
- default:
- break;
- }
-
- return copy;
-}
-
-static void
-destroy_message_body (enum GNUNET_MESSENGER_MessageKind kind, struct GNUNET_MESSENGER_MessageBody *body)
-{
- switch (kind)
- {
- case GNUNET_MESSENGER_KIND_NAME:
- GNUNET_free(body->name.name);
- break;
- case GNUNET_MESSENGER_KIND_TEXT:
- GNUNET_free(body->text.text);
- break;
- case GNUNET_MESSENGER_KIND_FILE:
- GNUNET_free(body->file.uri);
- break;
- case GNUNET_MESSENGER_KIND_PRIVATE:
- GNUNET_free(body->private.data);
- break;
- default:
- break;
- }
-}
-
-void
-destroy_message (struct GNUNET_MESSENGER_Message *message)
-{
- destroy_message_body (message->header.kind, &(message->body));
-
- GNUNET_free(message);
-}
-
-static void
-fold_short_message (const struct GNUNET_MESSENGER_Message *message, struct GNUNET_MESSENGER_ShortMessage *shortened)
-{
- shortened->kind = message->header.kind;
-
- GNUNET_memcpy(&(shortened->body), &(message->body), sizeof(struct GNUNET_MESSENGER_MessageBody));
-}
-
-static void
-unfold_short_message (struct GNUNET_MESSENGER_ShortMessage *shortened, struct GNUNET_MESSENGER_Message *message)
-{
- destroy_message_body (message->header.kind, &(message->body));
-
- message->header.kind = shortened->kind;
-
- GNUNET_memcpy(&(message->body), &(shortened->body), sizeof(struct GNUNET_MESSENGER_MessageBody));
-}
-
-#define member_size(type, member) sizeof(((type*) NULL)->member)
-
-static uint16_t
-get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind)
-{
- uint16_t length = 0;
-
- switch (kind)
- {
- case GNUNET_MESSENGER_KIND_INFO:
- length += member_size(struct GNUNET_MESSENGER_Message, body.info.host_key);
- length += member_size(struct GNUNET_MESSENGER_Message, body.info.unique_id);
- break;
- case GNUNET_MESSENGER_KIND_JOIN:
- length += member_size(struct GNUNET_MESSENGER_Message, body.join.key);
- break;
- case GNUNET_MESSENGER_KIND_LEAVE:
- break;
- case GNUNET_MESSENGER_KIND_NAME:
- break;
- case GNUNET_MESSENGER_KIND_KEY:
- length += member_size(struct GNUNET_MESSENGER_Message, body.key.key);
- break;
- case GNUNET_MESSENGER_KIND_PEER:
- length += member_size(struct GNUNET_MESSENGER_Message, body.peer.peer);
- break;
- case GNUNET_MESSENGER_KIND_ID:
- length += member_size(struct GNUNET_MESSENGER_Message, body.id.id);
- break;
- case GNUNET_MESSENGER_KIND_MISS:
- length += member_size(struct GNUNET_MESSENGER_Message, body.miss.peer);
- break;
- case GNUNET_MESSENGER_KIND_MERGE:
- length += member_size(struct GNUNET_MESSENGER_Message, body.merge.previous);
- break;
- case GNUNET_MESSENGER_KIND_REQUEST:
- length += member_size(struct GNUNET_MESSENGER_Message, body.request.hash);
- break;
- case GNUNET_MESSENGER_KIND_INVITE:
- length += member_size(struct GNUNET_MESSENGER_Message, body.invite.door);
- length += member_size(struct GNUNET_MESSENGER_Message, body.invite.key);
- break;
- case GNUNET_MESSENGER_KIND_TEXT:
- break;
- case GNUNET_MESSENGER_KIND_FILE:
- length += member_size(struct GNUNET_MESSENGER_Message, body.file.key);
- length += member_size(struct GNUNET_MESSENGER_Message, body.file.hash);
- length += NAME_MAX;
- break;
- case GNUNET_MESSENGER_KIND_PRIVATE:
- length += member_size(struct GNUNET_MESSENGER_Message, body.private.key);
- break;
- default:
- break;
- }
-
- return length;
-}
-
-uint16_t
-get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind)
-{
- uint16_t length = 0;
-
- length += member_size(struct GNUNET_MESSENGER_Message, header.signature);
- length += member_size(struct GNUNET_MESSENGER_Message, header.timestamp);
- length += member_size(struct GNUNET_MESSENGER_Message, header.sender_id);
- length += member_size(struct GNUNET_MESSENGER_Message, header.previous);
- length += member_size(struct GNUNET_MESSENGER_Message, header.kind);
-
- return length + get_message_body_kind_size (kind);
-}
-
-static uint16_t
-get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET_MESSENGER_MessageBody *body)
-{
- uint16_t length = 0;
-
- switch (kind)
- {
- case GNUNET_MESSENGER_KIND_NAME:
- length += (body->name.name? strlen (body->name.name) : 0);
- break;
- case GNUNET_MESSENGER_KIND_TEXT:
- length += strlen (body->text.text);
- break;
- case GNUNET_MESSENGER_KIND_FILE:
- length += strlen (body->file.uri);
- break;
- case GNUNET_MESSENGER_KIND_PRIVATE:
- length += body->private.length;
- break;
- default:
- break;
- }
-
- return length;
-}
-
-uint16_t
-get_message_size (const struct GNUNET_MESSENGER_Message *message)
-{
- return get_message_kind_size (message->header.kind) + get_message_body_size (message->header.kind, &(message->body));
-}
-
-static uint16_t
-get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message)
-{
- if (message)
- return sizeof(message->kind) + get_message_body_kind_size (message->kind)
- + get_message_body_size (message->kind, &(message->body));
- else
- return sizeof(message->kind);
-}
-
-#define min(x, y) (x < y? x : y)
-
-#define encode_step_ext(dst, offset, src, size) do { \
- GNUNET_memcpy(dst + offset, src, size); \
- offset += size; \
-} while (0)
-
-#define encode_step(dst, offset, src) do { \
- encode_step_ext(dst, offset, src, sizeof(*src)); \
-} while(0)
-
-static void
-encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET_MESSENGER_MessageBody *body,
- uint16_t length, char *buffer, uint16_t offset)
-{
- switch (kind)
- {
- case GNUNET_MESSENGER_KIND_INFO:
- encode_step(buffer, offset, &(body->info.host_key));
- encode_step(buffer, offset, &(body->info.unique_id));
- break;
- case GNUNET_MESSENGER_KIND_JOIN:
- encode_step(buffer, offset, &(body->join.key));
- break;
- case GNUNET_MESSENGER_KIND_LEAVE:
- break;
- case GNUNET_MESSENGER_KIND_NAME:
- if (body->name.name)
- encode_step_ext(buffer, offset, body->name.name, min(length - offset, strlen(body->name.name)));
- break;
- case GNUNET_MESSENGER_KIND_KEY:
- encode_step(buffer, offset, &(body->key.key));
- break;
- case GNUNET_MESSENGER_KIND_PEER:
- encode_step(buffer, offset, &(body->peer.peer));
- break;
- case GNUNET_MESSENGER_KIND_ID:
- encode_step(buffer, offset, &(body->id.id));
- break;
- case GNUNET_MESSENGER_KIND_MISS:
- encode_step(buffer, offset, &(body->miss.peer));
- break;
- case GNUNET_MESSENGER_KIND_MERGE:
- encode_step(buffer, offset, &(body->merge.previous));
- break;
- case GNUNET_MESSENGER_KIND_REQUEST:
- encode_step(buffer, offset, &(body->request.hash));
- break;
- case GNUNET_MESSENGER_KIND_INVITE:
- encode_step(buffer, offset, &(body->invite.door));
- encode_step(buffer, offset, &(body->invite.key));
- break;
- case GNUNET_MESSENGER_KIND_TEXT:
- encode_step_ext(buffer, offset, body->text.text, min(length - offset, strlen(body->text.text)));
- break;
- case GNUNET_MESSENGER_KIND_FILE:
- encode_step(buffer, offset, &(body->file.key));
- encode_step(buffer, offset, &(body->file.hash));
- encode_step_ext(buffer, offset, body->file.name, NAME_MAX);
- encode_step_ext(buffer, offset, body->file.uri, min(length - offset, strlen(body->file.uri)));
- break;
- case GNUNET_MESSENGER_KIND_PRIVATE:
- encode_step(buffer, offset, &(body->private.key));
- encode_step_ext(buffer, offset, body->private.data, min(length - offset, body->private.length));
- break;
- default:
- break;
- }
-}
-
-void
-encode_message (const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer)
-{
- uint16_t offset = 0;
-
- encode_step(buffer, offset, &(message->header.signature));
- encode_step(buffer, offset, &(message->header.timestamp));
- encode_step(buffer, offset, &(message->header.sender_id));
- encode_step(buffer, offset, &(message->header.previous));
- encode_step(buffer, offset, &(message->header.kind));
-
- encode_message_body (message->header.kind, &(message->body), length, buffer, offset);
-}
-
-static void
-encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, char *buffer)
-{
- uint16_t offset = 0;
-
- encode_step(buffer, offset, &(message->kind));
-
- encode_message_body (message->kind, &(message->body), length, buffer, offset);
-}
-
-#define decode_step_ext(src, offset, dst, size) do { \
- GNUNET_memcpy(dst, src + offset, size); \
- offset += size; \
-} while (0)
-
-#define decode_step(src, offset, dst) do { \
- decode_step_ext(src, offset, dst, sizeof(*dst)); \
-} while (0)
-
-#define decode_step_malloc(src, offset, dst, size, zero) do { \
- dst = GNUNET_malloc(size + zero); \
- if (zero) dst[size] = 0; \
- decode_step_ext(src, offset, dst, size); \
-} while (0)
-
-static void
-decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, struct GNUNET_MESSENGER_MessageBody *body,
- uint16_t length, const char *buffer, uint16_t offset)
-{
- switch (*kind)
- {
- case GNUNET_MESSENGER_KIND_INFO:
- decode_step(buffer, offset, &(body->info.host_key));
- decode_step(buffer, offset, &(body->info.unique_id));
- break;
- case GNUNET_MESSENGER_KIND_JOIN:
- decode_step(buffer, offset, &(body->join.key));
- break;
- case GNUNET_MESSENGER_KIND_LEAVE:
- break;
- case GNUNET_MESSENGER_KIND_NAME:
- if (length - offset > 0)
- decode_step_malloc(buffer, offset, body->name.name, length - offset, 1);
- else
- body->name.name = NULL;
- break;
- case GNUNET_MESSENGER_KIND_KEY:
- decode_step(buffer, offset, &(body->key.key));
- break;
- case GNUNET_MESSENGER_KIND_PEER:
- decode_step(buffer, offset, &(body->peer.peer));
- break;
- case GNUNET_MESSENGER_KIND_ID:
- decode_step(buffer, offset, &(body->id.id));
- break;
- case GNUNET_MESSENGER_KIND_MISS:
- decode_step(buffer, offset, &(body->miss.peer));
- break;
- case GNUNET_MESSENGER_KIND_MERGE:
- decode_step(buffer, offset, &(body->merge.previous));
- break;
- case GNUNET_MESSENGER_KIND_REQUEST:
- decode_step(buffer, offset, &(body->request.hash));
- break;
- case GNUNET_MESSENGER_KIND_INVITE:
- decode_step(buffer, offset, &(body->invite.door));
- decode_step(buffer, offset, &(body->invite.key));
- break;
- case GNUNET_MESSENGER_KIND_TEXT:
- decode_step_malloc(buffer, offset, body->text.text, length - offset, 1);
- break;
- case GNUNET_MESSENGER_KIND_FILE:
- decode_step(buffer, offset, &(body->file.key));
- decode_step(buffer, offset, &(body->file.hash));
- decode_step_ext(buffer, offset, body->file.name, NAME_MAX);
- decode_step_malloc(buffer, offset, body->file.uri, length - offset, 1);
- break;
- case GNUNET_MESSENGER_KIND_PRIVATE:
- decode_step(buffer, offset, &(body->private.key));
-
- body->private.length = (length - offset);
- decode_step_malloc(buffer, offset, body->private.data, length - offset, 0);
- break;
- default:
- *kind = GNUNET_MESSENGER_KIND_UNKNOWN;
- break;
- }
-}
-
-int
-decode_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer)
-{
- uint16_t offset = 0;
-
- if (length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN))
- return GNUNET_NO;
-
- decode_step(buffer, offset, &(message->header.signature));
- decode_step(buffer, offset, &(message->header.timestamp));
- decode_step(buffer, offset, &(message->header.sender_id));
- decode_step(buffer, offset, &(message->header.previous));
- decode_step(buffer, offset, &(message->header.kind));
-
- if (length < get_message_kind_size (message->header.kind))
- return GNUNET_NO;
-
- decode_message_body (&(message->header.kind), &(message->body), length, buffer, offset);
-
- return GNUNET_YES;
-}
-
-static int
-decode_short_message (struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, const char *buffer)
-{
- uint16_t offset = 0;
-
- if (length < get_short_message_size (NULL))
- return GNUNET_NO;
-
- decode_step(buffer, offset, &(message->kind));
-
- if (length < get_short_message_size (message))
- return GNUNET_NO;
-
- decode_message_body (&(message->kind), &(message->body), length, buffer, offset);
-
- return GNUNET_YES;
-}
-
-void
-hash_message (uint16_t length, const char *buffer, struct GNUNET_HashCode *hash)
-{
- GNUNET_CRYPTO_hash (buffer + sizeof(struct GNUNET_CRYPTO_EcdsaSignature),
- length - sizeof(struct GNUNET_CRYPTO_EcdsaSignature), hash);
-}
-
-void
-sign_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer,
- const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Ego *ego)
-{
- struct GNUNET_MESSENGER_MessageSignature signature;
-
- signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
- signature.purpose.size = htonl (sizeof(signature));
-
- GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode));
-
- GNUNET_IDENTITY_sign(&(ego->priv), &signature, &(message->header.signature));
- GNUNET_memcpy(buffer, &(message->header.signature), sizeof(struct GNUNET_CRYPTO_EcdsaSignature));
-}
-
-int
-verify_message (const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash,
- const struct GNUNET_IDENTITY_PublicKey *key)
-{
- struct GNUNET_MESSENGER_MessageSignature signature;
-
- signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
- signature.purpose.size = htonl (sizeof(signature));
-
- GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode));
-
- return GNUNET_IDENTITY_signature_verify(GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature,
- &(message->header.signature), key);
-}
-
-int
-encrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PublicKey *key)
-{
- struct GNUNET_MESSENGER_ShortMessage shortened;
-
- fold_short_message (message, &shortened);
-
- const uint16_t length = get_short_message_size (&shortened);
-
- message->header.kind = GNUNET_MESSENGER_KIND_PRIVATE;
- message->body.private.data = GNUNET_malloc(length);
-
- encode_short_message (&shortened, length, message->body.private.data);
-
- if (GNUNET_IDENTITY_encrypt (message->body.private.data, length, key, &(message->body.private.key),
- message->body.private.data)
- == length)
- {
- destroy_message_body (shortened.kind, &(shortened.body));
- return GNUNET_YES;
- }
- else
- {
- unfold_short_message (&shortened, message);
- return GNUNET_NO;
- }
-}
-
-int
-decrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PrivateKey *key)
-{
- if (message->body.private.length != GNUNET_IDENTITY_decrypt (message->body.private.data,
- message->body.private.length, key,
- &(message->body.private.key),
- message->body.private.data))
- return GNUNET_NO;
-
- struct GNUNET_MESSENGER_ShortMessage shortened;
-
- if (GNUNET_YES != decode_short_message (&shortened, message->body.private.length, message->body.private.data))
- return GNUNET_NO;
-
- unfold_short_message (&shortened, message);
- return GNUNET_YES;
-}
-
-struct GNUNET_MQ_Envelope*
-pack_message (struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash,
- const struct GNUNET_MESSENGER_Ego *ego, int mode)
-{
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Packing message: %u\n", message->header.kind);
-
- struct GNUNET_MessageHeader *header;
-
- uint16_t length = get_message_size (message);
-
- struct GNUNET_MQ_Envelope *env;
- char *buffer;
-
- if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE == mode)
- {
- env = GNUNET_MQ_msg_extra(header, length, GNUNET_MESSAGE_TYPE_CADET_CLI);
-
- buffer = (char*) &(header[1]);
- }
- else
- {
- env = NULL;
-
- buffer = GNUNET_malloc(length);
- }
-
- encode_message (message, length, buffer);
-
- if (hash)
- {
- hash_message (length, buffer, hash);
-
- if (ego)
- sign_message (message, length, buffer, hash, ego);
- }
-
- if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE != mode)
- GNUNET_free(buffer);
-
- return env;
-}