mirror of
https://github.com/neocturne/fastd.git
synced 2025-05-14 12:25:07 +02:00
Make crypto handshake with floating peers work
This commit is contained in:
parent
b69d34071b
commit
22a6b57065
5 changed files with 94 additions and 43 deletions
|
@ -211,7 +211,7 @@ void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer b
|
||||||
switch (reply_code) {
|
switch (reply_code) {
|
||||||
case REPLY_SUCCESS:
|
case REPLY_SUCCESS:
|
||||||
pr_info(ctx, "Handshake with %P successful.", peer);
|
pr_info(ctx, "Handshake with %P successful.", peer);
|
||||||
fastd_peer_set_established(ctx, peer);
|
fastd_peer_set_established(peer);
|
||||||
ctx->conf->protocol->init_peer(ctx, peer);
|
ctx->conf->protocol->init_peer(ctx, peer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -134,9 +134,14 @@ fastd_peer* fastd_peer_add_temp(fastd_context *ctx, const fastd_peer_address *ad
|
||||||
fastd_peer* fastd_peer_merge(fastd_context *ctx, fastd_peer *perm_peer, fastd_peer *temp_peer) {
|
fastd_peer* fastd_peer_merge(fastd_context *ctx, fastd_peer *perm_peer, fastd_peer *temp_peer) {
|
||||||
pr_debug(ctx, "merging peer %P into %P", temp_peer, perm_peer);
|
pr_debug(ctx, "merging peer %P into %P", temp_peer, perm_peer);
|
||||||
|
|
||||||
|
ctx->conf->protocol->free_peer_state(ctx, perm_peer);
|
||||||
|
|
||||||
perm_peer->address = temp_peer->address;
|
perm_peer->address = temp_peer->address;
|
||||||
perm_peer->state = fastd_peer_is_established(temp_peer) ? STATE_ESTABLISHED : STATE_WAIT;
|
perm_peer->state = fastd_peer_is_established(temp_peer) ? STATE_ESTABLISHED : STATE_WAIT;
|
||||||
perm_peer->seen = temp_peer->seen;
|
perm_peer->seen = temp_peer->seen;
|
||||||
|
perm_peer->protocol_state = temp_peer->protocol_state;
|
||||||
|
|
||||||
|
temp_peer->protocol_state = NULL;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ctx->n_eth_addr; i++) {
|
for (i = 0; i < ctx->n_eth_addr; i++) {
|
||||||
|
|
|
@ -98,7 +98,7 @@ static inline bool fastd_peer_is_established(const fastd_peer *peer) {
|
||||||
return (peer->state == STATE_ESTABLISHED || peer->state == STATE_TEMP_ESTABLISHED);
|
return (peer->state == STATE_ESTABLISHED || peer->state == STATE_TEMP_ESTABLISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer) {
|
static inline void fastd_peer_set_established(fastd_peer *peer) {
|
||||||
switch(peer->state) {
|
switch(peer->state) {
|
||||||
case STATE_WAIT:
|
case STATE_WAIT:
|
||||||
peer->state = STATE_ESTABLISHED;
|
peer->state = STATE_ESTABLISHED;
|
||||||
|
@ -109,7 +109,6 @@ static inline void fastd_peer_set_established(fastd_context *ctx, fastd_peer *pe
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pr_warn(ctx, "tried to set an already established connection to established");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,8 @@ struct _fastd_protocol_peer_config {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _protocol_handshake {
|
typedef struct _protocol_handshake {
|
||||||
|
const fastd_peer_config *peer_config;
|
||||||
|
|
||||||
handshake_state state;
|
handshake_state state;
|
||||||
ecc_secret_key_256 secret_key;
|
ecc_secret_key_256 secret_key;
|
||||||
ecc_public_key_256 public_key;
|
ecc_public_key_256 public_key;
|
||||||
|
@ -250,7 +252,7 @@ static inline void free_handshake(protocol_handshake *handshake) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_handshake(fastd_context *ctx, fastd_peer *peer, bool initiate) {
|
static void new_handshake(fastd_context *ctx, fastd_peer *peer, const fastd_peer_config *peer_config, bool initiate) {
|
||||||
protocol_handshake **handshake;
|
protocol_handshake **handshake;
|
||||||
|
|
||||||
if (initiate)
|
if (initiate)
|
||||||
|
@ -262,6 +264,8 @@ static void new_handshake(fastd_context *ctx, fastd_peer *peer, bool initiate) {
|
||||||
|
|
||||||
*handshake = malloc(sizeof(protocol_handshake));
|
*handshake = malloc(sizeof(protocol_handshake));
|
||||||
|
|
||||||
|
(*handshake)->peer_config = peer_config;
|
||||||
|
|
||||||
(*handshake)->state = HANDSHAKE_STATE_INIT;
|
(*handshake)->state = HANDSHAKE_STATE_INIT;
|
||||||
|
|
||||||
fastd_random_bytes(ctx, (*handshake)->secret_key.s, 32, false);
|
fastd_random_bytes(ctx, (*handshake)->secret_key.s, 32, false);
|
||||||
|
@ -280,22 +284,25 @@ static void protocol_init_peer(fastd_context *ctx, fastd_peer *peer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fastd_peer_is_temporary(peer)) {
|
||||||
|
pr_warn(ctx, "trying to initialize session for temporary peer %P", peer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
create_peer_state(ctx, peer);
|
create_peer_state(ctx, peer);
|
||||||
|
|
||||||
if (!fastd_peer_is_temporary(peer)) {
|
new_handshake(ctx, peer, peer->config, true);
|
||||||
new_handshake(ctx, peer, true);
|
|
||||||
|
|
||||||
fastd_buffer buffer = fastd_buffer_alloc(sizeof(protocol_handshake_init_packet), 0, 0);
|
fastd_buffer buffer = fastd_buffer_alloc(sizeof(protocol_handshake_init_packet), 0, 0);
|
||||||
protocol_handshake_init_packet *packet = buffer.data;
|
protocol_handshake_init_packet *packet = buffer.data;
|
||||||
|
|
||||||
memset(packet->common.noncepad, 0, NONCEBYTES);
|
memset(packet->common.noncepad, 0, NONCEBYTES);
|
||||||
packet->common.type = HANDSHAKE_PACKET_INIT;
|
packet->common.type = HANDSHAKE_PACKET_INIT;
|
||||||
memcpy(packet->common.sender_key, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->common.sender_key, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->common.receipient_key, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->common.receipient_key, peer->protocol_state->initiating_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->handshake_key, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->handshake_key, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
||||||
|
|
||||||
fastd_task_put_send(ctx, peer, buffer);
|
fastd_task_put_send(ctx, peer, buffer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void respond_handshake(fastd_context *ctx, fastd_peer *peer) {
|
static void respond_handshake(fastd_context *ctx, fastd_peer *peer) {
|
||||||
|
@ -307,7 +314,7 @@ static void respond_handshake(fastd_context *ctx, fastd_peer *peer) {
|
||||||
memcpy(hashinput, peer->protocol_state->accepting_handshake->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput, peer->protocol_state->accepting_handshake->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+2*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+2*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+3*PUBLICKEYBYTES, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+3*PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
|
|
||||||
crypto_hash_sha256(hashbuf, hashinput, 4*PUBLICKEYBYTES);
|
crypto_hash_sha256(hashbuf, hashinput, 4*PUBLICKEYBYTES);
|
||||||
|
|
||||||
|
@ -323,7 +330,7 @@ static void respond_handshake(fastd_context *ctx, fastd_peer *peer) {
|
||||||
ecc_25519_secret_add(&s, &eb, &peer->protocol_state->accepting_handshake->secret_key);
|
ecc_25519_secret_add(&s, &eb, &peer->protocol_state->accepting_handshake->secret_key);
|
||||||
|
|
||||||
ecc_25519_work work, workX;
|
ecc_25519_work work, workX;
|
||||||
ecc_25519_load(&work, &peer->config->protocol_config->public_key);
|
ecc_25519_load(&work, &peer->protocol_state->accepting_handshake->peer_config->protocol_config->public_key);
|
||||||
ecc_25519_load(&workX, &peer->protocol_state->accepting_handshake->peer_key);
|
ecc_25519_load(&workX, &peer->protocol_state->accepting_handshake->peer_key);
|
||||||
|
|
||||||
ecc_25519_scalarmult(&work, &d, &work);
|
ecc_25519_scalarmult(&work, &d, &work);
|
||||||
|
@ -344,7 +351,7 @@ static void respond_handshake(fastd_context *ctx, fastd_peer *peer) {
|
||||||
memset(packet->common.noncepad, 0, NONCEBYTES);
|
memset(packet->common.noncepad, 0, NONCEBYTES);
|
||||||
packet->common.type = HANDSHAKE_PACKET_RESPONSE;
|
packet->common.type = HANDSHAKE_PACKET_RESPONSE;
|
||||||
memcpy(packet->common.sender_key, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->common.sender_key, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->common.receipient_key, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->common.receipient_key, peer->protocol_state->accepting_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->handshake_key, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(packet->handshake_key, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->handshake_key2, peer->protocol_state->accepting_handshake->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->handshake_key2, peer->protocol_state->accepting_handshake->public_key.p, PUBLICKEYBYTES);
|
||||||
|
|
||||||
|
@ -355,7 +362,7 @@ static void respond_handshake(fastd_context *ctx, fastd_peer *peer) {
|
||||||
peer->protocol_state->accepting_handshake->state = HANDSHAKE_STATE_RESPONSE;
|
peer->protocol_state->accepting_handshake->state = HANDSHAKE_STATE_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void establish(fastd_context *ctx, fastd_peer *peer, bool initiator) {
|
static void establish(fastd_context *ctx, fastd_peer *peer, const fastd_peer_config *peer_config, bool initiator) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
peer->protocol_state->session.valid = true;
|
peer->protocol_state->session.valid = true;
|
||||||
|
@ -369,6 +376,16 @@ static void establish(fastd_context *ctx, fastd_peer *peer, bool initiator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_info(ctx, "Connection with %P established.", peer);
|
pr_info(ctx, "Connection with %P established.", peer);
|
||||||
|
|
||||||
|
if (fastd_peer_is_temporary(peer)) {
|
||||||
|
fastd_peer *perm_peer;
|
||||||
|
for (perm_peer = ctx->peers; perm_peer; perm_peer = perm_peer->next) {
|
||||||
|
if (perm_peer->config == peer_config) {
|
||||||
|
fastd_peer_merge(ctx, perm_peer, peer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMACBYTES]) {
|
static void finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMACBYTES]) {
|
||||||
|
@ -379,7 +396,7 @@ static void finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMA
|
||||||
|
|
||||||
memcpy(hashinput, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+2*PUBLICKEYBYTES, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+2*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+3*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+3*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
|
|
||||||
crypto_hash_sha256(hashbuf, hashinput, 4*PUBLICKEYBYTES);
|
crypto_hash_sha256(hashbuf, hashinput, 4*PUBLICKEYBYTES);
|
||||||
|
@ -396,7 +413,7 @@ static void finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMA
|
||||||
ecc_25519_secret_add(&s, &da, &peer->protocol_state->initiating_handshake->secret_key);
|
ecc_25519_secret_add(&s, &da, &peer->protocol_state->initiating_handshake->secret_key);
|
||||||
|
|
||||||
ecc_25519_work work, workY;
|
ecc_25519_work work, workY;
|
||||||
ecc_25519_load(&work, &peer->config->protocol_config->public_key);
|
ecc_25519_load(&work, &peer->protocol_state->initiating_handshake->peer_config->protocol_config->public_key);
|
||||||
ecc_25519_load(&workY, &peer->protocol_state->initiating_handshake->peer_key);
|
ecc_25519_load(&workY, &peer->protocol_state->initiating_handshake->peer_key);
|
||||||
|
|
||||||
ecc_25519_scalarmult(&work, &e, &work);
|
ecc_25519_scalarmult(&work, &e, &work);
|
||||||
|
@ -408,7 +425,7 @@ static void finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMA
|
||||||
memcpy(hashinput+4*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->sigma.p, PUBLICKEYBYTES);
|
memcpy(hashinput+4*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->sigma.p, PUBLICKEYBYTES);
|
||||||
crypto_hash_sha256(peer->protocol_state->initiating_handshake->shared_handshake_key, hashinput, 5*PUBLICKEYBYTES);
|
crypto_hash_sha256(peer->protocol_state->initiating_handshake->shared_handshake_key, hashinput, 5*PUBLICKEYBYTES);
|
||||||
|
|
||||||
memcpy(hashinput, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput, peer->protocol_state->initiating_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
|
|
||||||
if(crypto_auth_hmacsha256_verify(t, hashinput, 2*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->shared_handshake_key) != 0) {
|
if(crypto_auth_hmacsha256_verify(t, hashinput, 2*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->shared_handshake_key) != 0) {
|
||||||
|
@ -425,7 +442,7 @@ static void finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMA
|
||||||
memset(packet->common.noncepad, 0, NONCEBYTES);
|
memset(packet->common.noncepad, 0, NONCEBYTES);
|
||||||
packet->common.type = HANDSHAKE_PACKET_FINISH;
|
packet->common.type = HANDSHAKE_PACKET_FINISH;
|
||||||
memcpy(packet->common.sender_key, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->common.sender_key, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->common.receipient_key, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->common.receipient_key, peer->protocol_state->initiating_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->handshake_key, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(packet->handshake_key, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(packet->handshake_key2, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
memcpy(packet->handshake_key2, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
||||||
|
|
||||||
|
@ -439,17 +456,17 @@ static void finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMA
|
||||||
memcpy(hashinput, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput, peer->protocol_state->initiating_handshake->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+2*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+2*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+3*PUBLICKEYBYTES, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+3*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+4*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->sigma.p, PUBLICKEYBYTES);
|
memcpy(hashinput+4*PUBLICKEYBYTES, peer->protocol_state->initiating_handshake->sigma.p, PUBLICKEYBYTES);
|
||||||
crypto_hash_sha256(peer->protocol_state->session.key, hashinput, 5*PUBLICKEYBYTES);
|
crypto_hash_sha256(peer->protocol_state->session.key, hashinput, 5*PUBLICKEYBYTES);
|
||||||
|
|
||||||
establish(ctx, peer, true);
|
establish(ctx, peer, peer->protocol_state->initiating_handshake->peer_config, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMACBYTES]) {
|
static void handle_finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_t t[HMACBYTES]) {
|
||||||
uint8_t hashinput[5*PUBLICKEYBYTES];
|
uint8_t hashinput[5*PUBLICKEYBYTES];
|
||||||
|
|
||||||
memcpy(hashinput, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput, peer->protocol_state->accepting_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
|
|
||||||
if(crypto_auth_hmacsha256_verify(t, hashinput, 2*PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->shared_handshake_key) != 0) {
|
if(crypto_auth_hmacsha256_verify(t, hashinput, 2*PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->shared_handshake_key) != 0) {
|
||||||
|
@ -462,12 +479,32 @@ static void handle_finish_handshake(fastd_context *ctx, fastd_peer *peer, uint8_
|
||||||
|
|
||||||
memcpy(hashinput, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput, peer->protocol_state->accepting_handshake->peer_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+2*PUBLICKEYBYTES, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+2*PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->peer_config->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+3*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
memcpy(hashinput+3*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
|
||||||
memcpy(hashinput+4*PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->sigma.p, PUBLICKEYBYTES);
|
memcpy(hashinput+4*PUBLICKEYBYTES, peer->protocol_state->accepting_handshake->sigma.p, PUBLICKEYBYTES);
|
||||||
crypto_hash_sha256(peer->protocol_state->session.key, hashinput, 5*PUBLICKEYBYTES);
|
crypto_hash_sha256(peer->protocol_state->session.key, hashinput, 5*PUBLICKEYBYTES);
|
||||||
|
|
||||||
establish(ctx, peer, false);
|
establish(ctx, peer, peer->protocol_state->accepting_handshake->peer_config, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const fastd_peer_config* match_sender_key(fastd_context *ctx, const fastd_peer *peer, const protocol_handshake_packet *packet) {
|
||||||
|
if (peer->config) {
|
||||||
|
if (memcmp(peer->config->protocol_config->public_key.p, packet->common.sender_key, PUBLICKEYBYTES) == 0)
|
||||||
|
return peer->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fastd_peer_is_temporary(peer) || fastd_peer_is_floating(peer)) {
|
||||||
|
fastd_peer_config *config;
|
||||||
|
for (config = ctx->conf->peers; config; config = config->next) {
|
||||||
|
if (!fastd_peer_config_is_floating(config))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (memcmp(config->protocol_config->public_key.p, packet->common.sender_key, PUBLICKEYBYTES) == 0)
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
|
static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
|
||||||
|
@ -483,11 +520,6 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
|
||||||
|
|
||||||
protocol_handshake_packet *packet = buffer.data;
|
protocol_handshake_packet *packet = buffer.data;
|
||||||
|
|
||||||
if (!peer->config) {
|
|
||||||
pr_debug(ctx, "received protocol handshake from temporary peer %P", peer);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!peer->protocol_state)
|
if (!peer->protocol_state)
|
||||||
create_peer_state(ctx, peer);
|
create_peer_state(ctx, peer);
|
||||||
|
|
||||||
|
@ -496,10 +528,7 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(peer->config->protocol_config->public_key.p, packet->common.sender_key, PUBLICKEYBYTES) != 0) {
|
const fastd_peer_config *peer_config = match_sender_key(ctx, peer, packet);
|
||||||
pr_debug(ctx, "received protocol handshake with wrong sender key from %P", peer);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (packet->common.type) {
|
switch (packet->common.type) {
|
||||||
case HANDSHAKE_PACKET_INIT:
|
case HANDSHAKE_PACKET_INIT:
|
||||||
|
@ -508,12 +537,17 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!peer_config) {
|
||||||
|
pr_debug(ctx, "received protocol handshake init with wrong sender key from %P", peer);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
pr_debug(ctx, "received protocol handshake init from %P", peer);
|
pr_debug(ctx, "received protocol handshake init from %P", peer);
|
||||||
|
|
||||||
new_handshake(ctx, peer, false);
|
new_handshake(ctx, peer, peer_config, false);
|
||||||
memcpy(peer->protocol_state->accepting_handshake->peer_key.p, packet->init.handshake_key, PUBLICKEYBYTES);
|
memcpy(peer->protocol_state->accepting_handshake->peer_key.p, packet->init.handshake_key, PUBLICKEYBYTES);
|
||||||
|
|
||||||
fastd_peer_set_established(ctx, peer);
|
fastd_peer_set_established(peer);
|
||||||
respond_handshake(ctx, peer);
|
respond_handshake(ctx, peer);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -529,6 +563,11 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (peer->protocol_state->initiating_handshake->peer_config != peer_config) {
|
||||||
|
pr_debug(ctx, "received protocol handshake response with wrong sender key from %P", peer);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (memcmp(peer->protocol_state->initiating_handshake->public_key.p, packet->response.handshake_key, PUBLICKEYBYTES) != 0) {
|
if (memcmp(peer->protocol_state->initiating_handshake->public_key.p, packet->response.handshake_key, PUBLICKEYBYTES) != 0) {
|
||||||
pr_debug(ctx, "received protocol handshake response with unexpected handshake key from %P", peer);
|
pr_debug(ctx, "received protocol handshake response with unexpected handshake key from %P", peer);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -552,6 +591,11 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (peer->protocol_state->accepting_handshake->peer_config != peer_config) {
|
||||||
|
pr_debug(ctx, "received protocol handshake finish with wrong sender key from %P", peer);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (memcmp(peer->protocol_state->accepting_handshake->public_key.p, packet->finish.handshake_key, PUBLICKEYBYTES) != 0) {
|
if (memcmp(peer->protocol_state->accepting_handshake->public_key.p, packet->finish.handshake_key, PUBLICKEYBYTES) != 0) {
|
||||||
pr_debug(ctx, "received protocol handshake finish with unexpected handshake key from %P", peer);
|
pr_debug(ctx, "received protocol handshake finish with unexpected handshake key from %P", peer);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -596,6 +640,7 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
|
||||||
|
|
||||||
if (crypto_secretbox_xsalsa20poly1305_open(recv_buffer.data, buffer.data, buffer.len, nonce, peer->protocol_state->session.key) != 0) {
|
if (crypto_secretbox_xsalsa20poly1305_open(recv_buffer.data, buffer.data, buffer.len, nonce, peer->protocol_state->session.key) != 0) {
|
||||||
pr_debug(ctx, "verification failed for packet received from %P", peer);
|
pr_debug(ctx, "verification failed for packet received from %P", peer);
|
||||||
|
fastd_buffer_free(recv_buffer);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,10 +682,12 @@ static void protocol_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buf
|
||||||
}
|
}
|
||||||
|
|
||||||
static void protocol_free_peer_state(fastd_context *ctx, fastd_peer *peer) {
|
static void protocol_free_peer_state(fastd_context *ctx, fastd_peer *peer) {
|
||||||
free_handshake(peer->protocol_state->initiating_handshake);
|
if (peer->protocol_state) {
|
||||||
free_handshake(peer->protocol_state->accepting_handshake);
|
free_handshake(peer->protocol_state->initiating_handshake);
|
||||||
|
free_handshake(peer->protocol_state->accepting_handshake);
|
||||||
|
|
||||||
free(peer->protocol_state);
|
free(peer->protocol_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
|
||||||
if (!fastd_peer_is_established(peer)) {
|
if (!fastd_peer_is_established(peer)) {
|
||||||
pr_info(ctx, "Connection with %P established.", peer);
|
pr_info(ctx, "Connection with %P established.", peer);
|
||||||
|
|
||||||
fastd_peer_set_established(ctx, peer);
|
fastd_peer_set_established(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fastd_peer_is_temporary(peer)) {
|
if (fastd_peer_is_temporary(peer)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue