diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-01-07 17:07:20 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-01-07 17:07:20 +0000 |
commit | f278bb4ea15e3fec5fd426d40a460ddaf1e68f8c (patch) | |
tree | c10b2f4ddf2707e627983584bee77f28ac391b94 /src/identity-token/gnunet-service-identity-token.c | |
parent | 80d2de6cdc4d253c7fbc6a4bc067d856aab9cca9 (diff) | |
download | gnunet-f278bb4ea15e3fec5fd426d40a460ddaf1e68f8c.tar.gz gnunet-f278bb4ea15e3fec5fd426d40a460ddaf1e68f8c.zip |
- update token handling
Diffstat (limited to 'src/identity-token/gnunet-service-identity-token.c')
-rw-r--r-- | src/identity-token/gnunet-service-identity-token.c | 188 |
1 files changed, 110 insertions, 78 deletions
diff --git a/src/identity-token/gnunet-service-identity-token.c b/src/identity-token/gnunet-service-identity-token.c index 5fcf47e14..00fc25852 100644 --- a/src/identity-token/gnunet-service-identity-token.c +++ b/src/identity-token/gnunet-service-identity-token.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "gnunet_namestore_service.h" | 30 | #include "gnunet_namestore_service.h" |
31 | #include <jansson.h> | 31 | #include <jansson.h> |
32 | #include "gnunet_signatures.h" | 32 | #include "gnunet_signatures.h" |
33 | #include "identity-token.h" | ||
33 | 34 | ||
34 | /** | 35 | /** |
35 | * First pass state | 36 | * First pass state |
@@ -101,7 +102,7 @@ static struct GNUNET_TIME_Relative min_rel_exp; | |||
101 | /** | 102 | /** |
102 | * Currently processed token | 103 | * Currently processed token |
103 | */ | 104 | */ |
104 | static char* token; | 105 | static struct IdentityToken *token; |
105 | 106 | ||
106 | /** | 107 | /** |
107 | * Label for currently processed token | 108 | * Label for currently processed token |
@@ -109,6 +110,21 @@ static char* token; | |||
109 | static char* label; | 110 | static char* label; |
110 | 111 | ||
111 | /** | 112 | /** |
113 | * Scopes for processed token | ||
114 | */ | ||
115 | static char* scopes; | ||
116 | |||
117 | /** | ||
118 | * Expiration for processed token | ||
119 | */ | ||
120 | static uint64_t rd_exp; | ||
121 | |||
122 | /** | ||
123 | * ECDHE Privkey for processed token metadata | ||
124 | */ | ||
125 | static struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_privkey; | ||
126 | |||
127 | /** | ||
112 | * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format | 128 | * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format |
113 | * | 129 | * |
114 | */ | 130 | */ |
@@ -181,20 +197,16 @@ static void | |||
181 | handle_token_update (void *cls, | 197 | handle_token_update (void *cls, |
182 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 198 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
183 | { | 199 | { |
184 | char *token_header; | 200 | char *token_metadata; |
185 | char *token_payload; | 201 | char *write_ptr; |
186 | char *token_payload_json; | 202 | char *enc_token_str; |
187 | char *new_token; | ||
188 | char *new_payload_str; | ||
189 | char *new_payload_base64; | ||
190 | char *sig_str; | ||
191 | const char *key; | 203 | const char *key; |
192 | char *padding; | 204 | const char *iss; |
205 | const char *aud; | ||
193 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | 206 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; |
207 | struct GNUNET_CRYPTO_EcdhePrivateKey *new_ecdhe_privkey; | ||
194 | struct EgoEntry *ego_entry = cls; | 208 | struct EgoEntry *ego_entry = cls; |
195 | struct GNUNET_GNSRECORD_Data token_record; | 209 | struct GNUNET_GNSRECORD_Data token_record[2]; |
196 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | ||
197 | struct GNUNET_CRYPTO_EcdsaSignature sig; | ||
198 | struct GNUNET_HashCode key_hash; | 210 | struct GNUNET_HashCode key_hash; |
199 | struct GNUNET_TIME_Relative token_rel_exp; | 211 | struct GNUNET_TIME_Relative token_rel_exp; |
200 | struct GNUNET_TIME_Relative token_ttl; | 212 | struct GNUNET_TIME_Relative token_ttl; |
@@ -203,13 +215,13 @@ handle_token_update (void *cls, | |||
203 | struct GNUNET_TIME_Absolute new_exp; | 215 | struct GNUNET_TIME_Absolute new_exp; |
204 | struct GNUNET_TIME_Absolute new_iat; | 216 | struct GNUNET_TIME_Absolute new_iat; |
205 | struct GNUNET_TIME_Absolute new_nbf; | 217 | struct GNUNET_TIME_Absolute new_nbf; |
218 | struct IdentityToken *new_token; | ||
206 | json_t *payload_json; | 219 | json_t *payload_json; |
207 | json_t *value; | 220 | json_t *value; |
208 | json_t *cur_value; | 221 | json_t *cur_value; |
209 | json_t *new_payload_json; | ||
210 | json_t *token_nbf_json; | 222 | json_t *token_nbf_json; |
211 | json_t *token_exp_json; | 223 | json_t *token_exp_json; |
212 | json_error_t json_err; | 224 | size_t token_metadata_len; |
213 | 225 | ||
214 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 226 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
215 | 227 | ||
@@ -222,16 +234,7 @@ handle_token_update (void *cls, | |||
222 | //but this service will reissue new tokens that can be retrieved from GNS | 234 | //but this service will reissue new tokens that can be retrieved from GNS |
223 | //automatically. | 235 | //automatically. |
224 | 236 | ||
225 | token_header = strtok (token, "."); | 237 | payload_json = token->payload; |
226 | |||
227 | token_payload = strtok (NULL, "."); | ||
228 | |||
229 | GNUNET_STRINGS_base64_decode (token_payload, | ||
230 | strlen (token_payload), | ||
231 | &token_payload_json); | ||
232 | |||
233 | payload_json = json_loads (token_payload_json, JSON_DECODE_ANY, &json_err); | ||
234 | GNUNET_free (token_payload_json); | ||
235 | 238 | ||
236 | token_exp_json = json_object_get (payload_json, "exp"); | 239 | token_exp_json = json_object_get (payload_json, "exp"); |
237 | token_nbf_json = json_object_get (payload_json, "nbf"); | 240 | token_nbf_json = json_object_get (payload_json, "nbf"); |
@@ -252,34 +255,42 @@ handle_token_update (void *cls, | |||
252 | token = NULL; | 255 | token = NULL; |
253 | GNUNET_free (label); | 256 | GNUNET_free (label); |
254 | label = NULL; | 257 | label = NULL; |
258 | GNUNET_free (scopes); | ||
259 | scopes = NULL; | ||
255 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 260 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); |
256 | return; | 261 | return; |
257 | } | 262 | } |
258 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
259 | "Token is expired. Create a new one\n"); | 264 | "Token is expired. Create a new one\n"); |
265 | iss = json_string_value (json_object_get (payload_json, "iss")); | ||
266 | aud = json_string_value (json_object_get (payload_json, "aud")); | ||
267 | new_token = identity_token_create (iss, aud); | ||
260 | new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp); | 268 | new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp); |
261 | new_nbf = GNUNET_TIME_absolute_get (); | 269 | new_nbf = GNUNET_TIME_absolute_get (); |
262 | new_iat = new_nbf; | 270 | new_iat = new_nbf; |
263 | new_payload_json = json_object(); | 271 | |
264 | json_object_foreach(payload_json, key, value) { | 272 | json_object_foreach(payload_json, key, value) { |
265 | if (0 == strcmp (key, "exp")) | 273 | if (0 == strcmp (key, "exp")) |
266 | { | 274 | { |
267 | json_object_set_new (new_payload_json, key, json_integer (new_exp.abs_value_us)); | 275 | identity_token_add_json (new_token, key, json_integer (new_exp.abs_value_us)); |
268 | } | 276 | } |
269 | else if (0 == strcmp (key, "nbf")) | 277 | else if (0 == strcmp (key, "nbf")) |
270 | { | 278 | { |
271 | json_object_set_new (new_payload_json, key, json_integer (new_nbf.abs_value_us)); | 279 | identity_token_add_json (new_token, key, json_integer (new_nbf.abs_value_us)); |
272 | } | 280 | } |
273 | else if (0 == strcmp (key, "iat")) | 281 | else if (0 == strcmp (key, "iat")) |
274 | { | 282 | { |
275 | json_object_set_new (new_payload_json, key, json_integer (new_iat.abs_value_us)); | 283 | identity_token_add_json (new_token, key, json_integer (new_iat.abs_value_us)); |
276 | } | 284 | } |
277 | else if ((0 == strcmp (key, "iss")) | 285 | else if ((0 == strcmp (key, "iss")) |
278 | || (0 == strcmp (key, "aud")) | 286 | || (0 == strcmp (key, "aud"))) |
279 | || (0 == strcmp (key, "sub")) | 287 | { |
288 | //Omit | ||
289 | } | ||
290 | else if ((0 == strcmp (key, "sub")) | ||
280 | || (0 == strcmp (key, "rnl"))) | 291 | || (0 == strcmp (key, "rnl"))) |
281 | { | 292 | { |
282 | json_object_set (new_payload_json, key, value); | 293 | identity_token_add_json (new_token, key, value); |
283 | } | 294 | } |
284 | else { | 295 | else { |
285 | GNUNET_CRYPTO_hash (key, | 296 | GNUNET_CRYPTO_hash (key, |
@@ -291,63 +302,60 @@ handle_token_update (void *cls, | |||
291 | { | 302 | { |
292 | cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map, | 303 | cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map, |
293 | &key_hash); | 304 | &key_hash); |
294 | json_object_set (new_payload_json, key, cur_value); | 305 | identity_token_add_json (new_token, key, cur_value); |
295 | } | 306 | } |
296 | } | 307 | } |
297 | } | 308 | } |
298 | 309 | ||
299 | // reassemble and set | 310 | // reassemble and set |
300 | new_payload_str = json_dumps (new_payload_json, JSON_COMPACT); | 311 | GNUNET_assert (identity_token_serialize (new_token, |
312 | priv_key, | ||
313 | &new_ecdhe_privkey, | ||
314 | &enc_token_str)); | ||
315 | |||
301 | json_decref (payload_json); | 316 | json_decref (payload_json); |
302 | json_decref (new_payload_json); | 317 | |
303 | GNUNET_STRINGS_base64_encode (new_payload_str, | 318 | token_record[0].data = enc_token_str; |
304 | strlen (new_payload_str), | 319 | token_record[0].data_size = strlen (enc_token_str) + 1; |
305 | &new_payload_base64); | 320 | token_record[0].expiration_time = rd_exp; //Old expiration time |
306 | //Remove padding | 321 | token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN; |
307 | padding = strtok(new_payload_base64, "="); | 322 | token_record[0].flags = GNUNET_GNSRECORD_RF_NONE; |
308 | while (NULL != padding) | 323 | |
309 | padding = strtok(NULL, "="); | 324 | //Meta |
310 | 325 | token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey) | |
311 | GNUNET_asprintf (&new_token, "%s,%s", token_header, new_payload_base64); | 326 | + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) |
312 | purpose = | 327 | + strlen (scopes) + 1; //With 0-Terminator |
313 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | 328 | token_metadata = GNUNET_malloc (token_metadata_len); |
314 | strlen (new_token)); | 329 | write_ptr = token_metadata; |
315 | purpose->size = | 330 | memcpy (token_metadata, new_ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); |
316 | htonl (strlen (new_token) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); | 331 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey); |
317 | purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); | 332 | memcpy (write_ptr, &token->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); |
318 | memcpy (&purpose[1], new_token, strlen (new_token)); | 333 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); |
319 | if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key, | 334 | memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator; |
320 | purpose, | 335 | |
321 | &sig)) | 336 | token_record[1].data = token_metadata; |
322 | GNUNET_break(0); | 337 | token_record[1].data_size = token_metadata_len; |
323 | GNUNET_free (new_token); | 338 | token_record[1].expiration_time = rd_exp; |
324 | sig_str = GNUNET_STRINGS_data_to_string_alloc (&sig, | 339 | token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA; |
325 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); | 340 | token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE; |
326 | GNUNET_asprintf (&new_token, "%s.%s.%s", | 341 | |
327 | token_header, new_payload_base64, sig_str); | ||
328 | GNUNET_free (sig_str); | ||
329 | GNUNET_free (new_payload_str); | ||
330 | GNUNET_free (new_payload_base64); | ||
331 | GNUNET_free (purpose); | ||
332 | |||
333 | token_record.data = new_token; | ||
334 | token_record.data_size = strlen (new_token); | ||
335 | token_record.expiration_time = new_exp.abs_value_us; | ||
336 | token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN; | ||
337 | token_record.flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
338 | ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | 342 | ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, |
339 | priv_key, | 343 | priv_key, |
340 | label, | 344 | label, |
341 | 1, | 345 | 2, |
342 | &token_record, | 346 | token_record, |
343 | &store_token_cont, | 347 | &store_token_cont, |
344 | ego_entry); | 348 | ego_entry); |
345 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token); | 349 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token); |
346 | GNUNET_free (new_token); | 350 | identity_token_destroy (new_token); |
351 | GNUNET_free (new_ecdhe_privkey); | ||
352 | GNUNET_free (enc_token_str); | ||
347 | GNUNET_free (token); | 353 | GNUNET_free (token); |
348 | token = NULL; | 354 | token = NULL; |
349 | GNUNET_free (label); | 355 | GNUNET_free (label); |
350 | label = NULL; | 356 | label = NULL; |
357 | GNUNET_free (scopes); | ||
358 | scopes = NULL; | ||
351 | } | 359 | } |
352 | 360 | ||
353 | static void | 361 | static void |
@@ -395,6 +403,9 @@ token_collect (void *cls, | |||
395 | const struct GNUNET_GNSRECORD_Data *rd) | 403 | const struct GNUNET_GNSRECORD_Data *rd) |
396 | { | 404 | { |
397 | struct EgoEntry *ego_entry = cls; | 405 | struct EgoEntry *ego_entry = cls; |
406 | const struct GNUNET_GNSRECORD_Data *token_record; | ||
407 | const struct GNUNET_GNSRECORD_Data *token_metadata_record; | ||
408 | struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key; | ||
398 | 409 | ||
399 | if (NULL == lbl) | 410 | if (NULL == lbl) |
400 | { | 411 | { |
@@ -411,17 +422,38 @@ token_collect (void *cls, | |||
411 | } | 422 | } |
412 | 423 | ||
413 | //There should be only a single record for a token under a label | 424 | //There should be only a single record for a token under a label |
414 | if ((1 != rd_count) | 425 | if (2 != rd_count) |
415 | || (rd->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN) | ||
416 | || (0 == (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags))) | ||
417 | { | 426 | { |
418 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 427 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); |
419 | return; | 428 | return; |
420 | } | 429 | } |
421 | token = GNUNET_GNSRECORD_value_to_string (rd->record_type, | 430 | |
422 | rd->data, | 431 | if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA) |
423 | rd->data_size); | 432 | { |
433 | token_metadata_record = &rd[0]; | ||
434 | token_record = &rd[1]; | ||
435 | } else { | ||
436 | token_record = &rd[0]; | ||
437 | token_metadata_record = &rd[1]; | ||
438 | } | ||
439 | GNUNET_assert (token_metadata_record->record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA); | ||
440 | GNUNET_assert (token_record->record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN); | ||
441 | |||
442 | //Get metadata and decrypt token | ||
443 | ecdhe_privkey = *((struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data); | ||
444 | aud_key = (struct GNUNET_CRYPTO_EcdsaPublicKey *)&ecdhe_privkey+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey); | ||
445 | scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
446 | |||
447 | identity_token_parse2 (token_record->data, | ||
448 | &ecdhe_privkey, | ||
449 | aud_key, | ||
450 | &token); | ||
451 | |||
452 | //token = GNUNET_GNSRECORD_value_to_string (rd->record_type, | ||
453 | // rd->data, | ||
454 | // rd->data_size); | ||
424 | label = GNUNET_strdup (lbl); | 455 | label = GNUNET_strdup (lbl); |
456 | rd_exp = token_record->expiration_time; | ||
425 | 457 | ||
426 | GNUNET_SCHEDULER_add_now (&handle_token_update, ego_entry); | 458 | GNUNET_SCHEDULER_add_now (&handle_token_update, ego_entry); |
427 | } | 459 | } |