-add parallel delegationr resolution
[oweals/gnunet.git] / src / credential / plugin_gnsrecord_credential.c
index 6ae3b8980c956e1436fbf72efcf0f81073df2542..281113a3461dd280d07ac3c71b26027cf4f9a325 100644 (file)
@@ -29,6 +29,7 @@
 #include "gnunet_gnsrecord_lib.h"
 #include "gnunet_credential_service.h"
 #include "gnunet_gnsrecord_plugin.h"
+#include "gnunet_signatures.h"
 
 
 /**
@@ -51,41 +52,69 @@ credential_value_to_string (void *cls,
 
   switch (type)
   {
-   case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+   case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
    {
-    struct GNUNET_CREDENTIAL_RecordData cred;
-    char *cred_str;
+    struct GNUNET_CREDENTIAL_AttributeRecordData attr;
+    char *attr_str;
     char *subject_pkey;
-    char *issuer_pkey;
-    uint32_t cf; // Credential flags
-    uint32_t mdd; // Max delegation depth
-    if (data_size < sizeof (struct GNUNET_CREDENTIAL_RecordData))
-        return NULL; /* malformed */
-    memcpy (&cred,
-              data,
-              sizeof (cred));
-    cdata = data;  
-    subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key);
-    issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key);
-    cf = ntohl (cred.credential_flags);
-    mdd = ntohl (cred.max_delegation_depth);
-
-     GNUNET_asprintf (&cred_str,
-                     "%s %s %u %u %s",
-                     subject_pkey,
-                     issuer_pkey,
-                     (unsigned int) cf,
-                     (unsigned int) mdd,
-                     &cdata[sizeof (cred)]);
-      GNUNET_free (subject_pkey);
-      GNUNET_free (issuer_pkey);
-
-
-
-    return cred_str;
+    
+    if (data_size < sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData))
+      return NULL; /* malformed */
+    memcpy (&attr,
+            data,
+            sizeof (attr));
+    cdata = data;
+    subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&attr.subject_key);
+    if (data_size == sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData))
+    {
+      return subject_pkey;
+    } else {
+      GNUNET_asprintf (&attr_str,
+                       "%s %s",
+                       subject_pkey,
+                       &cdata[sizeof (attr)]);
     }
-  default:
-    return NULL;
+    GNUNET_free (subject_pkey);
+    return attr_str;
+   }
+   case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+   {
+     struct GNUNET_CREDENTIAL_CredentialRecordData cred;
+     struct GNUNET_TIME_Absolute etime_abs;
+     char *cred_str;
+     char *subject_pkey;
+     char *issuer_pkey;
+     char *signature;
+     const char *expiration;
+
+
+     if (data_size < sizeof (struct GNUNET_CREDENTIAL_CredentialRecordData))
+       return NULL; /* malformed */
+     memcpy (&cred,
+             data,
+             sizeof (cred));
+     cdata = data;  
+     subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key);
+     issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key);
+     etime_abs.abs_value_us = GNUNET_ntohll(cred.expiration);
+     expiration = GNUNET_STRINGS_absolute_time_to_string (etime_abs);
+     GNUNET_STRINGS_base64_encode ((char*)&cred.signature,
+                                   sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
+                                   &signature);
+     GNUNET_asprintf (&cred_str,
+                      "%s.%s -> %s | %s | %s",
+                      issuer_pkey,
+                      &cdata[sizeof (cred)],
+                      subject_pkey,
+                      signature,
+                      expiration);
+     GNUNET_free (subject_pkey);
+     GNUNET_free (issuer_pkey);
+     GNUNET_free (signature);
+     return cred_str;
+   }
+   default:
+   return NULL;
   }
 }
 
@@ -103,43 +132,81 @@ credential_value_to_string (void *cls,
  */
 static int
 credential_string_to_value (void *cls,
-                     uint32_t type,
-                     const char *s,
-                     void **data,
-                     size_t *data_size)
+                            uint32_t type,
+                            const char *s,
+                            void **data,
+                            size_t *data_size)
 {
   if (NULL == s)
     return GNUNET_SYSERR;
   switch (type)
   {
-   case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
-    { 
-      struct GNUNET_CREDENTIAL_RecordData *cred;
-      unsigned int cf; // credential flags
-      unsigned int mdd; // max delegation depth
+    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));
+
 
-      size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
+        return GNUNET_OK;
+      }
+    case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+      { 
+        struct GNUNET_CREDENTIAL_CredentialRecordData *cred;
+
+        size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
         if (enclen % 5 > 0)
           enclen += 5 - enclen % 5;
         enclen /= 5; /* 260/5 = 52 */
-      char subject_pkey[enclen + 1];
-      char issuer_pkey[enclen + 1];
-      char name[253 + 1];
+        char subject_pkey[enclen + 1];
+        char issuer_pkey[enclen + 1];
+        char name[253 + 1];
+        char signature[128]; //TODO max payload size
+        char expiration[256];
 
-      if (5 != SSCANF (s,
-                         "%52s %52s %u %u %253s",
-                         subject_pkey,
+        struct GNUNET_CRYPTO_EcdsaSignature *sig;
+        struct GNUNET_TIME_Absolute etime_abs;
+
+        if (5 != SSCANF (s,
+                         "%52s.%253s -> %52s | %s | %255[0-9a-zA-Z: ]",
                          issuer_pkey,
-                         &cf,
-                         &mdd,
-                         name))
+                         name,
+                         subject_pkey,
+                         signature,
+                         expiration))
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       _("Unable to parse CRED record string `%s'\n"),
                       s);
           return GNUNET_SYSERR;
         }
-        *data_size = sizeof (struct GNUNET_CREDENTIAL_RecordData) + strlen (name) + 1;
+        *data_size = sizeof (struct GNUNET_CREDENTIAL_CredentialRecordData) + strlen (name) + 1;
         *data = cred = GNUNET_malloc (*data_size);
         GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
                                                     strlen (subject_pkey),
@@ -147,19 +214,26 @@ credential_string_to_value (void *cls,
         GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
                                                     strlen (issuer_pkey),
                                                     &cred->issuer_key);
-        cred->credential_flags = htonl (cf);
-        cred->max_delegation_depth = htonl (mdd);
+        GNUNET_STRINGS_fancy_time_to_absolute (expiration,
+                                               &etime_abs);
+        GNUNET_STRINGS_base64_decode (signature,
+                                      strlen (signature),
+                                      (char**)&sig);
+        cred->signature = *sig;
+        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));
+        GNUNET_free (sig);
         GNUNET_memcpy (&cred[1],
                        name,
                        strlen (name));
 
 
-      *data = GNUNET_strdup (s);
-      *data_size = strlen (s);
-      return GNUNET_OK;
-    }
-  default:
-    return GNUNET_SYSERR;
+        return GNUNET_OK;
+      }
+    default:
+      return GNUNET_SYSERR;
   }
 }
 
@@ -173,6 +247,7 @@ static struct {
   uint32_t number;
 } name_map[] = {
   { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL },
+  { "ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE },
   { NULL, UINT32_MAX }
 };
 
@@ -186,13 +261,13 @@ static struct {
  */
 static uint32_t
 credential_typename_to_number (void *cls,
-                        const char *gns_typename)
+                               const char *gns_typename)
 {
   unsigned int i;
 
   i=0;
   while ( (name_map[i].name != NULL) &&
-         (0 != strcasecmp (gns_typename, name_map[i].name)) )
+          (0 != strcasecmp (gns_typename, name_map[i].name)) )
     i++;
   return name_map[i].number;
 }
@@ -207,13 +282,13 @@ credential_typename_to_number (void *cls,
  */
 static const char *
 credential_number_to_typename (void *cls,
-                        uint32_t type)
+                               uint32_t type)
 {
   unsigned int i;
 
   i=0;
   while ( (name_map[i].name != NULL) &&
-         (type != name_map[i].number) )
+          (type != name_map[i].number) )
     i++;
   return name_map[i].name;
 }