gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r36790 - gnunet/src/identity-token


From: gnunet
Subject: [GNUnet-SVN] r36790 - gnunet/src/identity-token
Date: Tue, 5 Jan 2016 18:06:07 +0100

Author: schanzen
Date: 2016-01-05 18:06:07 +0100 (Tue, 05 Jan 2016)
New Revision: 36790

Added:
   gnunet/src/identity-token/identity-token.c
   gnunet/src/identity-token/identity-token.h
Modified:
   gnunet/src/identity-token/Makefile.am
   gnunet/src/identity-token/plugin_rest_identity_token.c
Log:
- Refactor


Modified: gnunet/src/identity-token/Makefile.am
===================================================================
--- gnunet/src/identity-token/Makefile.am       2016-01-05 12:36:47 UTC (rev 
36789)
+++ gnunet/src/identity-token/Makefile.am       2016-01-05 17:06:07 UTC (rev 
36790)
@@ -42,7 +42,8 @@
  -ljansson
 
 libgnunet_plugin_rest_identity_token_la_SOURCES = \
-  plugin_rest_identity_token.c
+  plugin_rest_identity_token.c \
+       identity-token.c
 libgnunet_plugin_rest_identity_token_la_LIBADD = \
        $(top_builddir)/src/identity/libgnunetidentity.la \
        $(top_builddir)/src/rest/libgnunetrest.la \

Added: gnunet/src/identity-token/identity-token.c
===================================================================
--- gnunet/src/identity-token/identity-token.c                          (rev 0)
+++ gnunet/src/identity-token/identity-token.c  2016-01-05 17:06:07 UTC (rev 
36790)
@@ -0,0 +1,716 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2010-2015 Christian Grothoff (and other contributing 
authors)
+
+      GNUnet is free software; you can redistribute it and/or modify
+      it under the terms of the GNU General Public License as published
+      by the Free Software Foundation; either version 3, or (at your
+      option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      General Public License for more details.
+
+      You should have received a copy of the GNU General Public License
+      along with GNUnet; see the file COPYING.  If not, write to the
+      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file identity-token/identity-token.c
+ * @brief helper library to manage identity tokens
+ * @author Martin Schanzenbach
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_signatures.h"
+#include "identity-token.h"
+#include <jansson.h>
+
+
+/**
+ * Crypto helper functions
+ */
+
+static int
+create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
+                         struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
+                         struct GNUNET_CRYPTO_SymmetricInitializationVector 
*iv)
+{
+  struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
+
+  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);
+  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),
+                     ctx_key, strlen (ctx_key),
+                     NULL, 0);
+  static const char ctx_iv[] = "gnuid-aes-ctx-iv";
+  GNUNET_CRYPTO_kdf (iv, sizeof (struct 
GNUNET_CRYPTO_SymmetricInitializationVector),
+                     new_key_hash, sizeof (struct GNUNET_HashCode),
+                     ctx_iv, strlen (ctx_iv),
+                     NULL, 0);
+  return GNUNET_OK;
+}
+
+/**
+ * Decrypts metainfo part from a token code
+ */
+static int
+decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                   const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key,
+                   const char *enc_str,
+                   size_t enc_str_len,
+                   char **result_str)
+{
+  struct GNUNET_HashCode new_key_hash;
+  struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
+  struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
+
+  char *str_buf = GNUNET_malloc (enc_str_len);
+  size_t str_size;
+
+  //Calculate symmetric key from ecdh parameters
+  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key,
+                                                        ecdh_key,
+                                                        &new_key_hash));
+
+  create_sym_key_from_ecdh (&new_key_hash,
+                            &enc_key,
+                            &enc_iv);
+
+  str_size = GNUNET_CRYPTO_symmetric_decrypt (enc_str,
+                                              enc_str_len,
+                                              &enc_key,
+                                              &enc_iv,
+                                              str_buf);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decrypted bytes: %d Expected bytes: 
%d\n", str_size, enc_str_len);
+  if (-1 == str_size)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
+    return GNUNET_SYSERR;
+  }
+  *result_str = GNUNET_malloc (str_size+1);
+  memcpy (*result_str, str_buf, str_size);
+  (*result_str)[str_size] = '\0';
+  GNUNET_free (str_buf);
+  return GNUNET_OK;
+
+}
+
+/**
+ * Encrypt string using pubkey and ECDHE
+ * Returns ECDHE pubkey to be used for decryption
+ */
+static int
+encrypt_str_ecdhe (const char *data,
+                   const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
+                   char **enc_data_str,
+                   struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey)
+{
+  struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey;
+  struct GNUNET_CRYPTO_SymmetricSessionKey skey;
+  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
+  struct GNUNET_HashCode new_key_hash;
+  
+  // ECDH keypair E = eG
+  ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
+  GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_privkey,
+                                      ecdh_pubkey);
+
+  *enc_data_str = GNUNET_malloc (strlen (data));
+
+  // Derived key K = H(eB)
+  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
+                                                        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", data);
+  GNUNET_CRYPTO_symmetric_encrypt (data, strlen (data),
+                                   &skey, &iv,
+                                   *enc_data_str);
+  GNUNET_free (ecdh_privkey);
+  return GNUNET_OK;
+}
+
+
+
+
+/**
+ * Identity Token API
+ */
+
+
+/**
+ * Create an Identity Token
+ *
+ * @param type the JSON API resource type
+ * @param id the JSON API resource id
+ * @return a new JSON API resource or NULL on error.
+ */
+struct IdentityToken*
+identity_token_create (const char* issuer,
+                       const char* audience)
+{
+  struct IdentityToken *token;
+
+  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));
+
+  GNUNET_STRINGS_string_to_data  (audience,
+                                  strlen (audience),
+                                  &token->aud_key,
+                                  sizeof (struct 
GNUNET_CRYPTO_EcdsaPublicKey));
+
+  return token;
+}
+
+void
+identity_token_destroy (struct IdentityToken *token)
+{
+  json_decref (token->header);
+  json_decref (token->payload);
+  GNUNET_free (token);
+}
+
+void
+identity_token_add_attr (const struct IdentityToken *token,
+                         const char* key,
+                         const char* value)
+{
+  GNUNET_assert (NULL != token);
+  GNUNET_assert (NULL != token->payload);
+
+  json_object_set_new (token->payload, key, json_string (value));
+}
+
+void
+identity_token_add_json (const struct IdentityToken *token,
+                         const char* key,
+                         json_t* value)
+{
+  GNUNET_assert (NULL != token);
+  GNUNET_assert (NULL != token->payload);
+
+  json_object_set_new (token->payload, key, value);
+}
+
+
+int
+identity_token_parse (const char* raw_data,
+                      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);
+  ecdh_pubkey_str = strtok (tmp_buf, ",");
+  enc_token_str = strtok (NULL, ",");
+
+  GNUNET_STRINGS_string_to_data (ecdh_pubkey_str,
+                                 strlen (ecdh_pubkey_str),
+                                 &ecdh_pubkey,
+                                 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
+  enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
+                                                strlen (enc_token_str),
+                                                &enc_token);
+  if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
+                                      &ecdh_pubkey,
+                                      enc_token,
+                                      enc_token_len,
+                                      &token_str))
+  {
+    GNUNET_free (tmp_buf);
+    GNUNET_free (enc_token);
+    return GNUNET_SYSERR;
+  }
+
+  header_base64 = 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);
+  GNUNET_free (enc_token);
+  GNUNET_free (token_str);
+  GNUNET_free (tmp_buf);
+  GNUNET_free (payload);
+  GNUNET_free (header);
+  return GNUNET_OK;
+}
+
+int
+identity_token_to_string (const struct IdentityToken *token,
+                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                          char **result)
+{
+  char *payload_str;
+  char *header_str;
+  char *payload_base64;
+  char *header_base64;
+  char *padding;
+  char *signature_target;
+  char *signature_str;
+  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
+  header_str = json_dumps (token->header, JSON_COMPACT);
+  GNUNET_STRINGS_base64_encode (header_str,
+                                strlen (header_str),
+                                &header_base64);
+  //Remove GNUNET padding of base64
+  padding = strtok(header_base64, "=");
+  while (NULL != padding)
+    padding = strtok(NULL, "=");
+
+  payload_str = json_dumps (token->payload, JSON_COMPACT);
+  GNUNET_STRINGS_base64_encode (payload_str,
+                                strlen (payload_str),
+                                &payload_base64);
+
+  //Remove GNUNET padding of base64
+  padding = strtok(payload_base64, "=");
+  while (NULL != padding)
+    padding = strtok(NULL, "=");
+
+  GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64);
+  purpose =
+    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
+                   strlen (signature_target));
+  purpose->size =
+    htonl (strlen (signature_target) + sizeof (struct 
GNUNET_CRYPTO_EccSignaturePurpose));
+  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
+  memcpy (&purpose[1], signature_target, strlen (signature_target));
+  if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
+                                             purpose,
+                                             (struct 
GNUNET_CRYPTO_EcdsaSignature *)&token->signature))
+  {
+    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;
+  }
+
+  GNUNET_STRINGS_base64_encode ((const char*)&token->signature,
+                                sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
+                                &signature_str);
+  GNUNET_asprintf (result, "%s.%s.%s",
+                   header_base64, payload_base64, signature_str);
+  GNUNET_free (signature_target);
+  GNUNET_free (payload_str);
+  GNUNET_free (header_str);
+  GNUNET_free (signature_str);
+  GNUNET_free (payload_base64);
+  GNUNET_free (header_base64);
+  GNUNET_free (purpose);
+  return GNUNET_OK;
+}
+
+int
+identity_token_serialize (const struct IdentityToken *token,
+                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                          char **result)
+{
+  char *token_str;
+  char *enc_token;
+  char *dh_key_str;
+  char *enc_token_base64;
+  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
+
+  GNUNET_assert (GNUNET_OK == identity_token_to_string (token,
+                                                        priv_key,
+                                                        &token_str));
+
+  GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
+                                                 &token->aud_key,
+                                                 &enc_token,
+                                                 &ecdh_pubkey));
+  GNUNET_STRINGS_base64_encode (enc_token,
+                                strlen (token_str),
+                                &enc_token_base64);
+  dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
+                                                    sizeof (struct 
GNUNET_CRYPTO_EcdhePublicKey));
+  GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64);
+  GNUNET_free (dh_key_str);
+  GNUNET_free (enc_token_base64);
+  GNUNET_free (enc_token);
+  GNUNET_free (token_str);
+  return GNUNET_OK;
+}
+
+struct IdentityTokenCodePayload*
+identity_token_code_payload_create (const char* nonce,
+                                    const struct GNUNET_CRYPTO_EcdsaPublicKey* 
identity_pkey,
+                                    const char* lbl_str)
+{
+  struct IdentityTokenCodePayload* payload;
+
+  payload = GNUNET_malloc (sizeof (struct IdentityTokenCodePayload));
+  GNUNET_asprintf (&payload->nonce, nonce, strlen (nonce));
+  payload->identity_key = *identity_pkey;
+  GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str));
+  return payload;
+}
+
+void
+identity_token_code_payload_destroy (struct IdentityTokenCodePayload* payload)
+{
+  GNUNET_free (payload->nonce);
+  GNUNET_free (payload->label);
+  GNUNET_free (payload);
+}
+
+void
+identity_token_code_payload_serialize (struct IdentityTokenCodePayload 
*payload,
+                                       char **result)
+{
+  char* identity_key_str;
+
+  identity_key_str = GNUNET_STRINGS_data_to_string_alloc 
(&payload->identity_key,
+                                                          sizeof (struct 
GNUNET_CRYPTO_EcdsaPublicKey));
+
+  GNUNET_asprintf (result, 
+                   "{\"nonce\": \"%u\",\"identity\": \"%s\",\"label\": 
\"%s\"}",
+                   payload->nonce, identity_key_str, payload->label);
+  GNUNET_free (identity_key_str);
+
+}
+
+
+/**
+ * Create the token code
+ * The metadata is encrypted with a share ECDH derived secret using B (aud_key)
+ * and e (ecdh_privkey)
+ * The token_code also contains E (ecdh_pubkey) and a signature over the
+ * metadata and E
+ */
+struct IdentityTokenCode*
+identity_token_code_create (const char* nonce_str,
+                            const struct GNUNET_CRYPTO_EcdsaPublicKey* 
identity_pkey,
+                            const char* lbl_str,
+                            const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
+{
+  struct IdentityTokenCode *token_code;
+  struct IdentityTokenCodePayload *code_payload;
+
+  token_code = GNUNET_malloc (sizeof (struct IdentityTokenCode));
+  code_payload = identity_token_code_payload_create (nonce_str,
+                                                     identity_pkey,
+                                                     lbl_str);
+  token_code->aud_key = *aud_key;
+  token_code->payload = code_payload;
+
+
+  return token_code;
+}
+
+void
+identity_token_code_destroy (struct IdentityTokenCode *token_code)
+{
+  identity_token_code_payload_destroy (token_code->payload);
+  GNUNET_free (token_code);
+}
+
+int
+identity_token_code_serialize (struct IdentityTokenCode *identity_token_code,
+                               const struct GNUNET_CRYPTO_EcdsaPrivateKey 
*priv_key,
+                               char **result)
+{
+  char *code_payload_str;
+  char *enc_token_code_payload;
+  char *token_code_payload_str;
+  char *token_code_sig_str;
+  char *token_code_str;
+  char *dh_key_str;
+  char *write_ptr;
+
+  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
+
+  identity_token_code_payload_serialize (identity_token_code->payload,
+                                         &code_payload_str);
+
+  GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
+                                                 &identity_token_code->aud_key,
+                                                 &enc_token_code_payload,
+                                                 
&identity_token_code->ecdh_pubkey));
+
+  purpose = 
+    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 
+                   sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
+                   strlen (code_payload_str)); // E_K (code_str)
+  purpose->size = 
+    htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
+           sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
+           strlen (code_payload_str));
+  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE);
+  write_ptr = (char*) &purpose[1];
+  memcpy (write_ptr,
+          &identity_token_code->ecdh_pubkey,
+          sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
+  write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
+  memcpy (write_ptr, enc_token_code_payload, strlen (code_payload_str));
+  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
+                                                        purpose,
+                                                        
&identity_token_code->signature));
+  GNUNET_STRINGS_base64_encode (enc_token_code_payload,
+                                strlen (code_payload_str),
+                                &token_code_payload_str);
+  token_code_sig_str = GNUNET_STRINGS_data_to_string_alloc 
(&identity_token_code->signature,
+                                                            sizeof (struct 
GNUNET_CRYPTO_EcdsaSignature));
+
+  dh_key_str = GNUNET_STRINGS_data_to_string_alloc 
(&identity_token_code->ecdh_pubkey,
+                                                    sizeof (struct 
GNUNET_CRYPTO_EcdhePublicKey));
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s to encrypt\n", 
dh_key_str);
+  GNUNET_asprintf (&token_code_str, "{\"meta\": \"%s\", \"ecdh\": \"%s\", 
\"signature\": \"%s\"}",
+                   token_code_payload_str, dh_key_str, token_code_sig_str);
+  GNUNET_STRINGS_base64_encode (token_code_str, strlen (token_code_str), 
result);
+  GNUNET_free (dh_key_str);
+  GNUNET_free (purpose);
+  GNUNET_free (token_code_str);
+  GNUNET_free (token_code_sig_str);
+  GNUNET_free (code_payload_str);
+  GNUNET_free (enc_token_code_payload);
+  GNUNET_free (token_code_payload_str);
+  return GNUNET_OK;
+}
+
+int
+identity_token_code_payload_parse(const char *raw_data,
+                                  const struct GNUNET_CRYPTO_EcdsaPrivateKey 
*priv_key,
+                                  const struct GNUNET_CRYPTO_EcdhePublicKey 
*ecdhe_pkey,
+                                  struct IdentityTokenCodePayload **result)
+{
+  const char* label_str;
+  const char* nonce_str;
+  const char* identity_key_str;
+
+  json_t *root;
+  json_t *label_json;
+  json_t *identity_json;
+  json_t *nonce_json;
+  json_error_t err_json;
+  char* meta_str;
+  struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey;
+
+  if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
+                                      ecdhe_pkey,
+                                      raw_data,
+                                      strlen (raw_data),
+                                      &meta_str))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata decryption failed\n");
+    return GNUNET_SYSERR;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata: %s\n", meta_str);
+  root = json_loads (meta_str, JSON_DECODE_ANY, &err_json);
+  if (!root)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error parsing metadata: %s\n", err_json.text);
+    GNUNET_free (meta_str);
+    return GNUNET_SYSERR;
+  }
+
+  identity_json = json_object_get (root, "identity");
+  if (!json_is_string (identity_json))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error parsing metadata: %s\n", err_json.text);
+    json_decref (root);
+    GNUNET_free (meta_str);
+    return GNUNET_SYSERR;
+  }
+  identity_key_str = json_string_value (identity_json);
+  GNUNET_STRINGS_string_to_data (identity_key_str,
+                                 strlen (identity_key_str),
+                                 &id_pkey,
+                                 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+
+
+  label_json = json_object_get (root, "label");
+  if (!json_is_string (label_json))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error parsing metadata: %s\n", err_json.text);
+    json_decref (root);
+    GNUNET_free (meta_str);
+    return GNUNET_SYSERR;
+  }
+
+  label_str = json_string_value (label_json);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found label: %s\n", label_str);
+
+  nonce_json = json_object_get (root, "nonce");
+  if (!json_is_string (label_json))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error parsing metadata: %s\n", err_json.text);
+    json_decref (root);
+    GNUNET_free (meta_str);
+    return GNUNET_SYSERR;
+  }
+
+  nonce_str = json_string_value (nonce_json);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found nonce: %s\n", nonce_str);
+
+  *result = identity_token_code_payload_create (nonce_str,
+                                                (const struct 
GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
+                                                label_str);
+  GNUNET_free (meta_str);
+  json_decref (root);
+  return GNUNET_OK;
+
+}
+
+int
+identity_token_code_parse (const char *raw_data,
+                           const struct GNUNET_CRYPTO_EcdsaPrivateKey 
*priv_key,
+                           struct IdentityTokenCode **result)
+{
+  const char* enc_meta_str;
+  const char* ecdh_enc_str;
+  const char* signature_enc_str;
+
+  json_t *root;
+  json_t *signature_json;
+  json_t *ecdh_json;
+  json_t *enc_meta_json;
+  json_error_t err_json;
+  char* enc_meta;
+  char* token_code_decoded;
+  char* write_ptr;
+  size_t enc_meta_len;
+  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
+  struct IdentityTokenCode *token_code;
+  struct IdentityTokenCodePayload *token_code_payload;
+
+  token_code_decoded = NULL;
+  GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), 
&token_code_decoded);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Token Code: %s\n", token_code_decoded);
+  root = json_loads (token_code_decoded, JSON_DECODE_ANY, &err_json);
+  if (!root)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "%s\n", err_json.text);
+    return GNUNET_SYSERR;
+  }
+
+  signature_json = json_object_get (root, "signature");
+  ecdh_json = json_object_get (root, "ecdh");
+  enc_meta_json = json_object_get (root, "meta");
+
+  signature_enc_str = json_string_value (signature_json);
+  ecdh_enc_str = json_string_value (ecdh_json);
+  enc_meta_str = json_string_value (enc_meta_json);
+
+  token_code = GNUNET_malloc (sizeof (struct IdentityTokenCode));
+
+  if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
+                                                  strlen (ecdh_enc_str),
+                                                  &token_code->ecdh_pubkey,
+                                                  sizeof  (struct 
GNUNET_CRYPTO_EcdhePublicKey)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in metadata\n", 
ecdh_enc_str);
+    json_decref (root);
+    GNUNET_free (token_code);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "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),
+                                                  &token_code->signature,
+                                                  sizeof (struct 
GNUNET_CRYPTO_EcdsaSignature)))
+  {
+    json_decref (root);
+    GNUNET_free (token_code_decoded);
+    GNUNET_free (token_code);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in 
metadata\n");
+    return GNUNET_SYSERR;
+  }
+
+  enc_meta_len = GNUNET_STRINGS_base64_decode (enc_meta_str,
+                                               strlen (enc_meta_str),
+                                               &enc_meta);
+
+
+  identity_token_code_payload_parse (enc_meta,
+                                     priv_key,
+                                     (const struct 
GNUNET_CRYPTO_EcdhePublicKey*)&token_code->ecdh_pubkey,
+                                     &token_code_payload);
+
+  token_code->payload = token_code_payload;
+  //TODO: check signature here
+  purpose = 
+    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 
+                   sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
+                   enc_meta_len); // E_K (code_str)
+  purpose->size = 
+    htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
+           sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
+           enc_meta_len);
+  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE);
+  write_ptr = (char*) &purpose[1];
+  memcpy (write_ptr, &token_code->ecdh_pubkey, sizeof (struct 
GNUNET_CRYPTO_EcdhePublicKey));
+  write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
+  memcpy (write_ptr, enc_meta, enc_meta_len);
+
+  if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify 
(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE,
+                                               purpose,
+                                               &token_code->signature,
+                                               
&token_code_payload->identity_key))
+  {
+    identity_token_code_destroy (token_code);
+    GNUNET_free (token_code_decoded);
+    json_decref (root);
+    GNUNET_free (purpose);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error verifying signature for token code\n");
+    return GNUNET_SYSERR;
+  }
+  *result = token_code;
+  GNUNET_free (purpose);
+
+  GNUNET_free (enc_meta);
+  GNUNET_free (token_code_decoded);
+  json_decref (root);
+  return GNUNET_OK;
+
+}
+
+
+
+/* end of identity-token.c */

Added: gnunet/src/identity-token/identity-token.h
===================================================================
--- gnunet/src/identity-token/identity-token.h                          (rev 0)
+++ gnunet/src/identity-token/identity-token.h  2016-01-05 17:06:07 UTC (rev 
36790)
@@ -0,0 +1,128 @@
+
+#ifndef GNUNET_IDENTITY_TOKEN_H
+#define GNUNET_IDENTITY_TOKEN_H
+
+
+
+#include "gnunet_crypto_lib.h"
+#include <jansson.h>
+
+struct IdentityToken
+{
+  /**
+   * JSON header
+   */
+  json_t *header;
+
+  /**
+   * JSON Payload
+   */
+  json_t *payload;
+
+  /**
+   * Token Signature
+   */
+  struct GNUNET_CRYPTO_EcdsaSignature signature;
+  
+  /**
+   * Audience Pubkey
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
+};
+
+struct IdentityTokenCodePayload
+{
+  /**
+   * Nonce
+   */
+  char* nonce;
+
+  /**
+   * Label
+   */
+  char *label;
+
+  /**
+   * Issuing Identity
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey identity_key;
+};
+
+
+struct IdentityTokenCode
+{
+  /**
+   * Meta info
+   */
+  struct IdentityTokenCodePayload *payload;
+
+  /**
+   * ECDH Pubkey
+   */
+  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
+
+  /**
+   * Signature
+   */
+  struct GNUNET_CRYPTO_EcdsaSignature signature;
+
+  /**
+   * Target identity
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
+};
+
+
+
+struct IdentityToken*
+identity_token_create (const char* issuer,
+                       const char* audience);
+
+void
+identity_token_destroy (struct IdentityToken *token);
+
+void
+identity_token_add_attr (const struct IdentityToken *token,
+                         const char* key,
+                         const char* value);
+void
+identity_token_add_json (const struct IdentityToken *token,
+                         const char* key,
+                         json_t* value);
+
+int 
+identity_token_serialize (const struct IdentityToken *token,
+                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                          char **result);
+
+int
+identity_token_parse (const char* raw_data,
+                      const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                      struct IdentityToken **result);
+
+int
+identity_token_to_string (const struct IdentityToken *token,
+                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+                          char **result);
+
+struct IdentityTokenCode*
+identity_token_code_create (const char* nonce_str,
+                            const struct GNUNET_CRYPTO_EcdsaPublicKey* 
identity_pkey,
+                            const char* lbl_str,
+                            const struct GNUNET_CRYPTO_EcdsaPublicKey 
*aud_key);
+
+int
+identity_token_code_serialize (struct IdentityTokenCode *identity_token_code,
+                               const struct GNUNET_CRYPTO_EcdsaPrivateKey 
*priv_key,
+                               char **result);
+
+void
+identity_token_code_destroy (struct IdentityTokenCode *token_code);
+
+
+int
+identity_token_code_parse (const char* raw_data,
+                           const struct GNUNET_CRYPTO_EcdsaPrivateKey 
*priv_key,
+                           struct IdentityTokenCode **result);
+
+#endif

Modified: gnunet/src/identity-token/plugin_rest_identity_token.c
===================================================================
--- gnunet/src/identity-token/plugin_rest_identity_token.c      2016-01-05 
12:36:47 UTC (rev 36789)
+++ gnunet/src/identity-token/plugin_rest_identity_token.c      2016-01-05 
17:06:07 UTC (rev 36790)
@@ -34,6 +34,7 @@
 #include "microhttpd.h"
 #include <jansson.h>
 #include "gnunet_signatures.h"
+#include "identity-token.h"
 
 /**
  * REST root namespace
@@ -287,14 +288,14 @@
   char *emsg;
 
   /**
-   * JSON header
+   * Identity Token
    */
-  json_t *header;
+  struct IdentityToken *token;
 
   /**
-   * JSON payload
+   * Identity Token Code
    */
-  json_t *payload;
+  struct IdentityTokenCode *token_code;
 
   /**
    * Response object
@@ -339,7 +340,10 @@
     GNUNET_NAMESTORE_disconnect (handle->ns_handle);
   if (NULL != handle->attr_map)
     GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
-
+  if (NULL != handle->token)
+    identity_token_destroy (handle->token);
+  if (NULL != handle->token_code)
+    identity_token_code_destroy (handle->token_code);
   if (NULL != handle->url)
     GNUNET_free (handle->url);
   if (NULL != handle->emsg)
@@ -419,146 +423,14 @@
   GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle);
 }
 
-static int
-create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
-                         struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
-                         struct GNUNET_CRYPTO_SymmetricInitializationVector 
*iv)
-{
-  struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
 
-  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);
-  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),
-                     ctx_key, strlen (ctx_key),
-                     NULL, 0);
-  static const char ctx_iv[] = "gnuid-aes-ctx-iv";
-  GNUNET_CRYPTO_kdf (iv, sizeof (struct 
GNUNET_CRYPTO_SymmetricInitializationVector),
-                     new_key_hash, sizeof (struct GNUNET_HashCode),
-                     ctx_iv, strlen (ctx_iv),
-                     NULL, 0);
-  return GNUNET_OK;
-}
 
 
-/**
- * Encrypt string using pubkey and ECDHE
- * Returns ECDHE pubkey to be used for decryption
- */
-static int
-encrypt_str_ecdhe (const char *data,
-                   const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
-                   char **enc_data_str,
-                   struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey)
-{
-  struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey;
-  struct GNUNET_CRYPTO_SymmetricSessionKey skey;
-  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
-  struct GNUNET_HashCode new_key_hash;
-  
-  // ECDH keypair E = eG
-  ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
-  GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_privkey,
-                                      ecdh_pubkey);
 
-  *enc_data_str = GNUNET_malloc (strlen (data));
 
-  // Derived key K = H(eB)
-  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
-                                                        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", data);
-  GNUNET_CRYPTO_symmetric_encrypt (data, strlen (data),
-                                   &skey, &iv,
-                                   *enc_data_str);
-  GNUNET_free (ecdh_privkey);
-  return GNUNET_OK;
-}
 
 
-/**
- * Create the token code
- * The metadata is encrypted with a share ECDH derived secret using B (aud_key)
- * and e (ecdh_privkey)
- * The token_code also contains E (ecdh_pubkey) and a signature over the
- * metadata and E
- */
-static int 
-create_token_code (const char* nonce_str,
-                   const char* identity_pkey_str,
-                   const char* lbl_str,
-                   const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                   const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
-                   char **token_code_str)
-{
-  char *write_ptr;
-  char *code_meta_str;
-  char *token_code_sig_str;
-  char *token_code_payload_str;
-  char *token_code_payload;
-  char *dh_key_str;
-  char *param_str;
-  struct GNUNET_CRYPTO_EcdsaSignature sig;
-  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
-  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
 
-  GNUNET_asprintf (&code_meta_str, 
-                   "{\"nonce\": \"%u\",\"identity\": \"%s\",\"label\": 
\"%s\"}",
-                   nonce_str, identity_pkey_str, lbl_str);
-
-  token_code_payload = NULL;
-  GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_meta_str,
-                                                 aud_key,
-                                                 &token_code_payload,
-                                                 &ecdh_pubkey));
-
-  purpose = 
-    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 
-                   sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
-                   strlen (code_meta_str)); // E_K (code_str)
-  purpose->size = 
-    htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
-           sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
-           strlen (code_meta_str));
-  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE);
-  write_ptr = (char*) &purpose[1];
-  memcpy (write_ptr, &ecdh_pubkey, sizeof (struct 
GNUNET_CRYPTO_EcdhePublicKey));
-  write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
-  memcpy (write_ptr, token_code_payload, strlen (code_meta_str));
-  if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
-                                             purpose,
-                                             &sig))
-  {
-    GNUNET_free (purpose);
-    return GNUNET_SYSERR;
-  }
-  
-  GNUNET_STRINGS_base64_encode (token_code_payload,
-                                strlen (code_meta_str),
-                                &token_code_payload_str);
-  token_code_sig_str = GNUNET_STRINGS_data_to_string_alloc (&sig,
-                                                            sizeof (struct 
GNUNET_CRYPTO_EcdsaSignature));
-  dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
-                                                    sizeof (struct 
GNUNET_CRYPTO_EcdhePublicKey));
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s to encrypt\n", 
dh_key_str);
-  GNUNET_asprintf (&param_str, "{\"meta\": \"%s\", \"ecdh\": \"%s\", 
\"signature\": \"%s\"}",
-                   token_code_payload_str, dh_key_str, token_code_sig_str);
-  GNUNET_STRINGS_base64_encode (param_str, strlen (param_str), token_code_str);
-  GNUNET_free (dh_key_str);
-  GNUNET_free (purpose);
-  GNUNET_free (code_meta_str);
-  GNUNET_free (token_code_sig_str);
-  GNUNET_free (param_str);
-  GNUNET_free (token_code_payload);
-  GNUNET_free (token_code_payload_str);
-  return GNUNET_OK;
-}
-
-
-
 /**
  * Build a GNUid token for identity
  * @param handle the handle
@@ -573,10 +445,8 @@
                        const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
-  struct GNUNET_CRYPTO_EcdsaSignature token_sig;
+  struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
   struct GNUNET_CRYPTO_EcdsaPublicKey aud_pkey;
-  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
-  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
   struct JsonApiResource *json_resource;
   struct RequestHandle *handle = cls;
   struct GNUNET_GNSRECORD_Data token_record;
@@ -585,20 +455,11 @@
   json_t *token_str;
   json_t *name_str;
   json_t *token_code_json;
-  char *header_str;
-  char *payload_str;
-  char *header_base64;
-  char *payload_base64;
-  char *sig_str;
   char *lbl_str;
-  char *token;
   char *exp_str;
   char *token_code_str;
   char *audience;
   char *nonce_str;
-  char *record_data;
-  char *dh_key_str;
-  char *enc_token;
   char *enc_token_str;
   uint64_t time;
   uint64_t exp_time;
@@ -651,12 +512,17 @@
   rnd_key = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, 
UINT64_MAX);
   GNUNET_STRINGS_base64_encode ((char*)&rnd_key, sizeof (uint64_t), &lbl_str);
   priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
-  if (GNUNET_OK != create_token_code (nonce_str,
-                                      handle->ego_entry->keystring,
-                                      lbl_str,
-                                      priv_key,                                
   
-                                      &aud_pkey,
-                                      &token_code_str))
+  GNUNET_CRYPTO_ecdsa_key_get_public (priv_key,
+                                      &pub_key);
+
+  handle->token_code = identity_token_code_create (nonce_str,
+                                                   &pub_key,
+                                                   lbl_str,
+                                                   &aud_pkey);
+
+  if (GNUNET_OK != identity_token_code_serialize (handle->token_code,
+                                                  priv_key,
+                                                  &token_code_str))
   {
     handle->emsg = GNUNET_strdup ("Unable to create ref token!\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
@@ -692,66 +558,17 @@
   exp_time = time + etime_rel.rel_value_us;
 
   //json_object_set_new (handle->payload, "lbl", json_string (lbl_str));
-  json_object_set_new (handle->payload, "sub", json_string 
(handle->ego_entry->identifier));
-  json_object_set_new (handle->payload, "nbf", json_integer (time));
-  json_object_set_new (handle->payload, "iat", json_integer (time));
-  json_object_set_new (handle->payload, "exp", json_integer (exp_time));
-  json_object_set_new (handle->payload, "nonce",
-                       json_string (nonce_str));
+  identity_token_add_attr (handle->token, "sub", 
handle->ego_entry->identifier);
+  identity_token_add_json (handle->token, "nbf", json_integer (time));
+  identity_token_add_json (handle->token, "iat", json_integer (time));
+  identity_token_add_json (handle->token, "exp", json_integer (exp_time));
+  identity_token_add_attr (handle->token, "nonce", nonce_str);
 
-  header_str = json_dumps (handle->header, JSON_COMPACT);
-  GNUNET_STRINGS_base64_encode (header_str,
-                                strlen (header_str),
-                                &header_base64);
-  char* padding = strtok(header_base64, "=");
-  while (NULL != padding)
-    padding = strtok(NULL, "=");
+  GNUNET_assert (identity_token_serialize (handle->token,
+                                           priv_key,
+                                           &enc_token_str));
 
-  payload_str = json_dumps (handle->payload, JSON_COMPACT);
-  GNUNET_STRINGS_base64_encode (payload_str,
-                                strlen (payload_str),
-                                &payload_base64);
-  padding = strtok(payload_base64, "=");
-  while (NULL != padding)
-    padding = strtok(NULL, "=");
 
-  GNUNET_asprintf (&token, "%s,%s", header_base64, payload_base64);
-  purpose = 
-    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 
-                   strlen (token));
-  purpose->size = 
-    htonl (strlen (token) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
-  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
-  memcpy (&purpose[1], token, strlen (token));
-  if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
-                                             purpose,
-                                             &token_sig))
-    GNUNET_break(0);
-  GNUNET_free (token);
-  GNUNET_STRINGS_base64_encode ((const char*)&token_sig,
-                                sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
-                                &sig_str);
-  GNUNET_asprintf (&token, "%s.%s.%s",
-                   header_base64, payload_base64, sig_str);
-  GNUNET_free (sig_str);
-  GNUNET_free (header_str);
-  GNUNET_free (header_base64);
-  GNUNET_free (payload_str);
-  GNUNET_free (payload_base64);
-  GNUNET_free (purpose);
-  json_decref (handle->header);
-  json_decref (handle->payload);
-
-
-  GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token,
-                                                 &aud_pkey,
-                                                 &enc_token,
-                                                 &ecdh_pubkey));
-  GNUNET_STRINGS_base64_encode (enc_token,
-                                strlen (token),
-                                &enc_token_str);
-  dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
-                                                    sizeof (struct 
GNUNET_CRYPTO_EcdhePublicKey));
   handle->resp_object = GNUNET_REST_jsonapi_object_new ();
 
   json_resource = GNUNET_REST_jsonapi_resource_new 
(GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
@@ -761,9 +578,6 @@
                                          
GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
                                          name_str);
   json_decref (name_str);
-
-
-
   token_str = json_string (enc_token_str);
   GNUNET_REST_jsonapi_resource_add_attr (json_resource,                        
                 
                                          GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
@@ -775,9 +589,8 @@
   GNUNET_free (token_code_str);
   json_decref (token_code_json);
   GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
-  GNUNET_asprintf (&record_data, "%s,%s", dh_key_str, enc_token_str);
-  token_record.data = record_data;
-  token_record.data_size = strlen (record_data) + 1;
+  token_record.data = enc_token_str;
+  token_record.data_size = strlen (enc_token_str) + 1;
   token_record.expiration_time = exp_time;
   token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
   token_record.flags = GNUNET_GNSRECORD_RF_NONE;
@@ -789,11 +602,7 @@
                                                   &token_record,
                                                   &store_token_cont,
                                                   handle);
-  GNUNET_free (record_data);
   GNUNET_free (lbl_str);
-  GNUNET_free (token);
-  GNUNET_free (dh_key_str);
-  GNUNET_free (enc_token);
   GNUNET_free (enc_token_str);
   json_decref (token_str);
 }
@@ -848,7 +657,7 @@
                                                rd->data,
                                                rd->data_size);
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
-      json_object_set_new (handle->payload, label, json_string (data));
+      identity_token_add_attr (handle->token, label, data);
       GNUNET_free (data);
     }
     GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
@@ -872,7 +681,7 @@
 
   if (0 < json_array_size (attr_arr))
   {
-    json_object_set (handle->payload, label, attr_arr);
+    identity_token_add_json (handle->token, label, attr_arr);
   }
   json_decref (attr_arr);
   GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
@@ -964,13 +773,9 @@
   audience = GNUNET_CONTAINER_multihashmap_get 
(handle->conndata_handle->url_param_map,
                                                 &key);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience to issue token for: %s\n", 
audience);
-  handle->header = json_object ();
-  json_object_set_new (handle->header, "alg", json_string ("ED512"));
-  json_object_set_new (handle->header, "typ", json_string ("JWT"));
 
-  handle->payload = json_object ();
-  json_object_set_new (handle->payload, "iss", json_string 
(ego_entry->keystring));
-  json_object_set_new (handle->payload, "aud", json_string (audience));
+  handle->token = identity_token_create (ego_entry->keystring,
+                                         audience);
 
 
   //Get identity attributes
@@ -1150,52 +955,9 @@
 
 }
 
-/**
- * Decrypts metainfo part from a token code
- */
-static int
-decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
-                   const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key,
-                   const char *enc_str,
-                   size_t enc_str_len,
-                   char **result_str)
-{
-  struct GNUNET_HashCode new_key_hash;
-  struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
-  struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
 
-  char *str_buf = GNUNET_malloc (enc_str_len);
-  size_t str_size;
 
-  //Calculate symmetric key from ecdh parameters
-  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key,
-                                                        ecdh_key,
-                                                        &new_key_hash));
 
-  create_sym_key_from_ecdh (&new_key_hash,
-                            &enc_key,
-                            &enc_iv);
-
-  str_size = GNUNET_CRYPTO_symmetric_decrypt (enc_str,
-                                              enc_str_len,
-                                              &enc_key,
-                                              &enc_iv,
-                                              str_buf);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decrypted bytes: %d Expected bytes: 
%d\n", str_size, enc_str_len);
-  if (-1 == str_size)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
-    return GNUNET_SYSERR;
-  }
-  *result_str = GNUNET_malloc (str_size+1);
-  memcpy (*result_str, str_buf, str_size);
-  (*result_str)[str_size] = '\0';
-  GNUNET_free (str_buf);
-  return GNUNET_OK;
-
-}
-
-
 static void
 process_lookup_result (void *cls, uint32_t rd_count,
                        const struct GNUNET_GNSRECORD_Data *rd)
@@ -1205,12 +967,7 @@
   struct MHD_Response *resp;
   char *result;
   char* token_str;
-  char* ecdh_pubkey_str;
-  char* enc_token;
-  char* enc_token_str;
   char* record_str;
-  size_t enc_token_len;
-  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
 
   handle->lookup_request = NULL;
   if (1 != rd_count)
@@ -1228,27 +985,19 @@
     GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN,
                                       rd->data,
                                       rd->data_size);
+  
+  //Decrypt and parse
+  GNUNET_assert (GNUNET_OK ==  identity_token_parse (record_str,
+                                                     handle->priv_key,
+                                                     &handle->token));
+  
+  //Readable
+  GNUNET_assert (GNUNET_OK == identity_token_to_string (handle->token,
+                                                        handle->priv_key,
+                                                        &token_str));
 
-  ecdh_pubkey_str = strtok (record_str, ",");
-  enc_token_str = strtok (NULL, ",");
-
-  GNUNET_STRINGS_string_to_data (ecdh_pubkey_str,
-                                 strlen (ecdh_pubkey_str),
-                                 &ecdh_pubkey,
-                                 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
-  enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
-                                                strlen (enc_token_str),
-                                                &enc_token);
-
-  GNUNET_assert (GNUNET_OK == decrypt_str_ecdhe ( handle->priv_key,
-                                                  &ecdh_pubkey,
-                                                  enc_token,
-                                                  enc_token_len,
-                                                  &token_str));
-
   json_object_set_new (root, "access_token", json_string (token_str));
   json_object_set_new (root, "token_type", json_string ("gnuid"));
-  GNUNET_free (enc_token);
   GNUNET_free (token_str);
   GNUNET_free (record_str);
 
@@ -1262,167 +1011,6 @@
 }
 
 
-static int
-extract_values_from_token_code (const char *token_code,
-                                const struct GNUNET_CRYPTO_EcdsaPrivateKey 
*priv_key,
-                                struct GNUNET_CRYPTO_EcdsaSignature *signature,
-                                struct GNUNET_CRYPTO_EcdhePublicKey 
*ecdhe_pkey,
-                                char **label,
-                                struct GNUNET_CRYPTO_EcdsaPublicKey *id_pkey)
-{
-  const char* enc_meta_str;
-  const char* ecdh_enc_str;
-  const char* signature_enc_str;
-  const char* label_str;
-  const char* identity_key_str;
-
-  json_t *root;
-  json_t *signature_json;
-  json_t *ecdh_json;
-  json_t *enc_meta_json;
-  json_t *label_json;
-  json_t *identity_json;
-  json_error_t err_json;
-  char* enc_meta;
-  char* meta_str;
-  char* token_code_decoded;
-  char* write_ptr;
-  size_t enc_meta_len;
-  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
-
-  GNUNET_STRINGS_base64_decode (token_code, strlen (token_code), 
&token_code_decoded);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Token Code: %s\n", token_code_decoded);
-  root = json_loads (token_code_decoded, JSON_DECODE_ANY, &err_json);
-  if (!root)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "%s\n", err_json.text);
-    return GNUNET_SYSERR;
-  }
-
-  signature_json = json_object_get (root, "signature");
-  ecdh_json = json_object_get (root, "ecdh");
-  enc_meta_json = json_object_get (root, "meta");
-
-  signature_enc_str = json_string_value (signature_json);
-  ecdh_enc_str = json_string_value (ecdh_json);
-  enc_meta_str = json_string_value (enc_meta_json);
-  if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
-                                                  strlen (ecdh_enc_str),
-                                                  ecdhe_pkey,
-                                                  sizeof  (struct 
GNUNET_CRYPTO_EcdhePublicKey)))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in metadata\n", 
ecdh_enc_str);
-    json_decref (root);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "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),
-                                                  signature,
-                                                  sizeof (struct 
GNUNET_CRYPTO_EcdsaSignature)))
-  {
-    json_decref (root);
-    GNUNET_free (token_code_decoded);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in 
metadata\n");
-    return GNUNET_SYSERR;
-  }
-  enc_meta_len = GNUNET_STRINGS_base64_decode (enc_meta_str,
-                                               strlen (enc_meta_str),
-                                               &enc_meta);
-
-
-  if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
-                                      ecdhe_pkey,
-                                      enc_meta,
-                                      enc_meta_len,
-                                      &meta_str))
-  {
-    GNUNET_free (enc_meta);
-    json_decref(root);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata decryption failed\n");
-    return GNUNET_SYSERR;
-  }
-
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata: %s\n", meta_str);
-  json_decref (root);
-  GNUNET_free (token_code_decoded);
-  root = json_loads (meta_str, JSON_DECODE_ANY, &err_json);
-  if (!root)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Error parsing metadata: %s\n", err_json.text);
-    GNUNET_free (meta_str);
-    return GNUNET_SYSERR;
-  }
-  
-  identity_json = json_object_get (root, "identity");
-  if (!json_is_string (identity_json))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Error parsing metadata: %s\n", err_json.text);
-    json_decref (root);
-    GNUNET_free (meta_str);
-    return GNUNET_SYSERR;
-  }
-  identity_key_str = json_string_value (identity_json);
-  GNUNET_STRINGS_string_to_data (identity_key_str,
-                                 strlen (identity_key_str),
-                                 id_pkey,
-                                 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
-
-  //TODO: check signature here
-  purpose = 
-    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 
-                   sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
-                   enc_meta_len); // E_K (code_str)
-  purpose->size = 
-    htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
-           sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
-           enc_meta_len);
-  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE);
-  write_ptr = (char*) &purpose[1];
-  memcpy (write_ptr, ecdhe_pkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
-  write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
-  memcpy (write_ptr, enc_meta, enc_meta_len);
-
-  if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify 
(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE,
-                              purpose,
-                              signature,
-                              id_pkey))
-  {
-    json_decref (root);
-    GNUNET_free (meta_str);
-    GNUNET_free (purpose);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Error verifying signature for token code\n");
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (purpose);
-
-  GNUNET_free (enc_meta);
-
-  label_json = json_object_get (root, "label");
-  if (!json_is_string (label_json))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Error parsing metadata: %s\n", err_json.text);
-    json_decref (root);
-    GNUNET_free (meta_str);
-    return GNUNET_SYSERR;
-  }
-
-  label_str = json_string_value (label_json);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found label: %s\n", label_str);
-  GNUNET_asprintf (label, "%s", label_str);
-
-    GNUNET_free (meta_str);
-  json_decref (root);
-  return GNUNET_OK;
-
-}
-
-
 static void
 exchange_token_code_cb (void *cls,
                         struct GNUNET_IDENTITY_Ego *ego,
@@ -1429,14 +1017,10 @@
                         void **ctx,
                         const char *name)
 {
-  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
-  struct GNUNET_CRYPTO_EcdsaSignature sig;
-  struct GNUNET_CRYPTO_EcdhePublicKey echde_pkey;
   struct RequestHandle *handle = cls;
   struct GNUNET_HashCode key;
   char* code;
   char* lookup_query;
-  char* label;
 
   handle->op = NULL;
 
@@ -1464,26 +1048,21 @@
 
   handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (ego);
 
-  label = NULL;
-
-  if (GNUNET_SYSERR == extract_values_from_token_code (code,
-                                                       handle->priv_key,
-                                                       &sig,
-                                                       &echde_pkey,
-                                                       &label,
-                                                       &pkey))
+  if (GNUNET_SYSERR == identity_token_code_parse (code,
+                                                  handle->priv_key,
+                                                  &handle->token_code))
   {
     handle->emsg = GNUNET_strdup ("Error extracting values from token code.");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for token under %s\n", label);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for token under %s\n",
+              handle->token_code->payload->label);
   handle->gns_handle = GNUNET_GNS_connect (cfg);
-  GNUNET_asprintf (&lookup_query, "%s.gnu", label);
-  GNUNET_free (label);
+  GNUNET_asprintf (&lookup_query, "%s.gnu", 
handle->token_code->payload->label);
   handle->lookup_request = GNUNET_GNS_lookup (handle->gns_handle,
                                               lookup_query,
-                                              &pkey,
+                                              
&handle->token_code->payload->identity_key,
                                               GNUNET_GNSRECORD_TYPE_ID_TOKEN,
                                               GNUNET_GNS_LO_LOCAL_MASTER,
                                               NULL,




reply via email to

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