static int handle_ping_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata) { DHT *dht = (DHT *)object; int rc; if (length != DHT_PING_SIZE) { return 1; } PING *ping = dht->ping; if (id_equal(packet + 1, ping->dht->self_public_key)) { return 1; } uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; // generate key to encrypt ping_id with recipient privkey DHT_get_shared_key_sent(ping->dht, shared_key, packet + 1); uint8_t ping_plain[PING_PLAIN_SIZE]; // Decrypt ping_id rc = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, PING_PLAIN_SIZE + CRYPTO_MAC_SIZE, ping_plain); if (rc != sizeof(ping_plain)) { return 1; } if (ping_plain[0] != NET_PACKET_PING_RESPONSE) { return 1; } uint64_t ping_id; memcpy(&ping_id, ping_plain + 1, sizeof(ping_id)); uint8_t data[PING_DATA_SIZE]; if (ping_array_check(data, sizeof(data), &ping->ping_array, ping_id) != sizeof(data)) { return 1; } if (!id_equal(packet + 1, data)) { return 1; } IP_Port ipp; memcpy(&ipp, data + CRYPTO_PUBLIC_KEY_SIZE, sizeof(IP_Port)); if (!ipport_equal(&ipp, &source)) { return 1; } addto_lists(dht, source, packet + 1); return 0; }
static int handle_ping_response(void *_dht, IP_Port source, const uint8_t *packet, uint16_t length) { DHT *dht = _dht; int rc; if (length != DHT_PING_SIZE) return 1; PING *ping = dht->ping; if (id_equal(packet + 1, ping->dht->self_public_key)) return 1; uint8_t shared_key[crypto_box_BEFORENMBYTES]; // generate key to encrypt ping_id with recipient privkey DHT_get_shared_key_sent(ping->dht, shared_key, packet + 1); uint8_t ping_plain[PING_PLAIN_SIZE]; // Decrypt ping_id rc = decrypt_data_symmetric(shared_key, packet + 1 + crypto_box_PUBLICKEYBYTES, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, PING_PLAIN_SIZE + crypto_box_MACBYTES, ping_plain); if (rc != sizeof(ping_plain)) return 1; if (ping_plain[0] != NET_PACKET_PING_RESPONSE) return 1; uint64_t ping_id; memcpy(&ping_id, ping_plain + 1, sizeof(ping_id)); uint8_t data[PING_DATA_SIZE]; if (ping_array_check(data, sizeof(data), &ping->ping_array, ping_id) != sizeof(data)) return 1; if (!id_equal(packet + 1, data)) return 1; IP_Port ipp; memcpy(&ipp, data + crypto_box_PUBLICKEYBYTES, sizeof(IP_Port)); if (!ipport_equal(&ipp, &source)) return 1; addto_lists(dht, source, packet + 1); return 0; }
/* Checks if the sendback is valid and returns the public key contained in it in ret_pubkey and the * ip contained in it in ret_ip_port * * sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big * ret_pubkey must be at least crypto_box_PUBLICKEYBYTES big * ret_ip_port must be at least 1 big * * return ~0 on failure * return num (see new_sendback(...)) on success */ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, uint8_t *ret_pubkey, IP_Port *ret_ip_port) { uint64_t sback; memcpy(&sback, sendback, sizeof(uint64_t)); uint8_t data[sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)]; if (ping_array_check(data, sizeof(data), &onion_c->announce_ping_array, sback) != sizeof(data)) return ~0; memcpy(ret_pubkey, data + sizeof(uint32_t), crypto_box_PUBLICKEYBYTES); memcpy(ret_ip_port, data + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES, sizeof(IP_Port)); uint32_t num; memcpy(&num, data, sizeof(uint32_t)); return num; }