libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit 50aebeabe539a9bb8e6b563c5ad5fcf1d4968eae
parent 051e2f64428217295b0c73c22766fd477bfd5dc2
Author: Jacki <jacki@thejackimonster.de>
Date:   Fri, 16 Jan 2026 22:12:52 +0100

Implement function for random secret generation

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Minclude/gnunet/gnunet_chat_lib.h | 16++++++++++++++++
Msrc/gnunet_chat_lib.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h @@ -2033,6 +2033,22 @@ GNUNET_CHAT_discourse_iterate_contacts (struct GNUNET_CHAT_Discourse *discourse, GNUNET_CHAT_DiscourseContactCallback callback, void *cls); +/** + * Generates a chat account <i>secret</i> which can be used + * in case the user may not pick a secret manually. The length + * can be explicitly provided. + * + * The provided buffer to store the secret needs to have enough + * space in memory for at least the amount of requested characters. + * + * @param[out] secret Chat account secret + * @param[in] secret_len Length of secret + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_CHAT_generate_secret (char *secret, + uint32_t secret_len); + /**@}*/ #endif /* GNUNET_CHAT_LIB_H_ */ diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -3309,3 +3309,61 @@ GNUNET_CHAT_discourse_iterate_contacts (struct GNUNET_CHAT_Discourse *discourse, return iterations; } + +enum GNUNET_GenericReturnValue +GNUNET_CHAT_generate_secret (char *secret, + uint32_t secret_len) +{ + GNUNET_CHAT_VERSION_ASSERT(); + + if (secret_len <= 0) + return GNUNET_SYSERR; + + const uint32_t requested = secret_len * 5 / 8 + 1; + const uint32_t size = ((requested*8) + (((requested*8) % 5) > 0 ? 5 - ((requested*8) % 5) : 0)) / 5; + + char *raw_secret = GNUNET_malloc(requested); + char *buf; + + if (!raw_secret) + return GNUNET_SYSERR; + + if (size > secret_len) + { + buf = GNUNET_malloc(size); + + if (!buf) + { + GNUNET_free(raw_secret); + return GNUNET_SYSERR; + } + } + else + buf = secret; + + GNUNET_CRYPTO_random_block( + GNUNET_CRYPTO_QUALITY_STRONG, + raw_secret, + requested + ); + + enum GNUNET_GenericReturnValue result; + result = GNUNET_STRINGS_data_to_string( + raw_secret, + requested, + buf, + size + ) == NULL? GNUNET_SYSERR : GNUNET_OK; + + GNUNET_CRYPTO_zero_keys(raw_secret, requested); + GNUNET_free(raw_secret); + + if (buf != secret) + { + GNUNET_memcpy(secret, buf, secret_len); + GNUNET_CRYPTO_zero_keys(buf, size); + GNUNET_free(buf); + } + + return result; +}