diff options
-rw-r--r-- | src/identity-token/Makefile.am | 4 | ||||
-rw-r--r-- | src/identity-token/gnunet-service-identity-token.c | 188 | ||||
-rw-r--r-- | src/identity-token/identity-token.c | 144 | ||||
-rw-r--r-- | src/identity-token/identity-token.h | 7 | ||||
-rw-r--r-- | src/identity-token/plugin_rest_identity_token.c | 82 | ||||
-rw-r--r-- | src/include/gnunet_gnsrecord_lib.h | 7 |
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 /** |