- add delegation resolution
authorSchanzenbach, Martin <mschanzenbach@posteo.de>
Wed, 7 Dec 2016 13:56:57 +0000 (14:56 +0100)
committerSchanzenbach, Martin <mschanzenbach@posteo.de>
Wed, 7 Dec 2016 13:56:57 +0000 (14:56 +0100)
src/credential/gnunet-service-credential.c
src/credential/plugin_gnsrecord_credential.c
src/credential/test_credential_verify.sh

index 662c26a5e32f4568934bd9d8da627f9f91545eaa..bf85b1583b4dc3aab404b12ce76dff5b14c8bf6d 100644 (file)
@@ -100,6 +100,11 @@ struct AttributeQueueEntry
    * Parent attribute delegation
    */
   struct AttributeQueueEntry *parent;
+
+  /**
+   * Trailing attribute context
+   */
+  char *attr_trailer;
 };
 
 
@@ -364,40 +369,74 @@ start_backward_resolution (void* cls,
   const struct GNUNET_CREDENTIAL_AttributeRecordData *attr;
   struct CredentialRecordEntry *cred_pointer;
   struct AttributeQueueEntry *attr_entry;
+  char *expanded_attr;
+  char *check_attr;
   int i;
+  
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Got %d attrs\n", rd_count);
 
   for (i=0; i < rd_count; i++) 
   {
     if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
       continue;
+
     attr = rd[i].data;
+    attr_entry = GNUNET_new (struct AttributeQueueEntry);
+    attr_entry->data_size = rd[i].data_size;
+    if (NULL != vrh->current_attribute &&
+        NULL != vrh->current_attribute->attr_trailer)
+    {
+      if (rd[i].data_size == sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData))
+      {
+        GNUNET_asprintf (&expanded_attr,
+                         "%s",
+                         vrh->current_attribute->attr_trailer);
+
+      } else {
+        GNUNET_asprintf (&expanded_attr,
+                         "%s.%s",
+                         (char*)&attr[1],
+                         vrh->current_attribute->attr_trailer);
+      }
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Expanded to %s\n", expanded_attr);
+      attr_entry->data_size += strlen (vrh->current_attribute->attr_trailer) + 1;
+    } else {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Not Expanding %s\n", (char*)&attr[1]);
+    }
+    attr_entry->data = GNUNET_malloc (attr_entry->data_size);
+    memcpy (attr_entry->data,
+            rd[i].data,
+            rd[i].data_size);
+    if (NULL != vrh->current_attribute && NULL != vrh->current_attribute->attr_trailer)
+    {
+      memcpy ((char*)&attr_entry->data[1],
+              expanded_attr,
+              strlen (expanded_attr));
+    } 
+    check_attr = (char*)&attr_entry->data[1];
+    check_attr[attr_entry->data_size] = '\0';
+    attr_entry->parent = vrh->current_attribute;
+
+    GNUNET_CONTAINER_DLL_insert (vrh->attr_queue_head,
+                                 vrh->attr_queue_tail,
+                                 attr_entry);
     for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL; 
         cred_pointer = cred_pointer->next){
       cred = cred_pointer->data;
-      
-      attr_entry = GNUNET_new (struct AttributeQueueEntry);
-
-      attr_entry->data = GNUNET_malloc (rd[i].data_size);
-      memcpy (attr_entry->data,
-              rd[i].data,
-              rd[i].data_size);
-      attr_entry->data_size = rd[i].data_size;
-
-      attr_entry->parent = vrh->current_attribute;
-
-      GNUNET_CONTAINER_DLL_insert (vrh->attr_queue_head,
-                                   vrh->attr_queue_tail,
-                                   attr_entry);
-
       if(0 != memcmp (&attr->subject_key, 
                       &cred_pointer->data->issuer_key,
                       sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
         continue;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Checking if %s matches %s\n",
+                  (char*)&attr_entry->data[1], (char*)&cred[1]);
 
-      if (0 != strcmp ((char*)&attr[1], (char*)&cred[1]))
+      if (0 != strcmp ((char*)&attr_entry->data[1], (char*)&cred[1]))
         continue;
 
-
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Found issuer\n");
       vrh->credential = GNUNET_malloc (rd[i].data_size);
@@ -417,9 +456,9 @@ start_backward_resolution (void* cls,
   //Start from next to head
   vrh->current_attribute = vrh->attr_queue_head;
 
-  if(vrh->current_attribute != NULL)
+  if(NULL == vrh->current_attribute)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "We are all out of attributes...\n");
     send_lookup_response (vrh);
     return;
@@ -432,14 +471,32 @@ start_backward_resolution (void* cls,
 
 
   //Start with backward resolution
+  char issuer_attribute_name[strlen ((char*)&vrh->current_attribute->data[1])];
+  char *lookup_attr;
+  strcpy (issuer_attribute_name,
+          (char*)&vrh->current_attribute->data[1]);
+  char *next_attr = strtok (issuer_attribute_name, ".");
+    GNUNET_asprintf (&lookup_attr,
+                   "%s.gnu",
+                   next_attr);
+  next_attr += strlen (next_attr) + 1;
+  vrh->current_attribute->attr_trailer = GNUNET_strdup (next_attr);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Looking up %s\n", lookup_attr);
+  if (NULL != vrh->current_attribute->attr_trailer)
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "%s still to go...\n", vrh->current_attribute->attr_trailer);
+
   vrh->lookup_request = GNUNET_GNS_lookup (gns,
-                                           (char*)&vrh->current_attribute->data[1],
+                                           lookup_attr,
                                            &vrh->current_attribute->data->subject_key, //issuer_key,
                                            GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
                                            GNUNET_GNS_LO_DEFAULT,
                                            NULL, //shorten_key, always NULL
                                            &start_backward_resolution,
                                            vrh);
+  GNUNET_free (lookup_attr);
 } 
 
 
@@ -513,8 +570,6 @@ handle_credential_query (void* cls,
 
   }
 
-  GNUNET_break (0); //TODO remove when implemented
-
   /**
    * Check for attributes from the issuer and follow the chain 
    * till you get the required subject's attributes
@@ -524,6 +579,9 @@ handle_credential_query (void* cls,
           vrh->issuer_attribute);
   strcpy (issuer_attribute_name + strlen (vrh->issuer_attribute),
           ".gnu");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Looking up %s\n", issuer_attribute_name);
+
   //Start with backward resolution
   GNUNET_GNS_lookup (gns,
                      issuer_attribute_name,
index 90ac393d017d3d2f62da4128b798dae19dfb6a77..ece4be1e33bfc7770aae779b5e605b8fb820cd23 100644 (file)
@@ -65,10 +65,15 @@ credential_value_to_string (void *cls,
             sizeof (attr));
     cdata = data;
     subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&attr.subject_key);
-    GNUNET_asprintf (&attr_str,
-                     "%s.%s",
-                     subject_pkey,
-                     &cdata[sizeof (attr)]);
+    if (data_size == sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData))
+    {
+      return subject_pkey;
+    } else {
+      GNUNET_asprintf (&attr_str,
+                       "%s %s",
+                       subject_pkey,
+                       &cdata[sizeof (attr)]);
+    }
     GNUNET_free (subject_pkey);
     return attr_str;
    }
@@ -82,7 +87,7 @@ credential_value_to_string (void *cls,
      char *signature;
      const char *expiration;
 
-     
+
      if (data_size < sizeof (struct GNUNET_CREDENTIAL_CredentialRecordData))
        return NULL; /* malformed */
      memcpy (&cred,
@@ -136,6 +141,41 @@ credential_string_to_value (void *cls,
     return GNUNET_SYSERR;
   switch (type)
   {
+    case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
+      {
+        struct GNUNET_CREDENTIAL_AttributeRecordData *attr;
+        char attr_str[253 + 1];
+        char subject_pkey[52 + 1];
+        int matches = 0;
+        matches = SSCANF (s,
+                          "%s %s",
+                          subject_pkey,
+                          attr_str);
+        if (0 == matches)
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                      _("Unable to parse ATTR record string `%s'\n"),
+                      s);
+          return GNUNET_SYSERR;
+
+        }
+        if (1 == matches) {
+          *data_size = sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData);
+        } else if (2 == matches) {
+          *data_size = sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData) + strlen (attr_str) + 1;
+        }
+        *data = attr = GNUNET_malloc (*data_size);
+        GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
+                                                    strlen (subject_pkey),
+                                                    &attr->subject_key);
+        if (NULL != attr_str)
+          GNUNET_memcpy (&attr[1],
+                         attr_str,
+                         strlen (attr_str));
+
+
+        return GNUNET_OK;
+      }
     case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
       { 
         struct GNUNET_CREDENTIAL_CredentialRecordData *cred;
@@ -183,7 +223,7 @@ credential_string_to_value (void *cls,
         cred->expiration = GNUNET_htonll (etime_abs.abs_value_us);
         cred->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
         cred->purpose.size = htonl (strlen (name) + 1 + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
-                             sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + sizeof (uint64_t));
+                                    sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + sizeof (uint64_t));
         GNUNET_free (sig);
         GNUNET_memcpy (&cred[1],
                        name,
@@ -207,6 +247,7 @@ static struct {
   uint32_t number;
 } name_map[] = {
   { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL },
+  { "ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE },
   { NULL, UINT32_MAX }
 };
 
index 6e5ba46472769c6551244afa968228715e5e5650..ab3c78f410907e9088b506e8664967621c2a5790 100755 (executable)
@@ -31,7 +31,8 @@ TEST_ATTR="user"
 INTERMEDIATE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testintermediate | awk '{print $3}')
 SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}')
 ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}')
-CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR -c test_credential_lookup.conf`
+AUTHORITY_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testauthority | awk '{print $3}')
+CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf`
 
 TEST_CREDENTIAL="t1"
 gnunet-namestore -p -z testsubject -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
@@ -43,17 +44,13 @@ AUTHORITY_ATTR="test"
 gnunet-namestore -p -z testauthority -a -n $AUTHORITY_ATTR -t ATTR -V "$INTERMEDIATE_KEY $INTERMEDIATE_ATTR.$TEST_ATTR" -e 5m -c test_credential_lookup.conf
 
 #TODO2 Add -z swich like in gnunet-gns
-#RES_CRED=`$DO_TIMEOUT gnunet-credential --verify --issuer=$ISSUER_KEY --attribute="$TEST_ATTR" --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf`
-valgrind gnunet-credential --verify --issuer=$AUTHORITY_KEY --attribute=$AUTHORITY_ATTR --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf
+RES_CRED=`gnunet-credential --verify --issuer=$AUTHORITY_KEY --attribute=$AUTHORITY_ATTR --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf`
 
 #TODO cleanup properly
 gnunet-namestore -z testsubject -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf
 gnunet-arm -e -c test_credential_lookup.conf
 
-#TODO3 proper test
-exit 0
-
-if [ "$RES_CRED" == "Ok!" ]
+if [ "$RES_CRED" == "Successful." ]
 then
   exit 0
 else