2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
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.
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.
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.
22 * @file identity-provider/identity_token.c
23 * @brief helper library to manage identity tokens
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "gnunet_signatures.h"
29 #include "identity_token.h"
35 #define JWT_ALG_VALUE "ED512"
39 #define JWT_TYP_VALUE "jwt"
42 * Crypto helper functions
46 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
47 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
48 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
50 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
52 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
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),
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),
71 * Decrypts data part from a token code
74 decrypt_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,
80 struct GNUNET_HashCode new_key_hash;
81 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
82 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
84 char *str_buf = GNUNET_malloc (cyphertext_len);
87 //Calculate symmetric key from ecdh parameters
88 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key,
92 create_sym_key_from_ecdh (&new_key_hash,
96 str_size = GNUNET_CRYPTO_symmetric_decrypt (cyphertext,
101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
102 "Decrypted bytes: %zd Expected bytes: %zd\n",
107 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
108 GNUNET_free (str_buf);
109 return GNUNET_SYSERR;
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);
120 * Decrypt string using pubkey and ECDHE
123 decrypt_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,
129 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
130 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
131 struct GNUNET_HashCode new_key_hash;
133 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
134 *plaintext = GNUNET_malloc (ciphertext_len);
136 // Derived key K = H(eB)
137 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
140 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
141 GNUNET_CRYPTO_symmetric_decrypt (ciphertext,
150 * Encrypt string using pubkey and ECDHE
151 * Returns ECDHE pubkey to be used for decryption
154 encrypt_str_ecdhe (const char *plaintext,
155 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
157 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
158 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey)
160 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
161 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
162 struct GNUNET_HashCode new_key_hash;
165 // ECDH keypair E = eG
166 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
167 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
170 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
171 *cyphertext = GNUNET_malloc (strlen (plaintext));
173 // Derived key K = H(eB)
174 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
177 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%zd)",
181 enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext,
185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%zd)", enc_size);
196 * Create an Identity Token
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.
202 struct IdentityToken*
203 token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
204 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud)
206 struct IdentityToken *token;
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));
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);
226 token_destroy (struct IdentityToken *token)
228 struct TokenAttr *attr;
229 struct TokenAttr *tmp_attr;
230 struct TokenAttrValue *val;
231 struct TokenAttrValue *tmp_val;
233 for (attr = token->attr_head; NULL != attr;)
235 tmp_attr = attr->next;
236 GNUNET_CONTAINER_DLL_remove (token->attr_head,
239 for (val = attr->val_head; NULL != val;)
242 GNUNET_CONTAINER_DLL_remove (attr->val_head,
245 if (NULL != val->value)
246 GNUNET_free (val->value);
250 GNUNET_free (attr->name);
260 token_add_attr_json (struct IdentityToken *token,
264 struct TokenAttr *attr;
265 struct TokenAttrValue *new_val;
266 GNUNET_assert (NULL != token);
268 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
269 new_val->json_value = value;
271 for (attr = token->attr_head; NULL != attr; attr = attr->next)
273 if (0 == strcmp (key, attr->name))
279 attr = GNUNET_malloc (sizeof (struct TokenAttr));
280 attr->name = GNUNET_strdup (key);
281 GNUNET_CONTAINER_DLL_insert (token->attr_head,
286 GNUNET_CONTAINER_DLL_insert (attr->val_head,
292 token_add_attr (struct IdentityToken *token,
296 struct TokenAttr *attr;
297 struct TokenAttrValue *new_val;
298 GNUNET_assert (NULL != token);
300 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
301 new_val->value = GNUNET_strdup (value);
302 for (attr = token->attr_head; NULL != attr; attr = attr->next)
304 if (0 == strcmp (key, attr->name))
310 attr = GNUNET_malloc (sizeof (struct TokenAttr));
311 attr->name = GNUNET_strdup (key);
312 GNUNET_CONTAINER_DLL_insert (token->attr_head,
317 GNUNET_CONTAINER_DLL_insert (attr->val_head,
323 token_add_attr_int (struct IdentityToken *token,
327 struct TokenAttr *attr;
328 struct TokenAttrValue *new_val;
329 GNUNET_assert (NULL != token);
331 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
332 new_val->int_value = value;
333 for (attr = token->attr_head; NULL != attr; attr = attr->next)
335 if (0 == strcmp (key, attr->name))
341 attr = GNUNET_malloc (sizeof (struct TokenAttr));
342 attr->name = GNUNET_strdup (key);
343 GNUNET_CONTAINER_DLL_insert (token->attr_head,
348 GNUNET_CONTAINER_DLL_insert (attr->val_head,
354 parse_json_payload(const char* payload_base64,
355 struct IdentityToken *token)
359 const json_t *arr_value;
362 json_t *payload_json;
363 json_error_t err_json;
365 GNUNET_STRINGS_base64_decode (payload_base64,
366 strlen (payload_base64),
368 //TODO signature and aud key
369 payload_json = json_loads (payload, JSON_DECODE_ANY, &err_json);
371 json_object_foreach (payload_json, key, value)
373 if (json_is_array (value))
375 json_array_foreach (value, idx, arr_value)
377 if (json_is_integer (arr_value))
378 token_add_attr_int (token, key,
379 json_integer_value (arr_value));
380 else if (json_is_string (arr_value))
381 token_add_attr (token,
383 json_string_value (arr_value));
385 token_add_attr_json (token,
390 if (json_is_integer (value))
391 token_add_attr_int (token, key,
392 json_integer_value (value));
393 else if (json_is_string (value))
394 token_add_attr (token, key, json_string_value (value));
396 token_add_attr_json (token, key, (json_t*)value);
400 json_decref (payload_json);
401 GNUNET_free (payload);
405 token_parse2 (const char* raw_data,
406 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
407 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
408 struct IdentityToken **result)
414 char *payload_base64;
415 size_t enc_token_len;
417 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
418 strtok (tmp_buf, ",");
419 enc_token_str = strtok (NULL, ",");
421 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
422 strlen (enc_token_str),
424 if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key,
430 GNUNET_free (tmp_buf);
431 GNUNET_free (enc_token);
432 return GNUNET_SYSERR;
435 GNUNET_assert (NULL != strtok (token_str, "."));
436 payload_base64 = strtok (NULL, ".");
438 *result = GNUNET_malloc (sizeof (struct IdentityToken));
439 parse_json_payload (payload_base64, *result);
441 (*result)->aud_key = *aud_key;
442 GNUNET_free (enc_token);
443 GNUNET_free (token_str);
444 GNUNET_free (tmp_buf);
449 token_parse (const char* raw_data,
450 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
451 struct IdentityToken **result)
453 char *ecdh_pubkey_str;
458 char *payload_base64;
459 size_t enc_token_len;
460 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
462 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
463 ecdh_pubkey_str = strtok (tmp_buf, ",");
464 enc_token_str = strtok (NULL, ",");
466 GNUNET_assert (NULL != ecdh_pubkey_str);
467 GNUNET_assert (NULL != enc_token_str);
469 GNUNET_STRINGS_string_to_data (ecdh_pubkey_str,
470 strlen (ecdh_pubkey_str),
472 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
473 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
474 strlen (enc_token_str),
476 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
482 GNUNET_free (tmp_buf);
483 GNUNET_free (enc_token);
484 return GNUNET_SYSERR;
487 GNUNET_assert (NULL != strtok (token_str, "."));
488 payload_base64 = strtok (NULL, ".");
490 *result = GNUNET_malloc (sizeof (struct IdentityToken));
491 parse_json_payload (payload_base64, *result);
493 GNUNET_free (enc_token);
494 GNUNET_free (token_str);
495 GNUNET_free (tmp_buf);
500 create_json_payload (const struct IdentityToken *token)
502 struct TokenAttr *attr;
503 struct TokenAttrValue *val;
507 root = json_object();
508 for (attr = token->attr_head; NULL != attr; attr = attr->next)
510 for (val = attr->val_head; NULL != val; val = val->next)
512 if (NULL != val->value)
514 json_object_set_new (root,
516 json_string (val->value));
517 } else if (NULL != val->json_value) {
518 json_object_set (root,
522 json_object_set_new (root,
524 json_integer (val->int_value));
528 json_str = json_dumps (root, JSON_INDENT(1));
534 create_json_header(void)
539 root = json_object ();
540 json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
541 json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
543 json_str = json_dumps (root, JSON_INDENT(1));
549 token_to_string (const struct IdentityToken *token,
550 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
555 char *payload_base64;
558 char *signature_target;
560 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
561 header_str = create_json_header();
562 GNUNET_STRINGS_base64_encode (header_str,
565 //Remove GNUNET padding of base64
566 padding = strtok(header_base64, "=");
567 while (NULL != padding)
568 padding = strtok(NULL, "=");
570 payload_str = create_json_payload (token);
571 GNUNET_STRINGS_base64_encode (payload_str,
572 strlen (payload_str),
575 //Remove GNUNET padding of base64
576 padding = strtok(payload_base64, "=");
577 while (NULL != padding)
578 padding = strtok(NULL, "=");
580 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64);
582 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
583 strlen (signature_target));
585 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
586 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
587 GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target));
588 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
590 (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature))
592 GNUNET_free (signature_target);
593 GNUNET_free (payload_str);
594 GNUNET_free (payload_base64);
595 GNUNET_free (header_base64);
596 GNUNET_free (purpose);
597 return GNUNET_SYSERR;
600 GNUNET_STRINGS_base64_encode ((const char*)&token->signature,
601 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
603 GNUNET_asprintf (result, "%s.%s.%s",
604 header_base64, payload_base64, signature_str);
605 GNUNET_free (signature_target);
606 GNUNET_free (payload_str);
607 GNUNET_free (header_str);
608 GNUNET_free (signature_str);
609 GNUNET_free (payload_base64);
610 GNUNET_free (header_base64);
611 GNUNET_free (purpose);
616 token_serialize (const struct IdentityToken *token,
617 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
618 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
624 char *enc_token_base64;
625 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
627 GNUNET_assert (GNUNET_OK == token_to_string (token,
631 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
636 GNUNET_STRINGS_base64_encode (enc_token,
639 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
640 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
641 GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64);
642 GNUNET_free (dh_key_str);
643 GNUNET_free (enc_token_base64);
644 GNUNET_free (enc_token);
645 GNUNET_free (token_str);
649 struct TokenTicketPayload*
650 ticket_payload_create (uint64_t nonce,
651 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
654 struct TokenTicketPayload* payload;
656 payload = GNUNET_malloc (sizeof (struct TokenTicketPayload));
657 payload->nonce = nonce;
658 payload->identity_key = *identity_pkey;
659 GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str));
664 ticket_payload_destroy (struct TokenTicketPayload* payload)
666 if (NULL != payload->label)
667 GNUNET_free (payload->label);
668 GNUNET_free (payload);
672 ticket_payload_serialize (struct TokenTicketPayload *payload,
675 char* identity_key_str;
677 identity_key_str = GNUNET_STRINGS_data_to_string_alloc (&payload->identity_key,
678 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
680 GNUNET_asprintf (result,
681 "{\"nonce\": \"%"SCNu64"\",\"identity\": \"%s\",\"label\": \"%s\"}",
682 payload->nonce, identity_key_str, payload->label);
683 GNUNET_free (identity_key_str);
689 * Create the token code
690 * The data is encrypted with a share ECDH derived secret using B (aud_key)
691 * and e (ecdh_privkey)
692 * The ticket also contains E (ecdh_pubkey) and a signature over the
696 ticket_create (uint64_t nonce,
697 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
699 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
701 struct TokenTicket *ticket;
702 struct TokenTicketPayload *code_payload;
704 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
705 code_payload = ticket_payload_create (nonce,
708 ticket->aud_key = *aud_key;
709 ticket->payload = code_payload;
716 ticket_destroy (struct TokenTicket *ticket)
718 ticket_payload_destroy (ticket->payload);
719 GNUNET_free (ticket);
723 ticket_serialize (struct TokenTicket *ticket,
724 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
727 char *code_payload_str;
728 char *enc_ticket_payload;
729 char *ticket_payload_str;
730 char *ticket_sig_str;
734 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
736 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
738 ticket_payload_serialize (ticket->payload,
741 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
745 &ticket->ecdh_pubkey));
747 GNUNET_free (ecdhe_privkey);
750 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
751 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
752 strlen (code_payload_str)); // E_K (code_str)
754 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
755 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
756 strlen (code_payload_str));
757 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
758 write_ptr = (char*) &purpose[1];
759 GNUNET_memcpy (write_ptr,
760 &ticket->ecdh_pubkey,
761 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
762 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
763 GNUNET_memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str));
764 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
766 &ticket->signature));
767 GNUNET_STRINGS_base64_encode (enc_ticket_payload,
768 strlen (code_payload_str),
769 &ticket_payload_str);
770 ticket_sig_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->signature,
771 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
773 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey,
774 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
775 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
776 GNUNET_asprintf (&ticket_str, "{\"data\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}",
777 ticket_payload_str, dh_key_str, ticket_sig_str);
778 GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result);
779 GNUNET_free (dh_key_str);
780 GNUNET_free (purpose);
781 GNUNET_free (ticket_str);
782 GNUNET_free (ticket_sig_str);
783 GNUNET_free (code_payload_str);
784 GNUNET_free (enc_ticket_payload);
785 GNUNET_free (ticket_payload_str);
790 ticket_payload_parse(const char *raw_data,
792 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
793 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
794 struct TokenTicketPayload **result)
796 const char* label_str;
797 const char* nonce_str;
798 const char* identity_key_str;
802 json_t *identity_json;
804 json_error_t err_json;
807 struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey;
809 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
815 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Data decryption failed\n");
816 return GNUNET_SYSERR;
819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data: %s\n", data_str);
820 root = json_loads (data_str, JSON_DECODE_ANY, &err_json);
823 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
824 "Error parsing data: %s\n", err_json.text);
825 GNUNET_free (data_str);
826 return GNUNET_SYSERR;
829 identity_json = json_object_get (root, "identity");
830 if (!json_is_string (identity_json))
832 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
833 "Error parsing data: %s\n", err_json.text);
835 GNUNET_free (data_str);
836 return GNUNET_SYSERR;
838 identity_key_str = json_string_value (identity_json);
839 GNUNET_STRINGS_string_to_data (identity_key_str,
840 strlen (identity_key_str),
842 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
845 label_json = json_object_get (root, "label");
846 if (!json_is_string (label_json))
848 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
849 "Error parsing data: %s\n", err_json.text);
851 GNUNET_free (data_str);
852 return GNUNET_SYSERR;
855 label_str = json_string_value (label_json);
856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str);
858 nonce_json = json_object_get (root, "nonce");
859 if (!json_is_string (label_json))
861 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
862 "Error parsing data: %s\n", err_json.text);
864 GNUNET_free (data_str);
865 return GNUNET_SYSERR;
868 nonce_str = json_string_value (nonce_json);
869 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str);
871 GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce));
873 *result = ticket_payload_create (nonce,
874 (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
876 GNUNET_free (data_str);
883 ticket_parse (const char *raw_data,
884 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
885 struct TokenTicket **result)
887 const char* enc_data_str;
888 const char* ecdh_enc_str;
889 const char* signature_enc_str;
892 json_t *signature_json;
894 json_t *enc_data_json;
895 json_error_t err_json;
897 char* ticket_decoded;
900 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
901 struct TokenTicket *ticket;
902 struct TokenTicketPayload *ticket_payload;
904 ticket_decoded = NULL;
905 GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded);
906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded);
907 root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json);
910 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
911 "%s\n", err_json.text);
912 return GNUNET_SYSERR;
915 signature_json = json_object_get (root, "signature");
916 ecdh_json = json_object_get (root, "ecdh");
917 enc_data_json = json_object_get (root, "data");
919 signature_enc_str = json_string_value (signature_json);
920 ecdh_enc_str = json_string_value (ecdh_json);
921 enc_data_str = json_string_value (enc_data_json);
923 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
925 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
926 strlen (ecdh_enc_str),
927 &ticket->ecdh_pubkey,
928 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)))
930 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in data\n", ecdh_enc_str);
932 GNUNET_free (ticket);
933 return GNUNET_SYSERR;
935 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for data decryption\n", ecdh_enc_str);
936 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str,
937 strlen (signature_enc_str),
939 sizeof (struct GNUNET_CRYPTO_EcdsaSignature)))
942 GNUNET_free (ticket_decoded);
943 GNUNET_free (ticket);
944 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in data\n");
945 return GNUNET_SYSERR;
948 enc_data_len = GNUNET_STRINGS_base64_decode (enc_data_str,
949 strlen (enc_data_str),
953 if (GNUNET_OK != ticket_payload_parse (enc_data,
956 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
960 GNUNET_free (enc_data);
961 GNUNET_free (ticket_decoded);
962 GNUNET_free (ticket);
963 return GNUNET_SYSERR;
966 ticket->payload = ticket_payload;
968 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
969 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
970 enc_data_len); // E_K (code_str)
972 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
973 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
975 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
976 write_ptr = (char*) &purpose[1];
977 GNUNET_memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
978 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
979 GNUNET_memcpy (write_ptr, enc_data, enc_data_len);
981 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET,
984 &ticket_payload->identity_key))
986 ticket_destroy (ticket);
987 GNUNET_free (ticket_decoded);
989 GNUNET_free (purpose);
990 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
991 "Error verifying signature for ticket\n");
992 return GNUNET_SYSERR;
995 GNUNET_free (purpose);
997 GNUNET_free (enc_data);
998 GNUNET_free (ticket_decoded);
1006 /* end of identity_token.c */