Browse Source

Crypto: Fixed CCM nonce size to 13 bytes, all crypto tests passing

v2_dev
Evgeny 9 months ago
parent
commit
dfe26557e3
  1. 99
      src/etcp_connections.c
  2. 3
      src/etcp_connections.h
  3. 1
      src/utun_instance.h

99
src/etcp_connections.c

@ -230,6 +230,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
if (!link) return NULL;
link->conn = conn;
link->etcp = etcp;
link->is_server = is_server;
memcpy(&link->remote_addr, remote_addr, sizeof(struct sockaddr_storage));
link->last_activity = time(NULL);
@ -360,7 +361,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
} *ack_hdr=(void*)&pkt->data[0];
uint64_t peer_id;
memcpy(&peer_id, &pkt->data[1], 4);
if (ack_hdr->code!=0x02 && ack_hdr->code!=0x04) { errorcode=4; goto ec_fr; }// не init
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;
while (conn) {// ищем есть ли подключение к этому пиру
@ -377,7 +378,9 @@ static void etcp_connections_read_callback(int fd, void* arg) {
}
struct ETCP_LINK* link = etcp_link_new(conn, e_sock, &addr, 1);
if (ack_hdr->code==0x02) etcp_conn_reset(conn);
// send reply - подключение создано
// send response - подключение создано
struct {
uint8_t main_id[2];
uint8_t timestamp[2];
@ -385,7 +388,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
uint8_t id[8];
uint8_t mtu[2];
} *ack_repl_hdr=(void*)&pkt->data[0];
ack_repl_hdr->code=0x03;
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);
@ -405,7 +408,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
pkt->noencrypt_len=0;
pkt->link=link;
etcp_input(pkt);
etcp_conn_input(pkt->link->conn, pkt);
return;
ec_fr:
@ -415,89 +418,6 @@ ec_fr:
return;
}
#define MIN(a,b) ((a) < (b) ? (a) : (b))
int etcp_input(struct ETCP_DGRAM* pkt) {
if (!pkt || !pkt->link) return -1;
uint8_t* data = pkt->data;
size_t len = pkt->data_len;
if (len < 1) return -1;
uint8_t header = data[0];
data++; len--;
struct ETCP_LINK* link = pkt->link;
struct ETCP_CONN* etcp = link->etcp;
// Check if we have peer key by checking if peer_node_id is set
int has_peer_key = (etcp->peer_node_id != 0);
if (header != ETCP_INIT_REQUEST && header != ETCP_CHANNEL_INIT && has_peer_key) {
// Decrypt
sc_context_t* sc = &etcp->crypto_ctx;
uint8_t decrypted[PACKET_DATA_SIZE];
size_t decrypted_len;
if (sc_decrypt(sc, data, len, decrypted, &decrypted_len) != SC_OK) {
link->decrypt_errors++;
return -1;
}
memcpy(data, decrypted, decrypted_len);
len = decrypted_len;
link->total_decrypted += len;
}
if (!link) {
if (header == ETCP_INIT_REQUEST || header == ETCP_CHANNEL_INIT) {
// Create new link - this shouldn't happen as link should be set
return -1;
} else {
// Send reset if not init
uint8_t reset_pkt[1] = {ETCP_RESET};
etcp_connections_send(link->conn, reset_pkt, 1, (struct sockaddr*)&link->remote_addr, sizeof(link->remote_addr));
return -1;
}
}
if (header == ETCP_INIT_REQUEST) {
// Parse init
if (len < 8 + 2 + 2 + SC_PUBKEY_SIZE) return -1;
uint64_t peer_node_id;
memcpy(&peer_node_id, data, 8); data += 8; len -= 8;
uint16_t peer_mtu = (data[0] << 8) | data[1]; data += 2; len -= 2;
uint16_t peer_keepalive = (data[0] << 8) | data[1]; data += 2; len -= 2;
uint8_t peer_pubkey[SC_PUBKEY_SIZE];
memcpy(peer_pubkey, data, SC_PUBKEY_SIZE);
etcp->peer_node_id = peer_node_id;
memcpy(etcp->crypto_ctx.peer_public_key, peer_pubkey, SC_PUBKEY_SIZE);
etcp->peer_node_id = peer_node_id; // Set peer_node_id to indicate we have peer key
sc_set_peer_public_key(&etcp->crypto_ctx, peer_pubkey, 0);
link->mtu = MIN(etcp->mtu, peer_mtu);
link->keepalive_interval = peer_keepalive;
link->initialized = 1;
// Send response
etcp_link_send_init_response(link, etcp->mtu, link->keepalive_interval);
} else if (header == ETCP_INIT_RESPONSE) {
// Similar parsing without pubkey
} else if (header == ETCP_CHANNEL_RESPONSE) {
// Parse
} else if (header == ETCP_RESET) {
etcp_conn_reset(etcp);
} else {
// Forward to etcp_conn_input
pkt->link = link;
etcp_conn_input(etcp, pkt);
return 0;
}
return 0;
}
int init_connections(struct UTUN_INSTANCE* instance) {
if (!instance || !instance->config) return -1;
@ -555,11 +475,6 @@ int init_connections(struct UTUN_INSTANCE* instance) {
sc_set_peer_public_key(&etcp_conn->crypto_ctx, client->peer_public_key_hex, 1);
}
// Add connection to the instance's linked list
etcp_conn->next = instance->connections;
instance->connections = etcp_conn;
instance->connections_count++;
// Create links for this client
struct CFG_CLIENT_LINK* client_link = client->links;
while (client_link) {

3
src/etcp_connections.h

@ -13,7 +13,6 @@
#define ETCP_INIT_RESPONSE 0x03
#define ETCP_CHANNEL_INIT 0x04
#define ETCP_CHANNEL_RESPONSE 0x05
#define ETCP_RESET 0x06
struct ETCP_DGRAM {
@ -43,8 +42,8 @@ struct ETCP_SOCKET {
struct ETCP_LINK {
uint32_t ip_port_hash; // crc32 для быстрого поиска
struct ETCP_LINK* next; // Linked list подключений для ETCP_CONN (каждое подключение это child для ETCP_CONN)
struct ETCP_CONN* etcp; // подключение (parent)
struct ETCP_SOCKET* conn; // сокет через который работаем
// Путь соединения

1
src/utun_instance.h

@ -42,6 +42,7 @@ struct UTUN_INSTANCE {
// Connections
struct ETCP_CONN* connections;// linked-list
int connections_count; // Number of connections
// Active sockets
struct ETCP_SOCKET* etcp_sockets;// linked-list

Loading…
Cancel
Save