diff --git a/toxcore/onion.c b/toxcore/onion.c index 33bb54ca..938b861e 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -141,6 +141,54 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion return 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + len; } +/* Create a onion packet to be sent over tcp. + * + * Use Onion_Path path to create packet for data of length to dest. + * Maximum length of data is ONION_MAX_DATA_SIZE. + * packet should be at least ONION_MAX_PACKET_SIZE big. + * + * return -1 on failure. + * return length of created packet on success. + */ +int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest, + const uint8_t *data, uint32_t length) +{ + if (crypto_box_NONCEBYTES + SIZE_IPPORT + SEND_BASE * 2 + length > max_packet_length || length == 0) + return -1; + + to_net_family(&dest.ip); + uint8_t step1[SIZE_IPPORT + length]; + + + ipport_pack(step1, &dest); + memcpy(step1 + SIZE_IPPORT, data, length); + + uint8_t nonce[crypto_box_NONCEBYTES]; + random_nonce(nonce); + + uint8_t step2[SIZE_IPPORT + SEND_BASE + length]; + ipport_pack(step2, &path->ip_port3); + memcpy(step2 + SIZE_IPPORT, path->public_key3, crypto_box_PUBLICKEYBYTES); + + int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1), + step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); + + if ((uint32_t)len != SIZE_IPPORT + length + crypto_box_MACBYTES) + return -1; + + ipport_pack(packet + crypto_box_NONCEBYTES, &path->ip_port2); + memcpy(packet + crypto_box_NONCEBYTES + SIZE_IPPORT, path->public_key2, crypto_box_PUBLICKEYBYTES); + len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2), + packet + crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES); + + if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES) + return -1; + + memcpy(packet, nonce, crypto_box_NONCEBYTES); + + return crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES + len; +} + /* Create and send a onion packet. * * Use Onion_Path path to send data of length to dest. diff --git a/toxcore/onion.h b/toxcore/onion.h index 5dedd60d..e8e7042c 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -92,6 +92,19 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest, const uint8_t *data, uint32_t length); + +/* Create a onion packet to be sent over tcp. + * + * Use Onion_Path path to create packet for data of length to dest. + * Maximum length of data is ONION_MAX_DATA_SIZE. + * packet should be at least ONION_MAX_PACKET_SIZE big. + * + * return -1 on failure. + * return length of created packet on success. + */ +int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest, + const uint8_t *data, uint32_t length); + /* Create and send a onion packet. * * Use Onion_Path path to send data of length to dest.