diff options
Diffstat (limited to 'core/net_crypto.c')
-rw-r--r-- | core/net_crypto.c | 51 |
1 files changed, 45 insertions, 6 deletions
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 */ |
222 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) | 222 | int 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. */ |
244 | int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length) | 247 | static 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 | ||
269 | static cryptopacket_handler_callback cryptopackethandlers[256] = {0}; | ||
270 | |||
271 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb) | ||
272 | { | ||
273 | cryptopackethandlers[byte] = cb; | ||
274 | } | ||
275 | |||
276 | static 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; |