aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-07 17:07:20 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-07 17:07:20 +0000
commitf278bb4ea15e3fec5fd426d40a460ddaf1e68f8c (patch)
treec10b2f4ddf2707e627983584bee77f28ac391b94 /src
parent80d2de6cdc4d253c7fbc6a4bc067d856aab9cca9 (diff)
- update token handling
Diffstat (limited to 'src')
-rw-r--r--src/identity-token/Makefile.am4
-rw-r--r--src/identity-token/gnunet-service-identity-token.c188
-rw-r--r--src/identity-token/identity-token.c144
-rw-r--r--src/identity-token/identity-token.h7
-rw-r--r--src/identity-token/plugin_rest_identity_token.c82
-rw-r--r--src/include/gnunet_gnsrecord_lib.h7
6 files changed, 312 insertions, 120 deletions
diff --git a/src/identity-token/Makefile.am b/src/identity-token/Makefile.am
index 874ac2db03..974de98d9b 100644
--- a/src/identity-token/Makefile.am
+++ b/src/identity-token/Makefile.am
@@ -31,8 +31,8 @@ libexec_PROGRAMS = \
gnunet-service-identity-token
gnunet_service_identity_token_SOURCES = \
- gnunet-service-identity-token.c
-
+ gnunet-service-identity-token.c \
+ identity-token.c
gnunet_service_identity_token_LDADD = \
$(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
$(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/identity-token/gnunet-service-identity-token.c b/src/identity-token/gnunet-service-identity-token.c
index 5fcf47e148..00fc25852d 100644
--- a/src/identity-token/gnunet-service-identity-token.c
+++ b/src/identity-token/gnunet-service-identity-token.c
@@ -30,6 +30,7 @@
#include "gnunet_namestore_service.h"
#include <jansson.h>
#include "gnunet_signatures.h"
+#include "identity-token.h"
/**
* First pass state
@@ -101,7 +102,7 @@ static struct GNUNET_TIME_Relative min_rel_exp;
/**
* Currently processed token
*/
-static char* token;
+static struct IdentityToken *token;
/**
* Label for currently processed token
@@ -109,6 +110,21 @@ static char* token;
static char* label;
/**
+ * Scopes for processed token
+ */
+static char* scopes;
+
+/**
+ * Expiration for processed token
+ */
+static uint64_t rd_exp;
+
+/**
+ * ECDHE Privkey for processed token metadata
+ */
+static struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_privkey;
+
+/**
* DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
*
*/
@@ -181,20 +197,16 @@ static void
handle_token_update (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- char *token_header;
- char *token_payload;
- char *token_payload_json;
- char *new_token;
- char *new_payload_str;
- char *new_payload_base64;
- char *sig_str;
+ char *token_metadata;
+ char *write_ptr;
+ char *enc_token_str;
const char *key;
- char *padding;
+ const char *iss;
+ const char *aud;
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *new_ecdhe_privkey;
struct EgoEntry *ego_entry = cls;
- struct GNUNET_GNSRECORD_Data token_record;
- struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
- struct GNUNET_CRYPTO_EcdsaSignature sig;
+ struct GNUNET_GNSRECORD_Data token_record[2];
struct GNUNET_HashCode key_hash;
struct GNUNET_TIME_Relative token_rel_exp;
struct GNUNET_TIME_Relative token_ttl;
@@ -203,13 +215,13 @@ handle_token_update (void *cls,
struct GNUNET_TIME_Absolute new_exp;
struct GNUNET_TIME_Absolute new_iat;
struct GNUNET_TIME_Absolute new_nbf;
+ struct IdentityToken *new_token;
json_t *payload_json;
json_t *value;
json_t *cur_value;
- json_t *new_payload_json;
json_t *token_nbf_json;
json_t *token_exp_json;
- json_error_t json_err;
+ size_t token_metadata_len;
priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
@@ -222,16 +234,7 @@ handle_token_update (void *cls,
//but this service will reissue new tokens that can be retrieved from GNS
//automatically.
- token_header = strtok (token, ".");
-
- token_payload = strtok (NULL, ".");
-
- GNUNET_STRINGS_base64_decode (token_payload,
- strlen (token_payload),
- &token_payload_json);
-
- payload_json = json_loads (token_payload_json, JSON_DECODE_ANY, &json_err);
- GNUNET_free (token_payload_json);
+ payload_json = token->payload;
token_exp_json = json_object_get (payload_json, "exp");
token_nbf_json = json_object_get (payload_json, "nbf");
@@ -252,34 +255,42 @@ handle_token_update (void *cls,
token = NULL;
GNUNET_free (label);
label = NULL;
+ GNUNET_free (scopes);
+ scopes = NULL;
GNUNET_NAMESTORE_zone_iterator_next (ns_it);
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Token is expired. Create a new one\n");
+ iss = json_string_value (json_object_get (payload_json, "iss"));
+ aud = json_string_value (json_object_get (payload_json, "aud"));
+ new_token = identity_token_create (iss, aud);
new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
new_nbf = GNUNET_TIME_absolute_get ();
new_iat = new_nbf;
- new_payload_json = json_object();
+
json_object_foreach(payload_json, key, value) {
if (0 == strcmp (key, "exp"))
{
- json_object_set_new (new_payload_json, key, json_integer (new_exp.abs_value_us));
+ identity_token_add_json (new_token, key, json_integer (new_exp.abs_value_us));
}
else if (0 == strcmp (key, "nbf"))
{
- json_object_set_new (new_payload_json, key, json_integer (new_nbf.abs_value_us));
+ identity_token_add_json (new_token, key, json_integer (new_nbf.abs_value_us));
}
else if (0 == strcmp (key, "iat"))
{
- json_object_set_new (new_payload_json, key, json_integer (new_iat.abs_value_us));
+ identity_token_add_json (new_token, key, json_integer (new_iat.abs_value_us));
}
else if ((0 == strcmp (key, "iss"))
- || (0 == strcmp (key, "aud"))
- || (0 == strcmp (key, "sub"))
+ || (0 == strcmp (key, "aud")))
+ {
+ //Omit
+ }
+ else if ((0 == strcmp (key, "sub"))
|| (0 == strcmp (key, "rnl")))
{
- json_object_set (new_payload_json, key, value);
+ identity_token_add_json (new_token, key, value);
}
else {
GNUNET_CRYPTO_hash (key,
@@ -291,63 +302,60 @@ handle_token_update (void *cls,
{
cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map,
&key_hash);
- json_object_set (new_payload_json, key, cur_value);
+ identity_token_add_json (new_token, key, cur_value);
}
}
}
// reassemble and set
- new_payload_str = json_dumps (new_payload_json, JSON_COMPACT);
+ GNUNET_assert (identity_token_serialize (new_token,
+ priv_key,
+ &new_ecdhe_privkey,
+ &enc_token_str));
+
json_decref (payload_json);
- json_decref (new_payload_json);
- GNUNET_STRINGS_base64_encode (new_payload_str,
- strlen (new_payload_str),
- &new_payload_base64);
- //Remove padding
- padding = strtok(new_payload_base64, "=");
- while (NULL != padding)
- padding = strtok(NULL, "=");
-
- GNUNET_asprintf (&new_token, "%s,%s", token_header, new_payload_base64);
- purpose =
- GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
- strlen (new_token));
- purpose->size =
- htonl (strlen (new_token) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
- purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
- memcpy (&purpose[1], new_token, strlen (new_token));
- if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
- purpose,
- &sig))
- GNUNET_break(0);
- GNUNET_free (new_token);
- sig_str = GNUNET_STRINGS_data_to_string_alloc (&sig,
- sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
- GNUNET_asprintf (&new_token, "%s.%s.%s",
- token_header, new_payload_base64, sig_str);
- GNUNET_free (sig_str);
- GNUNET_free (new_payload_str);
- GNUNET_free (new_payload_base64);
- GNUNET_free (purpose);
-
- token_record.data = new_token;
- token_record.data_size = strlen (new_token);
- token_record.expiration_time = new_exp.abs_value_us;
- token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
- token_record.flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+
+ token_record[0].data = enc_token_str;
+ token_record[0].data_size = strlen (enc_token_str) + 1;
+ token_record[0].expiration_time = rd_exp; //Old expiration time
+ token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
+ token_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
+
+ //Meta
+ token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
+ + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)
+ + strlen (scopes) + 1; //With 0-Terminator
+ token_metadata = GNUNET_malloc (token_metadata_len);
+ write_ptr = token_metadata;
+ memcpy (token_metadata, new_ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
+ write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
+ memcpy (write_ptr, &token->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+ write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
+ memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator;
+
+ token_record[1].data = token_metadata;
+ token_record[1].data_size = token_metadata_len;
+ token_record[1].expiration_time = rd_exp;
+ token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
+ token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
+
ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
priv_key,
label,
- 1,
- &token_record,
+ 2,
+ token_record,
&store_token_cont,
ego_entry);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token);
- GNUNET_free (new_token);
+ identity_token_destroy (new_token);
+ GNUNET_free (new_ecdhe_privkey);
+ GNUNET_free (enc_token_str);
GNUNET_free (token);
token = NULL;
GNUNET_free (label);
label = NULL;
+ GNUNET_free (scopes);
+ scopes = NULL;
}
static void
@@ -395,6 +403,9 @@ token_collect (void *cls,
const struct GNUNET_GNSRECORD_Data *rd)
{
struct EgoEntry *ego_entry = cls;
+ const struct GNUNET_GNSRECORD_Data *token_record;
+ const struct GNUNET_GNSRECORD_Data *token_metadata_record;
+ struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key;
if (NULL == lbl)
{
@@ -411,17 +422,38 @@ token_collect (void *cls,
}
//There should be only a single record for a token under a label
- if ((1 != rd_count)
- || (rd->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN)
- || (0 == (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags)))
+ if (2 != rd_count)
{
GNUNET_NAMESTORE_zone_iterator_next (ns_it);
return;
}
- token = GNUNET_GNSRECORD_value_to_string (rd->record_type,
- rd->data,
- rd->data_size);
+
+ if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
+ {
+ token_metadata_record = &rd[0];
+ token_record = &rd[1];
+ } else {
+ token_record = &rd[0];
+ token_metadata_record = &rd[1];
+ }
+ GNUNET_assert (token_metadata_record->record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA);
+ GNUNET_assert (token_record->record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN);
+
+ //Get metadata and decrypt token
+ ecdhe_privkey = *((struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data);
+ aud_key = (struct GNUNET_CRYPTO_EcdsaPublicKey *)&ecdhe_privkey+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey);
+ scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+
+ identity_token_parse2 (token_record->data,
+ &ecdhe_privkey,
+ aud_key,
+ &token);
+
+ //token = GNUNET_GNSRECORD_value_to_string (rd->record_type,
+ // rd->data,
+ // rd->data_size);
label = GNUNET_strdup (lbl);
+ rd_exp = token_record->expiration_time;
GNUNET_SCHEDULER_add_now (&handle_token_update, ego_entry);
}
diff --git a/src/identity-token/identity-token.c b/src/identity-token/identity-token.c
index 9f22f16715..dc0154c215 100644
--- a/src/identity-token/identity-token.c
+++ b/src/identity-token/identity-token.c
@@ -57,21 +57,23 @@ create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
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,
+ const char *cyphertext,
+ size_t cyphertext_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);
+ char *str_buf = GNUNET_malloc (cyphertext_len);
size_t str_size;
//Calculate symmetric key from ecdh parameters
@@ -83,15 +85,16 @@ decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
&enc_key,
&enc_iv);
- str_size = GNUNET_CRYPTO_symmetric_decrypt (enc_str,
- enc_str_len,
+ str_size = GNUNET_CRYPTO_symmetric_decrypt (cyphertext,
+ cyphertext_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);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decrypted bytes: %d Expected bytes: %d\n", str_size, cyphertext_len);
if (-1 == str_size)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
+ GNUNET_free (str_buf);
return GNUNET_SYSERR;
}
*result_str = GNUNET_malloc (str_size+1);
@@ -103,37 +106,71 @@ decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
}
/**
+ * Decrypt string using pubkey and ECDHE
+*/
+static int
+decrypt_str_ecdhe2 (const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
+ const char *ciphertext,
+ size_t ciphertext_len,
+ char **plaintext)
+{
+ struct GNUNET_CRYPTO_SymmetricSessionKey skey;
+ struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
+ struct GNUNET_HashCode new_key_hash;
+
+ //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
+ *plaintext = GNUNET_malloc (ciphertext_len);
+
+ // Derived key K = H(eB)
+ GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
+ aud_key,
+ &new_key_hash));
+ create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
+ GNUNET_CRYPTO_symmetric_decrypt (ciphertext,
+ ciphertext_len,
+ &skey, &iv,
+ *plaintext);
+ 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,
+encrypt_str_ecdhe (const char *plaintext,
const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
- char **enc_data_str,
+ char **cyphertext,
+ struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
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;
-
+ ssize_t enc_size;
+
// ECDH keypair E = eG
- ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
- GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_privkey,
+ *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
+ GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
ecdh_pubkey);
- *enc_data_str = GNUNET_malloc (strlen (data));
+ //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
+ *cyphertext = GNUNET_malloc (strlen (plaintext));
// Derived key K = H(eB)
- GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
+ 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);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypting string %s\n (len=%d)",
+ 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);
return GNUNET_OK;
}
@@ -209,6 +246,65 @@ identity_token_add_json (const struct IdentityToken *token,
int
+identity_token_parse2 (const char* raw_data,
+ 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, ",");
+ enc_token_str = strtok (NULL, ",");
+
+ enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
+ strlen (enc_token_str),
+ &enc_token);
+ if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key,
+ aud_key,
+ 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
+
+
+ *result = GNUNET_malloc (sizeof (struct IdentityToken));
+ (*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
identity_token_parse (const char* raw_data,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
struct IdentityToken **result)
@@ -342,6 +438,7 @@ identity_token_to_string (const struct IdentityToken *token,
int
identity_token_serialize (const struct IdentityToken *token,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+ struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
char **result)
{
char *token_str;
@@ -357,6 +454,7 @@ identity_token_serialize (const struct IdentityToken *token,
GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
&token->aud_key,
&enc_token,
+ ecdh_privkey,
&ecdh_pubkey));
GNUNET_STRINGS_base64_encode (enc_token,
strlen (token_str),
@@ -456,6 +554,7 @@ identity_token_code_serialize (struct IdentityTokenCode *identity_token_code,
char *token_code_str;
char *dh_key_str;
char *write_ptr;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
@@ -465,8 +564,11 @@ identity_token_code_serialize (struct IdentityTokenCode *identity_token_code,
GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
&identity_token_code->aud_key,
&enc_token_code_payload,
+ &ecdhe_privkey,
&identity_token_code->ecdh_pubkey));
+ GNUNET_free (ecdhe_privkey);
+
purpose =
GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
@@ -509,6 +611,7 @@ identity_token_code_serialize (struct IdentityTokenCode *identity_token_code,
int
identity_token_code_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 IdentityTokenCodePayload **result)
@@ -528,7 +631,7 @@ identity_token_code_payload_parse(const char *raw_data,
if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
ecdhe_pkey,
raw_data,
- strlen (raw_data),
+ data_len,
&meta_str))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata decryption failed\n");
@@ -668,6 +771,7 @@ identity_token_code_parse (const char *raw_data,
identity_token_code_payload_parse (enc_meta,
+ enc_meta_len,
priv_key,
(const struct GNUNET_CRYPTO_EcdhePublicKey*)&token_code->ecdh_pubkey,
&token_code_payload);
diff --git a/src/identity-token/identity-token.h b/src/identity-token/identity-token.h
index 06819547a1..1520dcf6aa 100644
--- a/src/identity-token/identity-token.h
+++ b/src/identity-token/identity-token.h
@@ -93,6 +93,7 @@ identity_token_add_json (const struct IdentityToken *token,
int
identity_token_serialize (const struct IdentityToken *token,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
+ struct GNUNET_CRYPTO_EcdhePrivateKey **ecdhe_privkey,
char **result);
int
@@ -101,6 +102,12 @@ identity_token_parse (const char* raw_data,
struct IdentityToken **result);
int
+identity_token_parse2 (const char* raw_data,
+ const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
+ struct IdentityToken **result);
+
+int
identity_token_to_string (const struct IdentityToken *token,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
char **result);
diff --git a/src/identity-token/plugin_rest_identity_token.c b/src/identity-token/plugin_rest_identity_token.c
index 97ac9b5af7..580d34ed00 100644
--- a/src/identity-token/plugin_rest_identity_token.c
+++ b/src/identity-token/plugin_rest_identity_token.c
@@ -447,9 +447,10 @@ sign_and_return_token (void *cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
struct GNUNET_CRYPTO_EcdsaPublicKey aud_pkey;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
struct JsonApiResource *json_resource;
struct RequestHandle *handle = cls;
- struct GNUNET_GNSRECORD_Data token_record;
+ struct GNUNET_GNSRECORD_Data token_record[2];
struct GNUNET_HashCode key;
struct GNUNET_TIME_Relative etime_rel;
json_t *token_str;
@@ -461,9 +462,13 @@ sign_and_return_token (void *cls,
char *audience;
char *nonce_str;
char *enc_token_str;
+ char *token_metadata;
+ char *scopes;
+ char* write_ptr;
uint64_t time;
uint64_t exp_time;
uint64_t rnd_key;
+ size_t token_metadata_len;
//Remote nonce
nonce_str = NULL;
@@ -564,11 +569,7 @@ sign_and_return_token (void *cls,
identity_token_add_json (handle->token, "exp", json_integer (exp_time));
identity_token_add_attr (handle->token, "nonce", nonce_str);
- GNUNET_assert (identity_token_serialize (handle->token,
- priv_key,
- &enc_token_str));
-
-
+
handle->resp_object = GNUNET_REST_jsonapi_object_new ();
json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
@@ -589,17 +590,62 @@ sign_and_return_token (void *cls,
GNUNET_free (token_code_str);
json_decref (token_code_json);
GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
- 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;
+ //Token in a serialized encrypted format
+ GNUNET_assert (identity_token_serialize (handle->token,
+ priv_key,
+ &ecdhe_privkey,
+ &enc_token_str));
+
+ //Token record E,E_K (Token)
+ token_record[0].data = enc_token_str;
+ token_record[0].data_size = strlen (enc_token_str) + 1;
+ token_record[0].expiration_time = exp_time;
+ token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
+ token_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
+
+
+ //Meta info
+ GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_ATTR_LIST,
+ strlen (GNUNET_IDENTITY_TOKEN_ATTR_LIST),
+ &key);
+
+ scopes = NULL;
+ if ( GNUNET_YES !=
+ GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
+ &key) )
+ {
+ handle->emsg = GNUNET_strdup ("Scopes missing!\n");
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+ scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
+ &key);
+
+ token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
+ + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)
+ + strlen (scopes) + 1; //With 0-Terminator
+ token_metadata = GNUNET_malloc (token_metadata_len);
+ write_ptr = token_metadata;
+ memcpy (token_metadata, ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
+ write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
+ memcpy (write_ptr, &aud_pkey, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+ write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
+ memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator;
+
+ GNUNET_free (ecdhe_privkey);
+
+ token_record[1].data = token_metadata;
+ token_record[1].data_size = token_metadata_len;
+ token_record[1].expiration_time = exp_time;
+ token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
+ token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
+
//Persist token
handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
priv_key,
lbl_str,
- 1,
- &token_record,
+ 2,
+ token_record,
&store_token_cont,
handle);
GNUNET_free (lbl_str);
@@ -970,12 +1016,12 @@ process_lookup_result (void *cls, uint32_t rd_count,
char* record_str;
handle->lookup_request = NULL;
- if (1 != rd_count)
+ if (2 != rd_count)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Number of tokens %d != 1.",
+ "Number of tokens %d != 2.",
rd_count);
- handle->emsg = GNUNET_strdup ("Number of tokens != 1.");
+ handle->emsg = GNUNET_strdup ("Number of tokens != 2.");
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
@@ -985,12 +1031,12 @@ process_lookup_result (void *cls, uint32_t rd_count,
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,
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h
index 76eb69a8a4..718365f95c 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -91,11 +91,14 @@ extern "C"
#define GNUNET_GNSRECORD_TYPE_ID_ATTR 65544
/**
- * Record type for an identity token (of IDENTITY).
+ * Record type for an identity token (of IDENTITY-TOKEN).
*/
#define GNUNET_GNSRECORD_TYPE_ID_TOKEN 65545
-
+/**
+ * Record type for the private metadata of an identity token (of IDENTITY-TOKEN).
+ */
+#define GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA 65546
/**