CRITICAL FIX: Actually implement encryption in etcp_link_send and decryption in etcp_input using sc_encrypt/sc_decrypt.
This commit is contained in:
1 parent
7b338e1adf
commit
6760a941e1
1 file changed
+81
-3
+81
-3
@@ -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) {
|
||||||
|
|||||||
Reference in new issue
Block a user