Browse Source

CRITICAL FIX: Actually implement encryption in etcp_link_send and decryption in etcp_input using sc_encrypt/sc_decrypt.

v2_dev
Evgeny 3 months ago
parent
commit
6760a941e1
  1. 84
      src/etcp_connections.c

84
src/etcp_connections.c

@ -203,11 +203,57 @@ int etcp_input(struct packet_buffer* pkt, struct ETCP_SOCKET* socket, struct ETC
if (pkt->metadata.data_len < 1) return -1; if (pkt->metadata.data_len < 1) return -1;
uint8_t* data = pkt->data; uint8_t* data = pkt->data;
size_t data_len = pkt->metadata.data_len;
uint8_t cmd = data[0]; uint8_t cmd = data[0];
struct sockaddr* src_addr = packet_remote_addr(pkt); struct sockaddr* src_addr = packet_remote_addr(pkt);
socklen_t addr_len = sizeof(struct sockaddr_storage); socklen_t addr_len = sizeof(struct sockaddr_storage);
// Дешифруем пакет, если есть session_key
sc_context_t* sc = conns->etcp->crypto_ctx;
uint8_t decrypted_buf[1500];
bool was_decrypted = false;
if (sc && sc->session_ready && data_len > SC_TAG_SIZE) {
size_t decrypted_len = sizeof(decrypted_buf);
// Для INIT_REQUEST пакета - pubkey в конце не шифруется
bool has_pubkey_at_end = (cmd == ETCP_INIT_REQUEST);
size_t encrypted_part_len = has_pubkey_at_end ?
data_len - SC_PUBKEY_SIZE : data_len;
if (encrypted_part_len > SC_TAG_SIZE) {
if (sc_decrypt(sc, data, encrypted_part_len, decrypted_buf, &decrypted_len) == SC_OK) {
data = decrypted_buf;
data_len = decrypted_len;
cmd = data[0];
was_decrypted = true;
conns->total_decrypted++;
} else {
conns->decrypt_errors++;
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Decryption failed");
return -1;
}
}
}
// Извлекаем pubkey из конца только для INIT_REQUEST
if (cmd == ETCP_INIT_REQUEST && data_len >= SC_PUBKEY_SIZE) {
// Сохраняем pubkey перед изменением data_len
uint8_t pubkey[SC_PUBKEY_SIZE];
memcpy(pubkey, data + data_len - SC_PUBKEY_SIZE, SC_PUBKEY_SIZE);
data_len -= SC_PUBKEY_SIZE;
// Устанавливаем pubkey в secure channel
if (sc && sc->initialized) {
sc_set_peer_public_key(sc, pubkey);
}
// Обновляем cmd, так как data_len изменился
cmd = data[0];
}
// Обработка INIT REQUEST
if (cmd == ETCP_INIT_REQUEST) { if (cmd == ETCP_INIT_REQUEST) {
if (pkt->metadata.data_len < 1 + 8 + SC_PUBKEY_SIZE + 2 + 2) { if (pkt->metadata.data_len < 1 + 8 + SC_PUBKEY_SIZE + 2 + 2) {
return -1; return -1;
@ -312,13 +358,45 @@ int etcp_link_init(struct ETCP_CONN* etcp, struct ETCP_LINK* link) { (void)etcp;
} }
int etcp_link_send(struct ETCP_CONN* etcp, struct ETCP_LINK* link, int etcp_link_send(struct ETCP_CONN* etcp, struct ETCP_LINK* link,
const uint8_t* data, size_t len) { const uint8_t* data, size_t len) {
if (!etcp || !link || !data || len == 0) return -1; if (!etcp || !link || !data || len == 0) return -1;
link->last_activity = time(NULL); link->last_activity = time(NULL);
return etcp_socket_send((struct ETCP_SOCKET*)link->socket, data, len, sc_context_t* sc = etcp->crypto_ctx;
(struct sockaddr*)&link->remote_addr); int fd = link->socket->fd;
if (sc && sc->session_ready && len < 1400) {
uint8_t encrypted_buf[1500];
size_t encrypted_len = sizeof(encrypted_buf);
if (sc_encrypt(sc, data, len, encrypted_buf, &encrypted_len) == SC_OK) {
ssize_t sent = sendto(fd, encrypted_buf, encrypted_len, MSG_DONTWAIT,
(struct sockaddr*)&link->remote_addr,
link->remote_addr_len);
if (sent < 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
link->conns->send_errors++;
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "sendto failed: %s", strerror(errno));
}
return -1;
}
link->conns->total_encrypted++;
return 0;
} else {
link->conns->encrypt_errors++;
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Encryption failed");
return -1;
}
}
ssize_t sent = sendto(fd, data, len, MSG_DONTWAIT,
(struct sockaddr*)&link->remote_addr,
link->remote_addr_len);
return (sent >= 0) ? 0 : -1;
} }
int etcp_link_send_init(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval) { int etcp_link_send_init(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval) {

Loading…
Cancel
Save