#include "platform.h"
#include "plugin_block.h"
#include "block_dns.h"
+#include "gnunet_signatures.h"
#define DEBUG_DHT GNUNET_NO
if (reply_block_size == 0)
return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
- if (reply_block_size < sizeof(struct GNUNET_DNS_Record))
+ if (reply_block_size != sizeof(struct GNUNET_DNS_Record))
return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
const struct GNUNET_DNS_Record* rec = reply_block;
- if(reply_block_size != (sizeof(struct GNUNET_DNS_Record) + rec->namelen - 1))
+
+ if (ntohl(rec->purpose.size) != sizeof(struct GNUNET_DNS_Record) - sizeof(struct GNUNET_CRYPTO_RsaSignature))
+ return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
+
+ if (GNUNET_TIME_relative_get_zero().value == GNUNET_TIME_absolute_get_remaining(rec->expiration_time).value)
+ return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
+
+ if (GNUNET_OK != GNUNET_CRYPTO_rsa_verify (htonl(GNUNET_SIGNATURE_PURPOSE_DNS_RECORD),
+ &rec->purpose,
+ &rec->signature,
+ &rec->peer))
return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
/* How to decide whether there are no more? */
if (type != GNUNET_BLOCK_TYPE_DNS)
return GNUNET_SYSERR;
const struct GNUNET_DNS_Record* rec = block;
- GNUNET_CRYPTO_hash(rec->name, rec->namelen, key);
+ memcpy(key, &rec->service_descriptor, sizeof(GNUNET_HashCode));
return GNUNET_OK;
}
#define _GNVPN_BLOCKDNS_H_
#include "gnunet_common.h"
+#include "gnunet_crypto_lib.h"
/**
- * Bitmask describing what ip-services are supported by services
- * It is 2 bytes long
+ * Bitmask describing what IP-protocols are supported by the service
*/
-struct GNUNET_ipservices {
- unsigned UDP:1 GNUNET_PACKED;
- unsigned TCP:1 GNUNET_PACKED;
- unsigned RESERVED:14 GNUNET_PACKED;
+enum GNUNET_DNS_ServiceTypes
+{
+ GNUNET_DNS_SERVICE_TYPE_UDP = 1,
+ GNUNET_DNS_SERVICE_TYPE_TCP = 2
};
+
/**
* This is the structure describing an dns-record such as www.gnunet.
*/
struct GNUNET_DNS_Record
{
+ /**
+ * Signature of the peer affirming that he is offering the service.
+ */
+ struct GNUNET_CRYPTO_RsaSignature signature;
+
+ /**
+ * Beginning of signed portion of the record, signs everything until
+ * the end of the struct.
+ */
+ struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
+
/**
* The peer providing this service
*/
- struct GNUNET_PeerIdentity peer;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded peer;
/**
* The descriptor for the service
GNUNET_HashCode service_descriptor;
/**
- * What connection-types (UDP, TCP, ...) are supported by the service
+ * When does this record expire?
*/
- struct GNUNET_ipservices connectiontypes;
+ struct GNUNET_TIME_Absolute expiration_time;
/**
- * The length of the name of the service
+ * Four TCP and UDP-Ports that are used by this service, big endian format
*/
- unsigned char namelen;
+ uint64_t ports;
/**
- * The name of the service
- * This is namelen bytes
+ * What connection-types (UDP, TCP, ...) are supported by the service.
+ * Contains an 'enum GNUNET_DNS_ServiceTypes' in big endian format.
*/
- char name[1];
+ uint32_t service_type;
};
#endif
*/
#define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 10
+/**
+ * Signature of an GNUNET_DNS_Record
+ */
+#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD 11
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#include "gnunet_dht_service.h"
#include "gnunet_block_lib.h"
#include "block_dns.h"
+#include "gnunet_crypto_lib.h"
+#include "gnunet_signatures.h"
struct dns_cls {
struct GNUNET_SCHEDULER_Handle *sched;
unsigned short dnsoutport;
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
struct answer_packet_list *head;
struct answer_packet_list *tail;
};
return;
char* name = "philipptoelke.gnunet.";
- size_t size = sizeof(struct GNUNET_DNS_Record) + strlen(name);
- struct GNUNET_DNS_Record *data = alloca(size);
- memset(data, 0, size);
- memcpy(data->name, name, strlen(name) + 1);
- data->namelen = strlen(name) + 1;
- *((unsigned int*)&data->service_descriptor) = 0x11223344;
- *((unsigned int*)&data->peer) = 0x55667788;
-
- GNUNET_HashCode key;
- GNUNET_CRYPTO_hash(name, strlen(name)+1, &key);
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Putting with key %08x, len is %d\n", *((unsigned int*)&key), strlen(name));
+ size_t size = sizeof(struct GNUNET_DNS_Record);
+ struct GNUNET_DNS_Record data;
+ memset(&data, 0, size);
+
+ data.purpose.size = htonl(size - sizeof(struct GNUNET_CRYPTO_RsaSignature));
+ data.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_DNS_RECORD;
+
+ GNUNET_CRYPTO_hash(name, strlen(name)+1, &data.service_descriptor);
+
+ char* keyfile;
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(mycls.cfg, "GNUNETD",
+ "HOSTKEY", &keyfile))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not read keyfile-value\n");
+ if (keyfile != NULL) GNUNET_free(keyfile);
+ return;
+ }
+
+ struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file(keyfile);
+ GNUNET_free(keyfile);
+
+ GNUNET_CRYPTO_rsa_key_get_public(my_private_key, &data.peer);
+
+ data.expiration_time = GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS);
+
+ /* Sign the block
+ */
+
+ if (GNUNET_OK != GNUNET_CRYPTO_rsa_sign(my_private_key,
+ &data.purpose,
+ &data.signature))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n");
+ return;
+ }
+ GNUNET_free(my_private_key);
+
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Putting with key %08x\n", *((unsigned int*)&data.service_descriptor));
GNUNET_DHT_put(mycls.dht,
- &key,
- GNUNET_DHT_RO_NONE,
- GNUNET_BLOCK_TYPE_DNS,
- size,
- (char*)data,
- GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS),
- GNUNET_TIME_UNIT_MINUTES,
- NULL,
- NULL);
+ &data.service_descriptor,
+ GNUNET_DHT_RO_NONE,
+ GNUNET_BLOCK_TYPE_DNS,
+ size,
+ (char*)&data,
+ GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS),
+ GNUNET_TIME_UNIT_MINUTES,
+ NULL,
+ NULL);
GNUNET_SCHEDULER_add_delayed (mycls.sched, GNUNET_TIME_UNIT_HOURS, publish_name, NULL);
}
{NULL, NULL, 0, 0}
};
+ mycls.cfg = cfg;
+
{
int i;
for (i = 0; i < 65536; i++) {