commit 0b05127d7b9567b80edc9f967d8faddd2a3d147e
parent 9e10880a657b23fee26e26018e4e75fa73804f9e
Author: Jacki <jacki@thejackimonster.de>
Date: Wed, 17 Jun 2026 20:03:43 +0200
Remove additional encryption in file messages, add function to verify hashes after download
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
6 files changed, 147 insertions(+), 414 deletions(-)
diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h
@@ -112,7 +112,7 @@ enum GNUNET_CHAT_MessageKind
GNUNET_CHAT_KIND_LOGIN = 3, /**< GNUNET_CHAT_KIND_LOGIN */
/**
- * The kind to inform that the application needs to cleanup
+ * The kind to inform that the application needs to cleanup
* resources related to the currently connected account.
*/
GNUNET_CHAT_KIND_LOGOUT = 4, /**< GNUNET_CHAT_KIND_LOGOUT */
@@ -316,7 +316,7 @@ typedef enum GNUNET_GenericReturnValue
* @param[in] uri Chat URI of the lobby or NULL on error
*/
typedef void
-(*GNUNET_CHAT_LobbyCallback) (void *cls,
+(*GNUNET_CHAT_LobbyCallback) (void *cls,
const struct GNUNET_CHAT_Uri *uri);
/**
@@ -677,7 +677,7 @@ const char*
GNUNET_CHAT_get_key (const struct GNUNET_CHAT_Handle *handle);
/**
- * Updates an attribute of a chat handle for related communication under a given
+ * Updates an attribute of a chat handle for related communication under a given
* <i>name</i> and a custom <i>value</i>.
*
* @param[in,out] handle Chat handle
@@ -690,7 +690,7 @@ GNUNET_CHAT_set_attribute (struct GNUNET_CHAT_Handle *handle,
const char *value);
/**
- * Deletes an attribute of a chat <i>handle</i> for related communication
+ * Deletes an attribute of a chat <i>handle</i> for related communication
* under a given <i>name</i>.
*
* @param[in,out] handle Chat handle
@@ -701,7 +701,7 @@ GNUNET_CHAT_delete_attribute (struct GNUNET_CHAT_Handle *handle,
const char *name);
/**
- * Calls an optional <i>callback</i> for each attribute of a given chat
+ * Calls an optional <i>callback</i> for each attribute of a given chat
* <i>handle</i>.
*
* @param[in,out] handle Chat handle
@@ -740,7 +740,7 @@ GNUNET_CHAT_unshare_attribute_from (struct GNUNET_CHAT_Handle *handle,
const char *name);
/**
- * Calls an optional <i>callback</i> for each attribute of a given chat
+ * Calls an optional <i>callback</i> for each attribute of a given chat
* <i>handle</i> shared with a specific chat <i>contact</i>.
*
* @param[in,out] handle Chat handle
@@ -826,7 +826,7 @@ GNUNET_CHAT_lobby_join (struct GNUNET_CHAT_Handle *handle,
const struct GNUNET_CHAT_Uri *uri);
/**
- * Requests a file with a given chat <i>handle</i> from a selected chat
+ * Requests a file with a given chat <i>handle</i> from a selected chat
* <i>uri</i> to potentially download it.
*
* @param[in,out] handle Chat handle
@@ -903,7 +903,7 @@ GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle,
void *cls);
/**
- * Returns the chat contact matching a given chat <i>handle</i>'s current
+ * Returns the chat contact matching a given chat <i>handle</i>'s current
* account.
*
* @param[in,out] handle Chat handle
@@ -922,7 +922,7 @@ const char*
GNUNET_CHAT_account_get_name (const struct GNUNET_CHAT_Account *account);
/**
- * Calls an optional <i>callback</i> for each attribute of a given chat
+ * Calls an optional <i>callback</i> for each attribute of a given chat
* <i>account</i> using a chat <i>handle</i>.
*
* @param[in,out] handle Chat handle
@@ -1084,7 +1084,7 @@ GNUNET_CHAT_contact_set_blocked (struct GNUNET_CHAT_Contact *contact,
* whether messages of it should be filtered.
*
* @param[in] contact Contact
- * @return #GNUNET_YES if the contact is blocked, #GNUNET_SYSERR on failure and
+ * @return #GNUNET_YES if the contact is blocked, #GNUNET_SYSERR on failure and
* #GNUNET_NO otherwise
*/
enum GNUNET_GenericReturnValue
@@ -1118,7 +1118,7 @@ GNUNET_CHAT_contact_untag (struct GNUNET_CHAT_Contact *contact,
*
* @param[in] contact Contact
* @param[in] tag Tag
- * @return #GNUNET_YES if the contact is tagged, #GNUNET_SYSERR on failure and
+ * @return #GNUNET_YES if the contact is tagged, #GNUNET_SYSERR on failure and
* #GNUNET_NO otherwise
*/
enum GNUNET_GenericReturnValue
@@ -1126,7 +1126,7 @@ GNUNET_CHAT_contact_is_tagged (const struct GNUNET_CHAT_Contact *contact,
const char *tag);
/**
- * Calls an optional <i>callback</i> for each tag of a given chat
+ * Calls an optional <i>callback</i> for each tag of a given chat
* <i>contact</i>.
*
* @param[in] contact Chat contact
@@ -1140,7 +1140,7 @@ GNUNET_CHAT_contact_iterate_tags (struct GNUNET_CHAT_Contact *contact,
void *cls);
/**
- * Calls an optional <i>callback</i> for each attribute of a given chat
+ * Calls an optional <i>callback</i> for each attribute of a given chat
* <i>contact</i>.
*
* @param[in,out] contact Chat contact
@@ -1349,8 +1349,8 @@ GNUNET_CHAT_context_send_read_receipt (struct GNUNET_CHAT_Context *context,
struct GNUNET_CHAT_Message *message);
/**
- * Uploads a local file specified via its <i>path</i> using symmetric encryption
- * and shares the regarding information to download and decrypt it in a given
+ * Uploads a local file specified via its <i>path</i> and shares the
+ * regarding information to download and verify it in a given
* chat <i>context</i>.
*
* @param[in,out] context Chat context
@@ -1392,7 +1392,7 @@ GNUNET_CHAT_context_send_tag (struct GNUNET_CHAT_Context *context,
const char *tag);
/**
- * Opens a chat discourse under a specific <i>id</i> in a given chat
+ * Opens a chat discourse under a specific <i>id</i> in a given chat
* <i>context</i> to send data live to other contacts.
*
* @param[in,out] context Chat context
@@ -1432,7 +1432,7 @@ GNUNET_CHAT_context_iterate_files (struct GNUNET_CHAT_Context *context,
void *cls);
/**
- * Iterates through the discourses of a given chat <i>context</i> with a
+ * Iterates through the discourses of a given chat <i>context</i> with a
* selected callback and custom closure.
*
* @param[in,out] context Chat context
@@ -1483,7 +1483,7 @@ struct GNUNET_CHAT_Contact*
GNUNET_CHAT_message_get_recipient (const struct GNUNET_CHAT_Message *message);
/**
- * Returns #GNUNET_YES if the <i>message</i> was sent by the related chat
+ * Returns #GNUNET_YES if the <i>message</i> was sent by the related chat
* handle, otherwise it returns #GNUNET_NO.
*
* @param[in] message Message
@@ -1504,35 +1504,35 @@ enum GNUNET_GenericReturnValue
GNUNET_CHAT_message_is_private (const struct GNUNET_CHAT_Message *message);
/**
- * Returns #GNUNET_YES if the <i>message</i> was received recently by related
+ * Returns #GNUNET_YES if the <i>message</i> was received recently by related
* chat handle, otherwise it returns #GNUNET_NO.
*
* @param[in] message Message
* @return #GNUNET_YES if the message was received recently,
- * otherwise #GNUNET_NO
+ * otherwise #GNUNET_NO
*/
enum GNUNET_GenericReturnValue
GNUNET_CHAT_message_is_recent (const struct GNUNET_CHAT_Message *message);
/**
- * Returns #GNUNET_YES if the <i>message</i> was received because of an
+ * Returns #GNUNET_YES if the <i>message</i> was received because of an
* update by related chat handle, otherwise it returns #GNUNET_NO.
*
* @param[in] message Message
* @return #GNUNET_YES if the message was received to update
- * a previous message, otherwise #GNUNET_NO
+ * a previous message, otherwise #GNUNET_NO
*/
enum GNUNET_GenericReturnValue
GNUNET_CHAT_message_is_update (const struct GNUNET_CHAT_Message *message);
/**
- * Returns #GNUNET_YES if the <i>message</i> was received because of a
- * deletion by related chat handle or if it has been deleted internally,
+ * Returns #GNUNET_YES if the <i>message</i> was received because of a
+ * deletion by related chat handle or if it has been deleted internally,
* otherwise it returns #GNUNET_NO.
*
* @param[in] message Message
* @return #GNUNET_YES if the message was received to delete
- * a previous message, otherwise #GNUNET_NO
+ * a previous message, otherwise #GNUNET_NO
*/
enum GNUNET_GenericReturnValue
GNUNET_CHAT_message_is_deleted (const struct GNUNET_CHAT_Message *message);
@@ -1596,7 +1596,7 @@ void*
GNUNET_CHAT_message_get_user_pointer (const struct GNUNET_CHAT_Message *message);
/**
- * Returns the account of a given <i>message</i> which is either
+ * Returns the account of a given <i>message</i> which is either
* its sender or target of the message depending on the kind of
* the message, otherwise it returns NULL.
*
@@ -1661,7 +1661,7 @@ GNUNET_CHAT_message_delete (struct GNUNET_CHAT_Message *message,
unsigned int delay);
/**
- * Iterates through the tag messages in the context of a given
+ * Iterates through the tag messages in the context of a given
* <i>message</i>.
*
* @param[in,out] message Message
@@ -1675,7 +1675,7 @@ GNUNET_CHAT_message_iterate_tags (struct GNUNET_CHAT_Message *message,
void *cls);
/**
- * Returns the amount of data from a given chat <i>message</i> if its
+ * Returns the amount of data from a given chat <i>message</i> if its
* kind is #GNUNET_CHAT_KIND_DATA, otherwise it returns zero.
*
* @param[in] message Message
@@ -1692,7 +1692,7 @@ GNUNET_CHAT_message_available (const struct GNUNET_CHAT_Message *message);
* @param[in] message Message
* @param[out] data Data buffer
* @param[in] size Data size
- * @return #GNUNET_OK on success, #GNUNET_NO if there's missing data
+ * @return #GNUNET_OK on success, #GNUNET_NO if there's missing data
* to read, otherwise #GNUNET_SYSERR on failure
*/
enum GNUNET_GenericReturnValue
@@ -1702,12 +1702,12 @@ GNUNET_CHAT_message_read (const struct GNUNET_CHAT_Message *message,
/**
* Feeds the data from a given chat <i>message</i> if its kind is
- * #GNUNET_CHAT_KIND_DATA into a specific file descriptor (of pipe for
+ * #GNUNET_CHAT_KIND_DATA into a specific file descriptor (of pipe for
* example).
*
* @param[in] message Message
* @param[in] fd File descriptor
- * @return #GNUNET_OK on success, #GNUNET_NO if there's not enough data
+ * @return #GNUNET_OK on success, #GNUNET_NO if there's not enough data
* to read, otherwise #GNUNET_SYSERR on failure
*/
enum GNUNET_GenericReturnValue
@@ -1754,7 +1754,7 @@ uint64_t
GNUNET_CHAT_file_get_local_size (const struct GNUNET_CHAT_File *file);
/**
- * Returns a new allocated uri to access the content of a given
+ * Returns a new allocated uri to access the content of a given
* <i>file</i> handle.
*
* @param[in] file File handle
@@ -1783,6 +1783,17 @@ enum GNUNET_GenericReturnValue
GNUNET_CHAT_file_is_ready (const struct GNUNET_CHAT_File *file);
/**
+ * Returns if a given <i>file</i> handle is verified
+ * to match its provided hash.
+ *
+ * @param[in] file File handle
+ * @return #GNUNET_YES when valid, #GNUNET_NO on mismatch
+ * and #GNUNET_SYSERR on error
+ */
+enum GNUNET_GenericReturnValue
+GNUNET_CHAT_file_is_valid (const struct GNUNET_CHAT_File *file);
+
+/**
* Returns the temporary file name of the decrypted file preview
* of a given <i>file</i> handle.
*
@@ -1936,7 +1947,7 @@ enum GNUNET_GenericReturnValue
GNUNET_CHAT_invitation_is_rejected (const struct GNUNET_CHAT_Invitation *invitation);
/**
- * Returns whether the intend from a given
+ * Returns whether the intend from a given
* <i>invitation</i>. is to open a direct chat or
* a group chat.
*
@@ -1959,7 +1970,7 @@ GNUNET_CHAT_discourse_get_id (const struct GNUNET_CHAT_Discourse *discourse);
* Returns whether a chat <i>discourse</i> is currently open.
*
* @param[in] discourse Chat discourse
- * @return #GNUNET_YES if the discourse is open, #GNUNET_SYSERR on failure and
+ * @return #GNUNET_YES if the discourse is open, #GNUNET_SYSERR on failure and
* #GNUNET_NO otherwise.
*/
enum GNUNET_GenericReturnValue
@@ -2020,7 +2031,7 @@ int
GNUNET_CHAT_discourse_get_fd (const struct GNUNET_CHAT_Discourse *discourse);
/**
- * Iterates through the subscribed chat contacts of a given chat <i>discourse</i>
+ * Iterates through the subscribed chat contacts of a given chat <i>discourse</i>
* with a selected callback and custom closure.
*
* @param[in,out] discourse Chat discourse
diff --git a/src/gnunet_chat_file.c b/src/gnunet_chat_file.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2021--2024 GNUnet e.V.
+ Copyright (C) 2021--2024, 2026 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
@@ -26,9 +26,11 @@
#include "gnunet_chat_context.h"
#include "gnunet_chat_handle.h"
+#include "gnunet_chat_util.h"
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_fs_service.h>
+#include <gnunet/gnunet_util_lib.h>
#include <string.h>
static void
@@ -61,28 +63,31 @@ file_create_from_message (struct GNUNET_CHAT_Handle *handle,
{
GNUNET_assert((handle) && (message) && (message->uri));
- struct GNUNET_CHAT_File* file = GNUNET_new(struct GNUNET_CHAT_File);
+ struct GNUNET_FS_Uri *uri = GNUNET_FS_uri_parse(message->uri, NULL);
- if (!file)
+ if (!uri)
return NULL;
- file->handle = handle;
- file->name = GNUNET_strndup(message->name, NAME_MAX);
-
- file->key = GNUNET_new(struct GNUNET_CRYPTO_SymmetricSessionKey);
+ const struct GNUNET_HashCode *hash = GNUNET_FS_uri_chk_get_file_hash(uri);
- if (!(file->key))
+ if ((!hash) || (0 != GNUNET_CRYPTO_hash_cmp(hash, &(message->hash))))
{
- GNUNET_free(file);
+ GNUNET_FS_uri_destroy(uri);
return NULL;
}
- GNUNET_memcpy(file->key, &(message->key),
- sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey));
- GNUNET_memcpy(&(file->hash), &(message->hash), sizeof(file->hash));
+ struct GNUNET_CHAT_File* file = GNUNET_new(struct GNUNET_CHAT_File);
+
+ if (!file)
+ return NULL;
+
+ file->handle = handle;
+ file->name = GNUNET_strndup(message->name, NAME_MAX);
+
+ memcpy(&(file->hash), hash, sizeof(file->hash));
file->meta = GNUNET_FS_meta_data_create();
- file->uri = GNUNET_FS_uri_parse(message->uri, NULL);
+ file->uri = uri;
file_initialize(file);
@@ -108,13 +113,11 @@ file_create_from_chk_uri (struct GNUNET_CHAT_Handle *handle,
file->handle = handle;
file->name = NULL;
- file->key = NULL;
-
- GNUNET_memcpy(&(file->hash), hash, sizeof(file->hash));
+ memcpy(&(file->hash), hash, sizeof(file->hash));
file->meta = GNUNET_FS_meta_data_create();
file->uri = GNUNET_FS_uri_dup(uri);
-
+
file_initialize(file);
return file;
@@ -123,8 +126,7 @@ file_create_from_chk_uri (struct GNUNET_CHAT_Handle *handle,
struct GNUNET_CHAT_File*
file_create_from_disk (struct GNUNET_CHAT_Handle *handle,
const char *name,
- const struct GNUNET_HashCode *hash,
- const struct GNUNET_CRYPTO_SymmetricSessionKey *key)
+ const struct GNUNET_HashCode *hash)
{
GNUNET_assert((handle) && (name) && (hash));
@@ -136,24 +138,6 @@ file_create_from_disk (struct GNUNET_CHAT_Handle *handle,
file->handle = handle;
file->name = GNUNET_strndup(name, NAME_MAX);
- if (!key)
- {
- file->key = NULL;
- goto skip_key;
- }
-
- file->key = GNUNET_new(struct GNUNET_CRYPTO_SymmetricSessionKey);
-
- if (!(file->key))
- {
- GNUNET_free(file);
- return NULL;
- }
-
- GNUNET_memcpy(file->key, key,
- sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey));
-
-skip_key:
GNUNET_memcpy(&(file->hash), hash, sizeof(file->hash));
file->meta = GNUNET_FS_meta_data_create();
@@ -176,9 +160,6 @@ file_destroy (struct GNUNET_CHAT_File *file)
if (!(file->preview))
goto skip_preview;
- if (!(file->key))
- goto skip_filename;
-
char *filename = handle_create_file_path(
file->handle, &(file->hash)
);
@@ -249,9 +230,6 @@ skip_preview:
if (file->meta)
GNUNET_FS_meta_data_destroy(file->meta);
- if (file->key)
- GNUNET_free(file->key);
-
if (file->name)
GNUNET_free(file->name);
@@ -350,10 +328,6 @@ file_update_upload (struct GNUNET_CHAT_File *file,
msg.header.kind = GNUNET_MESSENGER_KIND_FILE;
- if (file->key)
- GNUNET_memcpy(&(msg.body.file.key), file->key,
- sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey));
-
GNUNET_memcpy(&(msg.body.file.hash), &(file->hash), sizeof(file->hash));
GNUNET_strlcpy(msg.body.file.name, file->name, NAME_MAX);
msg.body.file.uri = GNUNET_FS_uri_to_string(file->uri);
diff --git a/src/gnunet_chat_file.h b/src/gnunet_chat_file.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2021--2024 GNUnet e.V.
+ Copyright (C) 2021--2024, 2026 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
@@ -25,6 +25,7 @@
#ifndef GNUNET_CHAT_FILE_H_
#define GNUNET_CHAT_FILE_H_
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_fs_service.h>
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_util_lib.h>
@@ -76,7 +77,7 @@ struct GNUNET_CHAT_File
char *name;
struct GNUNET_HashCode hash;
- struct GNUNET_CRYPTO_SymmetricSessionKey *key;
+
struct GNUNET_FS_MetaData *meta;
struct GNUNET_FS_Uri *uri;
@@ -125,21 +126,18 @@ file_create_from_chk_uri (struct GNUNET_CHAT_Handle *handle,
/**
* Creates a chat file handle from a local file on disk
- * under a given <i>name</i> using a <i>hash</i> and a
- * selected symmetric <i>key</i> with a selected chat
- * <i>handle</i>.
+ * under a given <i>name</i> using a <i>hash</i> with
+ * a selected chat <i>handle</i>.
*
* @param[in,out] handle Chat handle
* @param[in] name File name
* @param[in] hash File hash
- * @param[in] key Symmetric key
* @return New chat file handle
*/
struct GNUNET_CHAT_File*
file_create_from_disk (struct GNUNET_CHAT_Handle *handle,
const char *name,
- const struct GNUNET_HashCode *hash,
- const struct GNUNET_CRYPTO_SymmetricSessionKey *key);
+ const struct GNUNET_HashCode *hash);
/**
* Destroys a chat <i>file</i> handle and frees its memory.
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
@@ -211,14 +211,14 @@ GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle,
handle->next_secret,
sizeof(*(handle->next_secret))
);
-
+
GNUNET_free(handle->next_secret);
}
if ((secret) && (secret_len > 0))
{
handle->next_secret = GNUNET_new(struct GNUNET_HashCode);
-
+
if (handle->next_secret)
GNUNET_CRYPTO_hash(secret, secret_len, handle->next_secret);
}
@@ -246,7 +246,7 @@ GNUNET_CHAT_disconnect (struct GNUNET_CHAT_Handle *handle)
if ((!handle) || (handle->destruction))
return;
-
+
if (handle->connection)
GNUNET_SCHEDULER_cancel(handle->connection);
@@ -732,10 +732,10 @@ GNUNET_CHAT_request_file (struct GNUNET_CHAT_Handle *handle,
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!handle) || (handle->destruction) ||
+ if ((!handle) || (handle->destruction) ||
(!uri) || (GNUNET_CHAT_URI_TYPE_FS != uri->type))
return NULL;
-
+
if (!GNUNET_FS_uri_test_chk(uri->fs.uri))
return NULL;
@@ -759,13 +759,13 @@ GNUNET_CHAT_request_file (struct GNUNET_CHAT_Handle *handle,
if (!file)
return NULL;
- if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(handle->files, hash, file,
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(handle->files, hash, file,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
{
file_destroy(file);
file = NULL;
}
-
+
return file;
}
@@ -781,7 +781,7 @@ GNUNET_CHAT_upload_file (struct GNUNET_CHAT_Handle *handle,
if ((!handle) || (handle->destruction) ||
(!path))
return NULL;
-
+
struct GNUNET_HashCode hash;
if (GNUNET_OK != util_hash_file(path, &hash))
return NULL;
@@ -814,8 +814,7 @@ GNUNET_CHAT_upload_file (struct GNUNET_CHAT_Handle *handle,
file = file_create_from_disk(
handle,
basename(p),
- &hash,
- NULL
+ &hash
);
GNUNET_free(p);
@@ -1268,7 +1267,7 @@ GNUNET_CHAT_contact_set_blocked (struct GNUNET_CHAT_Contact *contact,
struct GNUNET_CHAT_ContactIterateContexts it;
it.contact = contact;
it.tag = NULL;
-
+
if (GNUNET_NO == blocked)
it.cb = contact_untag;
else if (GNUNET_YES == blocked)
@@ -1384,7 +1383,7 @@ GNUNET_CHAT_contact_get_attributes (struct GNUNET_CHAT_Contact *contact,
struct GNUNET_CHAT_InternalTickets *tickets;
tickets = contact->tickets_head;
-
+
while (tickets)
{
ticket_consume(
@@ -1663,7 +1662,7 @@ GNUNET_CHAT_context_request (struct GNUNET_CHAT_Context *context)
if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(
handle->contexts, &(key.hash)))
return GNUNET_SYSERR;
-
+
const struct GNUNET_PeerIdentity *pid = handle->pid;
if (!pid)
@@ -1736,7 +1735,7 @@ GNUNET_CHAT_context_get_contact (struct GNUNET_CHAT_Context *context)
find.ignore_key = GNUNET_MESSENGER_get_key(context->handle->messenger);
else
find.ignore_key = NULL;
-
+
find.contact = NULL;
int member_count = GNUNET_MESSENGER_iterate_members(
@@ -1901,22 +1900,12 @@ GNUNET_CHAT_context_send_file (struct GNUNET_CHAT_Context *context,
return NULL;
}
- struct GNUNET_CRYPTO_SymmetricSessionKey key;
- GNUNET_CRYPTO_symmetric_create_session_key(&key);
-
- if (GNUNET_OK != util_encrypt_file(filename, &hash, &key))
- {
- GNUNET_free(filename);
- return NULL;
- }
-
char* p = GNUNET_strdup(path);
file = file_create_from_disk(
context->handle,
basename(p),
- &hash,
- &key
+ &hash
);
GNUNET_free(p);
@@ -1970,7 +1959,7 @@ GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context,
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!context) || (!file) ||
+ if ((!context) || (!file) ||
(!(file->name)) || (strlen(file->name) > NAME_MAX) ||
(!(file->uri)) || (!(context->room)))
return GNUNET_SYSERR;
@@ -1980,12 +1969,6 @@ GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context,
msg.header.kind = GNUNET_MESSENGER_KIND_FILE;
- if (file->key)
- GNUNET_memcpy(&(msg.body.file.key), file->key,
- sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey));
- else
- memset(&(msg.body.file.key), 0, sizeof(msg.body.file.key));
-
GNUNET_memcpy(&(msg.body.file.hash), &(file->hash), sizeof(file->hash));
GNUNET_strlcpy(msg.body.file.name, file->name, NAME_MAX);
msg.body.file.uri = GNUNET_FS_uri_to_string(file->uri);
@@ -2314,7 +2297,7 @@ GNUNET_CHAT_message_is_tagged (const struct GNUNET_CHAT_Message *message,
const struct GNUNET_CHAT_InternalTagging *tagging = GNUNET_CONTAINER_multihashmap_get(
message->context->taggings, &(message->hash));
-
+
if (!tagging)
return GNUNET_NO;
@@ -2332,7 +2315,7 @@ GNUNET_CHAT_message_get_read_receipt (struct GNUNET_CHAT_Message *message,
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
+ if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
(!(message->context)))
return GNUNET_SYSERR;
@@ -2421,7 +2404,7 @@ GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message)
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
+ if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
(!(message->context)))
return NULL;
@@ -2440,7 +2423,7 @@ GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message)
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
+ if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
(!(message->context)))
return NULL;
@@ -2462,9 +2445,9 @@ GNUNET_CHAT_message_get_discourse (const struct GNUNET_CHAT_Message *message)
if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
(!(message->context)) || (!(message->context->discourses)))
return NULL;
-
+
struct GNUNET_CHAT_Discourse *discourse;
-
+
if (GNUNET_MESSENGER_KIND_SUBSCRIBTION == message->msg->header.kind)
discourse = GNUNET_CONTAINER_multishortmap_get(
message->context->discourses,
@@ -2485,7 +2468,7 @@ GNUNET_CHAT_message_get_target (const struct GNUNET_CHAT_Message *message)
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
+ if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
(!(message->context)))
return NULL;
@@ -2510,10 +2493,10 @@ GNUNET_CHAT_message_delete (struct GNUNET_CHAT_Message *message,
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
+ if ((!message) || (GNUNET_YES != message_has_msg(message)) ||
(!(message->context)))
return GNUNET_SYSERR;
-
+
struct GNUNET_TIME_Relative rel = GNUNET_TIME_relative_multiply(
GNUNET_TIME_relative_get_second_(), delay
);
@@ -2540,7 +2523,7 @@ GNUNET_CHAT_message_iterate_tags (struct GNUNET_CHAT_Message *message,
const struct GNUNET_CHAT_InternalTagging *tagging = GNUNET_CONTAINER_multihashmap_get(
message->context->taggings, &(message->hash));
-
+
if (!tagging)
return 0;
@@ -2724,6 +2707,39 @@ GNUNET_CHAT_file_is_ready (const struct GNUNET_CHAT_File *file)
}
+enum GNUNET_GenericReturnValue
+GNUNET_CHAT_file_is_valid (const struct GNUNET_CHAT_File *file)
+{
+ GNUNET_CHAT_VERSION_ASSERT();
+
+ if ((!file) || (file->status & GNUNET_CHAT_FILE_STATUS_MASK))
+ return GNUNET_SYSERR;
+
+ char *filename = handle_create_file_path(
+ file->handle, &(file->hash)
+ );
+
+ if (!filename)
+ return GNUNET_SYSERR;
+
+ struct GNUNET_HashCode hash;
+ enum GNUNET_GenericReturnValue result;
+
+ if (GNUNET_OK == util_hash_file(filename, &hash))
+ {
+ if (0 == GNUNET_CRYPTO_hash_cmp(&hash, &(file->hash)))
+ result = GNUNET_YES;
+ else
+ result = GNUNET_NO;
+ }
+ else
+ result = GNUNET_SYSERR;
+
+ GNUNET_free(filename);
+ return result;
+}
+
+
const char*
GNUNET_CHAT_file_open_preview (struct GNUNET_CHAT_File *file)
{
@@ -2731,49 +2747,24 @@ GNUNET_CHAT_file_open_preview (struct GNUNET_CHAT_File *file)
if (!file)
return NULL;
-
+
if (file->preview)
return file->preview;
-
+
char *filename = handle_create_file_path(
file->handle, &(file->hash)
);
if (!filename)
return NULL;
-
+
if (GNUNET_YES != GNUNET_DISK_file_test(filename))
- goto free_filename;
-
- if (!(file->key))
{
- file->preview = filename;
- return file->preview;
+ GNUNET_free(filename);
+ filename = NULL;
}
-
- file->preview = GNUNET_DISK_mktemp(
- file->name? file->name : ""
- );
-
- if (!(file->preview))
- goto free_filename;
-
- remove(file->preview);
- if (GNUNET_OK != GNUNET_DISK_file_copy(filename, file->preview))
- goto cleanup_preview;
-
- if (GNUNET_OK == util_decrypt_file(file->preview, &(file->hash), file->key))
- goto free_filename;
-
- remove(file->preview);
-
-cleanup_preview:
- GNUNET_free(file->preview);
- file->preview = NULL;
-
-free_filename:
- GNUNET_free(filename);
+ file->preview = filename;
return file->preview;
}
@@ -2786,22 +2777,6 @@ GNUNET_CHAT_file_close_preview (struct GNUNET_CHAT_File *file)
if ((!file) || (!(file->preview)))
return;
- if (!(file->key))
- goto skip_filename;
-
- char *filename = handle_create_file_path(
- file->handle, &(file->hash)
- );
-
- if (!filename)
- goto skip_filename;
-
- if (0 != strcmp(filename, file->preview))
- remove(file->preview);
-
- GNUNET_free(filename);
-
-skip_filename:
GNUNET_free(file->preview);
file->preview = NULL;
}
@@ -2872,7 +2847,7 @@ GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file,
const uint64_t size = GNUNET_FS_uri_chk_get_file_size(file->uri);
uint64_t offset;
- if (GNUNET_OK != GNUNET_DISK_file_size(filename, &offset,
+ if (GNUNET_OK != GNUNET_DISK_file_size(filename, &offset,
GNUNET_NO, GNUNET_YES))
offset = 0;
@@ -3041,7 +3016,7 @@ GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation)
handle->contexts, &(invitation->key.hash), context,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
goto destroy_context;
-
+
if (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type)
{
context_write_records(context);
@@ -3121,10 +3096,10 @@ GNUNET_CHAT_invitation_is_rejected (const struct GNUNET_CHAT_Invitation *invitat
const struct GNUNET_CHAT_InternalTagging *tagging = GNUNET_CONTAINER_multihashmap_get(
invitation->context->taggings, &(invitation->hash));
-
+
if (!tagging)
return GNUNET_NO;
-
+
if (internal_tagging_iterate(tagging, GNUNET_NO, NULL, NULL, NULL) > 0)
return GNUNET_YES;
else
@@ -3212,7 +3187,7 @@ GNUNET_CHAT_discourse_close (struct GNUNET_CHAT_Discourse *discourse)
if ((!discourse) || (!(discourse->context)) || (!(discourse->context->room)))
return;
-
+
struct GNUNET_MESSENGER_Message msg;
memset(&msg, 0, sizeof(msg));
@@ -3241,10 +3216,10 @@ GNUNET_CHAT_discourse_write (struct GNUNET_CHAT_Discourse *discourse,
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!discourse) || (!data) || (!(discourse->context)) ||
+ if ((!discourse) || (!data) || (!(discourse->context)) ||
(!(discourse->context->room)))
return GNUNET_SYSERR;
-
+
static const uint64_t max_size = (uint16_t) (
GNUNET_MAX_MESSAGE_SIZE - GNUNET_MIN_MESSAGE_SIZE -
sizeof (struct GNUNET_MESSENGER_Message)
diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c
@@ -142,200 +142,6 @@ util_hash_file (const char *filename,
return GNUNET_OK;
}
-enum GNUNET_GenericReturnValue
-util_encrypt_file (const char *filename,
- const struct GNUNET_HashCode *hash,
- const struct GNUNET_CRYPTO_SymmetricSessionKey *key)
-{
- GNUNET_assert((filename) && (hash));
-
- uint64_t size;
-
- if (GNUNET_OK != GNUNET_DISK_file_size(filename, &size, GNUNET_NO, GNUNET_YES))
- return GNUNET_SYSERR;
-
- struct GNUNET_DISK_FileHandle *file = GNUNET_DISK_file_open(
- filename, GNUNET_DISK_OPEN_READWRITE,
- GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE
- );
-
- if (!file)
- return GNUNET_SYSERR;
-
- if (!size)
- return GNUNET_DISK_file_close(file);
-
- struct GNUNET_DISK_MapHandle *mapping;
- const void* data = GNUNET_DISK_file_map(
- file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size
- );
-
- if ((!data) || (!mapping))
- {
- GNUNET_DISK_file_close(file);
- return GNUNET_SYSERR;
- }
-
- const uint64_t block_size = 1024*1024;
- ssize_t result = 0;
-
- const uint64_t blocks = ((size + block_size - 1) / block_size);
-
- if (!key)
- goto skip_encryption;
-
- struct GNUNET_CRYPTO_SymmetricInitializationVector first_iv;
-
- if (GNUNET_YES != GNUNET_CRYPTO_hkdf_gnunet (
- &first_iv, sizeof (first_iv),
- GNUNET_CHAT_SALT_FILE,
- sizeof (GNUNET_CHAT_SALT_FILE),
- key,
- sizeof (*key),
- GNUNET_CRYPTO_kdf_arg_auto(hash)))
- return GNUNET_SYSERR;
-
- struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
-
- for (uint64_t i = 0; i < blocks; i++)
- {
- const uint64_t index = (blocks - i - 1);
- const uint64_t offset = block_size * index;
-
- const uint64_t remaining = (size - offset);
- void* location = ((uint8_t*) data) + offset;
-
- if (index > 0)
- memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv));
- else
- memcpy(&iv, &first_iv, sizeof(iv));
-
- result = GNUNET_CRYPTO_symmetric_encrypt(
- location,
- remaining >= block_size? block_size : remaining,
- key,
- &iv,
- location
- );
-
- if (result < 0)
- break;
- }
-
-skip_encryption:
- if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping))
- result = -1;
-
- if (GNUNET_OK != GNUNET_DISK_file_sync(file))
- result = -1;
-
- if (GNUNET_OK != GNUNET_DISK_file_close(file))
- result = -1;
-
- if (result < 0)
- return GNUNET_SYSERR;
-
- return GNUNET_OK;
-}
-
-enum GNUNET_GenericReturnValue
-util_decrypt_file (const char *filename,
- const struct GNUNET_HashCode *hash,
- const struct GNUNET_CRYPTO_SymmetricSessionKey *key)
-{
- GNUNET_assert((filename) && (hash));
-
- uint64_t size;
-
- if (GNUNET_OK != GNUNET_DISK_file_size(filename, &size, GNUNET_NO, GNUNET_YES))
- return GNUNET_SYSERR;
-
- struct GNUNET_DISK_FileHandle *file = GNUNET_DISK_file_open(
- filename, GNUNET_DISK_OPEN_READWRITE,
- GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE
- );
-
- if (!file)
- return GNUNET_SYSERR;
-
- struct GNUNET_DISK_MapHandle *mapping = NULL;
- void* data = GNUNET_DISK_file_map(
- file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size
- );
-
- if ((!data) || (!mapping))
- {
- GNUNET_DISK_file_close(file);
- return GNUNET_SYSERR;
- }
-
- const uint64_t block_size = 1024*1024;
- struct GNUNET_HashCode check;
- ssize_t result = 0;
-
- const uint64_t blocks = ((size + block_size - 1) / block_size);
-
- if (!key)
- goto skip_decryption;
-
- struct GNUNET_CRYPTO_SymmetricInitializationVector first_iv;
-
- if (GNUNET_YES != GNUNET_CRYPTO_hkdf_gnunet (
- &first_iv, sizeof (first_iv),
- GNUNET_CHAT_SALT_FILE,
- sizeof (GNUNET_CHAT_SALT_FILE),
- key,
- sizeof (*key),
- GNUNET_CRYPTO_kdf_arg_auto(hash)))
- return GNUNET_SYSERR;
-
- struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
-
- for (uint64_t index = 0; index < blocks; index++)
- {
- const uint64_t offset = block_size * index;
-
- const uint64_t remaining = (size - offset);
- void* location = ((uint8_t*) data) + offset;
-
- if (index > 0)
- memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv));
- else
- memcpy(&iv, &first_iv, sizeof(iv));
-
- result = GNUNET_CRYPTO_symmetric_decrypt(
- location,
- remaining >= block_size? block_size : remaining,
- key,
- &iv,
- location
- );
-
- if (result < 0)
- break;
- }
-
-skip_decryption:
- GNUNET_CRYPTO_hash(data, size, &check);
-
- if (0 != GNUNET_CRYPTO_hash_cmp(hash, &check))
- result = -1;
-
- if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping))
- result = -1;
-
- if (GNUNET_OK != GNUNET_DISK_file_sync(file))
- result = -1;
-
- if (GNUNET_OK != GNUNET_DISK_file_close(file))
- result = -1;
-
- if (result < 0)
- return GNUNET_SYSERR;
-
- return GNUNET_OK;
-}
-
int
util_get_dirname (const char *directory,
const char *subdir,
diff --git a/src/gnunet_chat_util.h b/src/gnunet_chat_util.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2021--2024 GNUnet e.V.
+ Copyright (C) 2021--2024, 2026 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
@@ -64,7 +64,7 @@ util_shorthash_from_member (const struct GNUNET_MESSENGER_Contact *member,
struct GNUNET_ShortHashCode *shorthash);
/**
- * Converts a discourse id into a short hash variant for map access
+ * Converts a discourse id into a short hash variant for map access
* as key.
*
* @param[in] id Discourse id
@@ -108,37 +108,6 @@ util_hash_file (const char *filename,
struct GNUNET_HashCode *hash);
/**
- * Encrypts a file inplace under a given <i>filename</i>
- * with a selected symmetric <i>key</i> and its <i>hash</i>
- * as initialization vector.
- *
- * @param[in] filename File name
- * @param[in] hash Hash of file
- * @param[in] key Symmetric key
- * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
- */
-enum GNUNET_GenericReturnValue
-util_encrypt_file (const char *filename,
- const struct GNUNET_HashCode *hash,
- const struct GNUNET_CRYPTO_SymmetricSessionKey *key);
-
-/**
- * Decrypts a file inplace under a given <i>filename</i>
- * with a selected symmetric <i>key</i> and its <i>hash</i>
- * as parameter for the initialization vector and comparison
- * to verify success.
- *
- * @param[in] filename File name
- * @param[in] hash Hash of file
- * @param[in] key Symmetric key
- * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR
- */
-enum GNUNET_GenericReturnValue
-util_decrypt_file (const char *filename,
- const struct GNUNET_HashCode *hash,
- const struct GNUNET_CRYPTO_SymmetricSessionKey *key);
-
-/**
* Append the path of a <i>directory</i> and a custom
* subdirectory name to a composed <i>filename</i>.
*
@@ -219,7 +188,7 @@ util_lobby_name (const struct GNUNET_HashCode *hash,
char **name);
/**
- * Check whether an identity <i>name</i> could be a
+ * Check whether an identity <i>name</i> could be a
* standardized name for a lobby.
* @see util_lobby_name()
*