diff options
author | irungentoo <irungentoo@gmail.com> | 2014-04-29 20:45:32 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-04-29 20:45:32 -0400 |
commit | 3863e01e2207198c20bf278c107f24a8cfbf1a73 (patch) | |
tree | a49a417a68d9ccff7dd30824021bc6e1b408795f /toxcore/net_crypto.c | |
parent | 94545c3b50c6f87af702692ba171cacc577c669a (diff) |
Some more work done on the middle network protocol.
Handshake most likely has no more possible flaws to it, next thing
to do is to do the same with the data packets.
Wrote a couple more functions.
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r-- | toxcore/net_crypto.c | 231 |
1 files changed, 209 insertions, 22 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 97533512..81cff70a 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -212,7 +212,7 @@ static int handle_cookie_response(Net_Crypto *c, uint8_t *cookie, uint8_t *packe | |||
212 | return COOKIE_LENGTH; | 212 | return COOKIE_LENGTH; |
213 | } | 213 | } |
214 | 214 | ||
215 | #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) | 215 | #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH + crypto_box_MACBYTES) |
216 | 216 | ||
217 | /* Create a handshake packet and put it in packet. | 217 | /* Create a handshake packet and put it in packet. |
218 | * cookie must be COOKIE_LENGTH bytes. | 218 | * cookie must be COOKIE_LENGTH bytes. |
@@ -224,9 +224,18 @@ static int handle_cookie_response(Net_Crypto *c, uint8_t *cookie, uint8_t *packe | |||
224 | static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk, | 224 | static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk, |
225 | uint8_t *peer_real_pk) | 225 | uint8_t *peer_real_pk) |
226 | { | 226 | { |
227 | uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 227 | uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH]; |
228 | memcpy(plain, nonce, crypto_box_NONCEBYTES); | 228 | memcpy(plain, nonce, crypto_box_NONCEBYTES); |
229 | memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES); | 229 | memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES); |
230 | crypto_hash_sha512(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, cookie, COOKIE_LENGTH); | ||
231 | uint8_t cookie_plain[COOKIE_REQUEST_PLAIN_LENGTH]; | ||
232 | memcpy(cookie_plain, peer_real_pk, crypto_box_PUBLICKEYBYTES); | ||
233 | memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
234 | |||
235 | if (create_cookie(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, cookie_plain, | ||
236 | c->secret_symmetric_key) != 0) | ||
237 | return -1; | ||
238 | |||
230 | new_nonce(packet + 1 + COOKIE_LENGTH); | 239 | new_nonce(packet + 1 + COOKIE_LENGTH); |
231 | int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), | 240 | int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), |
232 | packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES); | 241 | packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES); |
@@ -242,18 +251,23 @@ static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cook | |||
242 | 251 | ||
243 | /* Handle a crypto handshake packet of length. | 252 | /* Handle a crypto handshake packet of length. |
244 | * put the nonce contained in the packet in nonce, | 253 | * put the nonce contained in the packet in nonce, |
245 | * the session public key in session_pk and | 254 | * the session public key in session_pk |
246 | * the real public key of the peer in peer_real_pk. | 255 | * the real public key of the peer in peer_real_pk and |
256 | * the cookie inside the encrypted part of the packet in cookie. | ||
257 | * | ||
258 | * if expected_real_pk isn't NULL it denotes the real public key | ||
259 | * the packet should be from. | ||
247 | * | 260 | * |
248 | * nonce must be at least crypto_box_NONCEBYTES | 261 | * nonce must be at least crypto_box_NONCEBYTES |
249 | * session_pk must be at least crypto_box_PUBLICKEYBYTES | 262 | * session_pk must be at least crypto_box_PUBLICKEYBYTES |
250 | * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES | 263 | * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES |
264 | * cookie must be at least COOKIE_LENGTH | ||
251 | * | 265 | * |
252 | * return -1 on failure. | 266 | * return -1 on failure. |
253 | * return 0 on success. | 267 | * return 0 on success. |
254 | */ | 268 | */ |
255 | static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, | 269 | static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, |
256 | uint8_t *packet, uint32_t length) | 270 | uint8_t *cookie, uint8_t *packet, uint32_t length, uint8_t *expected_real_pk) |
257 | { | 271 | { |
258 | if (length != HANDSHAKE_PACKET_LENGTH) | 272 | if (length != HANDSHAKE_PACKET_LENGTH) |
259 | return -1; | 273 | return -1; |
@@ -263,10 +277,17 @@ static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *sessi | |||
263 | if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0) | 277 | if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0) |
264 | return -1; | 278 | return -1; |
265 | 279 | ||
280 | if (expected_real_pk) | ||
281 | if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0) | ||
282 | return -1; | ||
283 | |||
266 | if (crypto_cmp(cookie_plain + crypto_box_PUBLICKEYBYTES, c->self_public_key, crypto_box_PUBLICKEYBYTES) != 0) | 284 | if (crypto_cmp(cookie_plain + crypto_box_PUBLICKEYBYTES, c->self_public_key, crypto_box_PUBLICKEYBYTES) != 0) |
267 | return -1; | 285 | return -1; |
268 | 286 | ||
269 | uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 287 | uint8_t cookie_hash[crypto_hash_sha512_BYTES]; |
288 | crypto_hash_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); | ||
289 | |||
290 | uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH]; | ||
270 | int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, | 291 | int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, |
271 | packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES, | 292 | packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES, |
272 | HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain); | 293 | HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain); |
@@ -274,41 +295,207 @@ static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *sessi | |||
274 | if (len != sizeof(plain)) | 295 | if (len != sizeof(plain)) |
275 | return -1; | 296 | return -1; |
276 | 297 | ||
298 | if (memcmp(cookie_hash, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, crypto_hash_sha512_BYTES) != 0) | ||
299 | return -1; | ||
300 | |||
277 | memcpy(nonce, plain, crypto_box_NONCEBYTES); | 301 | memcpy(nonce, plain, crypto_box_NONCEBYTES); |
278 | memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); | 302 | memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); |
303 | memcpy(cookie, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, COOKIE_LENGTH); | ||
279 | memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES); | 304 | memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES); |
280 | return 0; | 305 | return 0; |
281 | } | 306 | } |
282 | 307 | ||
283 | /* Handle a crypto handshake packet of length without opening the cookie from peer | 308 | |
284 | * with the real public key peer_real_pk. | 309 | static Crypto_Connection *get_crypto_connection(Net_Crypto *c, int crypt_connection_id) |
285 | * put the nonce contained in the packet in nonce and the session public key in | 310 | { |
286 | * session_pk. | 311 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) |
312 | return 0; | ||
313 | |||
314 | return &c->crypto_connections[crypt_connection_id]; | ||
315 | } | ||
316 | |||
317 | |||
318 | /* Sends a packet to the peer using the fastest route. | ||
287 | * | 319 | * |
288 | * nonce must be at least crypto_box_NONCEBYTES | 320 | * return -1 on failure. |
289 | * session_pk must be at least crypto_box_PUBLICKEYBYTES | 321 | * return 0 on success. |
322 | */ | ||
323 | static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) | ||
324 | { | ||
325 | //TODO | ||
326 | |||
327 | |||
328 | } | ||
329 | |||
330 | /* Add a new temp packet to send repeatedly. | ||
290 | * | 331 | * |
291 | * return -1 on failure. | 332 | * return -1 on failure. |
292 | * return 0 on success. | 333 | * return 0 on success. |
293 | */ | 334 | */ |
294 | static int handle_crypto_handshake_nocookie(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *packet, | 335 | static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length) |
295 | uint32_t length, uint8_t *peer_real_pk) | ||
296 | { | 336 | { |
297 | if (length != HANDSHAKE_PACKET_LENGTH) | 337 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) |
298 | return -1; | 338 | return -1; |
299 | 339 | ||
300 | uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 340 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
301 | int len = decrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, | ||
302 | packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES, | ||
303 | HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain); | ||
304 | 341 | ||
305 | if (len != sizeof(plain)) | 342 | if (conn == 0) |
306 | return -1; | 343 | return -1; |
307 | 344 | ||
308 | memcpy(nonce, plain, crypto_box_NONCEBYTES); | 345 | uint8_t *temp_packet = malloc(length); |
309 | memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); | 346 | |
347 | if (temp_packet == 0) | ||
348 | return -1; | ||
349 | |||
350 | if (conn->temp_packet) | ||
351 | free(conn->temp_packet); | ||
352 | |||
353 | memcpy(temp_packet, packet, length); | ||
354 | conn->temp_packet = temp_packet; | ||
355 | conn->temp_packet_length = length; | ||
356 | conn->temp_packet_sent_time = 0; | ||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | /* Clear the temp packet. | ||
361 | * | ||
362 | * return -1 on failure. | ||
363 | * return 0 on success. | ||
364 | */ | ||
365 | static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id) | ||
366 | { | ||
367 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
368 | |||
369 | if (conn == 0) | ||
370 | return -1; | ||
371 | |||
372 | if (conn->temp_packet) | ||
373 | free(conn->temp_packet); | ||
374 | |||
375 | conn->temp_packet = 0; | ||
376 | conn->temp_packet_length = 0; | ||
377 | conn->temp_packet_sent_time = 0; | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | |||
382 | /* Send the temp packet. | ||
383 | * | ||
384 | * return -1 on failure. | ||
385 | * return 0 on success. | ||
386 | */ | ||
387 | static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) | ||
388 | { | ||
389 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
390 | |||
391 | if (conn == 0) | ||
392 | return -1; | ||
393 | |||
394 | if (!conn->temp_packet) | ||
395 | return -1; | ||
396 | |||
397 | if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) | ||
398 | return -1; | ||
399 | |||
400 | conn->temp_packet_sent_time = current_time(); | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | /* Handle a packet that was recieved for the connection. | ||
405 | * | ||
406 | * return -1 on failure. | ||
407 | * return 0 on success. | ||
408 | */ | ||
409 | static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length) | ||
410 | { | ||
411 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) | ||
412 | return -1; | ||
413 | |||
414 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
415 | |||
416 | if (conn == 0) | ||
417 | return -1; | ||
418 | |||
419 | switch (packet[0]) { | ||
420 | case NET_PACKET_COOKIE_RESPONSE: { | ||
421 | if (conn->status != CRYPTO_CONN_COOKIE_REQUESTED) | ||
422 | return -1; | ||
423 | |||
424 | uint8_t cookie[COOKIE_LENGTH]; | ||
425 | |||
426 | if (handle_cookie_response(c, cookie, packet, length, conn->shared_key) != sizeof(cookie)) | ||
427 | return -1; | ||
428 | |||
429 | uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; | ||
430 | |||
431 | if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionpublic_key, | ||
432 | conn->public_key) != sizeof(handshake_packet)) | ||
433 | return -1; | ||
434 | |||
435 | if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) | ||
436 | return -1; | ||
437 | |||
438 | send_temp_packet(c, crypt_connection_id); | ||
439 | conn->status = CRYPTO_CONN_HANDSHAKE_SENT; | ||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | case NET_PACKET_CRYPTO_HS: { | ||
444 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTED || conn->status == CRYPTO_CONN_HANDSHAKE_SENT) { | ||
445 | uint8_t peer_real_pk[crypto_box_PUBLICKEYBYTES]; | ||
446 | uint8_t cookie[COOKIE_LENGTH]; | ||
447 | |||
448 | if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, cookie, packet, length, | ||
449 | conn->public_key) != 0) | ||
450 | return -1; | ||
451 | |||
452 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | ||
453 | |||
454 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | ||
455 | } else { | ||
456 | return -1; | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | case NET_PACKET_CRYPTO_DATA: { | ||
463 | if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) { | ||
464 | //TODO | ||
465 | } else { | ||
466 | return -1; | ||
467 | } | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | default: { | ||
473 | return -1; | ||
474 | } | ||
475 | } | ||
476 | |||
310 | return 0; | 477 | return 0; |
311 | } | 478 | } |
479 | |||
480 | |||
481 | void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c), | ||
482 | void *object) | ||
483 | { | ||
484 | c->new_connection_callback = new_connection_callback; | ||
485 | c->new_connection_callback_object = object; | ||
486 | } | ||
487 | |||
488 | static int handle_new_connection_handshake(Net_Crypto *c, uint8_t *data, uint16_t length) | ||
489 | { | ||
490 | |||
491 | |||
492 | } | ||
493 | |||
494 | int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | ||
495 | { | ||
496 | |||
497 | |||
498 | } | ||
312 | /* return 0 if there is no received data in the buffer. | 499 | /* return 0 if there is no received data in the buffer. |
313 | * return -1 if the packet was discarded. | 500 | * return -1 if the packet was discarded. |
314 | * return length of received data if successful. | 501 | * return length of received data if successful. |