Skip to content

Commit bf43cce

Browse files
committed
add protocol for exchanging signed network data
Signed-off-by: Felix Fietkau <[email protected]>
1 parent 547be90 commit bf43cce

19 files changed

+1457
-126
lines changed

CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ PROJECT(unetd C)
44

55

66
SET(SOURCES
7-
main.c network.c host.c service.c pex.c utils.c
7+
main.c network.c host.c service.c pex.c
88
wg.c wg-user.c
99
)
1010

@@ -30,7 +30,7 @@ ELSE()
3030
SET(ubus "")
3131
ENDIF()
3232

33-
ADD_LIBRARY(unet SHARED curve25519.c siphash.c sha512.c fprime.c f25519.c ed25519.c edsign.c auth-data.c chacha20.c)
33+
ADD_LIBRARY(unet SHARED curve25519.c siphash.c sha512.c fprime.c f25519.c ed25519.c edsign.c auth-data.c chacha20.c pex-msg.c utils.c)
3434
TARGET_LINK_LIBRARIES(unet ubox)
3535

3636
ADD_EXECUTABLE(unetd ${SOURCES})

PEX.md

+79
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,82 @@ No payload.
7676
Response to PEX_MSG_PING.
7777
No payload.
7878

79+
## Unencrypted messages (outside of the tunnel)
80+
81+
These are only supported for networks using signed network data that can be updated dynamically.
82+
The struct pex_hdr header is followed by a second header:
83+
84+
struct pex_ext_hdr {
85+
uint64_t nonce;
86+
uint8_t auth_id[8];
87+
};
88+
89+
- nonce: nonce for id hash
90+
- auth_id: first 8 bytes of the auth public key
91+
92+
In these messages, pex_hdr::id is XORed with siphash(req_id || req_id, auth_key)
93+
94+
### opcode=5: PEX_MSG_UPDATE_REQUEST
95+
96+
This message can be used outside of the wireguard tunnel in order to request signed network data
97+
It is used to ask a peer for the latest signed network data
98+
99+
Payload:
100+
struct pex_update_request {
101+
uint64_t cur_version;
102+
uint32_t req_id;
103+
};
104+
105+
- cur_version: latest version of the network data that the sender already has
106+
- req_id: request id copied to response messages
107+
108+
### opcode=6: PEX_MSG_UPDATE_RESPONSE
109+
110+
Used to send updated signed network data to a peer
111+
112+
Payload:
113+
struct pex_update_response {
114+
uint64_t req_id;
115+
uint32_t data_len;
116+
uint8_t e_key[32];
117+
};
118+
119+
followed by the first chunk of network data.
120+
121+
- req_id: request id of the PEX_MSG_UPDATE_REQUEST message
122+
- data_len: total length of the network data
123+
- e_key: ephemeral curve25519 public key
124+
125+
The network data is chacha20 encrypted with the following key:
126+
DH(e_key_priv, peer_key)
127+
And using req_id as nonce.
128+
129+
- e_key_priv: private key belonging to e_key
130+
- peer_key: public key belonging to the receiver (from the network data)
131+
132+
### opcode=7: PEX_MSG_UPDATE_RESPONSE_DATA
133+
134+
Continuation of PEX_MSG_UPDATE_RESPONSE network data
135+
136+
Payload:
137+
struct pex_update_response_data {
138+
uint64_t req_id;
139+
uint32_t offset;
140+
};
141+
142+
followed by encrypted network data
143+
144+
### opcode=8: PEX_MSG_UPDATE_RESPONSE_NO_DATA
145+
146+
Indicates that the network data with the timestamp given in PEX_MSG_UPDATE_REQUEST
147+
is up to date
148+
149+
Payload:
150+
151+
struct pex_update_response_no_data {
152+
uint64_t req_id;
153+
uint64_t cur_version;
154+
};
155+
156+
- req_id: request id of the PEX_MSG_UPDATE_REQUEST message
157+
- cur_version: latest version of the network data

auth-data.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "auth-data.h"
88

99
int unet_auth_data_validate(const uint8_t *key, const void *buf, size_t len,
10-
const char **json_data)
10+
uint64_t *timestamp, const char **json_data)
1111
{
1212
const struct unet_auth_hdr *hdr = buf;
1313
const struct unet_auth_data *data = net_data_auth_data_hdr(buf);
@@ -23,7 +23,7 @@ int unet_auth_data_validate(const uint8_t *key, const void *buf, size_t len,
2323
data->timestamp == 0)
2424
return -1;
2525

26-
if (memcmp(data->pubkey, key, EDSIGN_PUBLIC_KEY_SIZE) != 0)
26+
if (key && memcmp(data->pubkey, key, EDSIGN_PUBLIC_KEY_SIZE) != 0)
2727
return -2;
2828

2929
edsign_verify_init(&vst, hdr->signature, data->pubkey);
@@ -34,6 +34,9 @@ int unet_auth_data_validate(const uint8_t *key, const void *buf, size_t len,
3434
if (*(char *)(data + len - 1) != 0)
3535
return -2;
3636

37+
if (timestamp)
38+
*timestamp = be64_to_cpu(data->timestamp);
39+
3740
if (json_data)
3841
*json_data = (const char *)(data + 1);
3942

auth-data.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct unet_auth_data {
3030
} __packed;
3131

3232
int unet_auth_data_validate(const uint8_t *key, const void *buf, size_t len,
33-
const char **json_data);
33+
uint64_t *timestamp, const char **json_data);
3434

3535
static inline const struct unet_auth_data *
3636
net_data_auth_data_hdr(const void *net_data)

0 commit comments

Comments
 (0)