diff --git a/tools/chatgui/src/mainwindow.cpp b/tools/chatgui/src/mainwindow.cpp index fb0384e9..6995c6c5 100644 --- a/tools/chatgui/src/mainwindow.cpp +++ b/tools/chatgui/src/mainwindow.cpp @@ -27,8 +27,6 @@ extern "C" { #include "../transport/chat_core.h" #include "../../lib/mem.h" #include "../../lib/debug_config.h" -#include -#include } static MainWindow* s_mainWindow = nullptr; @@ -405,91 +403,8 @@ void MainWindow::onCreateGroupRequested() { QString name = dlg.groupName(); if (name.isEmpty()) return; - /* генерация X25519 ключей */ - uint8_t x25519_pub[32] = {0}, x25519_priv[32] = {0}; - { - EVP_PKEY* pkey = nullptr; - EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, nullptr); - if (ctx) { - EVP_PKEY_keygen_init(ctx); - EVP_PKEY_generate(ctx, &pkey); - EVP_PKEY_CTX_free(ctx); - } - if (pkey) { - size_t pkLen = 32, skLen = 32; - EVP_PKEY_get_raw_public_key(pkey, x25519_pub, &pkLen); - EVP_PKEY_get_raw_private_key(pkey, x25519_priv, &skLen); - EVP_PKEY_free(pkey); - } - } - - /* генерация Ed25519 ключей */ - uint8_t ed25519_pub[32] = {0}, ed25519_priv[32] = {0}; - EVP_PKEY* ed_pkey = nullptr; - { - EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, nullptr); - if (ctx) { - EVP_PKEY_keygen_init(ctx); - EVP_PKEY_generate(ctx, &ed_pkey); - EVP_PKEY_CTX_free(ctx); - } - if (ed_pkey) { - size_t pkLen = 32, skLen = 32; - EVP_PKEY_get_raw_public_key(ed_pkey, ed25519_pub, &pkLen); - EVP_PKEY_get_raw_private_key(ed_pkey, ed25519_priv, &skLen); - } - } - - /* случайный channel_id (uint64 → decimal string) */ - uint64_t chId = 0; - RAND_bytes((uint8_t*)&chId, sizeof(chId)); - QString channelId = QString::number(chId); - - /* owner_node_id из instance */ - uint64_t ownerNodeId = m_node->nodeIdHex().toULongLong(nullptr, 16); - - /* Ed25519 подпись: channel_id || name || owner_node_id(8 LE) || x25519_pub(32) || ed25519_pub(32) */ - uint8_t sig[64] = {0}; - if (ed_pkey) { - QByteArray nameUtf8 = name.toUtf8(); - QByteArray chIdUtf8 = channelId.toUtf8(); - size_t msgLen = chIdUtf8.size() + 1 + nameUtf8.size() + 1 + 8 + 32 + 32; - uint8_t* msg = (uint8_t*)malloc(msgLen); - if (msg) { - uint8_t* p = msg; - memcpy(p, chIdUtf8.constData(), chIdUtf8.size()); p += chIdUtf8.size(); *p++ = '\0'; - memcpy(p, nameUtf8.constData(), nameUtf8.size()); p += nameUtf8.size(); *p++ = '\0'; - memcpy(p, &ownerNodeId, 8); p += 8; - memcpy(p, x25519_pub, 32); p += 32; - memcpy(p, ed25519_pub, 32); p += 32; - - EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); - if (mdctx) { - EVP_DigestSignInit(mdctx, nullptr, nullptr, nullptr, ed_pkey); - size_t siglen = 64; - EVP_DigestSign(mdctx, sig, &siglen, msg, msgLen); - EVP_MD_CTX_free(mdctx); - } - free(msg); - } - EVP_PKEY_free(ed_pkey); - } + char* name_copy = u_strdup(name.toUtf8().constData()); + if (name_copy) gui_bridge_post_uasync_fn(chat_core_create_channel_auto_trampoline, name_copy); - /* отправляем в uasync-поток */ - struct chat_channel_create* req = (struct chat_channel_create*)u_malloc(sizeof(*req)); - memset(req, 0, sizeof(*req)); - snprintf(req->channel_id, sizeof(req->channel_id), "%s", qPrintable(channelId)); - snprintf(req->name, sizeof(req->name), "%s", name.toUtf8().constData()); - req->owner_node_id = ownerNodeId; - memcpy(req->x25519_pubkey, x25519_pub, 32); - memcpy(req->x25519_privkey, x25519_priv, 32); - memcpy(req->ed25519_pubkey, ed25519_pub, 32); - memcpy(req->ed25519_privkey, ed25519_priv, 32); - memcpy(req->signature, sig, 64); - - gui_bridge_post_uasync_fn(chat_core_create_channel_trampoline, req); - m_pendingChannelSelect = channelId; - - DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "MainWindow: create group request posted ch=%s name=%s", - qPrintable(channelId), qPrintable(name)); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "MainWindow: create group request posted name=%s", qPrintable(name)); } diff --git a/tools/chatgui/transport/chat_channel.c b/tools/chatgui/transport/chat_channel.c index c14a52f0..0fe08b52 100644 --- a/tools/chatgui/transport/chat_channel.c +++ b/tools/chatgui/transport/chat_channel.c @@ -21,6 +21,7 @@ #include #include +#include /* ─── Ed25519 подпись join-сообщения ─── */ @@ -163,6 +164,65 @@ void chat_core_create_channel_trampoline(void* arg) { u_free(req); } +void chat_core_create_channel_auto_trampoline(void* arg) { + chat_core_create_channel_auto((const char*)arg); + u_free(arg); +} + +void chat_core_create_channel_auto(const char* name) { + if (!g_cc.initialized || !name) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: create_channel_auto — not initialized or NULL name", CC_ID); + return; + } + DEBUG_INFO(DEBUG_CATEGORY_CONNECTIVITY, "%s: create_channel_auto BEGIN name=%s", CC_ID, name); + + uint8_t x25519_pub[32] = {0}, x25519_priv[32] = {0}; + { EVP_PKEY* pkey = NULL; EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL); + if (ctx) { EVP_PKEY_keygen_init(ctx); EVP_PKEY_generate(ctx, &pkey); EVP_PKEY_CTX_free(ctx); } + if (pkey) { size_t pkLen = 32, skLen = 32; EVP_PKEY_get_raw_public_key(pkey, x25519_pub, &pkLen); EVP_PKEY_get_raw_private_key(pkey, x25519_priv, &skLen); EVP_PKEY_free(pkey); } } + + uint8_t ed25519_pub[32] = {0}, ed25519_priv[32] = {0}; + EVP_PKEY* ed_pkey = NULL; + { EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL); + if (ctx) { EVP_PKEY_keygen_init(ctx); EVP_PKEY_generate(ctx, &ed_pkey); EVP_PKEY_CTX_free(ctx); } + if (ed_pkey) { size_t pkLen = 32, skLen = 32; EVP_PKEY_get_raw_public_key(ed_pkey, ed25519_pub, &pkLen); EVP_PKEY_get_raw_private_key(ed_pkey, ed25519_priv, &skLen); } } + + uint64_t chId = 0; RAND_bytes((uint8_t*)&chId, sizeof(chId)); + char channelId[64]; snprintf(channelId, sizeof(channelId), "%llu", (unsigned long long)chId); + + uint8_t sig[64] = {0}; + if (ed_pkey) { + size_t nameLen = strlen(name); + size_t chIdLen = strlen(channelId); + size_t msgLen = chIdLen + 1 + nameLen + 1 + 8 + 32 + 32; + uint8_t* msg = u_malloc(msgLen); + if (msg) { + uint8_t* p = msg; + memcpy(p, channelId, chIdLen); p += chIdLen; *p++ = '\0'; + memcpy(p, name, nameLen); p += nameLen; *p++ = '\0'; + memcpy(p, &g_cc.my_node_id, 8); p += 8; + memcpy(p, x25519_pub, 32); p += 32; + memcpy(p, ed25519_pub, 32); + EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); + if (mdctx) { EVP_DigestSignInit(mdctx, NULL, NULL, NULL, ed_pkey); size_t sl = 64; EVP_DigestSign(mdctx, sig, &sl, msg, msgLen); EVP_MD_CTX_free(mdctx); } + u_free(msg); + } + EVP_PKEY_free(ed_pkey); + } + + struct chat_channel_create* req = u_calloc(1, sizeof(*req)); + if (!req) return; + snprintf(req->channel_id, sizeof(req->channel_id), "%s", channelId); + snprintf(req->name, sizeof(req->name), "%s", name); + req->owner_node_id = g_cc.my_node_id; + memcpy(req->x25519_pubkey, x25519_pub, 32); memcpy(req->x25519_privkey, x25519_priv, 32); + memcpy(req->ed25519_pubkey, ed25519_pub, 32); memcpy(req->ed25519_privkey, ed25519_priv, 32); + memcpy(req->signature, sig, 64); + + chat_core_create_channel(req); + u_free(req); +} + /* ─── управление подключением к каналу (выбор в GUI) ─── */ void chat_core_connect_channel(const char* ch_id) { diff --git a/tools/chatgui/transport/chat_core.h b/tools/chatgui/transport/chat_core.h index 86307d47..a2c15aed 100644 --- a/tools/chatgui/transport/chat_core.h +++ b/tools/chatgui/transport/chat_core.h @@ -60,6 +60,7 @@ void chat_core_ensure_channel_ready(const char* ch_id); void chat_core_create_channel(struct chat_channel_create* req); void chat_core_create_channel_trampoline(void* arg); void chat_core_create_channel_auto(const char* name); +void chat_core_create_channel_auto_trampoline(void* arg); /* ── Утилиты ── */