-remove debug output
[oweals/gnunet.git] / src / identity-provider / identity_token.c
index 10e142ca0301ea1d5d07b9f93a1e900e4fc2d291..673d0b03769602054cc4282a05584096dfaac97c 100644 (file)
 #include "identity_token.h"
 #include <jansson.h>
 
+#define JWT_ALG "alg"
+
+#define JWT_ALG_VALUE "ED512"
+
+#define JWT_TYP "typ"
+
+#define JWT_TYP_VALUE "jwt"
 
 /**
  * Crypto helper functions
@@ -43,7 +50,7 @@ create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
 
   GNUNET_CRYPTO_hash_to_enc (new_key_hash,
                              &new_key_hash_str);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
   static const char ctx_key[] = "gnuid-aes-ctx-key";
   GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
                      new_key_hash, sizeof (struct GNUNET_HashCode),
@@ -90,7 +97,7 @@ decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
                                               &enc_key,
                                               &enc_iv,
                                               str_buf);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decrypted bytes: %d Expected bytes: %d\n", str_size, cyphertext_len);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypted bytes: %d Expected bytes: %d\n", str_size, cyphertext_len);
   if (-1 == str_size)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
@@ -164,19 +171,18 @@ encrypt_str_ecdhe (const char *plaintext,
                                                         pub_key,
                                                         &new_key_hash));
   create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypting string %s\n (len=%d)",
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%d)",
               plaintext,
               strlen (plaintext));
-  enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext, strlen (plaintext),
+  enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext,
+                                              strlen (plaintext),
                                               &skey, &iv,
                                               *cyphertext);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypted (len=%d)", enc_size);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%d)", enc_size);
   return GNUNET_OK;
 }
 
 
-
-
 /**
  * Identity Token API
  */
@@ -202,20 +208,10 @@ token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
   audience = GNUNET_STRINGS_data_to_string_alloc (aud,
                                                   sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
 
-
-
   token = GNUNET_malloc (sizeof (struct IdentityToken));
-
-  token->header = json_object();
-  token->payload = json_object();
-
-  json_object_set_new (token->header, "alg", json_string ("ED512"));
-  json_object_set_new (token->header, "typ", json_string ("JWT"));
-
-  json_object_set_new (token->payload, "iss", json_string (issuer));
-  json_object_set_new (token->payload, "aud", json_string (audience));
-  json_object_set_new (token->payload, "sub", json_string (issuer));
-
+  token_add_attr (token, "iss", issuer);
+  token_add_attr (token, "aud", audience);
+  token_add_attr (token, "sub", issuer);
   token->aud_key = *aud;
   GNUNET_free (issuer);
   GNUNET_free (audience);
@@ -225,50 +221,156 @@ token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
 void
 token_destroy (struct IdentityToken *token)
 {
-  json_decref (token->header);
-  json_decref (token->payload);
+  struct TokenAttr *attr;
+  struct TokenAttr *tmp_attr;
+  struct TokenAttrValue *val;
+  struct TokenAttrValue *tmp_val;
+
+  for (attr = token->attr_head; NULL != attr;)
+  {
+    tmp_attr = attr->next;
+    GNUNET_CONTAINER_DLL_remove (token->attr_head,
+                                 token->attr_tail,
+                                 attr);
+    for (val = attr->val_head; NULL != val;)
+    {
+      tmp_val = val->next;
+      GNUNET_CONTAINER_DLL_remove (attr->val_head,
+                                   attr->val_tail,
+                                   val);
+      if (NULL != val->value)
+        GNUNET_free (val->value);
+      GNUNET_free (val);
+      val = tmp_val;
+    }
+    GNUNET_free (attr->name);
+    GNUNET_free (attr);
+    attr = tmp_attr;
+  }
+
+  
   GNUNET_free (token);
 }
 
 void
-token_add_attr (const struct IdentityToken *token,
-                                         const char* key,
-                                         const char* value)
+token_add_attr (struct IdentityToken *token,
+                const char* key,
+                const char* value)
 {
+  struct TokenAttr *attr;
+  struct TokenAttrValue *new_val;
   GNUNET_assert (NULL != token);
-  GNUNET_assert (NULL != token->payload);
 
-  json_object_set_new (token->payload, key, json_string (value));
+  new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
+  new_val->value = GNUNET_strdup (value);
+  for (attr = token->attr_head; NULL != attr; attr = attr->next)
+  {
+    if (0 == strcmp (key, attr->name))
+      break;
+  }
+
+  if (NULL == attr)
+  {
+    attr = GNUNET_malloc (sizeof (struct TokenAttr));
+    attr->name = GNUNET_strdup (key);
+    GNUNET_CONTAINER_DLL_insert (token->attr_head,
+                                 token->attr_tail,
+                                 attr);
+  }
+
+  GNUNET_CONTAINER_DLL_insert (attr->val_head,
+                               attr->val_tail,
+                               new_val);
 }
 
 void
-token_add_json (const struct IdentityToken *token,
-                                         const char* key,
-                                         json_t* value)
+token_add_attr_int (struct IdentityToken *token,
+                    const char* key,
+                    uint64_t value)
 {
+  struct TokenAttr *attr;
+  struct TokenAttrValue *new_val;
   GNUNET_assert (NULL != token);
-  GNUNET_assert (NULL != token->payload);
 
-  json_object_set_new (token->payload, key, value);
+  new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
+  new_val->int_value = value;
+  for (attr = token->attr_head; NULL != attr; attr = attr->next)
+  {
+    if (0 == strcmp (key, attr->name))
+      break;
+  }
+
+  if (NULL == attr)
+  {
+    attr = GNUNET_malloc (sizeof (struct TokenAttr));
+    attr->name = GNUNET_strdup (key);
+    GNUNET_CONTAINER_DLL_insert (token->attr_head,
+                                 token->attr_tail,
+                                 attr);
+  }
+
+  GNUNET_CONTAINER_DLL_insert (attr->val_head,
+                               attr->val_tail,
+                               new_val);
 }
 
+static void
+parse_json_payload(const char* payload_base64,
+                   struct IdentityToken *token) 
+{
+  const char *key;
+  const json_t *value;
+  const json_t *arr_value;
+  char *payload;
+  int idx;
+  json_t *payload_json;
+  json_error_t err_json;
+
+  GNUNET_STRINGS_base64_decode (payload_base64,
+                                strlen (payload_base64),
+                                &payload);
+  //TODO signature and aud key
+  payload_json = json_loads (payload, JSON_DECODE_ANY, &err_json);
+
+  json_object_foreach (payload_json, key, value)
+  {
+    if (json_is_array (value))
+    {
+      json_array_foreach (value, idx, arr_value)
+      {
+        if (json_is_integer (arr_value))
+          token_add_attr_int (token, key,
+                              json_integer_value (arr_value));
+        else
+          token_add_attr (token,
+                          key,
+                          json_string_value (arr_value));
+      }
+    } else {
+      if (json_is_integer (value))
+        token_add_attr_int (token, key,
+                            json_integer_value (value));
+      else
+        token_add_attr (token, key, json_string_value (value));
+    }
+  }
+
+  json_decref (payload_json);
+  GNUNET_free (payload);
+}
 
 int
 token_parse2 (const char* raw_data,
-                                       const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
-                                       const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
-                                       struct IdentityToken **result)
+              const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
+              const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
+              struct IdentityToken **result)
 {
   char *enc_token_str;
   char *tmp_buf;
   char *token_str;
   char *enc_token;
-  char *header;
-  char *header_base64;
-  char *payload;
   char *payload_base64;
   size_t enc_token_len;
-  json_error_t err_json;
 
   GNUNET_asprintf (&tmp_buf, "%s", raw_data);
   strtok (tmp_buf, ",");
@@ -288,46 +390,31 @@ token_parse2 (const char* raw_data,
     return GNUNET_SYSERR;
   }
 
-  header_base64 = strtok (token_str, ".");
+  GNUNET_assert (NULL != strtok (token_str, "."));
   payload_base64 = strtok (NULL, ".");
 
-  GNUNET_STRINGS_base64_decode (header_base64,
-                                strlen (header_base64),
-                                &header);
-  GNUNET_STRINGS_base64_decode (payload_base64,
-                                strlen (payload_base64),
-                                &payload);
-  //TODO signature
-
-
   *result = GNUNET_malloc (sizeof (struct IdentityToken));
+  parse_json_payload (payload_base64, *result);
+
   (*result)->aud_key =  *aud_key;
-  (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json);
-  (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json);
   GNUNET_free (enc_token);
   GNUNET_free (token_str);
   GNUNET_free (tmp_buf);
-  GNUNET_free (payload);
-  GNUNET_free (header);
   return GNUNET_OK;
 }
 
 int
 token_parse (const char* raw_data,
-                                      const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                                      struct IdentityToken **result)
+             const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+             struct IdentityToken **result)
 {
   char *ecdh_pubkey_str;
   char *enc_token_str;
   char *tmp_buf;
   char *token_str;
   char *enc_token;
-  char *header;
-  char *header_base64;
-  char *payload;
   char *payload_base64;
   size_t enc_token_len;
-  json_error_t err_json;
   struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
 
   GNUNET_asprintf (&tmp_buf, "%s", raw_data);
@@ -352,33 +439,67 @@ token_parse (const char* raw_data,
     return GNUNET_SYSERR;
   }
 
-  header_base64 = strtok (token_str, ".");
+  GNUNET_assert (NULL != strtok (token_str, "."));
   payload_base64 = strtok (NULL, ".");
 
-  GNUNET_STRINGS_base64_decode (header_base64,
-                                strlen (header_base64),
-                                &header);
-  GNUNET_STRINGS_base64_decode (payload_base64,
-                                strlen (payload_base64),
-                                &payload);
-  //TODO signature and aud key
-
-
   *result = GNUNET_malloc (sizeof (struct IdentityToken));
-  (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json);
-  (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json);
+  parse_json_payload (payload_base64, *result);
+
   GNUNET_free (enc_token);
   GNUNET_free (token_str);
   GNUNET_free (tmp_buf);
-  GNUNET_free (payload);
-  GNUNET_free (header);
   return GNUNET_OK;
 }
 
+static char*
+create_json_payload (const struct IdentityToken *token)
+{
+  struct TokenAttr *attr;
+  struct TokenAttrValue *val;
+  json_t *root;
+  char *json_str;
+
+  root = json_object();
+  for (attr = token->attr_head; NULL != attr; attr = attr->next)
+  {
+    for (val = attr->val_head; NULL != val; val = val->next)
+    {
+      if (NULL != val->value)
+      {
+        json_object_set_new (root,
+                             attr->name,
+                             json_string (val->value)); 
+      } else {
+        json_object_set_new (root,
+                             attr->name,
+                             json_integer (val->int_value));
+      }
+    }
+  }
+  json_str = json_dumps (root, JSON_INDENT(1));
+  json_decref (root);
+  return json_str;
+}
+
+static char*
+create_json_header(void)
+{
+  json_t *root;
+  char *json_str;
+
+  root = json_object ();
+  json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
+  json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
+
+  json_str = json_dumps (root, JSON_INDENT(1));
+  json_decref (root);
+  return json_str;
+}
+
 int
 token_to_string (const struct IdentityToken *token,
-                                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                                          char **result)
+                 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                 char **result)
 {
   char *payload_str;
   char *header_str;
@@ -388,7 +509,7 @@ token_to_string (const struct IdentityToken *token,
   char *signature_target;
   char *signature_str;
   struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
-  header_str = json_dumps (token->header, JSON_COMPACT);
+  header_str = create_json_header();
   GNUNET_STRINGS_base64_encode (header_str,
                                 strlen (header_str),
                                 &header_base64);
@@ -397,7 +518,7 @@ token_to_string (const struct IdentityToken *token,
   while (NULL != padding)
     padding = strtok(NULL, "=");
 
-  payload_str = json_dumps (token->payload, JSON_COMPACT);
+  payload_str = create_json_payload (token);
   GNUNET_STRINGS_base64_encode (payload_str,
                                 strlen (payload_str),
                                 &payload_base64);
@@ -421,9 +542,7 @@ token_to_string (const struct IdentityToken *token,
   {
     GNUNET_free (signature_target);
     GNUNET_free (payload_str);
-    GNUNET_free (header_str);
     GNUNET_free (payload_base64);
-    GNUNET_free (header_base64);
     GNUNET_free (purpose);
     return GNUNET_SYSERR;
   }
@@ -445,9 +564,9 @@ token_to_string (const struct IdentityToken *token,
 
 int
 token_serialize (const struct IdentityToken *token,
-                                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                                          struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
-                                          char **result)
+                 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
+                 char **result)
 {
   char *token_str;
   char *enc_token;
@@ -456,8 +575,8 @@ token_serialize (const struct IdentityToken *token,
   struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
 
   GNUNET_assert (GNUNET_OK == token_to_string (token,
-                                                                        priv_key,
-                                                                        &token_str));
+                                               priv_key,
+                                               &token_str));
 
   GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
                                                  &token->aud_key,
@@ -479,8 +598,8 @@ token_serialize (const struct IdentityToken *token,
 
 struct TokenTicketPayload*
 ticket_payload_create (const char* nonce,
-                                                const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
-                                                const char* lbl_str)
+                       const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
+                       const char* lbl_str)
 {
   struct TokenTicketPayload* payload;
 
@@ -494,14 +613,16 @@ ticket_payload_create (const char* nonce,
 void
 ticket_payload_destroy (struct TokenTicketPayload* payload)
 {
-  GNUNET_free (payload->nonce);
-  GNUNET_free (payload->label);
+  if (NULL != payload->nonce)
+    GNUNET_free (payload->nonce);
+  if (NULL != payload->label)
+    GNUNET_free (payload->label);
   GNUNET_free (payload);
 }
 
 void
 ticket_payload_serialize (struct TokenTicketPayload *payload,
-                                                   char **result)
+                          char **result)
 {
   char* identity_key_str;
 
@@ -525,17 +646,17 @@ ticket_payload_serialize (struct TokenTicketPayload *payload,
  */
 struct TokenTicket*
 ticket_create (const char* nonce_str,
-                                        const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
-                                        const char* lbl_str,
-                                        const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
+               const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
+               const char* lbl_str,
+               const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
 {
   struct TokenTicket *ticket;
   struct TokenTicketPayload *code_payload;
 
   ticket = GNUNET_malloc (sizeof (struct TokenTicket));
   code_payload = ticket_payload_create (nonce_str,
-                                                                 identity_pkey,
-                                                                 lbl_str);
+                                        identity_pkey,
+                                        lbl_str);
   ticket->aud_key = *aud_key;
   ticket->payload = code_payload;
 
@@ -552,8 +673,8 @@ ticket_destroy (struct TokenTicket *ticket)
 
 int
 ticket_serialize (struct TokenTicket *ticket,
-                                           const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                                           char **result)
+                  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                  char **result)
 {
   char *code_payload_str;
   char *enc_ticket_payload;
@@ -567,7 +688,7 @@ ticket_serialize (struct TokenTicket *ticket,
   struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
 
   ticket_payload_serialize (ticket->payload,
-                                                     &code_payload_str);
+                            &code_payload_str);
 
   GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
                                                  &ticket->aud_key,
@@ -594,7 +715,7 @@ ticket_serialize (struct TokenTicket *ticket,
   memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str));
   GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
                                                         purpose,
-                                                       &ticket->signature));
+                                                        &ticket->signature));
   GNUNET_STRINGS_base64_encode (enc_ticket_payload,
                                 strlen (code_payload_str),
                                 &ticket_payload_str);
@@ -603,7 +724,7 @@ ticket_serialize (struct TokenTicket *ticket,
 
   dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey,
                                                     sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
   GNUNET_asprintf (&ticket_str, "{\"meta\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}",
                    ticket_payload_str, dh_key_str, ticket_sig_str);
   GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result);
@@ -619,10 +740,10 @@ ticket_serialize (struct TokenTicket *ticket,
 
 int
 ticket_payload_parse(const char *raw_data,
-                                              ssize_t data_len,
-                                              const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                                              const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
-                                              struct TokenTicketPayload **result)
+                     ssize_t data_len,
+                     const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                     const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
+                     struct TokenTicketPayload **result)
 {
   const char* label_str;
   const char* nonce_str;
@@ -646,7 +767,7 @@ ticket_payload_parse(const char *raw_data,
     return GNUNET_SYSERR;
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata: %s\n", meta_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Metadata: %s\n", meta_str);
   root = json_loads (meta_str, JSON_DECODE_ANY, &err_json);
   if (!root)
   {
@@ -683,7 +804,7 @@ ticket_payload_parse(const char *raw_data,
   }
 
   label_str = json_string_value (label_json);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found label: %s\n", label_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str);
 
   nonce_json = json_object_get (root, "nonce");
   if (!json_is_string (label_json))
@@ -696,11 +817,11 @@ ticket_payload_parse(const char *raw_data,
   }
 
   nonce_str = json_string_value (nonce_json);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found nonce: %s\n", nonce_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str);
 
   *result = ticket_payload_create (nonce_str,
-                                                            (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
-                                                            label_str);
+                                   (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
+                                   label_str);
   GNUNET_free (meta_str);
   json_decref (root);
   return GNUNET_OK;
@@ -709,8 +830,8 @@ ticket_payload_parse(const char *raw_data,
 
 int
 ticket_parse (const char *raw_data,
-                                       const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                                       struct TokenTicket **result)
+              const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+              struct TokenTicket **result)
 {
   const char* enc_meta_str;
   const char* ecdh_enc_str;
@@ -731,7 +852,7 @@ ticket_parse (const char *raw_data,
 
   ticket_decoded = NULL;
   GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Token Code: %s\n", ticket_decoded);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded);
   root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json);
   if (!root)
   {
@@ -760,7 +881,7 @@ ticket_parse (const char *raw_data,
     GNUNET_free (ticket);
     return GNUNET_SYSERR;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s for metadata decryption\n", ecdh_enc_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for metadata decryption\n", ecdh_enc_str);
   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str,
                                                   strlen (signature_enc_str),
                                                   &ticket->signature,
@@ -778,11 +899,18 @@ ticket_parse (const char *raw_data,
                                                &enc_meta);
 
 
-  ticket_payload_parse (enc_meta,
-                                                 enc_meta_len,
-                                                 priv_key,
-                                                 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
-                                                 &ticket_payload);
+  if (GNUNET_OK != ticket_payload_parse (enc_meta,
+                                         enc_meta_len,
+                                         priv_key,
+                                         (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
+                                         &ticket_payload))
+  {
+    json_decref (root);
+    GNUNET_free (enc_meta);
+    GNUNET_free (ticket_decoded);
+    GNUNET_free (ticket);
+    return GNUNET_SYSERR;
+  }
 
   ticket->payload = ticket_payload;
   //TODO: check signature here
@@ -810,7 +938,7 @@ ticket_parse (const char *raw_data,
     json_decref (root);
     GNUNET_free (purpose);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Error verifying signature for token code\n");
+                "Error verifying signature for ticket\n");
     return GNUNET_SYSERR;
   }
   *result = ticket;