chatgui: move crypto from MainWindow to transport layer

chat_channel.c: new chat_core_create_channel_auto(name) — generates
X25519/Ed25519 keys, random channel_id, Ed25519 signature, creates channel.
chat_core_create_channel_auto_trampoline for gui_bridge_post_uasync_fn.

mainwindow.cpp: onCreateGroupRequested() reduced from 100 to 15 lines.
Removed openssl/evp.h and openssl/rand.h includes from UI code.
This commit is contained in:
Evgeny committed 2026-07-23 22:43:13 +03:00
1 parent 3f662d85ba
commit 6c59ed43b2
3 files changed
+64 -88

No files matched your search

+3 -88
View File
@@ -27,8 +27,6 @@ extern "C" {
#include "../transport/chat_core.h"
#include "../../lib/mem.h"
#include "../../lib/debug_config.h"
#include <openssl/evp.h>
#include <openssl/rand.h>
}
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);
}
}
char* name_copy = u_strdup(name.toUtf8().constData());
if (name_copy) gui_bridge_post_uasync_fn(chat_core_create_channel_auto_trampoline, name_copy);
/* генерация 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);
}
/* отправляем в 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));
}