aboutsummaryrefslogtreecommitdiff
path: root/src/identity-provider/identity_token.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/identity-provider/identity_token.c')
-rw-r--r--src/identity-provider/identity_token.c964
1 files changed, 0 insertions, 964 deletions
diff --git a/src/identity-provider/identity_token.c b/src/identity-provider/identity_token.c
deleted file mode 100644
index 31249840b..000000000
--- a/src/identity-provider/identity_token.c
+++ /dev/null
@@ -1,964 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
20
21/**
22 * @file identity-provider/identity_token.c
23 * @brief helper library to manage identity tokens
24 * @author Martin Schanzenbach
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h"
29#include "identity_token.h"
30#include <jansson.h>
31#include <inttypes.h>
32
33#define JWT_ALG "alg"
34
35#define JWT_ALG_VALUE "ED512"
36
37#define JWT_TYP "typ"
38
39#define JWT_TYP_VALUE "jwt"
40
41/**
42 * Crypto helper functions
43 */
44
45static int
46create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
47 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
48 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
49{
50 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
51
52 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
53 &new_key_hash_str);
54 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
55 static const char ctx_key[] = "gnuid-aes-ctx-key";
56 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
57 new_key_hash, sizeof (struct GNUNET_HashCode),
58 ctx_key, strlen (ctx_key),
59 NULL, 0);
60 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
61 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
62 new_key_hash, sizeof (struct GNUNET_HashCode),
63 ctx_iv, strlen (ctx_iv),
64 NULL, 0);
65 return GNUNET_OK;
66}
67
68
69
70/**
71 * Decrypts data part from a token code
72 */
73static int
74decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
75 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key,
76 const char *cyphertext,
77 size_t cyphertext_len,
78 char **result_str)
79{
80 struct GNUNET_HashCode new_key_hash;
81 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
82 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
83
84 char *str_buf = GNUNET_malloc (cyphertext_len);
85 size_t str_size;
86
87 //Calculate symmetric key from ecdh parameters
88 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key,
89 ecdh_key,
90 &new_key_hash));
91
92 create_sym_key_from_ecdh (&new_key_hash,
93 &enc_key,
94 &enc_iv);
95
96 str_size = GNUNET_CRYPTO_symmetric_decrypt (cyphertext,
97 cyphertext_len,
98 &enc_key,
99 &enc_iv,
100 str_buf);
101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
102 "Decrypted bytes: %zd Expected bytes: %zd\n",
103 str_size,
104 cyphertext_len);
105 if (-1 == str_size)
106 {
107 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
108 GNUNET_free (str_buf);
109 return GNUNET_SYSERR;
110 }
111 *result_str = GNUNET_malloc (str_size+1);
112 GNUNET_memcpy (*result_str, str_buf, str_size);
113 (*result_str)[str_size] = '\0';
114 GNUNET_free (str_buf);
115 return GNUNET_OK;
116
117}
118
119/**
120 * Decrypt string using pubkey and ECDHE
121*/
122static int
123decrypt_str_ecdhe2 (const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey,
124 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
125 const char *ciphertext,
126 size_t ciphertext_len,
127 char **plaintext)
128{
129 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
130 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
131 struct GNUNET_HashCode new_key_hash;
132
133 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
134 *plaintext = GNUNET_malloc (ciphertext_len);
135
136 // Derived key K = H(eB)
137 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
138 aud_key,
139 &new_key_hash));
140 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
141 GNUNET_CRYPTO_symmetric_decrypt (ciphertext,
142 ciphertext_len,
143 &skey, &iv,
144 *plaintext);
145 return GNUNET_OK;
146}
147
148
149/**
150 * Encrypt string using pubkey and ECDHE
151 * Returns ECDHE pubkey to be used for decryption
152 */
153static int
154encrypt_str_ecdhe (const char *plaintext,
155 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
156 char **cyphertext,
157 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
158 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey)
159{
160 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
161 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
162 struct GNUNET_HashCode new_key_hash;
163 ssize_t enc_size;
164
165 // ECDH keypair E = eG
166 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
167 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
168 ecdh_pubkey);
169
170 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
171 *cyphertext = GNUNET_malloc (strlen (plaintext));
172
173 // Derived key K = H(eB)
174 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
175 pub_key,
176 &new_key_hash));
177 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%zd)",
179 plaintext,
180 strlen (plaintext));
181 enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext,
182 strlen (plaintext),
183 &skey, &iv,
184 *cyphertext);
185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%zd)", enc_size);
186 return GNUNET_OK;
187}
188
189
190/**
191 * Identity Token API
192 */
193
194
195/**
196 * Create an Identity Token
197 *
198 * @param type the JSON API resource type
199 * @param id the JSON API resource id
200 * @return a new JSON API resource or NULL on error.
201 */
202struct IdentityToken*
203token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
204 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud)
205{
206 struct IdentityToken *token;
207 char* audience;
208 char* issuer;
209
210 issuer = GNUNET_STRINGS_data_to_string_alloc (iss,
211 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
212 audience = GNUNET_STRINGS_data_to_string_alloc (aud,
213 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
214
215 token = GNUNET_malloc (sizeof (struct IdentityToken));
216 token_add_attr (token, "iss", issuer);
217 token_add_attr (token, "aud", audience);
218 token_add_attr (token, "sub", issuer);
219 token->aud_key = *aud;
220 GNUNET_free (issuer);
221 GNUNET_free (audience);
222 return token;
223}
224
225void
226token_destroy (struct IdentityToken *token)
227{
228 struct TokenAttr *attr;
229 struct TokenAttr *tmp_attr;
230 struct TokenAttrValue *val;
231 struct TokenAttrValue *tmp_val;
232
233 for (attr = token->attr_head; NULL != attr;)
234 {
235 tmp_attr = attr->next;
236 GNUNET_CONTAINER_DLL_remove (token->attr_head,
237 token->attr_tail,
238 attr);
239 for (val = attr->val_head; NULL != val;)
240 {
241 tmp_val = val->next;
242 GNUNET_CONTAINER_DLL_remove (attr->val_head,
243 attr->val_tail,
244 val);
245 if (NULL != val->value)
246 GNUNET_free (val->value);
247 GNUNET_free (val);
248 val = tmp_val;
249 }
250 GNUNET_free (attr->name);
251 GNUNET_free (attr);
252 attr = tmp_attr;
253 }
254
255
256 GNUNET_free (token);
257}
258
259void
260token_add_attr (struct IdentityToken *token,
261 const char* key,
262 const char* value)
263{
264 struct TokenAttr *attr;
265 struct TokenAttrValue *new_val;
266 GNUNET_assert (NULL != token);
267
268 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
269 new_val->value = GNUNET_strdup (value);
270 for (attr = token->attr_head; NULL != attr; attr = attr->next)
271 {
272 if (0 == strcmp (key, attr->name))
273 break;
274 }
275
276 if (NULL == attr)
277 {
278 attr = GNUNET_malloc (sizeof (struct TokenAttr));
279 attr->name = GNUNET_strdup (key);
280 GNUNET_CONTAINER_DLL_insert (token->attr_head,
281 token->attr_tail,
282 attr);
283 }
284
285 GNUNET_CONTAINER_DLL_insert (attr->val_head,
286 attr->val_tail,
287 new_val);
288}
289
290void
291token_add_attr_int (struct IdentityToken *token,
292 const char* key,
293 uint64_t value)
294{
295 struct TokenAttr *attr;
296 struct TokenAttrValue *new_val;
297 GNUNET_assert (NULL != token);
298
299 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
300 new_val->int_value = value;
301 for (attr = token->attr_head; NULL != attr; attr = attr->next)
302 {
303 if (0 == strcmp (key, attr->name))
304 break;
305 }
306
307 if (NULL == attr)
308 {
309 attr = GNUNET_malloc (sizeof (struct TokenAttr));
310 attr->name = GNUNET_strdup (key);
311 GNUNET_CONTAINER_DLL_insert (token->attr_head,
312 token->attr_tail,
313 attr);
314 }
315
316 GNUNET_CONTAINER_DLL_insert (attr->val_head,
317 attr->val_tail,
318 new_val);
319}
320
321static void
322parse_json_payload(const char* payload_base64,
323 struct IdentityToken *token)
324{
325 const char *key;
326 const json_t *value;
327 const json_t *arr_value;
328 char *payload;
329 int idx;
330 json_t *payload_json;
331 json_error_t err_json;
332
333 GNUNET_STRINGS_base64_decode (payload_base64,
334 strlen (payload_base64),
335 &payload);
336 //TODO signature and aud key
337 payload_json = json_loads (payload, JSON_DECODE_ANY, &err_json);
338
339 json_object_foreach (payload_json, key, value)
340 {
341 if (json_is_array (value))
342 {
343 json_array_foreach (value, idx, arr_value)
344 {
345 if (json_is_integer (arr_value))
346 token_add_attr_int (token, key,
347 json_integer_value (arr_value));
348 else
349 token_add_attr (token,
350 key,
351 json_string_value (arr_value));
352 }
353 } else {
354 if (json_is_integer (value))
355 token_add_attr_int (token, key,
356 json_integer_value (value));
357 else
358 token_add_attr (token, key, json_string_value (value));
359 }
360 }
361
362 json_decref (payload_json);
363 GNUNET_free (payload);
364}
365
366int
367token_parse2 (const char* raw_data,
368 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
369 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
370 struct IdentityToken **result)
371{
372 char *enc_token_str;
373 char *tmp_buf;
374 char *token_str;
375 char *enc_token;
376 char *payload_base64;
377 size_t enc_token_len;
378
379 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
380 strtok (tmp_buf, ",");
381 enc_token_str = strtok (NULL, ",");
382
383 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
384 strlen (enc_token_str),
385 &enc_token);
386 if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key,
387 aud_key,
388 enc_token,
389 enc_token_len,
390 &token_str))
391 {
392 GNUNET_free (tmp_buf);
393 GNUNET_free (enc_token);
394 return GNUNET_SYSERR;
395 }
396
397 GNUNET_assert (NULL != strtok (token_str, "."));
398 payload_base64 = strtok (NULL, ".");
399
400 *result = GNUNET_malloc (sizeof (struct IdentityToken));
401 parse_json_payload (payload_base64, *result);
402
403 (*result)->aud_key = *aud_key;
404 GNUNET_free (enc_token);
405 GNUNET_free (token_str);
406 GNUNET_free (tmp_buf);
407 return GNUNET_OK;
408}
409
410int
411token_parse (const char* raw_data,
412 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
413 struct IdentityToken **result)
414{
415 char *ecdh_pubkey_str;
416 char *enc_token_str;
417 char *tmp_buf;
418 char *token_str;
419 char *enc_token;
420 char *payload_base64;
421 size_t enc_token_len;
422 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
423
424 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
425 ecdh_pubkey_str = strtok (tmp_buf, ",");
426 enc_token_str = strtok (NULL, ",");
427
428 GNUNET_assert (NULL != ecdh_pubkey_str);
429 GNUNET_assert (NULL != enc_token_str);
430
431 GNUNET_STRINGS_string_to_data (ecdh_pubkey_str,
432 strlen (ecdh_pubkey_str),
433 &ecdh_pubkey,
434 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
435 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
436 strlen (enc_token_str),
437 &enc_token);
438 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
439 &ecdh_pubkey,
440 enc_token,
441 enc_token_len,
442 &token_str))
443 {
444 GNUNET_free (tmp_buf);
445 GNUNET_free (enc_token);
446 return GNUNET_SYSERR;
447 }
448
449 GNUNET_assert (NULL != strtok (token_str, "."));
450 payload_base64 = strtok (NULL, ".");
451
452 *result = GNUNET_malloc (sizeof (struct IdentityToken));
453 parse_json_payload (payload_base64, *result);
454
455 GNUNET_free (enc_token);
456 GNUNET_free (token_str);
457 GNUNET_free (tmp_buf);
458 return GNUNET_OK;
459}
460
461static char*
462create_json_payload (const struct IdentityToken *token)
463{
464 struct TokenAttr *attr;
465 struct TokenAttrValue *val;
466 json_t *root;
467 char *json_str;
468
469 root = json_object();
470 for (attr = token->attr_head; NULL != attr; attr = attr->next)
471 {
472 for (val = attr->val_head; NULL != val; val = val->next)
473 {
474 if (NULL != val->value)
475 {
476 json_object_set_new (root,
477 attr->name,
478 json_string (val->value));
479 } else {
480 json_object_set_new (root,
481 attr->name,
482 json_integer (val->int_value));
483 }
484 }
485 }
486 json_str = json_dumps (root, JSON_INDENT(1));
487 json_decref (root);
488 return json_str;
489}
490
491static char*
492create_json_header(void)
493{
494 json_t *root;
495 char *json_str;
496
497 root = json_object ();
498 json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
499 json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
500
501 json_str = json_dumps (root, JSON_INDENT(1));
502 json_decref (root);
503 return json_str;
504}
505
506int
507token_to_string (const struct IdentityToken *token,
508 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
509 char **result)
510{
511 char *payload_str;
512 char *header_str;
513 char *payload_base64;
514 char *header_base64;
515 char *padding;
516 char *signature_target;
517 char *signature_str;
518 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
519 header_str = create_json_header();
520 GNUNET_STRINGS_base64_encode (header_str,
521 strlen (header_str),
522 &header_base64);
523 //Remove GNUNET padding of base64
524 padding = strtok(header_base64, "=");
525 while (NULL != padding)
526 padding = strtok(NULL, "=");
527
528 payload_str = create_json_payload (token);
529 GNUNET_STRINGS_base64_encode (payload_str,
530 strlen (payload_str),
531 &payload_base64);
532
533 //Remove GNUNET padding of base64
534 padding = strtok(payload_base64, "=");
535 while (NULL != padding)
536 padding = strtok(NULL, "=");
537
538 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64);
539 purpose =
540 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
541 strlen (signature_target));
542 purpose->size =
543 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
544 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
545 GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target));
546 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
547 purpose,
548 (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature))
549 {
550 GNUNET_free (signature_target);
551 GNUNET_free (payload_str);
552 GNUNET_free (payload_base64);
553 GNUNET_free (header_base64);
554 GNUNET_free (purpose);
555 return GNUNET_SYSERR;
556 }
557
558 GNUNET_STRINGS_base64_encode ((const char*)&token->signature,
559 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
560 &signature_str);
561 GNUNET_asprintf (result, "%s.%s.%s",
562 header_base64, payload_base64, signature_str);
563 GNUNET_free (signature_target);
564 GNUNET_free (payload_str);
565 GNUNET_free (header_str);
566 GNUNET_free (signature_str);
567 GNUNET_free (payload_base64);
568 GNUNET_free (header_base64);
569 GNUNET_free (purpose);
570 return GNUNET_OK;
571}
572
573int
574token_serialize (const struct IdentityToken *token,
575 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
576 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
577 char **result)
578{
579 char *token_str;
580 char *enc_token;
581 char *dh_key_str;
582 char *enc_token_base64;
583 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
584
585 GNUNET_assert (GNUNET_OK == token_to_string (token,
586 priv_key,
587 &token_str));
588
589 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
590 &token->aud_key,
591 &enc_token,
592 ecdh_privkey,
593 &ecdh_pubkey));
594 GNUNET_STRINGS_base64_encode (enc_token,
595 strlen (token_str),
596 &enc_token_base64);
597 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
598 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
599 GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64);
600 GNUNET_free (dh_key_str);
601 GNUNET_free (enc_token_base64);
602 GNUNET_free (enc_token);
603 GNUNET_free (token_str);
604 return GNUNET_OK;
605}
606
607struct TokenTicketPayload*
608ticket_payload_create (uint64_t nonce,
609 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
610 const char* lbl_str)
611{
612 struct TokenTicketPayload* payload;
613
614 payload = GNUNET_malloc (sizeof (struct TokenTicketPayload));
615 payload->nonce = nonce;
616 payload->identity_key = *identity_pkey;
617 GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str));
618 return payload;
619}
620
621void
622ticket_payload_destroy (struct TokenTicketPayload* payload)
623{
624 if (NULL != payload->label)
625 GNUNET_free (payload->label);
626 GNUNET_free (payload);
627}
628
629void
630ticket_payload_serialize (struct TokenTicketPayload *payload,
631 char **result)
632{
633 char* identity_key_str;
634
635 identity_key_str = GNUNET_STRINGS_data_to_string_alloc (&payload->identity_key,
636 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
637
638 GNUNET_asprintf (result,
639 "{\"nonce\": \"%"SCNu64"\",\"identity\": \"%s\",\"label\": \"%s\"}",
640 payload->nonce, identity_key_str, payload->label);
641 GNUNET_free (identity_key_str);
642
643}
644
645
646/**
647 * Create the token code
648 * The data is encrypted with a share ECDH derived secret using B (aud_key)
649 * and e (ecdh_privkey)
650 * The ticket also contains E (ecdh_pubkey) and a signature over the
651 * data and E
652 */
653struct TokenTicket*
654ticket_create (uint64_t nonce,
655 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
656 const char* lbl_str,
657 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
658{
659 struct TokenTicket *ticket;
660 struct TokenTicketPayload *code_payload;
661
662 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
663 code_payload = ticket_payload_create (nonce,
664 identity_pkey,
665 lbl_str);
666 ticket->aud_key = *aud_key;
667 ticket->payload = code_payload;
668
669
670 return ticket;
671}
672
673void
674ticket_destroy (struct TokenTicket *ticket)
675{
676 ticket_payload_destroy (ticket->payload);
677 GNUNET_free (ticket);
678}
679
680int
681ticket_serialize (struct TokenTicket *ticket,
682 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
683 char **result)
684{
685 char *code_payload_str;
686 char *enc_ticket_payload;
687 char *ticket_payload_str;
688 char *ticket_sig_str;
689 char *ticket_str;
690 char *dh_key_str;
691 char *write_ptr;
692 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
693
694 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
695
696 ticket_payload_serialize (ticket->payload,
697 &code_payload_str);
698
699 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
700 &ticket->aud_key,
701 &enc_ticket_payload,
702 &ecdhe_privkey,
703 &ticket->ecdh_pubkey));
704
705 GNUNET_free (ecdhe_privkey);
706
707 purpose =
708 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
709 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
710 strlen (code_payload_str)); // E_K (code_str)
711 purpose->size =
712 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
713 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
714 strlen (code_payload_str));
715 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
716 write_ptr = (char*) &purpose[1];
717 GNUNET_memcpy (write_ptr,
718 &ticket->ecdh_pubkey,
719 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
720 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
721 GNUNET_memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str));
722 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
723 purpose,
724 &ticket->signature));
725 GNUNET_STRINGS_base64_encode (enc_ticket_payload,
726 strlen (code_payload_str),
727 &ticket_payload_str);
728 ticket_sig_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->signature,
729 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
730
731 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey,
732 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
733 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
734 GNUNET_asprintf (&ticket_str, "{\"data\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}",
735 ticket_payload_str, dh_key_str, ticket_sig_str);
736 GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result);
737 GNUNET_free (dh_key_str);
738 GNUNET_free (purpose);
739 GNUNET_free (ticket_str);
740 GNUNET_free (ticket_sig_str);
741 GNUNET_free (code_payload_str);
742 GNUNET_free (enc_ticket_payload);
743 GNUNET_free (ticket_payload_str);
744 return GNUNET_OK;
745}
746
747int
748ticket_payload_parse(const char *raw_data,
749 ssize_t data_len,
750 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
751 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
752 struct TokenTicketPayload **result)
753{
754 const char* label_str;
755 const char* nonce_str;
756 const char* identity_key_str;
757
758 json_t *root;
759 json_t *label_json;
760 json_t *identity_json;
761 json_t *nonce_json;
762 json_error_t err_json;
763 char* data_str;
764 uint64_t nonce;
765 struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey;
766
767 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
768 ecdhe_pkey,
769 raw_data,
770 data_len,
771 &data_str))
772 {
773 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Data decryption failed\n");
774 return GNUNET_SYSERR;
775 }
776
777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data: %s\n", data_str);
778 root = json_loads (data_str, JSON_DECODE_ANY, &err_json);
779 if (!root)
780 {
781 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
782 "Error parsing data: %s\n", err_json.text);
783 GNUNET_free (data_str);
784 return GNUNET_SYSERR;
785 }
786
787 identity_json = json_object_get (root, "identity");
788 if (!json_is_string (identity_json))
789 {
790 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
791 "Error parsing data: %s\n", err_json.text);
792 json_decref (root);
793 GNUNET_free (data_str);
794 return GNUNET_SYSERR;
795 }
796 identity_key_str = json_string_value (identity_json);
797 GNUNET_STRINGS_string_to_data (identity_key_str,
798 strlen (identity_key_str),
799 &id_pkey,
800 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
801
802
803 label_json = json_object_get (root, "label");
804 if (!json_is_string (label_json))
805 {
806 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
807 "Error parsing data: %s\n", err_json.text);
808 json_decref (root);
809 GNUNET_free (data_str);
810 return GNUNET_SYSERR;
811 }
812
813 label_str = json_string_value (label_json);
814 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str);
815
816 nonce_json = json_object_get (root, "nonce");
817 if (!json_is_string (label_json))
818 {
819 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
820 "Error parsing data: %s\n", err_json.text);
821 json_decref (root);
822 GNUNET_free (data_str);
823 return GNUNET_SYSERR;
824 }
825
826 nonce_str = json_string_value (nonce_json);
827 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str);
828
829 GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce));
830
831 *result = ticket_payload_create (nonce,
832 (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
833 label_str);
834 GNUNET_free (data_str);
835 json_decref (root);
836 return GNUNET_OK;
837
838}
839
840int
841ticket_parse (const char *raw_data,
842 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
843 struct TokenTicket **result)
844{
845 const char* enc_data_str;
846 const char* ecdh_enc_str;
847 const char* signature_enc_str;
848
849 json_t *root;
850 json_t *signature_json;
851 json_t *ecdh_json;
852 json_t *enc_data_json;
853 json_error_t err_json;
854 char* enc_data;
855 char* ticket_decoded;
856 char* write_ptr;
857 size_t enc_data_len;
858 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
859 struct TokenTicket *ticket;
860 struct TokenTicketPayload *ticket_payload;
861
862 ticket_decoded = NULL;
863 GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded);
864 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded);
865 root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json);
866 if (!root)
867 {
868 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
869 "%s\n", err_json.text);
870 return GNUNET_SYSERR;
871 }
872
873 signature_json = json_object_get (root, "signature");
874 ecdh_json = json_object_get (root, "ecdh");
875 enc_data_json = json_object_get (root, "data");
876
877 signature_enc_str = json_string_value (signature_json);
878 ecdh_enc_str = json_string_value (ecdh_json);
879 enc_data_str = json_string_value (enc_data_json);
880
881 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
882
883 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
884 strlen (ecdh_enc_str),
885 &ticket->ecdh_pubkey,
886 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)))
887 {
888 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in data\n", ecdh_enc_str);
889 json_decref (root);
890 GNUNET_free (ticket);
891 return GNUNET_SYSERR;
892 }
893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for data decryption\n", ecdh_enc_str);
894 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str,
895 strlen (signature_enc_str),
896 &ticket->signature,
897 sizeof (struct GNUNET_CRYPTO_EcdsaSignature)))
898 {
899 json_decref (root);
900 GNUNET_free (ticket_decoded);
901 GNUNET_free (ticket);
902 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in data\n");
903 return GNUNET_SYSERR;
904 }
905
906 enc_data_len = GNUNET_STRINGS_base64_decode (enc_data_str,
907 strlen (enc_data_str),
908 &enc_data);
909
910
911 if (GNUNET_OK != ticket_payload_parse (enc_data,
912 enc_data_len,
913 priv_key,
914 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
915 &ticket_payload))
916 {
917 json_decref (root);
918 GNUNET_free (enc_data);
919 GNUNET_free (ticket_decoded);
920 GNUNET_free (ticket);
921 return GNUNET_SYSERR;
922 }
923
924 ticket->payload = ticket_payload;
925 purpose =
926 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
927 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
928 enc_data_len); // E_K (code_str)
929 purpose->size =
930 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
931 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
932 enc_data_len);
933 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
934 write_ptr = (char*) &purpose[1];
935 GNUNET_memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
936 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
937 GNUNET_memcpy (write_ptr, enc_data, enc_data_len);
938
939 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET,
940 purpose,
941 &ticket->signature,
942 &ticket_payload->identity_key))
943 {
944 ticket_destroy (ticket);
945 GNUNET_free (ticket_decoded);
946 json_decref (root);
947 GNUNET_free (purpose);
948 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
949 "Error verifying signature for ticket\n");
950 return GNUNET_SYSERR;
951 }
952 *result = ticket;
953 GNUNET_free (purpose);
954
955 GNUNET_free (enc_data);
956 GNUNET_free (ticket_decoded);
957 json_decref (root);
958 return GNUNET_OK;
959
960}
961
962
963
964/* end of identity_token.c */