summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c55
-rw-r--r--core/friend_requests.c44
-rw-r--r--core/net_crypto.c51
-rw-r--r--core/net_crypto.h10
4 files changed, 82 insertions, 78 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 5eae147c..057ee9ce 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -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 */
935static int handle_NATping(IP_Port source, uint8_t * packet, uint32_t length) 935static 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
1088void doDHT(void) 1069void 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
126static int friendreq_handlepacket(IP_Port source, uint8_t * packet, uint32_t length) 126static 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
158void friendreq_init(void) 142void 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 */
222int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) 222int 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. */
244int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length) 247static 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
269static cryptopacket_handler_callback cryptopackethandlers[256] = {0};
270
271void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb)
272{
273 cryptopackethandlers[byte] = cb;
274}
275
276static 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
30extern "C" { 31extern "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 */
89int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); 90int 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. 93typedef 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. */ 95void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb);
95int 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