summaryrefslogtreecommitdiff
path: root/toxcore/net_crypto.h
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/net_crypto.h')
-rw-r--r--toxcore/net_crypto.h332
1 files changed, 197 insertions, 135 deletions
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index da776527..25f8c2f7 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -24,21 +24,62 @@
24#ifndef NET_CRYPTO_H 24#ifndef NET_CRYPTO_H
25#define NET_CRYPTO_H 25#define NET_CRYPTO_H
26 26
27#include "Lossless_UDP.h" 27#include "DHT.h"
28 28#include "TCP_client.h"
29#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */
30#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */
31#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */
32#define CRYPTO_PACKET_GROUP_CHAT_GET_NODES 48 /* Group chat get Nodes packet */
33#define CRYPTO_PACKET_GROUP_CHAT_SEND_NODES 49 /* Group chat send Nodes packet */
34#define CRYPTO_PACKET_GROUP_CHAT_BROADCAST 50 /* Group chat broadcast packet */
35#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2)
36 29
37#define CRYPTO_CONN_NO_CONNECTION 0 30#define CRYPTO_CONN_NO_CONNECTION 0
38#define CRYPTO_CONN_HANDSHAKE_SENT 1 31#define CRYPTO_CONN_COOKIE_REQUESTING 1 //send cookie request packets
39#define CRYPTO_CONN_NOT_CONFIRMED 2 32#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets
40#define CRYPTO_CONN_ESTABLISHED 3 33#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets
41#define CRYPTO_CONN_TIMED_OUT 4 34#define CRYPTO_CONN_ESTABLISHED 4
35#define CRYPTO_CONN_TIMED_OUT 5
36
37#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */
38
39/* Minimum packet rate per second. */
40#define CRYPTO_PACKET_MIN_RATE 40.0
41
42/* Minimum packet queue max length. */
43#define CRYPTO_MIN_QUEUE_LENGTH 8
44
45#define MAX_CRYPTO_PACKET_SIZE 1400
46
47#define CRYPTO_DATA_PACKET_MIN_SIZE (1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + crypto_box_MACBYTES)
48
49/* Max size of data in packets TODO*/
50#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE)
51
52/* Interval in ms between sending cookie request/handshake packets. */
53#define CRYPTO_SEND_PACKET_INTERVAL 500
54/* The maximum number of times we try to send the cookie request and handshake
55 before giving up. */
56#define MAX_NUM_SENDPACKET_TRIES 8
57
58#define PACKET_ID_PADDING 0
59#define PACKET_ID_REQUEST 1
60#define PACKET_ID_KILL 2
61
62#define CRYPTO_RESERVED_PACKETS 16
63
64#define MAX_TCP_CONNECTIONS 32
65#define MAX_TCP_RELAYS_PEER 4
66
67#define STATUS_TCP_NULL 0
68#define STATUS_TCP_OFFLINE 1
69#define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */
70#define STATUS_TCP_ONLINE 3
71
72typedef struct {
73 uint64_t time;
74 uint16_t length;
75 uint8_t data[MAX_CRYPTO_DATA_SIZE];
76} Packet_Data;
77
78typedef struct {
79 Packet_Data *buffer[CRYPTO_PACKET_BUFFER_SIZE];
80 uint32_t buffer_start;
81 uint32_t buffer_end; /* packet numbers in array: {buffer_start, buffer_end) */
82} Packets_Array;
42 83
43typedef struct { 84typedef struct {
44 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */ 85 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
@@ -48,27 +89,73 @@ typedef struct {
48 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* Our private key for this session. */ 89 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* Our private key for this session. */
49 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ 90 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
50 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* The precomputed shared key from encrypt_precompute. */ 91 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* The precomputed shared key from encrypt_precompute. */
51 uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet 92 uint8_t status; /* 0 if no connection, 1 we are sending cookie request packets,
52 * (we have received a handshake but no empty data packet), 3 if the connection is established. 93 * 2 if we are sending handshake packets
53 * 4 if the connection is timed out. 94 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet),
95 * 4 if the connection is established.
96 * 5 if the connection is timed out.
54 */ 97 */
55 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ 98 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
56 uint64_t timeout; 99 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
100 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
101 uint64_t dht_public_key_timestamp; /* Timestamp of the last time we confirmed the key was correct. */
57 102
58} Crypto_Connection; 103 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
104 uint16_t temp_packet_length;
105 uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */
106 uint32_t temp_packet_num_sent;
107
108 IP_Port ip_port; /* The ip and port to contact this guy directly.*/
109 uint64_t direct_lastrecv_time; /* The Time at which we last received a direct packet in ms. */
110
111 Packets_Array send_array;
112 Packets_Array recv_array;
113
114 int (*connection_status_callback)(void *object, int id, uint8_t status);
115 void *connection_status_callback_object;
116 int connection_status_callback_id;
117
118 int (*connection_data_callback)(void *object, int id, uint8_t *data, uint16_t length);
119 void *connection_data_callback_object;
120 int connection_data_callback_id;
121
122 uint64_t last_request_packet_sent;
123
124 uint32_t packet_counter;
125 double packet_recv_rate;
126 uint64_t packet_counter_set;
127
128 double packet_send_rate;
129 uint32_t packets_left;
130 uint64_t last_packets_left_set;
131
132 uint8_t sending; /* indicates if data is being sent or not. */
59 133
60typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, 134 uint8_t killed; /* set to 1 to kill the connection. */
61 uint32_t len); 135
136 uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */
137 uint8_t con_number_tcp[MAX_TCP_CONNECTIONS];
138
139 Node_format tcp_relays[MAX_TCP_RELAYS_PEER];
140 uint16_t num_tcp_relays;
141} Crypto_Connection;
62 142
63typedef struct { 143typedef struct {
64 cryptopacket_handler_callback function; 144 IP_Port source;
65 void *object; 145 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
66} Cryptopacket_Handles; 146 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer. */
147 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
148 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
149 uint8_t *cookie;
150 uint8_t cookie_length;
151} New_Connection;
67 152
68typedef struct { 153typedef struct {
69 Lossless_UDP *lossless_udp; 154 DHT *dht;
70 155
71 Crypto_Connection *crypto_connections; 156 Crypto_Connection *crypto_connections;
157 TCP_Client_Connection *tcp_connections_new[MAX_TCP_CONNECTIONS];
158 TCP_Client_Connection *tcp_connections[MAX_TCP_CONNECTIONS];
72 159
73 uint32_t crypto_connections_length; /* Length of connections array. */ 160 uint32_t crypto_connections_length; /* Length of connections array. */
74 161
@@ -76,154 +163,131 @@ typedef struct {
76 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 163 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
77 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 164 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
78 165
79 Cryptopacket_Handles cryptopackethandlers[256]; 166 /* The secret key used for cookies */
80} Net_Crypto; 167 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
81 168
82#include "DHT.h" 169 int (*new_connection_callback)(void *object, New_Connection *n_c);
170 void *new_connection_callback_object;
171} Net_Crypto;
83 172
84/* return zero if the buffer contains only zeros. */
85uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen);
86 173
87/* Encrypts plain of length length to encrypted of length + 16 using the 174/* Set function to be called when someone requests a new connection to us.
88 * public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce. 175 *
176 * The set function should return -1 on failure and 0 on success.
89 * 177 *
90 * return -1 if there was a problem. 178 * n_c is only valid for the duration of the function call.
91 * return length of encrypted data if everything was fine.
92 */ 179 */
93int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 180void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
94 uint8_t *plain, uint32_t length, uint8_t *encrypted); 181 void *object);
95
96 182
97/* Decrypts encrypted of length length to plain of length length - 16 using the 183/* Accept a crypto connection.
98 * public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce.
99 * 184 *
100 * return -1 if there was a problem (decryption failed). 185 * return -1 on failure.
101 * return length of plain data if everything was fine. 186 * return connection id on success.
102 */ 187 */
103int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 188int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
104 uint8_t *encrypted, uint32_t length, uint8_t *plain);
105
106/* Fast encrypt/decrypt operations. Use if this is not a one-time communication.
107 encrypt_precompute does the shared-key generation once so it does not have
108 to be preformed on every encrypt/decrypt. */
109void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key);
110 189
111/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ 190/* Create a crypto connection.
112int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, 191 * If one to that real public key already exists, return it.
113 uint8_t *plain, uint32_t length, uint8_t *encrypted);
114
115/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */
116int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
117 uint8_t *encrypted, uint32_t length, uint8_t *plain);
118
119/* Encrypts plain of length length to encrypted of length + 16 using a
120 * secret key crypto_secretbox_KEYBYTES big and a 24 byte nonce.
121 * 192 *
122 * return -1 if there was a problem. 193 * return -1 on failure.
123 * return length of encrypted data if everything was fine. 194 * return connection id on success.
124 */ 195 */
125int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted); 196int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key);
126 197
127/* Decrypts encrypted of length length to plain of length length - 16 using a 198/* Copy friends DHT public key into dht_key.
128 * secret key crypto_secretbox_KEYBYTES big and a 24 byte nonce.
129 * 199 *
130 * return -1 if there was a problem (decryption failed). 200 * return 0 on failure (no key copied).
131 * return length of plain data if everything was fine. 201 * return timestamp on success (key copied).
132 */ 202 */
133int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain); 203uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
134
135/* Increment the given nonce by 1. */
136void increment_nonce(uint8_t *nonce);
137 204
138/* Fill the given nonce with random bytes. */ 205/* Set the DHT public key of the crypto connection.
139void random_nonce(uint8_t *nonce); 206 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
207 * the other peer.
208 *
209 * return -1 on failure.
210 * return 0 on success.
211 */
212int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp);
140 213
141/* Fill a key crypto_secretbox_KEYBYTES big with random bytes */ 214/* Set the direct ip of the crypto connection.
142void new_symmetric_key(uint8_t *key); 215 *
216 * return -1 on failure.
217 * return 0 on success.
218 */
219int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port);
143 220
144/*Gives a nonce guaranteed to be different from previous ones.*/ 221/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
145void new_nonce(uint8_t *nonce); 222 *
223 * The set function should return -1 on failure and 0 on success.
224 * Note that if this function is set, the connection will clear itself on disconnect.
225 * Object and id will be passed to this function untouched.
226 * status is 1 if the connection is going online, 0 if it is going offline.
227 *
228 * return -1 on failure.
229 * return 0 on success.
230 */
231int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object,
232 int id, uint8_t status), void *object, int id);
146 233
147/* return 0 if there is no received data in the buffer. 234/* Set function to be called when connection with crypt_connection_id receives a data packet of length.
148 * return -1 if the packet was discarded. 235 *
149 * return length of received data if successful. 236 * The set function should return -1 on failure and 0 on success.
237 * Object and id will be passed to this function untouched.
238 *
239 * return -1 on failure.
240 * return 0 on success.
150 */ 241 */
151int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data); 242int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
243 int id, uint8_t *data, uint16_t length), void *object, int id);
244
152 245
153/* returns the number of packet slots left in the sendbuffer. 246/* returns the number of packet slots left in the sendbuffer.
154 * return 0 if failure. 247 * return 0 if failure.
155 */ 248 */
156uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id); 249uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id);
157 250
158/* return 0 if data could not be put in packet queue. 251/* return -1 if data could not be put in packet queue.
159 * return 1 if data was put into the queue. 252 * return positive packet number if data was put into the queue.
160 */ 253 */
161int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); 254int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length);
162 255
163/* Create a request to peer. 256/* Add a tcp relay, associating it to a crypt_connection_id.
164 * send_public_key and send_secret_key are the pub/secret keys of the sender.
165 * recv_public_key is public key of reciever.
166 * packet must be an array of MAX_DATA_SIZE big.
167 * Data represents the data we send with the request with length being the length of the data.
168 * request_id is the id of the request (32 = friend request, 254 = ping request).
169 * 257 *
170 * return -1 on failure. 258 * return 0 if it was added.
171 * return the length of the created packet on success. 259 * return -1 if it wasn't.
172 */ 260 */
173int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, 261int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key);
174 uint8_t *data, uint32_t length, uint8_t request_id);
175 262
176/* puts the senders public key in the request in public_key, the data from the request 263/* Add a tcp relay to the array.
177 in data if a friend or ping request was sent to us and returns the length of the data. 264 *
178 packet is the request packet and length is its length 265 * return 0 if it was added.
179 return -1 if not valid request. */ 266 * return -1 if it wasn't.
180int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, 267 */
181 uint8_t *request_id, uint8_t *packet, uint16_t length); 268int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key);
182
183/* Function to call when request beginning with byte is received. */
184void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object);
185 269
186/* Start a secure connection with other peer who has public_key and ip_port. 270/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
271 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
187 * 272 *
188 * return -1 if failure. 273 * return number of relays copied to tcp_relays on success.
189 * return crypt_connection_id of the initialized connection if everything went well. 274 * return 0 on failure.
190 */ 275 */
191int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port); 276unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
192 277
193/* Kill a crypto connection. 278/* Kill a crypto connection.
194 * 279 *
195 * return 0 if killed successfully. 280 * return -1 on failure.
196 * return 1 if there was a problem. 281 * return 0 on success.
197 */ 282 */
198int crypto_kill(Net_Crypto *c, int crypt_connection_id); 283int crypto_kill(Net_Crypto *c, int crypt_connection_id);
199 284
200/* Handle an incoming connection.
201 *
202 * return -1 if no crypto inbound connection.
203 * return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection.
204 *
205 * Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce
206 * and the session public key for the connection in session_key.
207 * to accept it see: accept_crypto_inbound(...).
208 * to refuse it just call kill_connection(...) on the connection id.
209 */
210int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
211 285
212/* Accept an incoming connection using the parameters provided by crypto_inbound. 286/* return one of CRYPTO_CONN_* values indicating the state of the connection.
213 * 287 *
214 * return -1 if not successful. 288 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
215 * return crypt_connection_id if successful.
216 */
217int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce,
218 uint8_t *session_key);
219
220/* return 0 if no connection.
221 * return 1 we have sent a handshake
222 * return 2 if connexion is not confirmed yet (we have received a handshake but no empty data packet).
223 * return 3 if the connection is established.
224 * return 4 if the connection is timed out and waiting to be killed.
225 */ 289 */
226int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id); 290unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected);
227 291
228 292
229/* Generate our public and private keys. 293/* Generate our public and private keys.
@@ -244,15 +308,13 @@ void load_keys(Net_Crypto *c, uint8_t *keys);
244/* Create new instance of Net_Crypto. 308/* Create new instance of Net_Crypto.
245 * Sets all the global connection variables to their default values. 309 * Sets all the global connection variables to their default values.
246 */ 310 */
247Net_Crypto *new_net_crypto(Networking_Core *net); 311Net_Crypto *new_net_crypto(DHT *dht);
248 312
249/* Main loop. */ 313/* Main loop. */
250void do_net_crypto(Net_Crypto *c); 314void do_net_crypto(Net_Crypto *c);
251 315
252void kill_net_crypto(Net_Crypto *c); 316void kill_net_crypto(Net_Crypto *c);
253 317
254/* Initialize the cryptopacket handling. */
255void init_cryptopackets(void *dht);
256 318
257 319
258#endif 320#endif