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:
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;
+}