gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] 57/171: -fixes


From: gnunet
Subject: [GNUnet-SVN] [gnunet] 57/171: -fixes
Date: Thu, 04 Jan 2018 16:09:25 +0100

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

commit 33e847bf4edc06be68589467d0f6a31c07d911ac
Author: Schanzenbach, Martin <address@hidden>
AuthorDate: Sun Dec 18 16:52:59 2016 +0100

    -fixes
---
 src/credential/Makefile.am                      |   5 +-
 src/credential/credential.h                     |  76 +++++++
 src/credential/credential_api.c                 |  48 -----
 src/credential/credential_serialization.c       | 159 +++++++++------
 src/credential/credential_serialization.h       |  20 +-
 src/credential/gnunet-credential.c              |  21 +-
 src/credential/gnunet-service-credential.c      | 150 ++++++--------
 src/credential/plugin_gnsrecord_credential.c    | 115 +++--------
 src/credential/plugin_rest_credential.c         | 258 ++++++++++++++++++++++--
 src/credential/test_credential_issue.sh         |   4 +-
 src/credential/test_credential_lookup.conf      |   2 +-
 src/credential/test_credential_verify_simple.sh |   2 +-
 src/identity-provider/identity_provider_api.c   |  12 +-
 src/identity/plugin_rest_identity.c             |   3 -
 src/include/gnunet_credential_service.h         | 111 +++++-----
 src/jsonapi/jsonapi_document.c                  |  32 ++-
 16 files changed, 600 insertions(+), 418 deletions(-)

diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am
index 5f3b60270..0d9aed71b 100644
--- a/src/credential/Makefile.am
+++ b/src/credential/Makefile.am
@@ -74,8 +74,9 @@ gnunet_service_credential_LDADD = \
 
 
 libgnunetcredential_la_SOURCES = \
- credential_api.c credential.h \
- credential_serialization.c
+ credential_api.c \
+ credential_serialization.c \
+ credential_misc.c
 libgnunetcredential_la_LIBADD = \
  $(top_builddir)/src/util/libgnunetutil.la $(XLIB) 
 libgnunetcredential_la_LDFLAGS = \
diff --git a/src/credential/credential.h b/src/credential/credential.h
index 3ba8e9c9e..c5c0183cc 100644
--- a/src/credential/credential.h
+++ b/src/credential/credential.h
@@ -103,6 +103,82 @@ struct VerifyResultMessage
 
 };
 
+struct DelegationRecordData
+{
+  /**
+   * Subject key
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+  
+  /**
+   * Subject attributes
+   */
+  uint32_t subject_attribute_len GNUNET_PACKED;
+};
+
+
+struct ChainEntry
+{
+  /**
+   * Issuer key
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
+  
+  /**
+   * Subject key
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+  
+  /**
+   * Issuer attributes
+   */
+  uint32_t issuer_attribute_len GNUNET_PACKED;
+  
+  /**
+   * Subject attributes
+   */
+  uint32_t subject_attribute_len GNUNET_PACKED;
+};
+
+
+struct CredentialEntry
+{
+
+  /**
+   * The signature for this credential by the issuer
+   */
+  struct GNUNET_CRYPTO_EcdsaSignature signature;
+
+  /**
+   * Signature meta
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Public key of the issuer
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
+
+  /**
+   * Public key of the subject this credential was issued to
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+
+  /**
+   * Expiration time of this credential
+   */
+  uint64_t expiration GNUNET_PACKED;
+   
+  /**
+   * Issuer attribute length
+   */
+  uint32_t issuer_attribute_len;
+
+  /**
+   * Followed by the attribute string
+   */
+};
+
 
 GNUNET_NETWORK_STRUCT_END
 
diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c
index d9e01c1d3..e991b4153 100644
--- a/src/credential/credential_api.c
+++ b/src/credential/credential_api.c
@@ -430,52 +430,4 @@ GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle 
*handle,
   return vr;
 }
 
-/**
- * Issue an attribute to a subject
- *
- * @param handle handle to the Credential service
- * @param issuer the ego that should be used to issue the attribute
- * @param subject the subject of the attribute
- * @param attribute the name of the attribute
- * @return handle to the queued request
- */
-struct GNUNET_CREDENTIAL_CredentialRecordData *
-GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle,
-                         const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
-                         struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
-                         const char *attribute,
-                         struct GNUNET_TIME_Absolute *expiration)
-{
-  struct GNUNET_CREDENTIAL_CredentialRecordData *crd;
-
-  crd = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_CredentialRecordData) 
+ strlen (attribute) + 1);
-
-  crd->purpose.size = htonl (strlen (attribute) + 1 +
-                      sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
-                                       sizeof (struct 
GNUNET_CRYPTO_EccSignaturePurpose) +
-                      sizeof (uint64_t));
-  
-  crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
-  GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
-                                      &crd->issuer_key);
-  crd->subject_key = *subject;
-  crd->expiration = GNUNET_htonll (expiration->abs_value_us);
-  GNUNET_memcpy (&crd[1],
-                 attribute,
-                 strlen (attribute));
-  if (GNUNET_OK !=
-      GNUNET_CRYPTO_ecdsa_sign (issuer,
-                                &crd->purpose,
-                                &crd->signature))
-  {
-    GNUNET_break (0);
-    GNUNET_free (crd);
-    return NULL;
-  }
-  return crd;
-}
-
-
-
-
 /* end of credential_api.c */
diff --git a/src/credential/credential_serialization.c 
b/src/credential/credential_serialization.c
index b08920d96..0586e6baa 100644
--- a/src/credential/credential_serialization.c
+++ b/src/credential/credential_serialization.c
@@ -29,48 +29,8 @@
 #include "gnunet_util_lib.h"
 #include "gnunet_constants.h"
 #include "gnunet_credential_service.h"
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-struct DelegationRecordData
-{
-  /**
-   * Subject key
-   */
-  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
-  
-  /**
-   * Subject attributes
-   */
-  uint32_t subject_attribute_len GNUNET_PACKED;
-};
-
-
-struct ChainEntry
-{
-  /**
-   * Issuer key
-   */
-  struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
-  
-  /**
-   * Subject key
-   */
-  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
-  
-  /**
-   * Issuer attributes
-   */
-  uint32_t issuer_attribute_len GNUNET_PACKED;
-  
-  /**
-   * Subject attributes
-   */
-  uint32_t subject_attribute_len GNUNET_PACKED;
-};
-
-GNUNET_NETWORK_STRUCT_END
-
+#include "gnunet_signatures.h"
+#include "credential.h"
 
 /**
  * Calculate how many bytes we will need to serialize
@@ -83,7 +43,7 @@ GNUNET_NETWORK_STRUCT_END
  */
 size_t
 GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count,
-                                           const struct 
GNUNET_CREDENTIAL_DelegationSetRecord *dsr)
+                                           const struct 
GNUNET_CREDENTIAL_DelegationSet *dsr)
 {
   unsigned int i;
   size_t ret;
@@ -110,7 +70,7 @@ GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int 
ds_count,
  */
 ssize_t
 GNUNET_CREDENTIAL_delegation_set_serialize (unsigned int d_count,
-                                            const struct 
GNUNET_CREDENTIAL_DelegationSetRecord *dsr,
+                                            const struct 
GNUNET_CREDENTIAL_DelegationSet *dsr,
                                             size_t dest_size,
                                             char *dest)
 {
@@ -156,7 +116,7 @@ int
 GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len,
                                               const char *src,
                                               unsigned int d_count,
-                                              struct 
GNUNET_CREDENTIAL_DelegationSetRecord *dsr)
+                                              struct 
GNUNET_CREDENTIAL_DelegationSet *dsr)
 {
   struct DelegationRecordData rec;
   unsigned int i;
@@ -173,7 +133,7 @@ GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len,
     dsr[i].subject_attribute_len = ntohl ((uint32_t) 
rec.subject_attribute_len);
     if (off + dsr[i].subject_attribute_len > len)
       return GNUNET_SYSERR;
-    dsr[i].subject_attribute = &src[off];
+    dsr[i].subject_attribute = (char*)&src[off];
     off += dsr[i].subject_attribute_len;
   }
   return GNUNET_OK;
@@ -198,7 +158,7 @@ GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int 
d_count,
   size_t ret;
 
   ret = sizeof (struct ChainEntry) * (d_count);
-  ret += sizeof (struct ChainEntry) * (c_count);
+  ret += sizeof (struct CredentialEntry) * (c_count);
 
   for (i=0; i<d_count;i++)
   {
@@ -235,6 +195,7 @@ GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int 
d_count,
                                               char *dest)
 {
   struct ChainEntry rec;
+  struct CredentialEntry c_rec;
   unsigned int i;
   size_t off;
 
@@ -268,16 +229,19 @@ GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned 
int d_count,
   }
   for (i=0;i<c_count;i++)
   {
-    rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
-    rec.subject_attribute_len = htonl (0);
-    rec.issuer_key = cd[i].issuer_key;
-    rec.subject_key = cd[i].subject_key;
-    if (off + sizeof (rec) > dest_size)
+    c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
+    c_rec.issuer_key = cd[i].issuer_key;
+    c_rec.subject_key = cd[i].subject_key;
+    c_rec.signature = cd[i].signature;
+    c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
+    c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + 
cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
+    c_rec.expiration = htonl ((uint32_t) cd[i].expiration.abs_value_us);
+    if (off + sizeof (c_rec) > dest_size)
       return -1;
     GNUNET_memcpy (&dest[off],
-                   &rec,
-                   sizeof (rec));
-    off += sizeof (rec);
+                   &c_rec,
+                   sizeof (c_rec));
+    off += sizeof (c_rec);
     if (off + cd[i].issuer_attribute_len > dest_size)
       return -1;
     GNUNET_memcpy (&dest[off],
@@ -310,6 +274,7 @@ GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len,
                                                 struct 
GNUNET_CREDENTIAL_Credential *cd)
 {
   struct ChainEntry rec;
+  struct CredentialEntry c_rec;
   unsigned int i;
   size_t off;
 
@@ -335,13 +300,15 @@ GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t 
len,
   }
   for (i=0;i<c_count;i++)
   {
-    if (off + sizeof (rec) > len)
+    if (off + sizeof (c_rec) > len)
       return GNUNET_SYSERR;
-    GNUNET_memcpy (&rec, &src[off], sizeof (rec));
-    cd[i].issuer_attribute_len = ntohl ((uint32_t) rec.issuer_attribute_len);
-    cd[i].issuer_key = rec.issuer_key;
-    cd[i].subject_key = rec.subject_key;
-    off += sizeof (rec);
+    GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
+    cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
+    cd[i].issuer_key = c_rec.issuer_key;
+    cd[i].subject_key = c_rec.subject_key;
+    cd[i].signature = c_rec.signature;
+    cd[i].expiration.abs_value_us = ntohl((uint32_t) c_rec.expiration);
+    off += sizeof (c_rec);
     if (off + cd[i].issuer_attribute_len > len)
       return GNUNET_SYSERR;
     cd[i].issuer_attribute = &src[off];
@@ -350,4 +317,74 @@ GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len,
   return GNUNET_OK;
 }
 
+
+int
+GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential 
*cred,
+                                        char **data)
+{
+  size_t size;
+  struct CredentialEntry *cdata;
+
+  size = sizeof (struct CredentialEntry) + strlen (cred->issuer_attribute) + 1;
+  *data = GNUNET_malloc (size);
+  cdata = (struct CredentialEntry*)*data;
+  cdata->subject_key = cred->subject_key;
+  cdata->issuer_key = cred->issuer_key;
+  cdata->expiration = GNUNET_htonll (cred->expiration.abs_value_us);
+  cdata->signature = cred->signature;
+  cdata->issuer_attribute_len = htonl (strlen (cred->issuer_attribute) + 1);
+  cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
+  cdata->purpose.size = htonl (size - sizeof (struct 
GNUNET_CRYPTO_EcdsaSignature));
+  GNUNET_memcpy (&cdata[1],
+                 cred->issuer_attribute,
+                 strlen (cred->issuer_attribute));
+
+  if(GNUNET_OK != 
GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, 
+                                             &cdata->purpose,
+                                             &cdata->signature,
+                                             &cdata->issuer_key))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Invalid credential\n");
+    //return NULL;
+  }
+  return size;
+}
+
+struct GNUNET_CREDENTIAL_Credential*
+GNUNET_CREDENTIAL_credential_deserialize (const char* data,
+                                          size_t data_size)
+{
+  struct GNUNET_CREDENTIAL_Credential *cred;
+  struct CredentialEntry *cdata;
+  char *issuer_attribute;
+
+  if (data_size < sizeof (struct CredentialEntry))
+    return NULL;
+  cdata = (struct CredentialEntry*)data;
+  if(GNUNET_OK != 
GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, 
+                                             &cdata->purpose,
+                                             &cdata->signature,
+                                             &cdata->issuer_key))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Invalid credential\n");
+    //return NULL;
+  }
+  issuer_attribute = (char*)&cdata[1];
+
+  cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + 
ntohl(cdata->issuer_attribute_len));
+
+  cred->issuer_key = cdata->issuer_key;
+  cred->subject_key = cdata->subject_key;
+  GNUNET_memcpy (&cred[1],
+                 issuer_attribute,
+                 ntohl (cdata->issuer_attribute_len));
+  cred->signature = cdata->signature;
+  cred->issuer_attribute = (char*)&cred[1];
+  cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
+  return cred;
+}
+
+
 /* end of credential_serialization.c */
diff --git a/src/credential/credential_serialization.h 
b/src/credential/credential_serialization.h
index 39ac0103b..eb1327f34 100644
--- a/src/credential/credential_serialization.h
+++ b/src/credential/credential_serialization.h
@@ -25,6 +25,9 @@
  * and credentials
  * @author Martin Schanzenbach
  */
+#ifndef CREDENTIAL_SERIALIZATION_H
+#define CREDENTIAL_SERIALIZATION_H
+
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_constants.h"
@@ -40,7 +43,7 @@
  */
 size_t
 GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count,
-                                           const struct 
GNUNET_CREDENTIAL_DelegationSetRecord *dsr);
+                                           const struct 
GNUNET_CREDENTIAL_DelegationSet *dsr);
 
 /**
  * Serizalize the given delegation record entries
@@ -53,7 +56,7 @@ GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int 
ds_count,
  */
 ssize_t
 GNUNET_CREDENTIAL_delegation_set_serialize (unsigned int d_count,
-                                            const struct 
GNUNET_CREDENTIAL_DelegationSetRecord *dsr,
+                                            const struct 
GNUNET_CREDENTIAL_DelegationSet *dsr,
                                             size_t dest_size,
                                             char *dest);
 
@@ -71,7 +74,7 @@ int
 GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len,
                                               const char *src,
                                               unsigned int d_count,
-                                              struct 
GNUNET_CREDENTIAL_DelegationSetRecord *dsr);
+                                              struct 
GNUNET_CREDENTIAL_DelegationSet *dsr);
 
   /**
    * Calculate how many bytes we will need to serialize
@@ -127,4 +130,13 @@ GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len,
                                                     struct 
GNUNET_CREDENTIAL_Delegation *dd,
                                                     unsigned int c_count,
                                                     struct 
GNUNET_CREDENTIAL_Credential *cd);
-  /* end of credential_serialization.h */
+
+int
+GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential 
*cred,
+                                        char **data);
+
+struct GNUNET_CREDENTIAL_Credential*
+GNUNET_CREDENTIAL_credential_deserialize (const char* data,
+                                          size_t data_size);
+#endif
+/* end of credential_serialization.h */
diff --git a/src/credential/gnunet-credential.c 
b/src/credential/gnunet-credential.c
index a743458d5..b31c2f66e 100644
--- a/src/credential/gnunet-credential.c
+++ b/src/credential/gnunet-credential.c
@@ -26,6 +26,8 @@
 #include <gnunet_util_lib.h>
 #include <gnunet_credential_service.h>
 #include <gnunet_gnsrecord_lib.h>
+#include "credential_misc.h"
+#include "credential_serialization.h"
 
 /**
  * Configuration we are using.
@@ -220,7 +222,7 @@ identity_cb (void *cls,
              const struct GNUNET_IDENTITY_Ego *ego)
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
-  struct GNUNET_CREDENTIAL_CredentialRecordData *crd;
+  struct GNUNET_CREDENTIAL_Credential *crd;
   struct GNUNET_TIME_Absolute etime_abs;
   struct GNUNET_TIME_Relative etime_rel;
   char *res;
@@ -261,14 +263,13 @@ identity_cb (void *cls,
   privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
   GNUNET_free_non_null (issuer_ego_name);
   issuer_ego_name = NULL;
-  crd = GNUNET_CREDENTIAL_issue (credential,
-                                 privkey,
-                                 &subject_pkey,
-                                 issuer_attr,
-                                 &etime_abs);
-  res =  GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_CREDENTIAL,
-                                           crd,
-                                           sizeof (struct 
GNUNET_CREDENTIAL_CredentialRecordData) + strlen (issuer_attr) + 1);
+  crd = GNUNET_CREDENTIAL_credential_issue (privkey,
+                                            &subject_pkey,
+                                            issuer_attr,
+                                            &etime_abs);
+
+  res = GNUNET_CREDENTIAL_credential_to_string (crd);
+  GNUNET_free (crd);
   printf ("%s\n", res);
   GNUNET_SCHEDULER_shutdown ();
 }
@@ -354,7 +355,7 @@ run (void *cls,
                _("You must provide issuer and subject attributes\n"));
       GNUNET_SCHEDULER_shutdown ();
     }
-    
+
     printf ("Trying to find a chain from a credential under %s of %s to the 
attribute %s issued by %s\n",
             subject_credential, subject_key, issuer_attr, issuer_key);
 
diff --git a/src/credential/gnunet-service-credential.c 
b/src/credential/gnunet-service-credential.c
index 2b3eb8b4c..55907e0d7 100644
--- a/src/credential/gnunet-service-credential.c
+++ b/src/credential/gnunet-service-credential.c
@@ -46,7 +46,7 @@
 
 struct VerifyRequestHandle;
 
-struct DelegationSetEntry;
+struct DelegationSetQueueEntry;
 
 
 struct DelegationChainEntry
@@ -101,12 +101,7 @@ struct CredentialRecordEntry
   /**
    * Payload
    */
-  struct GNUNET_CREDENTIAL_CredentialRecordData *data;
-
-  /**
-   * Size
-   */
-  uint64_t data_size;
+  struct GNUNET_CREDENTIAL_Credential *credential;
 };
 
 /**
@@ -128,17 +123,17 @@ struct DelegationQueueEntry
   /**
    * Sets under this Queue
    */
-  struct DelegationSetEntry *set_entries_head;
+  struct DelegationSetQueueEntry *set_entries_head;
 
   /**
    * Sets under this Queue
    */
-  struct DelegationSetEntry *set_entries_tail;
+  struct DelegationSetQueueEntry *set_entries_tail;
 
   /**
    * Parent set
    */
-  struct DelegationSetEntry *parent_set;
+  struct DelegationSetQueueEntry *parent_set;
 
   /**
    * Required solutions
@@ -150,17 +145,17 @@ struct DelegationQueueEntry
  * DLL for delegation sets
  * Used for AND delegation set
  */
-struct DelegationSetEntry
+struct DelegationSetQueueEntry
 {
   /**
    * DLL
    */
-  struct DelegationSetEntry *next;
+  struct DelegationSetQueueEntry *next;
 
   /**
    * DLL
    */
-  struct DelegationSetEntry *prev;
+  struct DelegationSetQueueEntry *prev;
 
     /**
    * GNS handle
@@ -299,7 +294,7 @@ struct VerifyRequestHandle
   /**
    * Root Delegation Set
    */
-  struct DelegationSetEntry *root_set;
+  struct DelegationSetQueueEntry *root_set;
 
   /**
    * Current Delegation Pointer
@@ -307,16 +302,6 @@ struct VerifyRequestHandle
   struct DelegationQueueEntry *current_delegation;
 
   /**
-   * The found credential
-   */
-  struct GNUNET_CREDENTIAL_CredentialRecordData *credential;
-
-  /**
-   * Length of the credential
-   */
-  uint32_t credential_size;
-
-  /**
    * request id
    */
   uint32_t request_id;
@@ -351,10 +336,10 @@ static struct GNUNET_GNS_Handle *gns;
 
 
 static void
-cleanup_delegation_set (struct DelegationSetEntry *ds_entry)
+cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry)
 {
   struct DelegationQueueEntry *dq_entry;
-  struct DelegationSetEntry *child;
+  struct DelegationSetQueueEntry *child;
 
   if (NULL == ds_entry)
     return;
@@ -414,8 +399,6 @@ cleanup_handle (struct VerifyRequestHandle *vrh)
     GNUNET_GNS_lookup_cancel (vrh->lookup_request);
     vrh->lookup_request = NULL;
   }
-  if (NULL != vrh->credential)
-    GNUNET_free (vrh->credential);
   cleanup_delegation_set (vrh->root_set);
   if (NULL != vrh->issuer_attribute)
     GNUNET_free (vrh->issuer_attribute);
@@ -426,8 +409,8 @@ cleanup_handle (struct VerifyRequestHandle *vrh)
     GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head,
                                  vrh->cred_chain_tail,
                                  cr_entry);
-    if (NULL != cr_entry->data)
-      GNUNET_free (cr_entry->data);
+    if (NULL != cr_entry->credential);
+      GNUNET_free (cr_entry->credential);
     GNUNET_free (cr_entry);
   }
   GNUNET_free (vrh);
@@ -518,48 +501,45 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
   struct GNUNET_MQ_Envelope *env;
   struct VerifyResultMessage *rmsg;
   struct DelegationChainEntry *dce;
-  size_t size = vrh->credential_size;
   struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
   struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
-  struct GNUNET_CREDENTIAL_CredentialRecordData *crd;
   struct CredentialRecordEntry *cd;
+  size_t size;
   int i;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Sending response\n");
-  i = 0;
-  for (dce = vrh->delegation_chain_head;
-       NULL != dce;
-       dce = dce->next)
+  dce = vrh->delegation_chain_head;
+  for (i=0;i<vrh->delegation_chain_size;i++)
   {
     dd[i].issuer_key = dce->issuer_key;
     dd[i].subject_key = dce->subject_key;
     dd[i].issuer_attribute = dce->issuer_attribute;
     dd[i].issuer_attribute_len = strlen (dce->issuer_attribute)+1;
     dd[i].subject_attribute_len = 0;
+    dd[i].subject_attribute = NULL;
     if (NULL != dce->subject_attribute)
     {
       dd[i].subject_attribute = dce->subject_attribute;
       dd[i].subject_attribute_len = strlen(dce->subject_attribute)+1;
     }
-    i++;
+    dce = dce->next;
   }
 
   /**
    * Get serialized record data
    * Append at the end of rmsg
    */
-  i = 0;
-  for (cd = vrh->cred_chain_head;
-       NULL != cd;
-       cd = cd->next)
+  cd = vrh->cred_chain_head;
+  for (i=0;i<vrh->cred_chain_size;i++)
   {
-    crd = cd->data;
-    cred[i].issuer_key = crd->issuer_key;
-    cred[i].subject_key = crd->subject_key;
-    cred[i].issuer_attribute_len = strlen((char*)&crd[1])+1;
-    cred[i].issuer_attribute = (char*)&crd[1];
-    i++;
+    cred[i].issuer_key = cd->credential->issuer_key;
+    cred[i].subject_key = cd->credential->subject_key;
+    cred[i].issuer_attribute_len = strlen(cd->credential->issuer_attribute)+1;
+    cred[i].issuer_attribute = cd->credential->issuer_attribute;
+    cred[i].expiration = cd->credential->expiration;
+    cred[i].signature = cd->credential->signature;
+    cd = cd->next;
   }
   size = GNUNET_CREDENTIAL_delegation_chain_get_size 
(vrh->delegation_chain_size,
                                                       dd,
@@ -573,18 +553,18 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
   rmsg->d_count = htonl (vrh->delegation_chain_size);
   rmsg->c_count = htonl (vrh->cred_chain_size);
 
-  if (NULL != vrh->credential)
+  if (0 < vrh->cred_chain_size)
     rmsg->cred_found = htonl (GNUNET_YES);
   else
     rmsg->cred_found = htonl (GNUNET_NO);
 
   GNUNET_assert (-1 != 
-               GNUNET_CREDENTIAL_delegation_chain_serialize 
(vrh->delegation_chain_size,
-                                                             dd,
-                                                             
vrh->cred_chain_size,
-                                                             cred,
-                                                             size,
-                                                             (char*)&rmsg[1]));
+                 GNUNET_CREDENTIAL_delegation_chain_serialize 
(vrh->delegation_chain_size,
+                                                               dd,
+                                                               
vrh->cred_chain_size,
+                                                               cred,
+                                                               size,
+                                                               
(char*)&rmsg[1]));
 
   GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(vrh->client),
                   env);
@@ -604,12 +584,11 @@ backward_resolution (void* cls,
 {
 
   struct VerifyRequestHandle *vrh;
-  struct GNUNET_CREDENTIAL_CredentialRecordData *cred;
-  const struct GNUNET_CREDENTIAL_DelegationRecordData *sets;
+  const struct GNUNET_CREDENTIAL_DelegationRecord *sets;
   struct CredentialRecordEntry *cred_pointer;
-  struct DelegationSetEntry *current_set;
-  struct DelegationSetEntry *ds_entry;
-  struct DelegationSetEntry *tmp_set;
+  struct DelegationSetQueueEntry *current_set;
+  struct DelegationSetQueueEntry *ds_entry;
+  struct DelegationSetQueueEntry *tmp_set;
   struct DelegationQueueEntry *dq_entry;
   char *expanded_attr;
   char *lookup_attribute;
@@ -631,15 +610,15 @@ backward_resolution (void* cls,
       continue;
 
     sets = rd[i].data;
-    struct GNUNET_CREDENTIAL_DelegationSetRecord set[ntohl(sets->set_count)];
+    struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets->set_count)];
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Found new attribute delegation with %d sets. Creating new 
Job...\n",
-               ntohl (sets->set_count));
+                ntohl (sets->set_count));
 
     if (GNUNET_OK !=GNUNET_CREDENTIAL_delegation_set_deserialize 
(GNUNET_ntohll(sets->data_size),
-                                                  (const char*)&sets[1],
-                                                  ntohl(sets->set_count),
-                                                  set))
+                                                                  (const 
char*)&sets[1],
+                                                                  
ntohl(sets->set_count),
+                                                                  set))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Failed to deserialize!\n");
@@ -654,7 +633,7 @@ backward_resolution (void* cls,
     // Each AND
     for (j=0; j<ntohl(sets->set_count); j++)
     {
-      ds_entry = GNUNET_new (struct DelegationSetEntry);
+      ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
       if (NULL != current_set->attr_trailer)
       {
         if (0 == set[j].subject_attribute_len)
@@ -706,16 +685,17 @@ backward_resolution (void* cls,
       for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL; 
           cred_pointer = cred_pointer->next)
       {
-        cred = cred_pointer->data;
         if(0 != memcmp (&set->subject_key, 
-                        &cred_pointer->data->issuer_key,
+                        &cred_pointer->credential->issuer_key,
                         sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
           continue;
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                     "Checking if %s matches %s\n",
-                    ds_entry->unresolved_attribute_delegation, 
(char*)&cred[1]);
+                    ds_entry->unresolved_attribute_delegation,
+                    cred_pointer->credential->issuer_attribute);
 
-        if (0 != strcmp (ds_entry->unresolved_attribute_delegation, 
(char*)&cred[1]))
+        if (0 != strcmp (ds_entry->unresolved_attribute_delegation,
+                         cred_pointer->credential->issuer_attribute))
           continue;
 
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -742,11 +722,6 @@ backward_resolution (void* cls,
         {
           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                       "All solutions found\n");
-          vrh->credential = GNUNET_malloc (cred_pointer->data_size);
-          memcpy (vrh->credential,
-                  cred,
-                  cred_pointer->data_size);
-          vrh->credential_size = cred_pointer->data_size;
           //Found match
           send_lookup_response (vrh);
           return;
@@ -822,8 +797,8 @@ handle_credential_query (void* cls,
                          const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct VerifyRequestHandle *vrh = cls;
-  struct DelegationSetEntry *ds_entry;
-  const struct GNUNET_CREDENTIAL_CredentialRecordData *crd;
+  struct DelegationSetQueueEntry *ds_entry;
+  struct GNUNET_CREDENTIAL_Credential *crd;
   struct CredentialRecordEntry *cr_entry;
   int cred_record_count;
   int i;
@@ -835,22 +810,16 @@ handle_credential_query (void* cls,
     if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
       continue;
     cred_record_count++;
-    crd = rd[i].data;
-    if(GNUNET_OK != 
GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, 
-                                               &crd->purpose,
-                                               &crd->signature,
-                                               &crd->issuer_key))
+    crd = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data,
+                                                    rd[i].data_size);
+    if (NULL == crd)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "Invalid credential found\n");
       continue;
     }
     cr_entry = GNUNET_new (struct CredentialRecordEntry);
-    cr_entry->data = GNUNET_malloc (rd[i].data_size);
-    memcpy (cr_entry->data,
-            crd,
-            rd[i].data_size);
-    cr_entry->data_size = rd[i].data_size;
+    cr_entry->credential = crd;
     GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head,
                                       vrh->cred_chain_tail,
                                       cr_entry);
@@ -860,13 +829,8 @@ handle_credential_query (void* cls,
                      &vrh->issuer_key,
                      sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
       continue;
-    if (0 != strcmp ((char*)&crd[1], vrh->issuer_attribute))
+    if (0 != strcmp (crd->issuer_attribute, vrh->issuer_attribute))
       continue;
-    vrh->credential = GNUNET_malloc (rd[i].data_size);
-    memcpy (vrh->credential,
-            rd[i].data,
-            rd[i].data_size);
-    vrh->credential_size = rd[i].data_size;
     //Found match prematurely
     send_lookup_response (vrh);
     return;
@@ -884,7 +848,7 @@ handle_credential_query (void* cls,
           ".gnu");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Looking up %s\n", issuer_attribute_name);
-  ds_entry = GNUNET_new (struct DelegationSetEntry);
+  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
   ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
   memcpy (ds_entry->issuer_key,
           &vrh->issuer_key,
diff --git a/src/credential/plugin_gnsrecord_credential.c 
b/src/credential/plugin_gnsrecord_credential.c
index 1358afdb1..5c3c03832 100644
--- a/src/credential/plugin_gnsrecord_credential.c
+++ b/src/credential/plugin_gnsrecord_credential.c
@@ -31,7 +31,7 @@
 #include "gnunet_gnsrecord_plugin.h"
 #include "gnunet_signatures.h"
 #include "credential_serialization.h"
-
+#include "credential_misc.h"
 
 /**
  * Convert the 'value' of a record to a string.
@@ -55,18 +55,18 @@ credential_value_to_string (void *cls,
   {
    case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
    {
-    struct GNUNET_CREDENTIAL_DelegationRecordData sets;
+    struct GNUNET_CREDENTIAL_DelegationRecord sets;
     char *attr_str;
     char *subject_pkey;
     char *tmp_str;
     int i;
-    if (data_size < sizeof (struct GNUNET_CREDENTIAL_DelegationRecordData))
+    if (data_size < sizeof (struct GNUNET_CREDENTIAL_DelegationRecord))
       return NULL; /* malformed */
     memcpy (&sets,
             data,
             sizeof (sets));
     cdata = data;
-    struct GNUNET_CREDENTIAL_DelegationSetRecord set[ntohl(sets.set_count)];
+    struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets.set_count)];
     if (GNUNET_OK != GNUNET_CREDENTIAL_delegation_set_deserialize 
(GNUNET_ntohll (sets.data_size),
                                                                    
&cdata[sizeof (sets)],
                                                                    ntohl 
(sets.set_count),
@@ -116,38 +116,13 @@ credential_value_to_string (void *cls,
    }
    case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
    {
-     struct GNUNET_CREDENTIAL_CredentialRecordData cred;
-     struct GNUNET_TIME_Absolute etime_abs;
+     struct GNUNET_CREDENTIAL_Credential *cred;
      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);
+     cred = GNUNET_CREDENTIAL_credential_deserialize (data,
+                                                      data_size);
+     cred_str = GNUNET_CREDENTIAL_credential_to_string (cred);
+     GNUNET_free (cred);
      return cred_str;
    }
    default:
@@ -180,7 +155,7 @@ credential_string_to_value (void *cls,
   {
     case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
       {
-        struct GNUNET_CREDENTIAL_DelegationRecordData *sets;
+        struct GNUNET_CREDENTIAL_DelegationRecord *sets;
         char attr_str[253 + 1];
         char subject_pkey[52 + 1];
         char *token;
@@ -194,7 +169,7 @@ credential_string_to_value (void *cls,
         token = strtok (tmp_str, ",");
         entries = 0;
         tmp_data_size = 0;
-        *data_size = sizeof (struct GNUNET_CREDENTIAL_DelegationRecordData);
+        *data_size = sizeof (struct GNUNET_CREDENTIAL_DelegationRecord);
         while (NULL != token)
         {
           matches = SSCANF (token,
@@ -210,9 +185,9 @@ credential_string_to_value (void *cls,
             return GNUNET_SYSERR;
           }
           if (1 == matches) {
-            tmp_data_size += sizeof (struct 
GNUNET_CREDENTIAL_DelegationSetRecord);
+            tmp_data_size += sizeof (struct 
GNUNET_CREDENTIAL_DelegationRecordSet);
           } else if (2 == matches) {
-            tmp_data_size += sizeof (struct 
GNUNET_CREDENTIAL_DelegationSetRecord) + strlen (attr_str) + 1;
+            tmp_data_size += sizeof (struct 
GNUNET_CREDENTIAL_DelegationRecordSet) + strlen (attr_str) + 1;
           }
           entries++;
           token = strtok (NULL, ",");
@@ -220,8 +195,7 @@ credential_string_to_value (void *cls,
         GNUNET_free (tmp_str);
         tmp_str = GNUNET_strdup (s);
         token = strtok (tmp_str, ",");
-        struct GNUNET_CREDENTIAL_DelegationSetRecord *set;
-        set = GNUNET_malloc (entries * sizeof (struct 
GNUNET_CREDENTIAL_DelegationSetRecord));
+        struct GNUNET_CREDENTIAL_DelegationSet set[entries];
         for (i=0;i<entries;i++)
         {
           matches = SSCANF (token,
@@ -239,6 +213,7 @@ credential_string_to_value (void *cls,
         }
         tmp_data_size = GNUNET_CREDENTIAL_delegation_set_get_size (entries,
                                                                    set);
+        
         if (-1 == tmp_data_size)
           return GNUNET_SYSERR;
         *data_size += tmp_data_size;
@@ -247,6 +222,11 @@ credential_string_to_value (void *cls,
                                                     set,
                                                     tmp_data_size,
                                                     (char*)&sets[1]);
+        for (i=0;i<entries;i++)
+        {
+          if (0 != set[i].subject_attribute_len)
+            GNUNET_free ((char*)set[i].subject_attribute);
+        }
         sets->set_count = htonl (entries);
         sets->data_size = GNUNET_htonll (tmp_data_size);
 
@@ -255,58 +235,11 @@ credential_string_to_value (void *cls,
       }
     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 signature[128]; //TODO max payload size
-        char expiration[256];
-
-        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,
-                         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_CredentialRecordData) + 
strlen (name) + 1;
-        *data = cred = GNUNET_malloc (*data_size);
-        GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
-                                                    strlen (subject_pkey),
-                                                    &cred->subject_key);
-        GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
-                                                    strlen (issuer_pkey),
-                                                    &cred->issuer_key);
-        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));
-
+        struct GNUNET_CREDENTIAL_Credential *cred;
+        cred = GNUNET_CREDENTIAL_credential_from_string (s);
 
+        *data_size = GNUNET_CREDENTIAL_credential_serialize (cred,
+                                                             (char**)data);
         return GNUNET_OK;
       }
     default:
diff --git a/src/credential/plugin_rest_credential.c 
b/src/credential/plugin_rest_credential.c
index 11e6fb276..2df65d7ad 100644
--- a/src/credential/plugin_rest_credential.c
+++ b/src/credential/plugin_rest_credential.c
@@ -37,6 +37,14 @@
 
 #define GNUNET_REST_API_NS_CREDENTIAL "/credential"
 
+#define GNUNET_REST_API_NS_CREDENTIAL_ISSUE "/credential/issue"
+
+#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify"
+
+#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration"
+
+#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key"
+
 #define GNUNET_REST_JSONAPI_CREDENTIAL "credential"
 
 #define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential"
@@ -57,7 +65,7 @@ struct Plugin
 
 const struct GNUNET_CONFIGURATION_Handle *cfg;
 
-struct VerifyHandle
+struct RequestHandle
 {
   /**
    * Handle to Credential service.
@@ -70,6 +78,21 @@ struct VerifyHandle
   struct GNUNET_CREDENTIAL_Request *verify_request;
 
   /**
+   * Handle to issue request
+   */
+  struct GNUNET_CREDENTIAL_Request *issue_request;
+
+  /**
+   * Handle to identity
+   */
+  struct GNUNET_IDENTITY_Handle *identity;
+
+  /**
+   * Handle to identity operation
+   */
+  struct GNUNET_IDENTITY_Operation *id_op;
+
+  /**
    * Handle to rest request
    */
   struct GNUNET_REST_RequestHandle *rest_handle;
@@ -133,7 +156,7 @@ struct VerifyHandle
  * @param handle Handle to clean up
  */
 static void
-cleanup_handle (struct VerifyHandle *handle)
+cleanup_handle (struct RequestHandle *handle)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Cleaning up\n");
@@ -145,16 +168,13 @@ cleanup_handle (struct VerifyHandle *handle)
   if (NULL != handle->subject_attr)
     GNUNET_free (handle->subject_attr);
   if (NULL != handle->verify_request)
-  {
     GNUNET_CREDENTIAL_verify_cancel (handle->verify_request);
-    handle->verify_request = NULL;
-  }
   if (NULL != handle->credential)
-  {
     GNUNET_CREDENTIAL_disconnect (handle->credential);
-    handle->credential = NULL;
-  }
-
+  if (NULL != handle->id_op)
+    GNUNET_IDENTITY_cancel (handle->id_op);
+  if (NULL != handle->identity)
+    GNUNET_IDENTITY_disconnect (handle->identity);
   if (NULL != handle->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
@@ -172,7 +192,7 @@ cleanup_handle (struct VerifyHandle *handle)
 static void
 do_error (void *cls)
 {
-  struct VerifyHandle *handle = cls;
+  struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
 
   resp = GNUNET_REST_create_response (NULL);
@@ -280,7 +300,7 @@ handle_verify_response (void *cls,
                         struct GNUNET_CREDENTIAL_Credential *cred)
 {
 
-  struct VerifyHandle *handle = cls;
+  struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
   struct GNUNET_JSONAPI_Document *json_document;
   struct GNUNET_JSONAPI_Resource *json_resource;
@@ -355,7 +375,7 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle 
*conndata_handle,
                   const char* url,
                   void *cls)
 {
-  struct VerifyHandle *handle = cls;
+  struct RequestHandle *handle = cls;
   struct GNUNET_HashCode key;
   char *tmp;
   char *entity_attr;
@@ -478,6 +498,213 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle 
*conndata_handle,
 
 }
 
+void
+send_cred_response (struct RequestHandle *handle,
+                    struct GNUNET_CREDENTIAL_Credential *cred)
+{
+  struct MHD_Response *resp;
+  struct GNUNET_JSONAPI_Document *json_document;
+  struct GNUNET_JSONAPI_Resource *json_resource;
+  json_t *cred_obj;
+  char *result;
+  char *issuer;
+  char *subject;
+  char *signature;
+  char *id;
+
+  GNUNET_assert (NULL == cred);
+  issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
+  if (NULL == issuer)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Subject malformed\n");
+    return;
+  }
+  GNUNET_asprintf (&id,
+                   "%s.%s",
+                   issuer,
+                   (char*)&cred[1]);
+  subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
+  if (NULL == subject)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Subject malformed\n");
+    return;
+  }
+  GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
+                                sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
+                                &signature);
+  json_document = GNUNET_JSONAPI_document_new ();
+  json_resource = GNUNET_JSONAPI_resource_new 
(GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
+                                               id);
+  GNUNET_free (id);
+  cred_obj = json_object();
+  json_object_set_new (cred_obj, "issuer", json_string (issuer));
+  json_object_set_new (cred_obj, "subject", json_string (subject));
+  json_object_set_new (cred_obj, "expiration", json_integer( 
cred->expiration.abs_value_us));
+  json_object_set_new (cred_obj, "signature", json_string (signature));
+  GNUNET_JSONAPI_resource_add_attr (json_resource,
+                                    GNUNET_REST_JSONAPI_CREDENTIAL,
+                                    cred_obj);
+  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
+  GNUNET_JSONAPI_document_serialize (json_document, &result);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Result %s\n",
+              result);
+  json_decref (cred_obj);
+  GNUNET_JSONAPI_document_delete (json_document);
+  resp = GNUNET_REST_create_response (result);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_free (result);
+  GNUNET_free (signature);
+  GNUNET_free (issuer);
+  GNUNET_free (subject);
+  cleanup_handle (handle);
+}
+
+void
+get_cred_issuer_cb (void *cls,
+                    struct GNUNET_IDENTITY_Ego *ego,
+                    void **ctx,
+                    const char *name)
+{
+  struct RequestHandle *handle = cls;
+  struct GNUNET_TIME_Absolute etime_abs;
+  struct GNUNET_TIME_Relative etime_rel;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer_key;
+  struct GNUNET_HashCode key;
+  struct GNUNET_CREDENTIAL_Credential *cred;
+  char* expiration_str;
+  char* tmp;
+
+  handle->id_op = NULL;
+
+  if (NULL == name)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Issuer not configured!\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Connecting to credential service...\n");
+  handle->credential = GNUNET_CREDENTIAL_connect (cfg);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Connected\n");
+  if (NULL == handle->credential)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Connecting to CREDENTIAL failed\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION,
+                      strlen (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION),
+                      &key);
+  if ( GNUNET_NO ==
+       GNUNET_CONTAINER_multihashmap_contains 
(handle->rest_handle->url_param_map,
+                                               &key) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Missing expiration\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle); 
+    return;
+  }
+  expiration_str = GNUNET_CONTAINER_multihashmap_get 
(handle->rest_handle->url_param_map,
+                                                      &key);
+  if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str,
+                                                          &etime_rel))
+  {
+    etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
+  } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute 
(expiration_str,
+                                                                 &etime_abs))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Malformed expiration: %s\n", expiration_str);
+    GNUNET_SCHEDULER_add_now (&do_error, handle); 
+    return;
+  }
+  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR,
+                      strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR),
+                      &key);
+  if ( GNUNET_NO ==
+       GNUNET_CONTAINER_multihashmap_contains 
(handle->rest_handle->url_param_map,
+                                               &key) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Missing issuer attribute\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle); 
+    return;
+  }
+  handle->issuer_attr = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get 
+                                      (handle->rest_handle->url_param_map,
+                                       &key));
+  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY,
+                      strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY),
+                      &key);
+  if ( GNUNET_NO ==
+       GNUNET_CONTAINER_multihashmap_contains 
(handle->rest_handle->url_param_map,
+                                               &key) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Missing subject\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
+                                           &key);
+  if (NULL == tmp)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Malformed subject\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle); 
+    return;
+  }
+  if (GNUNET_OK !=
+      GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp,
+                                                  strlen (tmp),
+                                                  &handle->subject_key)) {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Malformed subject key\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego);
+  cred = GNUNET_CREDENTIAL_credential_issue (issuer_key,
+                                             &handle->subject_key,
+                                             handle->issuer_attr,
+                                             &etime_abs);
+  if (NULL == cred)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to create credential\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  send_cred_response (handle, cred);
+}
+
+
+static void
+issue_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
+                 const char* url,
+                 void *cls)
+{
+  struct RequestHandle *handle = cls;
+
+  handle->identity = GNUNET_IDENTITY_connect (cfg,
+                                              NULL,
+                                              NULL);
+  handle->id_op = GNUNET_IDENTITY_get(handle->identity,
+                                      "credential-issuer",
+                                      &get_cred_issuer_cb,
+                                      handle);
+  handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
+                                                       &do_error,
+                                                       handle);
+}
+
 /**
  * Handle rest request
  *
@@ -489,7 +716,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
               void *cls)
 {
   struct MHD_Response *resp;
-  struct VerifyHandle *handle = cls;
+  struct RequestHandle *handle = cls;
 
   //For GNS, independent of path return all options
   resp = GNUNET_REST_create_response (NULL);
@@ -519,7 +746,7 @@ rest_credential_process_request(struct 
GNUNET_REST_RequestHandle *conndata_handl
                                 GNUNET_REST_ResultProcessor proc,
                                 void *proc_cls)
 {
-  struct VerifyHandle *handle = GNUNET_new (struct VerifyHandle);
+  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
   struct GNUNET_REST_RequestHandlerError err;
 
   handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -528,7 +755,8 @@ rest_credential_process_request(struct 
GNUNET_REST_RequestHandle *conndata_handl
   handle->rest_handle = conndata_handle;
 
   static const struct GNUNET_REST_RequestHandler handlers[] = {
-    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL, &verify_cred_cont},
+    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, 
&verify_cred_cont},
+    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, 
&issue_cred_cont},
     {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont},
     GNUNET_REST_HANDLER_END
   };
diff --git a/src/credential/test_credential_issue.sh 
b/src/credential/test_credential_issue.sh
index b2ced204a..158d91c5b 100755
--- a/src/credential/test_credential_issue.sh
+++ b/src/credential/test_credential_issue.sh
@@ -39,6 +39,6 @@ then
 fi
 #Try import
 $DO_TIMEOUT gnunet-namestore -a -z testsubject -n c1 -t CRED -V "$CRED" -e 5m 
-c test_credential_lookup.conf
-
+RES=$?
 gnunet-arm -e -c test_credential_lookup.conf
-exit $?
+exit $RES
diff --git a/src/credential/test_credential_lookup.conf 
b/src/credential/test_credential_lookup.conf
index f4bf36c52..7aa193abd 100644
--- a/src/credential/test_credential_lookup.conf
+++ b/src/credential/test_credential_lookup.conf
@@ -14,7 +14,7 @@ AUTOSTART = YES
 #PREFIX = valgrind --leak-check=full --track-origins=yes 
--log-file=/tmp/credlog
 
 [rest]
-PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/restlog
+#PREFIX = valgrind --leak-check=full --track-origins=yes 
--log-file=/tmp/restlog
 
 [gns]
 #PREFIX = valgrind --leak-check=full --track-origins=yes
diff --git a/src/credential/test_credential_verify_simple.sh 
b/src/credential/test_credential_verify_simple.sh
index 924f2ab4a..c4fd8c7a3 100755
--- a/src/credential/test_credential_verify_simple.sh
+++ b/src/credential/test_credential_verify_simple.sh
@@ -39,7 +39,7 @@ RES_CRED=`gnunet-credential --verify --issuer=$ISSUER_KEY 
--attribute=$TEST_ATTR
 gnunet-namestore -z testsubject -d -n $TEST_CREDENTIAL -t CRED -e never -c 
test_credential_lookup.conf
 gnunet-identity -D testsubject -c test_credential_lookup.conf
 gnunet-arm -e -c test_credential_lookup.conf
-
+echo $RES_CRED
 #TODO3 proper test
 if [ "$RES_CRED" == "Successful." ]
 then
diff --git a/src/identity-provider/identity_provider_api.c 
b/src/identity-provider/identity_provider_api.c
index 28ff90fc4..1d242f66a 100644
--- a/src/identity-provider/identity_provider_api.c
+++ b/src/identity-provider/identity_provider_api.c
@@ -223,12 +223,12 @@ check_exchange_result (void *cls,
               const struct ExchangeResultMessage *erm)
 {
   char *str;
-  size_t size = ntohs (erm->header.size) - sizeof (*erm);
+  size_t size = ntohs (erm->header.size);
   
 
-  str = (char *) &erm[1];
+  str = (char *) &erm[0];
   if ( (size > sizeof (struct ExchangeResultMessage)) &&
-       ('\0' != str[size - sizeof (struct ExchangeResultMessage) - 1]) )
+       ('\0' != str[size - 1]) )
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
@@ -248,10 +248,10 @@ check_result (void *cls,
               const struct IssueResultMessage *irm)
 {
   char *str;
-  size_t size = ntohs (irm->header.size) - sizeof (*irm);
-  str = (char*) &irm[1];
+  size_t size = ntohs (irm->header.size);
+  str = (char*) &irm[0];
   if ( (size > sizeof (struct IssueResultMessage)) &&
-       ('\0' != str[size - sizeof (struct IssueResultMessage) - 1]) )
+       ('\0' != str[size - 1]) )
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
diff --git a/src/identity/plugin_rest_identity.c 
b/src/identity/plugin_rest_identity.c
index e64b2685a..5f34d0f1b 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -427,9 +427,6 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con,
       continue;
     json_resource = GNUNET_JSONAPI_resource_new 
(GNUNET_REST_JSONAPI_IDENTITY_EGO,
                                                       ego_entry->keystring);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Egoname: %s\n",
-                ego_entry->identifier);
     name_str = json_string (ego_entry->identifier);
     GNUNET_JSONAPI_resource_add_attr (
                                            json_resource,
diff --git a/src/include/gnunet_credential_service.h 
b/src/include/gnunet_credential_service.h
index 7419407d3..906163c14 100644
--- a/src/include/gnunet_credential_service.h
+++ b/src/include/gnunet_credential_service.h
@@ -74,65 +74,49 @@ enum GNUNET_CREDENTIAL_CredentialFlags {
 
 GNUNET_NETWORK_STRUCT_BEGIN
 /**
- * The credential record 
+ * The attribute delegation record
  */
-struct GNUNET_CREDENTIAL_CredentialRecordData {
-  
-  /**
-   * The signature for this credential by the issuer
-   */
-  struct GNUNET_CRYPTO_EcdsaSignature signature;
-  
-  /**
-   * Signature meta
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+struct GNUNET_CREDENTIAL_DelegationRecord {
 
   /**
-   * Public key of the issuer
+   * Number of delegation sets in this record
    */
-  struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
-  
+  uint32_t set_count;
+
   /**
-   * Public key of the subject this credential was issued to
+   * Length of delegation sets
    */
-  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
-  
+  uint64_t data_size;
   /**
-   * Expiration time of this credential
-   */
-  uint64_t expiration GNUNET_PACKED;
-  
-    /**
-   * Followed by the attribute string
+   * Followed by set_count DelegationSetRecords
+   *
    */
 };
 
-
 /**
  * The attribute delegation record
-*/
-struct GNUNET_CREDENTIAL_DelegationRecordData {
-  
-  uint32_t set_count;
+ */
+struct GNUNET_CREDENTIAL_DelegationRecordSet {
 
-  uint64_t data_size;
+  /**
+   * Public key of the subject this attribute was delegated to
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
 
-  char *data;
-  
   /**
-   * Followed by the attribute that was delegated to as string
-   * May be empty
+   * Length of attribute, may be 0
    */
+  uint32_t subject_attribute_len;
 };
 
 
+GNUNET_NETWORK_STRUCT_END
 
 /**
  * The attribute delegation record
-*/
-struct GNUNET_CREDENTIAL_DelegationSetRecord {
-  
+ */
+struct GNUNET_CREDENTIAL_DelegationSet {
+
   /**
    * Public key of the subject this attribute was delegated to
    */
@@ -140,20 +124,18 @@ struct GNUNET_CREDENTIAL_DelegationSetRecord {
 
   uint32_t subject_attribute_len;
 
-  const char *subject_attribute;
-  
   /**
-   * Followed by the attribute that was delegated to as string
-   * May be empty
+   * The subject attribute
    */
+  const char *subject_attribute;
 };
 
 
 /**
  * A delegation
-*/
+ */
 struct GNUNET_CREDENTIAL_Delegation {
-  
+
   /**
    * The issuer of the delegation
    */
@@ -188,9 +170,9 @@ struct GNUNET_CREDENTIAL_Delegation {
 
 /**
  * A credential
-*/
+ */
 struct GNUNET_CREDENTIAL_Credential {
-  
+
   /**
    * The issuer of the credential
    */
@@ -202,6 +184,16 @@ struct GNUNET_CREDENTIAL_Credential {
   struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
 
   /**
+   * Signature of this credential
+   */
+  struct GNUNET_CRYPTO_EcdsaSignature signature;
+
+  /**
+   * Expiration of this credential
+   */
+  struct GNUNET_TIME_Absolute expiration;
+
+  /**
    * Length of the attribute
    */
   uint32_t issuer_attribute_len;
@@ -210,11 +202,8 @@ struct GNUNET_CREDENTIAL_Credential {
    * The attribute
    */
   const char *issuer_attribute;
-  
-};
 
-
-GNUNET_NETWORK_STRUCT_END
+};
 
 
 
@@ -260,7 +249,7 @@ typedef void (*GNUNET_CREDENTIAL_VerifyResultProcessor) 
(void *cls,
  * @param result the record data that can be handed to the subject
  */
 typedef void (*GNUNET_CREDENTIAL_DelegateResultProcessor) (void *cls,
-                                                 uint32_t success);
+                                                           uint32_t success);
 
 /**
  * Iterator called on obtained result for an attribute delegation removal.
@@ -270,7 +259,7 @@ typedef void (*GNUNET_CREDENTIAL_DelegateResultProcessor) 
(void *cls,
  * @param result the record data that can be handed to the subject
  */
 typedef void (*GNUNET_CREDENTIAL_RemoveDelegateResultProcessor) (void *cls,
-                                                 uint32_t success);
+                                                                 uint32_t 
success);
 
 
 
@@ -330,10 +319,10 @@ GNUNET_CREDENTIAL_add_delegation (struct 
GNUNET_CREDENTIAL_Handle *handle,
  */
 struct GNUNET_CREDENTIAL_Request *
 GNUNET_CREDENTIAL_remove_delegation (struct GNUNET_CREDENTIAL_Handle *handle,
-                                  struct GNUNET_IDENTITY_Ego *issuer,
-                                  const char *attribute,
-                                  
GNUNET_CREDENTIAL_RemoveDelegateResultProcessor proc,
-                                  void *proc_cls);
+                                     struct GNUNET_IDENTITY_Ego *issuer,
+                                     const char *attribute,
+                                     
GNUNET_CREDENTIAL_RemoveDelegateResultProcessor proc,
+                                     void *proc_cls);
 
 
 
@@ -347,12 +336,12 @@ GNUNET_CREDENTIAL_remove_delegation (struct 
GNUNET_CREDENTIAL_Handle *handle,
  * @param expiration the TTL of the credential
  * @return handle to the queued request
  */
-struct GNUNET_CREDENTIAL_CredentialRecordData *
-GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle,
-                         const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
-                         struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
-                         const char *attribute,
-                         struct GNUNET_TIME_Absolute *expiration);
+struct GNUNET_CREDENTIAL_Credential*
+GNUNET_CREDENTIAL_credential_issue (
+                                    const struct GNUNET_CRYPTO_EcdsaPrivateKey 
*issuer,
+                                    struct GNUNET_CRYPTO_EcdsaPublicKey 
*subject,
+                                    const char *attribute,
+                                    struct GNUNET_TIME_Absolute *expiration);
 
 
 /**
diff --git a/src/jsonapi/jsonapi_document.c b/src/jsonapi/jsonapi_document.c
index 600b7ee6a..8022a9f6e 100644
--- a/src/jsonapi/jsonapi_document.c
+++ b/src/jsonapi/jsonapi_document.c
@@ -332,28 +332,20 @@ GNUNET_JSONAPI_document_to_json (const struct 
GNUNET_JSONAPI_Document *doc,
                          GNUNET_JSONAPI_KEY_ERRORS,
                          res_json);
   } else {
-    switch (doc->res_count)
+    if (0 == doc->res_count)
     {
-      case 0:
-        res_json = json_null();
-        break;
-      case 1:
+      res_json = json_null();
+    } else {
+      res_json = json_array ();
+      for (res = doc->res_list_head;
+           res != NULL;
+           res = res->next)
+      {
         GNUNET_assert (GNUNET_OK ==
-                       GNUNET_JSONAPI_resource_to_json (doc->res_list_head,
-                                                        &res_json));
-        break;
-      default:
-        res_json = json_array ();
-        for (res = doc->res_list_head;
-             res != NULL;
-             res = res->next)
-        {
-          GNUNET_assert (GNUNET_OK ==
-                         GNUNET_JSONAPI_resource_to_json (res,
-                                                          &res_json_tmp));
-          json_array_append (res_json, res_json_tmp);
-        }
-        break;
+                       GNUNET_JSONAPI_resource_to_json (res,
+                                                        &res_json_tmp));
+        json_array_append (res_json, res_json_tmp);
+      }
     }
     json_object_set_new (*root_json,
                          GNUNET_JSONAPI_KEY_DATA,

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]