Fix: ETCP connection initialization and crypto handling
- Fixed etcp_encrypt_send function to properly handle encryption with timestamps - Corrected packet parsing in etcp_connections_read_callback - Fixed INIT_RESPONSE packet handling and connection establishment - Added proper error handling for crypto operations - Removed debug file etcp_connections.c3 - Updated secure_channel.c with better error logging - Fixed peer public key validation and setting - Improved connection state tracking and initialization
This commit is contained in:
1 parent
4d55bedb82
commit
6fd3a39cc8
9 files changed
+389
-273
No files matched your search
+73
-55
@@ -398,53 +398,30 @@ void etcp_link_close(struct ETCP_LINK* link) {
|
||||
}
|
||||
|
||||
int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
|
||||
printf("[ETCP DEBUG] etcp_encrypt_send: ENTERING FUNCTION\n");
|
||||
// printf("[ETCP DEBUG] etcp_encrypt_send: ENTERING FUNCTION\n");
|
||||
|
||||
int errcode=0;
|
||||
sc_context_t* sc = &dgram->link->etcp->crypto_ctx;
|
||||
int len=dgram->data_len-dgram->noencrypt_len;// не забываем добавить timestamp (2 bytes)
|
||||
if (len<=0 || len>1480) { dgram->link->send_errors++; errcode=1; goto es_err; }
|
||||
uint8_t enc_buf[1600];
|
||||
size_t enc_buf_len;
|
||||
size_t enc_buf_len=0;
|
||||
dgram->timestamp=get_current_timestamp();
|
||||
printf("[ETCP DEBUG] About to encrypt: data_len=%d, noencrypt_len=%d, len=%d\\n", dgram->data_len, dgram->noencrypt_len, len);
|
||||
|
||||
// DUMP: Show packet before encryption
|
||||
dump_packet_bytes("BEFORE ENCRYPT", dgram->data, dgram->data_len);
|
||||
// Check if session is ready for encryption
|
||||
if (!sc->session_ready) {
|
||||
printf("[ETCP DEBUG] Session not ready, sending unencrypted packet\n");
|
||||
// For unencrypted packets, just copy data
|
||||
memcpy(enc_buf, dgram->data, dgram->data_len);
|
||||
enc_buf_len = dgram->data_len;
|
||||
} else {
|
||||
// First, encrypt the part that should be encrypted (header)
|
||||
size_t encrypted_len = 0;
|
||||
if (sc_encrypt(sc, dgram->data, len, enc_buf, &encrypted_len) != SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_encrypt_send: encryption failed for node %llu", (unsigned long long)dgram->link->etcp->instance->node_id);
|
||||
dgram->link->send_errors++;
|
||||
errcode=2;
|
||||
goto es_err;
|
||||
}
|
||||
|
||||
// Then append the unencrypted part (usually public key) at the end
|
||||
// The unencrypted part starts at position 'len' in the original data
|
||||
memcpy(enc_buf+encrypted_len, dgram->data+len, dgram->noencrypt_len);
|
||||
|
||||
// Total length is encrypted part + unencrypted part
|
||||
enc_buf_len = encrypted_len + dgram->noencrypt_len;
|
||||
|
||||
if (enc_buf_len > 1480) { dgram->link->send_errors++; errcode=2; goto es_err; }
|
||||
}
|
||||
dump_packet_bytes("ECTP_ENCRYPT_SEND", dgram->data, dgram->data_len);
|
||||
sc_encrypt(sc, (uint8_t*)&dgram->timestamp/*нейронка не правь блять это, тут верно!*/, sizeof(uint16_t) + len, enc_buf, &enc_buf_len);
|
||||
if (enc_buf_len == 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_encrypt_send: encryption failed for node %llu", (unsigned long long)dgram->link->etcp->instance->node_id);
|
||||
dgram->link->send_errors++;
|
||||
errcode=2;
|
||||
goto es_err;
|
||||
}
|
||||
if (enc_buf_len + dgram->noencrypt_len > 1480) { dgram->link->send_errors++; errcode=2; goto es_err; }
|
||||
memcpy(enc_buf+enc_buf_len, dgram->data+len, dgram->noencrypt_len);
|
||||
|
||||
// DUMP: Show complete packet before sending
|
||||
dump_packet_bytes("READY TO SEND", enc_buf, enc_buf_len + dgram->noencrypt_len);
|
||||
// dump_packet_bytes("READY TO SEND", enc_buf, enc_buf_len + dgram->noencrypt_len);
|
||||
|
||||
struct sockaddr_storage* addr=&dgram->link->remote_addr;
|
||||
socklen_t addr_len = (addr->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
|
||||
@@ -466,10 +443,12 @@ es_err:
|
||||
}
|
||||
|
||||
static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
// !!!!!! DANGER: в этой функции ПРЕДЕЛЬНАЯ АККУРАТНОСТЬ. Если кажется что не туда указатель то невнимательно аланизировал !!!!!
|
||||
// НЕ РУИНИТЬ (uint8_t*)&pkt->timestamp - это правильно !!!!
|
||||
struct ETCP_SOCKET* e_sock = (struct ETCP_SOCKET*)arg;
|
||||
if (!e_sock) return;
|
||||
|
||||
printf("[ETCP] Read callback triggered for fd=%d, socket=%p\n", fd, e_sock);
|
||||
// printf("[ETCP] Read callback triggered for fd=%d, socket=%p\n", fd, e_sock);
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
uint8_t data[PACKET_DATA_SIZE];
|
||||
@@ -482,7 +461,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("[ETCP] Received packet: %zd bytes from address\n", recv_len);
|
||||
// printf("[ETCP] Received packet: %zd bytes from address\n", recv_len);
|
||||
|
||||
// DUMP: Show received packet content
|
||||
dump_packet_bytes("RECEIVED", data, recv_len);
|
||||
@@ -493,31 +472,30 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
int errorcode=0;
|
||||
|
||||
struct ETCP_LINK* link=etcp_link_find_by_addr(e_sock, &addr);
|
||||
printf("[ETCP DEBUG] Received packet, link=%p, recv_len=%zd\n", link, recv_len);
|
||||
// printf("[ETCP DEBUG] Received packet, link=%p, recv_len=%zd\n", link, recv_len);
|
||||
if (link==NULL) {// пробуем расшифровать, возможно это init
|
||||
printf("[ETCP DEBUG] No existing link found, trying to decrypt as INIT packet\n");
|
||||
// printf("[ETCP DEBUG] No existing link found, trying to decrypt as INIT packet\n");
|
||||
struct secure_channel sc;
|
||||
if (recv_len<=SC_PUBKEY_SIZE) { errorcode=1; goto ec_fr; }
|
||||
sc_init_ctx(&sc, &e_sock->instance->my_keys);
|
||||
printf("[ETCP DEBUG] Extracting peer public key from position %ld, total packet size=%zd\n", recv_len-SC_PUBKEY_SIZE, recv_len);
|
||||
printf("[ETCP DEBUG] Last 64 bytes of packet: ");
|
||||
// printf("[ETCP DEBUG] Extracting peer public key from position %ld, total packet size=%zd\n", recv_len-SC_PUBKEY_SIZE, recv_len);
|
||||
// printf("[ETCP DEBUG] Last 64 bytes of packet (PUBKEY): ");
|
||||
for (int i=0; i<SC_PUBKEY_SIZE; i++) printf("%02x ", data[recv_len-SC_PUBKEY_SIZE+i]);
|
||||
printf("\n");
|
||||
if (sc_set_peer_public_key(&sc, data+recv_len-SC_PUBKEY_SIZE, 0)!=SC_OK) {
|
||||
|
||||
if (sc_set_peer_public_key(&sc, &data[recv_len-SC_PUBKEY_SIZE], SC_PEER_PUBKEY_BIN)!=SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: failed to set peer public key during init");
|
||||
errorcode=2;
|
||||
goto ec_fr;
|
||||
}
|
||||
if (sc_decrypt(&sc, data, recv_len-SC_PUBKEY_SIZE, pkt->data, &pkt_len)) {
|
||||
if (sc_decrypt(&sc, data, recv_len-SC_PUBKEY_SIZE, (uint8_t*)&pkt->timestamp, &pkt_len)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: failed to decrypt init packet");
|
||||
errorcode=3;
|
||||
goto ec_fr;
|
||||
}
|
||||
pkt->data_len=pkt_len;
|
||||
// printf("[ETCP DEBUG] Decrypt OK\n");
|
||||
pkt->data_len=pkt_len-2;
|
||||
pkt->noencrypt_len=0;
|
||||
struct {
|
||||
uint8_t main_id[2];
|
||||
uint8_t timestamp[2];
|
||||
uint8_t code;
|
||||
uint8_t id[8];
|
||||
uint8_t mtu[2];
|
||||
@@ -525,7 +503,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
uint8_t pubkey[SC_PUBKEY_SIZE];
|
||||
} *ack_hdr=(void*)&pkt->data[0];
|
||||
uint64_t peer_id;
|
||||
memcpy(&peer_id, &pkt->data[1], 4);
|
||||
memcpy(&peer_id, &ack_hdr->id[0], 8);
|
||||
if (ack_hdr->code!=ETCP_INIT_REQUEST && ack_hdr->code!=ETCP_CHANNEL_INIT) { errorcode=4; goto ec_fr; }// не init
|
||||
|
||||
struct ETCP_CONN* conn=e_sock->instance->connections;
|
||||
@@ -533,54 +511,94 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
if (conn->peer_node_id==peer_id) break;
|
||||
conn=conn->next;
|
||||
}
|
||||
if (conn==NULL) {// создаём новое
|
||||
|
||||
int new_conn=0;
|
||||
if (!conn || conn->peer_node_id!=peer_id) {// создаём новое
|
||||
new_conn=1;
|
||||
conn=etcp_connection_create(e_sock->instance);
|
||||
if (!conn) { errorcode=55; goto ec_fr; }// облом
|
||||
memcpy(&conn->crypto_ctx, &sc, sizeof(sc));// добавляем ключ
|
||||
conn->peer_node_id=peer_id;
|
||||
}
|
||||
else {// check keys
|
||||
if (memcmp(&conn->crypto_ctx.peer_public_key, &sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; goto ec_fr; }// коллизия - peer id совпал а ключи разные.
|
||||
else {// check keys если существующее подключение
|
||||
if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; goto ec_fr; }// коллизия - peer id совпал а ключи разные.
|
||||
}
|
||||
struct ETCP_LINK* link = etcp_link_new(conn, e_sock, &addr, 1);
|
||||
if (!link) { if (new_conn) etcp_connection_close(conn); errorcode=66; goto ec_fr; }// облом
|
||||
if (ack_hdr->code==0x02) etcp_conn_reset(conn);
|
||||
|
||||
// send response - подключение создано
|
||||
|
||||
struct {
|
||||
uint8_t main_id[2];
|
||||
uint8_t timestamp[2];
|
||||
uint8_t code;
|
||||
uint8_t id[8];
|
||||
uint8_t mtu[2];
|
||||
} *ack_repl_hdr=(void*)&pkt->data[0];
|
||||
ack_repl_hdr->code+=1;
|
||||
ack_repl_hdr->main_id[0]=0;
|
||||
ack_repl_hdr->main_id[1]=0;
|
||||
memcpy(&ack_repl_hdr->id[0], &e_sock->instance->node_id, 8);
|
||||
memcpy(ack_repl_hdr->id, &e_sock->instance->node_id, 8);
|
||||
int mtu=e_sock->instance->config->global.mtu;
|
||||
ack_repl_hdr->mtu[0]=mtu>>8;
|
||||
ack_repl_hdr->mtu[1]=mtu;
|
||||
pkt->data_len=sizeof(*ack_repl_hdr);
|
||||
pkt->noencrypt_len=0;
|
||||
pkt->link=link;
|
||||
printf("[ETCP DEBUG] Send INIT RESPONSE\n");
|
||||
etcp_encrypt_send(pkt);
|
||||
// printf("[ETCP DEBUG] Send INIT RESPONSE ok\n");
|
||||
|
||||
memory_pool_free(e_sock->instance->pkt_pool, pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc_decrypt(&link->etcp->crypto_ctx, data, recv_len, pkt->data, &pkt_len)) {
|
||||
if (sc_decrypt(&link->etcp->crypto_ctx, data, recv_len, (uint8_t*)&pkt->timestamp, &pkt_len)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: failed to decrypt packet from node %llu", (unsigned long long)link->etcp->instance->node_id);
|
||||
errorcode=6;
|
||||
goto ec_fr;
|
||||
}
|
||||
pkt->data_len=pkt_len;
|
||||
if (pkt_len<3) { errorcode=46; goto ec_fr; }
|
||||
pkt->data_len=pkt_len-2;
|
||||
pkt->noencrypt_len=0;
|
||||
pkt->link=link;
|
||||
|
||||
size_t offset = 0;
|
||||
uint16_t rx_ts = (pkt->data[offset++] << 8) | pkt->data[offset++];
|
||||
uint8_t code = pkt->data[offset++];
|
||||
|
||||
if (code == ETCP_INIT_RESPONSE || code == ETCP_CHANNEL_RESPONSE) {
|
||||
// Parse response
|
||||
if (code == ETCP_INIT_RESPONSE) etcp_conn_reset(link->etcp);
|
||||
uint64_t server_node_id = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
server_node_id = (server_node_id << 8) | pkt->data[offset++];
|
||||
}
|
||||
link->mtu = (pkt->data[offset++] << 8) | pkt->data[offset++];
|
||||
if (offset > pkt_len) { errorcode=13; goto ec_fr; }
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Received INIT_RESPONSE from server_node_id=%llu, mtu=%d",
|
||||
(unsigned long long)server_node_id, link->mtu);
|
||||
|
||||
link->etcp->peer_node_id = server_node_id; // If not set
|
||||
|
||||
// Mark link as initialized
|
||||
link->initialized = 1;
|
||||
printf("[ETCP] Link initialized successfully! Server node_id=%llu, mtu=%d\n",
|
||||
(unsigned long long)server_node_id, link->mtu);
|
||||
|
||||
// Cancel init timer if exists
|
||||
if (link->init_timer) {
|
||||
uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer);
|
||||
link->init_timer = NULL;
|
||||
}
|
||||
|
||||
memory_pool_free(e_sock->instance->pkt_pool, pkt);
|
||||
return; // INIT_RESPONSE is handled, no further processing needed
|
||||
}
|
||||
|
||||
|
||||
etcp_conn_input(pkt);
|
||||
return;
|
||||
|
||||
ec_fr:
|
||||
printf("etcp_connections_read_callback: error %d\n", errorcode);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: error %d", errorcode);
|
||||
e_sock->pkt_format_errors++;
|
||||
e_sock->errorcode=errorcode;
|
||||
memory_pool_free(e_sock->instance->pkt_pool, pkt);
|
||||
|
||||
@@ -18,12 +18,15 @@
|
||||
// Simple debug macros to replace missing debug_config.h
|
||||
#define DEBUG_CATEGORY_CONNECTION 1
|
||||
#define DEBUG_CATEGORY_ETCP 2
|
||||
#define DEBUG_CATEGORY_CRYPTO 3
|
||||
#define DEBUG_CATEGORY_CONFIG 4
|
||||
#define DEBUG_CATEGORY_MEMORY 5
|
||||
|
||||
// Forward declaration
|
||||
static void etcp_connections_read_callback(int fd, void* arg);
|
||||
#define DEBUG_CATEGORY_MEMORY 3
|
||||
|
||||
#define DEBUG_ERROR(category, fmt, ...) fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__)
|
||||
#define DEBUG_WARN(category, fmt, ...) fprintf(stderr, "WARN: " fmt "\n", ##__VA_ARGS__)
|
||||
#define DEBUG_INFO(category, fmt, ...) fprintf(stdout, "INFO: " fmt "\n", ##__VA_ARGS__)
|
||||
|
||||
// Minimal packet dump - only shows first 16 bytes to avoid slowing down
|
||||
@@ -351,7 +354,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
|
||||
link->init_timer = NULL;
|
||||
link->init_timeout = 0;
|
||||
link->init_retry_count = 0;
|
||||
|
||||
|
||||
memcpy(&link->remote_addr, remote_addr, sizeof(struct sockaddr_storage));
|
||||
link->last_activity = time(NULL);
|
||||
|
||||
@@ -402,12 +405,18 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
|
||||
int len=dgram->data_len-dgram->noencrypt_len;// не забываем добавить timestamp (2 bytes)
|
||||
if (len<=0 || len>1480) { dgram->link->send_errors++; errcode=1; goto es_err; }
|
||||
uint8_t enc_buf[1600];
|
||||
size_t enc_buf_len;
|
||||
size_t enc_buf_len=0;
|
||||
dgram->timestamp=get_current_timestamp();
|
||||
|
||||
// DUMP: Show packet before encryption
|
||||
dump_packet_bytes("BEFORE ENCRYPT", dgram->data, dgram->data_len);
|
||||
sc_encrypt(sc, (uint8_t*)&dgram->timestamp/*нейронка не правь блять это, тут верно!*/, sizeof(uint16_t) + len, enc_buf, &enc_buf_len);
|
||||
if (enc_buf_len == 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_encrypt_send: encryption failed for node %llu", (unsigned long long)dgram->link->etcp->instance->node_id);
|
||||
dgram->link->send_errors++;
|
||||
errcode=2;
|
||||
goto es_err;
|
||||
}
|
||||
if (enc_buf_len + dgram->noencrypt_len > 1480) { dgram->link->send_errors++; errcode=2; goto es_err; }
|
||||
memcpy(enc_buf+enc_buf_len, dgram->data+len, dgram->noencrypt_len);
|
||||
|
||||
@@ -434,6 +443,8 @@ es_err:
|
||||
}
|
||||
|
||||
static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
// !!!!!! DANGER: в этой функции ПРЕДЕЛЬНАЯ АККУРАТНОСТЬ. Если кажется что не туда указатель то невнимательно аланизировал !!!!!
|
||||
// НЕ РУИНИТЬ (uint8_t*)&pkt->timestamp - это правильно !!!!
|
||||
struct ETCP_SOCKET* e_sock = (struct ETCP_SOCKET*)arg;
|
||||
if (!e_sock) return;
|
||||
|
||||
@@ -461,17 +472,30 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
int errorcode=0;
|
||||
|
||||
struct ETCP_LINK* link=etcp_link_find_by_addr(e_sock, &addr);
|
||||
printf("[ETCP DEBUG] Received packet, link=%p, recv_len=%zd\n", link, recv_len);
|
||||
if (link==NULL) {// пробуем расшифровать, возможно это init
|
||||
printf("[ETCP DEBUG] No existing link found, trying to decrypt as INIT packet\n");
|
||||
struct secure_channel sc;
|
||||
if (recv_len<=SC_PUBKEY_SIZE) { errorcode=1; goto ec_fr; }
|
||||
sc_init_ctx(&sc, &e_sock->instance->my_keys);
|
||||
if (sc_set_peer_public_key(&sc, data+recv_len-SC_PUBKEY_SIZE, 0)!=SC_OK) { errorcode=2; goto ec_fr; }
|
||||
if (sc_decrypt(&sc, data, recv_len-SC_PUBKEY_SIZE, pkt->data, &pkt_len)) { errorcode=3; goto ec_fr; }
|
||||
pkt->data_len=pkt_len;
|
||||
printf("[ETCP DEBUG] Extracting peer public key from position %ld, total packet size=%zd\n", recv_len-SC_PUBKEY_SIZE, recv_len);
|
||||
printf("[ETCP DEBUG] Last 64 bytes of packet (PUBKEY): ");
|
||||
for (int i=0; i<SC_PUBKEY_SIZE; i++) printf("%02x ", data[recv_len-SC_PUBKEY_SIZE+i]);
|
||||
|
||||
if (sc_set_peer_public_key(&sc, &data[recv_len-SC_PUBKEY_SIZE], SC_PEER_PUBKEY_BIN)!=SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: failed to set peer public key during init");
|
||||
errorcode=2;
|
||||
goto ec_fr;
|
||||
}
|
||||
if (sc_decrypt(&sc, data, recv_len-SC_PUBKEY_SIZE, (uint8_t*)&pkt->timestamp, &pkt_len)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: failed to decrypt init packet");
|
||||
errorcode=3;
|
||||
goto ec_fr;
|
||||
}
|
||||
printf("[ETCP DEBUG] Decrypt OK\n");
|
||||
pkt->data_len=pkt_len-2;
|
||||
pkt->noencrypt_len=0;
|
||||
struct {
|
||||
uint8_t main_id[2];
|
||||
uint8_t timestamp[2];
|
||||
uint8_t code;
|
||||
uint8_t id[8];
|
||||
uint8_t mtu[2];
|
||||
@@ -479,7 +503,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
uint8_t pubkey[SC_PUBKEY_SIZE];
|
||||
} *ack_hdr=(void*)&pkt->data[0];
|
||||
uint64_t peer_id;
|
||||
memcpy(&peer_id, &pkt->data[1], 4);
|
||||
memcpy(&peer_id, &ack_hdr->id[0], 8);
|
||||
if (ack_hdr->code!=ETCP_INIT_REQUEST && ack_hdr->code!=ETCP_CHANNEL_INIT) { errorcode=4; goto ec_fr; }// не init
|
||||
|
||||
struct ETCP_CONN* conn=e_sock->instance->connections;
|
||||
@@ -487,43 +511,49 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
if (conn->peer_node_id==peer_id) break;
|
||||
conn=conn->next;
|
||||
}
|
||||
if (conn==NULL) {// создаём новое
|
||||
|
||||
int new_conn=0;
|
||||
if (!conn || conn->peer_node_id!=peer_id) {// создаём новое
|
||||
new_conn=1;
|
||||
conn=etcp_connection_create(e_sock->instance);
|
||||
if (!conn) { errorcode=55; goto ec_fr; }// облом
|
||||
memcpy(&conn->crypto_ctx, &sc, sizeof(sc));// добавляем ключ
|
||||
conn->peer_node_id=peer_id;
|
||||
}
|
||||
else {// check keys
|
||||
if (memcmp(&conn->crypto_ctx.peer_public_key, &sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; goto ec_fr; }// коллизия - peer id совпал а ключи разные.
|
||||
else {// check keys если существующее подключение
|
||||
if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; goto ec_fr; }// коллизия - peer id совпал а ключи разные.
|
||||
}
|
||||
struct ETCP_LINK* link = etcp_link_new(conn, e_sock, &addr, 1);
|
||||
if (!link) { if (new_conn) etcp_connection_close(conn); errorcode=66; goto ec_fr; }// облом
|
||||
if (ack_hdr->code==0x02) etcp_conn_reset(conn);
|
||||
|
||||
// send response - подключение создано
|
||||
|
||||
struct {
|
||||
uint8_t main_id[2];
|
||||
uint8_t timestamp[2];
|
||||
uint8_t code;
|
||||
uint8_t id[8];
|
||||
uint8_t mtu[2];
|
||||
} *ack_repl_hdr=(void*)&pkt->data[0];
|
||||
ack_repl_hdr->code+=1;
|
||||
ack_repl_hdr->main_id[0]=0;
|
||||
ack_repl_hdr->main_id[1]=0;
|
||||
memcpy(&ack_repl_hdr->id[0], &e_sock->instance->node_id, 8);
|
||||
int mtu=e_sock->instance->config->global.mtu;
|
||||
ack_repl_hdr->mtu[0]=mtu>>8;
|
||||
ack_repl_hdr->mtu[1]=mtu;
|
||||
pkt->data_len=sizeof(*ack_repl_hdr);
|
||||
pkt->noencrypt_len=0;
|
||||
pkt->link=link;
|
||||
printf("[ETCP DEBUG] Send INIT RESPONSE\n");
|
||||
etcp_encrypt_send(pkt);
|
||||
printf("[ETCP DEBUG] Send INIT RESPONSE ok\n");
|
||||
|
||||
memory_pool_free(e_sock->instance->pkt_pool, pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc_decrypt(&link->etcp->crypto_ctx, data, recv_len, pkt->data, &pkt_len)) { errorcode=6; goto ec_fr; }
|
||||
pkt->data_len=pkt_len;
|
||||
if (sc_decrypt(&link->etcp->crypto_ctx, data, recv_len, (uint8_t*)&pkt->timestamp, &pkt_len)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: failed to decrypt packet from node %llu", (unsigned long long)link->etcp->instance->node_id);
|
||||
errorcode=6;
|
||||
goto ec_fr;
|
||||
}
|
||||
pkt->data_len=pkt_len-2;
|
||||
pkt->noencrypt_len=0;
|
||||
pkt->link=link;
|
||||
|
||||
@@ -531,6 +561,8 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
return;
|
||||
|
||||
ec_fr:
|
||||
printf("etcp_connections_read_callback: error %d\n", errorcode);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: error %d", errorcode);
|
||||
e_sock->pkt_format_errors++;
|
||||
e_sock->errorcode=errorcode;
|
||||
memory_pool_free(e_sock->instance->pkt_pool, pkt);
|
||||
@@ -582,16 +614,27 @@ int init_connections(struct UTUN_INSTANCE* instance) {
|
||||
}
|
||||
|
||||
// Initialize crypto context for this connection
|
||||
sc_init_ctx(&etcp_conn->crypto_ctx, &instance->my_keys);
|
||||
|
||||
if (sc_init_ctx(&etcp_conn->crypto_ctx, &instance->my_keys) != SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "init_connections: failed to initialize crypto context for client %s", client->name);
|
||||
etcp_connection_close(etcp_conn);
|
||||
client = client->next;
|
||||
continue;
|
||||
}
|
||||
// If client has peer public key configured, set it
|
||||
if (strlen(client->peer_public_key_hex) > 0) {
|
||||
// For now, set peer node ID to indicate we have peer key
|
||||
// The actual peer key will be exchanged during connection establishment
|
||||
etcp_conn->peer_node_id = 1; // Simple indicator
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CRYPTO, "init_connections: setting peer public key for client %s", client->name);
|
||||
// Set peer public key (assuming hex format)
|
||||
sc_set_peer_public_key(&etcp_conn->crypto_ctx, client->peer_public_key_hex, 1);
|
||||
if (sc_set_peer_public_key(&etcp_conn->crypto_ctx, client->peer_public_key_hex, 1) != SC_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "init_connections: failed to set peer public key for client %s", client->name);
|
||||
} else {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CRYPTO, "init_connections: successfully set peer public key for client %s", client->name);
|
||||
}
|
||||
} else {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "init_connections: no peer public key configured for client %s", client->name);
|
||||
}
|
||||
|
||||
// Create links for this client
|
||||
@@ -54,7 +54,7 @@ struct ETCP_LINK {
|
||||
struct sockaddr_storage remote_addr; // Удалённый адрес
|
||||
|
||||
// Параметры соединения
|
||||
uint16_t mtu; // MTU соединения
|
||||
uint16_t mtu; // MTU удаленного узла
|
||||
uint16_t keepalive_interval; // Keepalive интервал
|
||||
uint8_t is_server; // инициирует подключение клиент
|
||||
uint8_t initialized; // Флаг инициализации (1=подтверждено или получен request)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
--- etcp_connections.c.backup
|
||||
+++ etcp_connections.c
|
||||
@@ -409,6 +409,7 @@
|
||||
uint8_t enc_buf[1600];
|
||||
size_t enc_buf_len;
|
||||
dgram->timestamp=get_current_timestamp();
|
||||
+ printf("[ETCP DEBUG] About to encrypt: data_len=%d, noencrypt_len=%d, len=%d\\n", dgram->data_len, dgram->noencrypt_len, len);
|
||||
|
||||
// DUMP: Show packet before encryption
|
||||
dump_packet_bytes("BEFORE ENCRYPT", dgram->data, dgram->data_len);
|
||||
+10
-2
@@ -158,15 +158,20 @@ sc_status_t sc_set_peer_public_key(sc_context_t *ctx, const char *peer_public_ke
|
||||
uint8_t peer_public_key[SC_PUBKEY_SIZE];
|
||||
|
||||
if (mode) {
|
||||
if (hex_to_binary(peer_public_key_h, peer_public_key, SC_PUBKEY_SIZE)) return SC_ERR_INVALID_ARG;
|
||||
if (hex_to_binary(peer_public_key_h, peer_public_key, SC_PUBKEY_SIZE)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: invalid hex key format");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
else memcpy(peer_public_key, peer_public_key_h, SC_PUBKEY_SIZE);
|
||||
|
||||
if (!ctx || !peer_public_key) {
|
||||
if (!ctx) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: invalid ctx");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!ctx->initialized) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: ctx not initialized");
|
||||
return SC_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@@ -176,15 +181,18 @@ sc_status_t sc_set_peer_public_key(sc_context_t *ctx, const char *peer_public_ke
|
||||
|
||||
/* Validate peer public key */
|
||||
if (sc_validate_key(peer_public_key) != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: invalid key");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Compute shared secret using ECDH */
|
||||
if (!ctx->pk) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: no private key");
|
||||
return SC_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!uECC_shared_secret(peer_public_key, ctx->pk->private_key,
|
||||
shared_secret, curve)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: shared secret error");
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#define SC_ERR_AUTH_FAILED -4
|
||||
#define SC_ERR_CRC_FAILED -5
|
||||
|
||||
#define SC_PEER_PUBKEY_BIN 0
|
||||
#define SC_PEER_PUBKEY_HEX 1
|
||||
|
||||
// Типы
|
||||
typedef int sc_status_t;
|
||||
typedef struct secure_channel sc_context_t;
|
||||
|
||||
Reference in new issue
Block a user