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-token/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"
34 #define JWT_ALG_VALUE "ED512"
38 #define JWT_TYP_VALUE "jwt"
41 * Crypto helper functions
45 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
46 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
47 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
49 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
51 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
53 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
54 static const char ctx_key[] = "gnuid-aes-ctx-key";
55 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
56 new_key_hash, sizeof (struct GNUNET_HashCode),
57 ctx_key, strlen (ctx_key),
59 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
60 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
61 new_key_hash, sizeof (struct GNUNET_HashCode),
62 ctx_iv, strlen (ctx_iv),
70 * Decrypts data part from a token code
73 decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
74 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key,
75 const char *cyphertext,
76 size_t cyphertext_len,
79 struct GNUNET_HashCode new_key_hash;
80 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
81 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
83 char *str_buf = GNUNET_malloc (cyphertext_len);
86 //Calculate symmetric key from ecdh parameters
87 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key,
91 create_sym_key_from_ecdh (&new_key_hash,
95 str_size = GNUNET_CRYPTO_symmetric_decrypt (cyphertext,
100 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypted bytes: %d Expected bytes: %d\n", str_size, cyphertext_len);
103 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
104 GNUNET_free (str_buf);
105 return GNUNET_SYSERR;
107 *result_str = GNUNET_malloc (str_size+1);
108 memcpy (*result_str, str_buf, str_size);
109 (*result_str)[str_size] = '\0';
110 GNUNET_free (str_buf);
116 * Decrypt string using pubkey and ECDHE
119 decrypt_str_ecdhe2 (const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey,
120 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
121 const char *ciphertext,
122 size_t ciphertext_len,
125 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
126 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
127 struct GNUNET_HashCode new_key_hash;
129 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
130 *plaintext = GNUNET_malloc (ciphertext_len);
132 // Derived key K = H(eB)
133 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
136 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
137 GNUNET_CRYPTO_symmetric_decrypt (ciphertext,
146 * Encrypt string using pubkey and ECDHE
147 * Returns ECDHE pubkey to be used for decryption
150 encrypt_str_ecdhe (const char *plaintext,
151 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
153 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
154 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey)
156 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
157 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
158 struct GNUNET_HashCode new_key_hash;
161 // ECDH keypair E = eG
162 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
163 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
166 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
167 *cyphertext = GNUNET_malloc (strlen (plaintext));
169 // Derived key K = H(eB)
170 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
173 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%d)",
177 enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext,
181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%d)", enc_size);
192 * Create an Identity Token
194 * @param type the JSON API resource type
195 * @param id the JSON API resource id
196 * @return a new JSON API resource or NULL on error.
198 struct IdentityToken*
199 token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
200 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud)
202 struct IdentityToken *token;
206 issuer = GNUNET_STRINGS_data_to_string_alloc (iss,
207 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
208 audience = GNUNET_STRINGS_data_to_string_alloc (aud,
209 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
211 token = GNUNET_malloc (sizeof (struct IdentityToken));
212 token_add_attr (token, "iss", issuer);
213 token_add_attr (token, "aud", audience);
214 token_add_attr (token, "sub", issuer);
215 token->aud_key = *aud;
216 GNUNET_free (issuer);
217 GNUNET_free (audience);
222 token_destroy (struct IdentityToken *token)
224 struct TokenAttr *attr;
225 struct TokenAttr *tmp_attr;
226 struct TokenAttrValue *val;
227 struct TokenAttrValue *tmp_val;
229 for (attr = token->attr_head; NULL != attr;)
231 tmp_attr = attr->next;
232 GNUNET_CONTAINER_DLL_remove (token->attr_head,
235 for (val = attr->val_head; NULL != val;)
238 GNUNET_CONTAINER_DLL_remove (attr->val_head,
241 if (NULL != val->value)
242 GNUNET_free (val->value);
246 GNUNET_free (attr->name);
256 token_add_attr (struct IdentityToken *token,
260 struct TokenAttr *attr;
261 struct TokenAttrValue *new_val;
262 GNUNET_assert (NULL != token);
264 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
265 new_val->value = GNUNET_strdup (value);
266 for (attr = token->attr_head; NULL != attr; attr = attr->next)
268 if (0 == strcmp (key, attr->name))
274 attr = GNUNET_malloc (sizeof (struct TokenAttr));
275 attr->name = GNUNET_strdup (key);
276 GNUNET_CONTAINER_DLL_insert (token->attr_head,
281 GNUNET_CONTAINER_DLL_insert (attr->val_head,
287 token_add_attr_int (struct IdentityToken *token,
291 struct TokenAttr *attr;
292 struct TokenAttrValue *new_val;
293 GNUNET_assert (NULL != token);
295 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
296 new_val->int_value = value;
297 for (attr = token->attr_head; NULL != attr; attr = attr->next)
299 if (0 == strcmp (key, attr->name))
305 attr = GNUNET_malloc (sizeof (struct TokenAttr));
306 attr->name = GNUNET_strdup (key);
307 GNUNET_CONTAINER_DLL_insert (token->attr_head,
312 GNUNET_CONTAINER_DLL_insert (attr->val_head,
318 parse_json_payload(const char* payload_base64,
319 struct IdentityToken *token)
323 const json_t *arr_value;
326 json_t *payload_json;
327 json_error_t err_json;
329 GNUNET_STRINGS_base64_decode (payload_base64,
330 strlen (payload_base64),
332 //TODO signature and aud key
333 payload_json = json_loads (payload, JSON_DECODE_ANY, &err_json);
335 json_object_foreach (payload_json, key, value)
337 if (json_is_array (value))
339 json_array_foreach (value, idx, arr_value)
341 if (json_is_integer (arr_value))
342 token_add_attr_int (token, key,
343 json_integer_value (arr_value));
345 token_add_attr (token,
347 json_string_value (arr_value));
350 if (json_is_integer (value))
351 token_add_attr_int (token, key,
352 json_integer_value (value));
354 token_add_attr (token, key, json_string_value (value));
358 json_decref (payload_json);
359 GNUNET_free (payload);
363 token_parse2 (const char* raw_data,
364 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
365 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
366 struct IdentityToken **result)
372 char *payload_base64;
373 size_t enc_token_len;
375 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
376 strtok (tmp_buf, ",");
377 enc_token_str = strtok (NULL, ",");
379 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
380 strlen (enc_token_str),
382 if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key,
388 GNUNET_free (tmp_buf);
389 GNUNET_free (enc_token);
390 return GNUNET_SYSERR;
393 GNUNET_assert (NULL != strtok (token_str, "."));
394 payload_base64 = strtok (NULL, ".");
396 *result = GNUNET_malloc (sizeof (struct IdentityToken));
397 parse_json_payload (payload_base64, *result);
399 (*result)->aud_key = *aud_key;
400 GNUNET_free (enc_token);
401 GNUNET_free (token_str);
402 GNUNET_free (tmp_buf);
407 token_parse (const char* raw_data,
408 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
409 struct IdentityToken **result)
411 char *ecdh_pubkey_str;
416 char *payload_base64;
417 size_t enc_token_len;
418 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
420 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
421 ecdh_pubkey_str = strtok (tmp_buf, ",");
422 enc_token_str = strtok (NULL, ",");
424 GNUNET_STRINGS_string_to_data (ecdh_pubkey_str,
425 strlen (ecdh_pubkey_str),
427 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
428 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
429 strlen (enc_token_str),
431 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
437 GNUNET_free (tmp_buf);
438 GNUNET_free (enc_token);
439 return GNUNET_SYSERR;
442 GNUNET_assert (NULL != strtok (token_str, "."));
443 payload_base64 = strtok (NULL, ".");
445 *result = GNUNET_malloc (sizeof (struct IdentityToken));
446 parse_json_payload (payload_base64, *result);
448 GNUNET_free (enc_token);
449 GNUNET_free (token_str);
450 GNUNET_free (tmp_buf);
455 create_json_payload (const struct IdentityToken *token)
457 struct TokenAttr *attr;
458 struct TokenAttrValue *val;
462 root = json_object();
463 for (attr = token->attr_head; NULL != attr; attr = attr->next)
465 for (val = attr->val_head; NULL != val; val = val->next)
467 if (NULL != val->value)
469 json_object_set_new (root,
471 json_string (val->value));
473 json_object_set_new (root,
475 json_integer (val->int_value));
479 json_str = json_dumps (root, JSON_INDENT(1));
485 create_json_header(void)
490 root = json_object ();
491 json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
492 json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
494 json_str = json_dumps (root, JSON_INDENT(1));
500 token_to_string (const struct IdentityToken *token,
501 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
506 char *payload_base64;
509 char *signature_target;
511 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
512 header_str = create_json_header();
513 GNUNET_STRINGS_base64_encode (header_str,
516 //Remove GNUNET padding of base64
517 padding = strtok(header_base64, "=");
518 while (NULL != padding)
519 padding = strtok(NULL, "=");
521 payload_str = create_json_payload (token);
522 GNUNET_STRINGS_base64_encode (payload_str,
523 strlen (payload_str),
526 //Remove GNUNET padding of base64
527 padding = strtok(payload_base64, "=");
528 while (NULL != padding)
529 padding = strtok(NULL, "=");
531 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64);
533 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
534 strlen (signature_target));
536 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
537 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
538 memcpy (&purpose[1], signature_target, strlen (signature_target));
539 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
541 (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature))
543 GNUNET_free (signature_target);
544 GNUNET_free (payload_str);
545 GNUNET_free (payload_base64);
546 GNUNET_free (purpose);
547 return GNUNET_SYSERR;
550 GNUNET_STRINGS_base64_encode ((const char*)&token->signature,
551 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
553 GNUNET_asprintf (result, "%s.%s.%s",
554 header_base64, payload_base64, signature_str);
555 GNUNET_free (signature_target);
556 GNUNET_free (payload_str);
557 GNUNET_free (header_str);
558 GNUNET_free (signature_str);
559 GNUNET_free (payload_base64);
560 GNUNET_free (header_base64);
561 GNUNET_free (purpose);
566 token_serialize (const struct IdentityToken *token,
567 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
568 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
574 char *enc_token_base64;
575 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
577 GNUNET_assert (GNUNET_OK == token_to_string (token,
581 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
586 GNUNET_STRINGS_base64_encode (enc_token,
589 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
590 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
591 GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64);
592 GNUNET_free (dh_key_str);
593 GNUNET_free (enc_token_base64);
594 GNUNET_free (enc_token);
595 GNUNET_free (token_str);
599 struct TokenTicketPayload*
600 ticket_payload_create (uint64_t nonce,
601 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
604 struct TokenTicketPayload* payload;
606 payload = GNUNET_malloc (sizeof (struct TokenTicketPayload));
607 payload->nonce = nonce;
608 payload->identity_key = *identity_pkey;
609 GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str));
614 ticket_payload_destroy (struct TokenTicketPayload* payload)
616 if (NULL != payload->label)
617 GNUNET_free (payload->label);
618 GNUNET_free (payload);
622 ticket_payload_serialize (struct TokenTicketPayload *payload,
625 char* identity_key_str;
627 identity_key_str = GNUNET_STRINGS_data_to_string_alloc (&payload->identity_key,
628 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
630 GNUNET_asprintf (result,
631 "{\"nonce\": \"%lu\",\"identity\": \"%s\",\"label\": \"%s\"}",
632 payload->nonce, identity_key_str, payload->label);
633 GNUNET_free (identity_key_str);
639 * Create the token code
640 * The data is encrypted with a share ECDH derived secret using B (aud_key)
641 * and e (ecdh_privkey)
642 * The ticket also contains E (ecdh_pubkey) and a signature over the
646 ticket_create (uint64_t nonce,
647 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
649 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
651 struct TokenTicket *ticket;
652 struct TokenTicketPayload *code_payload;
654 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
655 code_payload = ticket_payload_create (nonce,
658 ticket->aud_key = *aud_key;
659 ticket->payload = code_payload;
666 ticket_destroy (struct TokenTicket *ticket)
668 ticket_payload_destroy (ticket->payload);
669 GNUNET_free (ticket);
673 ticket_serialize (struct TokenTicket *ticket,
674 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
677 char *code_payload_str;
678 char *enc_ticket_payload;
679 char *ticket_payload_str;
680 char *ticket_sig_str;
684 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
686 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
688 ticket_payload_serialize (ticket->payload,
691 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
695 &ticket->ecdh_pubkey));
697 GNUNET_free (ecdhe_privkey);
700 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
701 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
702 strlen (code_payload_str)); // E_K (code_str)
704 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
705 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
706 strlen (code_payload_str));
707 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
708 write_ptr = (char*) &purpose[1];
710 &ticket->ecdh_pubkey,
711 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
712 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
713 memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str));
714 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
716 &ticket->signature));
717 GNUNET_STRINGS_base64_encode (enc_ticket_payload,
718 strlen (code_payload_str),
719 &ticket_payload_str);
720 ticket_sig_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->signature,
721 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
723 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey,
724 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
726 GNUNET_asprintf (&ticket_str, "{\"data\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}",
727 ticket_payload_str, dh_key_str, ticket_sig_str);
728 GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result);
729 GNUNET_free (dh_key_str);
730 GNUNET_free (purpose);
731 GNUNET_free (ticket_str);
732 GNUNET_free (ticket_sig_str);
733 GNUNET_free (code_payload_str);
734 GNUNET_free (enc_ticket_payload);
735 GNUNET_free (ticket_payload_str);
740 ticket_payload_parse(const char *raw_data,
742 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
743 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
744 struct TokenTicketPayload **result)
746 const char* label_str;
747 const char* nonce_str;
748 const char* identity_key_str;
752 json_t *identity_json;
754 json_error_t err_json;
757 struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey;
759 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
765 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Data decryption failed\n");
766 return GNUNET_SYSERR;
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data: %s\n", data_str);
770 root = json_loads (data_str, JSON_DECODE_ANY, &err_json);
773 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
774 "Error parsing data: %s\n", err_json.text);
775 GNUNET_free (data_str);
776 return GNUNET_SYSERR;
779 identity_json = json_object_get (root, "identity");
780 if (!json_is_string (identity_json))
782 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
783 "Error parsing data: %s\n", err_json.text);
785 GNUNET_free (data_str);
786 return GNUNET_SYSERR;
788 identity_key_str = json_string_value (identity_json);
789 GNUNET_STRINGS_string_to_data (identity_key_str,
790 strlen (identity_key_str),
792 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
795 label_json = json_object_get (root, "label");
796 if (!json_is_string (label_json))
798 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
799 "Error parsing data: %s\n", err_json.text);
801 GNUNET_free (data_str);
802 return GNUNET_SYSERR;
805 label_str = json_string_value (label_json);
806 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str);
808 nonce_json = json_object_get (root, "nonce");
809 if (!json_is_string (label_json))
811 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
812 "Error parsing data: %s\n", err_json.text);
814 GNUNET_free (data_str);
815 return GNUNET_SYSERR;
818 nonce_str = json_string_value (nonce_json);
819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str);
821 GNUNET_assert (0 != sscanf (nonce_str, "%lu", &nonce));
823 *result = ticket_payload_create (nonce,
824 (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
826 GNUNET_free (data_str);
833 ticket_parse (const char *raw_data,
834 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
835 struct TokenTicket **result)
837 const char* enc_data_str;
838 const char* ecdh_enc_str;
839 const char* signature_enc_str;
842 json_t *signature_json;
844 json_t *enc_data_json;
845 json_error_t err_json;
847 char* ticket_decoded;
850 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
851 struct TokenTicket *ticket;
852 struct TokenTicketPayload *ticket_payload;
854 ticket_decoded = NULL;
855 GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded);
856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded);
857 root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json);
860 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
861 "%s\n", err_json.text);
862 return GNUNET_SYSERR;
865 signature_json = json_object_get (root, "signature");
866 ecdh_json = json_object_get (root, "ecdh");
867 enc_data_json = json_object_get (root, "data");
869 signature_enc_str = json_string_value (signature_json);
870 ecdh_enc_str = json_string_value (ecdh_json);
871 enc_data_str = json_string_value (enc_data_json);
873 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
875 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
876 strlen (ecdh_enc_str),
877 &ticket->ecdh_pubkey,
878 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)))
880 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in data\n", ecdh_enc_str);
882 GNUNET_free (ticket);
883 return GNUNET_SYSERR;
885 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for data decryption\n", ecdh_enc_str);
886 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str,
887 strlen (signature_enc_str),
889 sizeof (struct GNUNET_CRYPTO_EcdsaSignature)))
892 GNUNET_free (ticket_decoded);
893 GNUNET_free (ticket);
894 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in data\n");
895 return GNUNET_SYSERR;
898 enc_data_len = GNUNET_STRINGS_base64_decode (enc_data_str,
899 strlen (enc_data_str),
903 if (GNUNET_OK != ticket_payload_parse (enc_data,
906 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
910 GNUNET_free (enc_data);
911 GNUNET_free (ticket_decoded);
912 GNUNET_free (ticket);
913 return GNUNET_SYSERR;
916 ticket->payload = ticket_payload;
918 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
919 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
920 enc_data_len); // E_K (code_str)
922 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
923 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
925 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
926 write_ptr = (char*) &purpose[1];
927 memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
928 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
929 memcpy (write_ptr, enc_data, enc_data_len);
931 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET,
934 &ticket_payload->identity_key))
936 ticket_destroy (ticket);
937 GNUNET_free (ticket_decoded);
939 GNUNET_free (purpose);
940 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
941 "Error verifying signature for ticket\n");
942 return GNUNET_SYSERR;
945 GNUNET_free (purpose);
947 GNUNET_free (enc_data);
948 GNUNET_free (ticket_decoded);
956 /* end of identity_token.c */