diff options
Diffstat (limited to 'core/net_crypto.c')
-rw-r--r-- | core/net_crypto.c | 139 |
1 files changed, 36 insertions, 103 deletions
diff --git a/core/net_crypto.c b/core/net_crypto.c index bdde7063..e01ed695 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -52,11 +52,6 @@ typedef struct | |||
52 | 52 | ||
53 | static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; | 53 | static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; |
54 | 54 | ||
55 | #define MAX_FRIEND_REQUESTS 32 | ||
56 | |||
57 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | ||
58 | static int outbound_friendrequests[MAX_FRIEND_REQUESTS]; | ||
59 | |||
60 | #define MAX_INCOMING 64 | 55 | #define MAX_INCOMING 64 |
61 | 56 | ||
62 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | 57 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ |
@@ -217,88 +212,63 @@ int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length) | |||
217 | return 1; | 212 | return 1; |
218 | } | 213 | } |
219 | 214 | ||
220 | /* send a friend request to peer with public_key and ip_port. | 215 | /* create a request to peer with public_key. |
221 | Data represents the data we send with the friends request. | 216 | packet must be an array of MAX_DATA_SIZE big. |
217 | Data represents the data we send with the request with length being the length of the data. | ||
218 | request_id is the id of the request (32 = friend request, 254 = ping request) | ||
222 | returns -1 on failure | 219 | returns -1 on failure |
223 | returns a positive friend request id that can be used later to see if it was sent correctly on success. */ | 220 | returns the length of the created packet on success */ |
224 | int send_friendrequest(uint8_t * public_key, IP_Port ip_port, uint8_t * data, uint32_t length) | 221 | int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id) |
225 | { | 222 | { |
226 | if(length > MAX_DATA_SIZE - 1 - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES) | 223 | if(MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING) |
227 | { | ||
228 | return -1; | ||
229 | } | ||
230 | uint32_t i; | ||
231 | for(i = 0; i < MAX_FRIEND_REQUESTS; ++i) | ||
232 | { | ||
233 | if(outbound_friendrequests[i] == -1) | ||
234 | { | ||
235 | break; | ||
236 | } | ||
237 | } | ||
238 | if(i == MAX_FRIEND_REQUESTS) | ||
239 | { | 224 | { |
240 | return -1; | 225 | return -1; |
241 | } | 226 | } |
242 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
243 | uint8_t nonce[crypto_box_NONCEBYTES]; | 227 | uint8_t nonce[crypto_box_NONCEBYTES]; |
244 | random_nonce(nonce); | 228 | random_nonce(nonce); |
245 | int len = encrypt_data(public_key, self_secret_key, nonce, data, length, | 229 | int len = encrypt_data(public_key, self_secret_key, nonce, data, length, |
246 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); | 230 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); |
247 | if(len == -1) | 231 | if(len == -1) |
248 | { | 232 | { |
249 | return -1; | 233 | return -1; |
250 | } | 234 | } |
251 | temp_data[0] = 1; | 235 | packet[0] = request_id; |
252 | memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | 236 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); |
253 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | 237 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); |
254 | int id = new_connection(ip_port); | 238 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); |
255 | if(id == -1) | 239 | |
256 | { | 240 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; |
257 | return -1; | ||
258 | } | ||
259 | if(write_packet(id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES) == 1) | ||
260 | { | ||
261 | outbound_friendrequests[i] = id; | ||
262 | return i; | ||
263 | } | ||
264 | return -1; | ||
265 | } | 241 | } |
266 | 242 | ||
267 | /* return -1 if failure | 243 | /* puts the senders public key in the request in public_key, the data from the request |
268 | return 0 if connection is still trying to send the request. | 244 | in data if a friend or ping request was sent to us and returns the length of the data. |
269 | return 1 if sent correctly | 245 | packet is the request packet and length is its length |
270 | return 2 if connection timed out */ | 246 | return -1 if not valid request. */ |
271 | int check_friendrequest(int friend_request) | 247 | int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint16_t length) |
272 | { | 248 | { |
273 | if(friend_request < 0 || friend_request > MAX_FRIEND_REQUESTS) | 249 | |
250 | if(length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | ||
251 | length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && | ||
252 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
274 | { | 253 | { |
275 | return -1; | 254 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); |
255 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
256 | memcpy(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, | ||
258 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data); | ||
259 | if(len1 == -1) | ||
260 | { | ||
261 | return -1; | ||
262 | } | ||
263 | return len1; | ||
276 | } | 264 | } |
277 | if(outbound_friendrequests[friend_request] == -1) | 265 | else |
278 | { | 266 | { |
279 | return -1; | 267 | return -1; |
280 | } | 268 | } |
281 | if(sendqueue(outbound_friendrequests[friend_request]) == 0) | ||
282 | { | ||
283 | kill_connection(outbound_friendrequests[friend_request]); | ||
284 | outbound_friendrequests[friend_request] = -1; | ||
285 | return 1; | ||
286 | } | ||
287 | int status = is_connected(outbound_friendrequests[friend_request]); | ||
288 | if(status == 4) | ||
289 | { | ||
290 | kill_connection(outbound_friendrequests[friend_request]); | ||
291 | outbound_friendrequests[friend_request] = -1; | ||
292 | return 2; | ||
293 | } | ||
294 | if(status == 0) | ||
295 | { | ||
296 | outbound_friendrequests[friend_request] = -1; | ||
297 | return 2; | ||
298 | } | ||
299 | return 0; | ||
300 | } | 269 | } |
301 | 270 | ||
271 | |||
302 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key | 272 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key |
303 | to peer with connection_id and public_key | 273 | to peer with connection_id and public_key |
304 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ | 274 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ |
@@ -359,43 +329,7 @@ int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce, | |||
359 | } | 329 | } |
360 | 330 | ||
361 | 331 | ||
362 | /* puts the public key of the friend if public_key, the data from the request | 332 | |
363 | in data if a friend request was sent to us and returns the length of the data. | ||
364 | return -1 if no valid friend requests. */ | ||
365 | int handle_friendrequest(uint8_t * public_key, uint8_t * data) | ||
366 | { | ||
367 | uint32_t i; | ||
368 | for(i = 0; i < MAX_INCOMING; ++i) | ||
369 | { | ||
370 | if(incoming_connections[i] != -1) | ||
371 | { | ||
372 | if(id_packet(incoming_connections[i]) == 1) | ||
373 | { | ||
374 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
375 | uint16_t len = read_packet(incoming_connections[i], temp_data); | ||
376 | if(len > crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1 | ||
377 | - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES) | ||
378 | { | ||
379 | memcpy(public_key, temp_data + 1, crypto_box_PUBLICKEYBYTES); | ||
380 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
381 | memcpy(nonce, temp_data + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_NONCEBYTES); | ||
382 | int len1 = decrypt_data(public_key, self_secret_key, nonce, temp_data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, | ||
383 | len - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1), data); | ||
384 | if(len1 != -1) | ||
385 | { | ||
386 | kill_connection(incoming_connections[i]); | ||
387 | /* kill_connection_in(incoming_connections[i], 1); //conection is useless now, kill it in 1 seconds */ | ||
388 | incoming_connections[i] = -1; | ||
389 | return len1; | ||
390 | } | ||
391 | } | ||
392 | kill_connection(incoming_connections[i]); /* conection is useless now, kill it. */ | ||
393 | incoming_connections[i] = -1; | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | return -1; | ||
398 | } | ||
399 | 333 | ||
400 | /* get crypto connection id from public key of peer | 334 | /* get crypto connection id from public key of peer |
401 | return -1 if there are no connections like we are looking for | 335 | return -1 if there are no connections like we are looking for |
@@ -714,7 +648,6 @@ static void receive_crypto() | |||
714 | void initNetCrypto() | 648 | void initNetCrypto() |
715 | { | 649 | { |
716 | memset(crypto_connections, 0 ,sizeof(crypto_connections)); | 650 | memset(crypto_connections, 0 ,sizeof(crypto_connections)); |
717 | memset(outbound_friendrequests, -1 ,sizeof(outbound_friendrequests)); | ||
718 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); | 651 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); |
719 | uint32_t i; | 652 | uint32_t i; |
720 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 653 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) |