modified the DNS_Record-block
authorPhilipp Tölke <toelke@in.tum.de>
Tue, 26 Oct 2010 13:55:55 +0000 (13:55 +0000)
committerPhilipp Tölke <toelke@in.tum.de>
Tue, 26 Oct 2010 13:55:55 +0000 (13:55 +0000)
src/block/plugin_block_dns.c
src/include/block_dns.h
src/include/gnunet_signatures.h
src/vpn/gnunet-service-dns.c

index 1e1a577fc416f9b4cc57af4a93fcf59d22113cf0..205cff4b8b869cd234c59d248f362146d73da11f 100644 (file)
@@ -27,6 +27,7 @@
 #include "platform.h"
 #include "plugin_block.h"
 #include "block_dns.h"
+#include "gnunet_signatures.h"
 
 #define DEBUG_DHT GNUNET_NO
 
@@ -65,11 +66,21 @@ block_plugin_dns_evaluate (void *cls,
     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? */
@@ -101,7 +112,7 @@ block_plugin_dns_get_key (void *cls,
   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;
 }
 
index d8f3fa50ec18b5d907c944fcdc0c1a7a6c22f3ae..6be82b126b83d1116dfb2bf7e5483824e4837dec 100644 (file)
@@ -2,26 +2,38 @@
 #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
@@ -30,20 +42,20 @@ struct GNUNET_DNS_Record
   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
index a3199c73585a3ae14ea69a1f49f7630562776d46..98c44948693857232ecd1b5ff014e9f3d064b060 100644 (file)
@@ -97,6 +97,11 @@ extern "C"
  */
 #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 */
 {
index 1ad3c8784f69d85162d45b6be1fba2235e277c96..0c688db34d2220c0f54cd2ffb146c13851e1912e 100644 (file)
@@ -36,6 +36,8 @@
 #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;
@@ -46,6 +48,8 @@ struct dns_cls {
 
        unsigned short dnsoutport;
 
+       const struct GNUNET_CONFIGURATION_Handle *cfg;
+
        struct answer_packet_list *head;
        struct answer_packet_list *tail;
 };
@@ -265,28 +269,55 @@ publish_name (void *cls,
     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);
 }
@@ -309,6 +340,8 @@ run (void *cls,
     {NULL, NULL, 0, 0}
   };
 
+  mycls.cfg = cfg;
+
   {
   int i;
   for (i = 0; i < 65536; i++) {