diff options
author | irungentoo <irungentoo@gmail.com> | 2013-08-14 18:26:00 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-08-14 18:26:00 -0400 |
commit | 4330bfbf871e769cf1599825bfb09ba56293d6a0 (patch) | |
tree | 7f4b5a11c6992e7c9cf6a95a4e03a0ba02a720a9 | |
parent | 95664357d42d4d71a093d011124b0b1be7c1e380 (diff) |
Metadata collection prevention part 1 of ???.
Crypto requests packets are packets that can be routed by nodes in the
DHT. In this pull request I have merged both Natping requests and friend
requests into one common packet (Crypto request packets). Both these
packets should now only be distinguishable by the size of the data in
them to an outside observer for an example on how to send and recieve
data with these packets see: friend_requests.c
Note that these packets are prefixed with id 32 (friend request packets)
which means this change is compatible with the currently running DHT
bootstrap servers.
Also changed small thing in DHT_test.c
-rw-r--r-- | core/DHT.c | 55 | ||||
-rw-r--r-- | core/friend_requests.c | 44 | ||||
-rw-r--r-- | core/net_crypto.c | 51 | ||||
-rw-r--r-- | core/net_crypto.h | 10 | ||||
-rw-r--r-- | testing/DHT_test.c | 4 |
5 files changed, 84 insertions, 80 deletions
@@ -932,49 +932,30 @@ static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
932 | } | 932 | } |
933 | 933 | ||
934 | /* Handle a received ping request for */ | 934 | /* Handle a received ping request for */ |
935 | static int handle_NATping(IP_Port source, uint8_t * packet, uint32_t length) | 935 | static int handle_NATping(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) |
936 | { | 936 | { |
937 | if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING | 937 | uint64_t ping_id; |
938 | || length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 938 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); |
939 | return 1; | ||
940 | |||
941 | /* check if request is for us. */ | ||
942 | if (id_equal(packet + 1, self_public_key)) { | ||
943 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
944 | uint8_t data[MAX_DATA_SIZE]; | ||
945 | |||
946 | int len = handle_request(public_key, data, packet, length); | ||
947 | if (len != sizeof(uint64_t) + 1) | ||
948 | return 1; | ||
949 | |||
950 | uint64_t ping_id; | ||
951 | memcpy(&ping_id, data + 1, sizeof(uint64_t)); | ||
952 | 939 | ||
953 | int friendnumber = friend_number(public_key); | 940 | int friendnumber = friend_number(source_pubkey); |
954 | if (friendnumber == -1) | 941 | if (friendnumber == -1) |
955 | return 1; | 942 | return 1; |
956 | 943 | ||
957 | Friend * friend = &friends_list[friendnumber]; | 944 | Friend * friend = &friends_list[friendnumber]; |
958 | 945 | ||
959 | if (data[0] == 0) { | 946 | if (packet[0] == 0) { |
960 | /* 1 is reply */ | 947 | /* 1 is reply */ |
961 | send_NATping(public_key, ping_id, 1); | 948 | send_NATping(source_pubkey, ping_id, 1); |
962 | friend->recvNATping_timestamp = unix_time(); | 949 | friend->recvNATping_timestamp = unix_time(); |
950 | return 0; | ||
951 | } else if (packet[0] == 1) { | ||
952 | if (friend->NATping_id == ping_id) { | ||
953 | friend->NATping_id = ((uint64_t)random_int() << 32) + random_int(); | ||
954 | friend->hole_punching = 1; | ||
963 | return 0; | 955 | return 0; |
964 | } else if (data[0] == 1) { | ||
965 | if (friend->NATping_id == ping_id) { | ||
966 | friend->NATping_id = ((uint64_t)random_int() << 32) + random_int(); | ||
967 | friend->hole_punching = 1; | ||
968 | return 0; | ||
969 | } | ||
970 | } | 956 | } |
971 | return 1; | ||
972 | } | 957 | } |
973 | 958 | return 1; | |
974 | /* if request is not for us, try routing it. */ | ||
975 | route_packet(packet + 1, packet, length); | ||
976 | |||
977 | return 0; | ||
978 | } | 959 | } |
979 | 960 | ||
980 | /* Get the most common ip in the ip_portlist | 961 | /* Get the most common ip in the ip_portlist |
@@ -1082,7 +1063,7 @@ void DHT_init(void) | |||
1082 | networking_registerhandler(1, &handle_ping_response); | 1063 | networking_registerhandler(1, &handle_ping_response); |
1083 | networking_registerhandler(2, &handle_getnodes); | 1064 | networking_registerhandler(2, &handle_getnodes); |
1084 | networking_registerhandler(3, &handle_sendnodes); | 1065 | networking_registerhandler(3, &handle_sendnodes); |
1085 | networking_registerhandler(254, &handle_NATping); | 1066 | cryptopacket_registerhandler(254, &handle_NATping); |
1086 | } | 1067 | } |
1087 | 1068 | ||
1088 | void doDHT(void) | 1069 | void doDHT(void) |
diff --git a/core/friend_requests.c b/core/friend_requests.c index 8276db29..ae19ebdd 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -123,39 +123,23 @@ static int request_received(uint8_t * client_id) | |||
123 | } | 123 | } |
124 | 124 | ||
125 | 125 | ||
126 | static int friendreq_handlepacket(IP_Port source, uint8_t * packet, uint32_t length) | 126 | static int friendreq_handlepacket(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) |
127 | { | 127 | { |
128 | if (packet[0] == 32) { | 128 | if (handle_friendrequest_isset == 0) |
129 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | 129 | return 1; |
130 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 130 | if (length <= sizeof(nospam)) |
131 | return 1; | 131 | return 1; |
132 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. | 132 | if (request_received(source_pubkey)) |
133 | if (handle_friendrequest_isset == 0) | 133 | return 1; |
134 | return 1; | 134 | if (memcmp(packet, &nospam, sizeof(nospam)) != 0) |
135 | 135 | return 1; | |
136 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 136 | |
137 | uint8_t data[MAX_DATA_SIZE]; | 137 | addto_receivedlist(source_pubkey); |
138 | int len = handle_request(public_key, data, packet, length); | 138 | (*handle_friendrequest)(source_pubkey, packet + 4, length - 4, handle_friendrequest_userdata); |
139 | if (len == -1) | 139 | return 0; |
140 | return 1; | ||
141 | if (len <= sizeof(nospam)) | ||
142 | return 1; | ||
143 | if (request_received(public_key)) | ||
144 | return 1; | ||
145 | if (memcmp(data, &nospam, sizeof(nospam)) != 0) | ||
146 | return 1; | ||
147 | |||
148 | addto_receivedlist(public_key); | ||
149 | (*handle_friendrequest)(public_key, data + 4, len - 4, handle_friendrequest_userdata); | ||
150 | } else { /* if request is not for us, try routing it. */ | ||
151 | if(route_packet(packet + 1, packet, length) == length) | ||
152 | return 0; | ||
153 | } | ||
154 | } | ||
155 | return 1; | ||
156 | } | 140 | } |
157 | 141 | ||
158 | void friendreq_init(void) | 142 | void friendreq_init(void) |
159 | { | 143 | { |
160 | networking_registerhandler(32, &friendreq_handlepacket); | 144 | cryptopacket_registerhandler(32, &friendreq_handlepacket); |
161 | } | 145 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index ab18dd63..376708ab 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -221,15 +221,18 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | |||
221 | returns the length of the created packet on success */ | 221 | returns the length of the created packet on success */ |
222 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) | 222 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) |
223 | { | 223 | { |
224 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING) | 224 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) |
225 | return -1; | 225 | return -1; |
226 | uint8_t nonce[crypto_box_NONCEBYTES]; | 226 | uint8_t nonce[crypto_box_NONCEBYTES]; |
227 | uint8_t temp[MAX_DATA_SIZE]; | ||
228 | memcpy(temp + 1, data, length); | ||
229 | temp[0] = request_id; | ||
227 | random_nonce(nonce); | 230 | random_nonce(nonce); |
228 | int len = encrypt_data(public_key, self_secret_key, nonce, data, length, | 231 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, length, |
229 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); | 232 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); |
230 | if (len == -1) | 233 | if (len == -1) |
231 | return -1; | 234 | return -1; |
232 | packet[0] = request_id; | 235 | packet[0] = 32; |
233 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); | 236 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); |
234 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); | 237 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); |
235 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); | 238 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); |
@@ -241,7 +244,7 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
241 | in data if a friend or ping request was sent to us and returns the length of the data. | 244 | in data if a friend or ping request was sent to us and returns the length of the data. |
242 | packet is the request packet and length is its length | 245 | packet is the request packet and length is its length |
243 | return -1 if not valid request. */ | 246 | return -1 if not valid request. */ |
244 | int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length) | 247 | static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, uint16_t length) |
245 | { | 248 | { |
246 | 249 | ||
247 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 250 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
@@ -249,16 +252,51 @@ int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t | |||
249 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 252 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
250 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); | 253 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); |
251 | uint8_t nonce[crypto_box_NONCEBYTES]; | 254 | uint8_t nonce[crypto_box_NONCEBYTES]; |
255 | uint8_t temp[MAX_DATA_SIZE]; | ||
252 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); | 256 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); |
253 | int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, | 257 | int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, |
254 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data); | 258 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); |
255 | if(len1 == -1) | 259 | if(len1 == -1 || len1 == 0) |
256 | return -1; | 260 | return -1; |
261 | request_id[0] = temp[0]; | ||
262 | --len1; | ||
263 | memcpy(data, temp + 1, len1); | ||
257 | return len1; | 264 | return len1; |
258 | } else | 265 | } else |
259 | return -1; | 266 | return -1; |
260 | } | 267 | } |
261 | 268 | ||
269 | static cryptopacket_handler_callback cryptopackethandlers[256] = {0}; | ||
270 | |||
271 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb) | ||
272 | { | ||
273 | cryptopackethandlers[byte] = cb; | ||
274 | } | ||
275 | |||
276 | static int cryptopacket_handle(IP_Port source, uint8_t * packet, uint32_t length) | ||
277 | { | ||
278 | if (packet[0] == 32) { | ||
279 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | ||
280 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | ||
281 | return 1; | ||
282 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. | ||
283 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
284 | uint8_t data[MAX_DATA_SIZE]; | ||
285 | uint8_t number; | ||
286 | int len = handle_request(public_key, data, &number, packet, length); | ||
287 | if (len == -1 || len == 0) | ||
288 | return 1; | ||
289 | if (!cryptopackethandlers[number]) return 1; | ||
290 | cryptopackethandlers[number](source, public_key, data, len - 1); | ||
291 | |||
292 | } else { /* if request is not for us, try routing it. */ | ||
293 | if(route_packet(packet + 1, packet, length) == length) | ||
294 | return 0; | ||
295 | } | ||
296 | } | ||
297 | return 1; | ||
298 | } | ||
299 | |||
262 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key | 300 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key |
263 | to peer with connection_id and public_key | 301 | to peer with connection_id and public_key |
264 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ | 302 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ |
@@ -579,6 +617,7 @@ void initNetCrypto(void) | |||
579 | { | 617 | { |
580 | memset(crypto_connections, 0 ,sizeof(crypto_connections)); | 618 | memset(crypto_connections, 0 ,sizeof(crypto_connections)); |
581 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); | 619 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); |
620 | networking_registerhandler(32, &cryptopacket_handle); | ||
582 | uint32_t i; | 621 | uint32_t i; |
583 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 622 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) |
584 | crypto_connections[i].number = ~0; | 623 | crypto_connections[i].number = ~0; |
diff --git a/core/net_crypto.h b/core/net_crypto.h index 135e099d..570b9373 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define NET_CRYPTO_H | 25 | #define NET_CRYPTO_H |
26 | 26 | ||
27 | #include "Lossless_UDP.h" | 27 | #include "Lossless_UDP.h" |
28 | #include "DHT.h" | ||
28 | 29 | ||
29 | #ifdef __cplusplus | 30 | #ifdef __cplusplus |
30 | extern "C" { | 31 | extern "C" { |
@@ -88,11 +89,10 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); | |||
88 | returns the length of the created packet on success */ | 89 | returns the length of the created packet on success */ |
89 | int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); | 90 | int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); |
90 | 91 | ||
91 | /* puts the senders public key in the request in public_key, the data from the request | 92 | |
92 | in data if a friend or ping request was sent to us and returns the length of the data. | 93 | typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t * source_pubkey, uint8_t *data, uint32_t len); |
93 | packet is the request packet and length is its length | 94 | /* Function to call when request beginning with byte is received */ |
94 | return -1 if not valid request. */ | 95 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb); |
95 | int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length); | ||
96 | 96 | ||
97 | /* Start a secure connection with other peer who has public_key and ip_port | 97 | /* Start a secure connection with other peer who has public_key and ip_port |
98 | returns -1 if failure | 98 | returns -1 if failure |
diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 350093fd..c5b367cf 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c | |||
@@ -53,10 +53,10 @@ void print_clientlist() | |||
53 | uint32_t i, j; | 53 | uint32_t i, j; |
54 | IP_Port p_ip; | 54 | IP_Port p_ip; |
55 | printf("___________________CLOSE________________________________\n"); | 55 | printf("___________________CLOSE________________________________\n"); |
56 | for(i = 0; i < 4; i++) { | 56 | for(i = 0; i < 32; i++) { |
57 | printf("ClientID: "); | 57 | printf("ClientID: "); |
58 | for(j = 0; j < 32; j++) { | 58 | for(j = 0; j < 32; j++) { |
59 | printf("%hhX", close_clientlist[i].client_id[j]); | 59 | printf("%02hhX", close_clientlist[i].client_id[j]); |
60 | } | 60 | } |
61 | p_ip = close_clientlist[i].ip_port; | 61 | p_ip = close_clientlist[i].ip_port; |
62 | printf("\nIP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); | 62 | printf("\nIP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); |