Browse Source

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.
topo_upd
Evgeny 2 months ago
parent
commit
6c59ed43b2
  1. 91
      tools/chatgui/src/mainwindow.cpp
  2. 60
      tools/chatgui/transport/chat_channel.c
  3. 1
      tools/chatgui/transport/chat_core.h

91
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 <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);
}
}
/* генерация 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));
}

60
tools/chatgui/transport/chat_channel.c

@ -21,6 +21,7 @@
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
/* ─── 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) {

1
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);
/* ── Утилиты ── */

Loading…
Cancel
Save