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"
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, "Decrypted bytes: %d Expected bytes: %d\n", str_size, cyphertext_len);
104 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
105 GNUNET_free (str_buf);
106 return GNUNET_SYSERR;
108 *result_str = GNUNET_malloc (str_size+1);
109 memcpy (*result_str, str_buf, str_size);
110 (*result_str)[str_size] = '\0';
111 GNUNET_free (str_buf);
117 * Decrypt string using pubkey and ECDHE
120 decrypt_str_ecdhe2 (const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey,
121 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
122 const char *ciphertext,
123 size_t ciphertext_len,
126 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
127 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
128 struct GNUNET_HashCode new_key_hash;
130 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
131 *plaintext = GNUNET_malloc (ciphertext_len);
133 // Derived key K = H(eB)
134 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
137 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
138 GNUNET_CRYPTO_symmetric_decrypt (ciphertext,
147 * Encrypt string using pubkey and ECDHE
148 * Returns ECDHE pubkey to be used for decryption
151 encrypt_str_ecdhe (const char *plaintext,
152 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
154 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
155 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey)
157 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
158 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
159 struct GNUNET_HashCode new_key_hash;
162 // ECDH keypair E = eG
163 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
164 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
167 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
168 *cyphertext = GNUNET_malloc (strlen (plaintext));
170 // Derived key K = H(eB)
171 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
174 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%d)",
178 enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext,
182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%d)", enc_size);
193 * Create an Identity Token
195 * @param type the JSON API resource type
196 * @param id the JSON API resource id
197 * @return a new JSON API resource or NULL on error.
199 struct IdentityToken*
200 token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
201 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud)
203 struct IdentityToken *token;
207 issuer = GNUNET_STRINGS_data_to_string_alloc (iss,
208 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
209 audience = GNUNET_STRINGS_data_to_string_alloc (aud,
210 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
212 token = GNUNET_malloc (sizeof (struct IdentityToken));
213 token_add_attr (token, "iss", issuer);
214 token_add_attr (token, "aud", audience);
215 token_add_attr (token, "sub", issuer);
216 token->aud_key = *aud;
217 GNUNET_free (issuer);
218 GNUNET_free (audience);
223 token_destroy (struct IdentityToken *token)
225 struct TokenAttr *attr;
226 struct TokenAttr *tmp_attr;
227 struct TokenAttrValue *val;
228 struct TokenAttrValue *tmp_val;
230 for (attr = token->attr_head; NULL != attr;)
232 tmp_attr = attr->next;
233 GNUNET_CONTAINER_DLL_remove (token->attr_head,
236 for (val = attr->val_head; NULL != val;)
239 GNUNET_CONTAINER_DLL_remove (attr->val_head,
242 if (NULL != val->value)
243 GNUNET_free (val->value);
247 GNUNET_free (attr->name);
257 token_add_attr (struct IdentityToken *token,
261 struct TokenAttr *attr;
262 struct TokenAttrValue *new_val;
263 GNUNET_assert (NULL != token);
265 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
266 new_val->value = GNUNET_strdup (value);
267 for (attr = token->attr_head; NULL != attr; attr = attr->next)
269 if (0 == strcmp (key, attr->name))
275 attr = GNUNET_malloc (sizeof (struct TokenAttr));
276 attr->name = GNUNET_strdup (key);
277 GNUNET_CONTAINER_DLL_insert (token->attr_head,
282 GNUNET_CONTAINER_DLL_insert (attr->val_head,
288 token_add_attr_int (struct IdentityToken *token,
292 struct TokenAttr *attr;
293 struct TokenAttrValue *new_val;
294 GNUNET_assert (NULL != token);
296 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
297 new_val->int_value = value;
298 for (attr = token->attr_head; NULL != attr; attr = attr->next)
300 if (0 == strcmp (key, attr->name))
306 attr = GNUNET_malloc (sizeof (struct TokenAttr));
307 attr->name = GNUNET_strdup (key);
308 GNUNET_CONTAINER_DLL_insert (token->attr_head,
313 GNUNET_CONTAINER_DLL_insert (attr->val_head,
319 parse_json_payload(const char* payload_base64,
320 struct IdentityToken *token)
324 const json_t *arr_value;
327 json_t *payload_json;
328 json_error_t err_json;
330 GNUNET_STRINGS_base64_decode (payload_base64,
331 strlen (payload_base64),
333 //TODO signature and aud key
334 payload_json = json_loads (payload, JSON_DECODE_ANY, &err_json);
336 json_object_foreach (payload_json, key, value)
338 if (json_is_array (value))
340 json_array_foreach (value, idx, arr_value)
342 if (json_is_integer (arr_value))
343 token_add_attr_int (token, key,
344 json_integer_value (arr_value));
346 token_add_attr (token,
348 json_string_value (arr_value));
351 if (json_is_integer (value))
352 token_add_attr_int (token, key,
353 json_integer_value (value));
355 token_add_attr (token, key, json_string_value (value));
359 json_decref (payload_json);
360 GNUNET_free (payload);
364 token_parse2 (const char* raw_data,
365 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
366 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
367 struct IdentityToken **result)
373 char *payload_base64;
374 size_t enc_token_len;
376 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
377 strtok (tmp_buf, ",");
378 enc_token_str = strtok (NULL, ",");
380 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
381 strlen (enc_token_str),
383 if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key,
389 GNUNET_free (tmp_buf);
390 GNUNET_free (enc_token);
391 return GNUNET_SYSERR;
394 GNUNET_assert (NULL != strtok (token_str, "."));
395 payload_base64 = strtok (NULL, ".");
397 *result = GNUNET_malloc (sizeof (struct IdentityToken));
398 parse_json_payload (payload_base64, *result);
400 (*result)->aud_key = *aud_key;
401 GNUNET_free (enc_token);
402 GNUNET_free (token_str);
403 GNUNET_free (tmp_buf);
408 token_parse (const char* raw_data,
409 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
410 struct IdentityToken **result)
412 char *ecdh_pubkey_str;
417 char *payload_base64;
418 size_t enc_token_len;
419 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
421 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
422 ecdh_pubkey_str = strtok (tmp_buf, ",");
423 enc_token_str = strtok (NULL, ",");
425 GNUNET_STRINGS_string_to_data (ecdh_pubkey_str,
426 strlen (ecdh_pubkey_str),
428 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
429 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
430 strlen (enc_token_str),
432 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
438 GNUNET_free (tmp_buf);
439 GNUNET_free (enc_token);
440 return GNUNET_SYSERR;
443 GNUNET_assert (NULL != strtok (token_str, "."));
444 payload_base64 = strtok (NULL, ".");
446 *result = GNUNET_malloc (sizeof (struct IdentityToken));
447 parse_json_payload (payload_base64, *result);
449 GNUNET_free (enc_token);
450 GNUNET_free (token_str);
451 GNUNET_free (tmp_buf);
456 create_json_payload (const struct IdentityToken *token)
458 struct TokenAttr *attr;
459 struct TokenAttrValue *val;
463 root = json_object();
464 for (attr = token->attr_head; NULL != attr; attr = attr->next)
466 for (val = attr->val_head; NULL != val; val = val->next)
468 if (NULL != val->value)
470 json_object_set_new (root,
472 json_string (val->value));
474 json_object_set_new (root,
476 json_integer (val->int_value));
480 json_str = json_dumps (root, JSON_INDENT(1));
486 create_json_header(void)
491 root = json_object ();
492 json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
493 json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
495 json_str = json_dumps (root, JSON_INDENT(1));
501 token_to_string (const struct IdentityToken *token,
502 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
507 char *payload_base64;
510 char *signature_target;
512 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
513 header_str = create_json_header();
514 GNUNET_STRINGS_base64_encode (header_str,
517 //Remove GNUNET padding of base64
518 padding = strtok(header_base64, "=");
519 while (NULL != padding)
520 padding = strtok(NULL, "=");
522 payload_str = create_json_payload (token);
523 GNUNET_STRINGS_base64_encode (payload_str,
524 strlen (payload_str),
527 //Remove GNUNET padding of base64
528 padding = strtok(payload_base64, "=");
529 while (NULL != padding)
530 padding = strtok(NULL, "=");
532 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64);
534 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
535 strlen (signature_target));
537 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
538 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
539 memcpy (&purpose[1], signature_target, strlen (signature_target));
540 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
542 (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature))
544 GNUNET_free (signature_target);
545 GNUNET_free (payload_str);
546 GNUNET_free (payload_base64);
547 GNUNET_free (purpose);
548 return GNUNET_SYSERR;
551 GNUNET_STRINGS_base64_encode ((const char*)&token->signature,
552 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
554 GNUNET_asprintf (result, "%s.%s.%s",
555 header_base64, payload_base64, signature_str);
556 GNUNET_free (signature_target);
557 GNUNET_free (payload_str);
558 GNUNET_free (header_str);
559 GNUNET_free (signature_str);
560 GNUNET_free (payload_base64);
561 GNUNET_free (header_base64);
562 GNUNET_free (purpose);
567 token_serialize (const struct IdentityToken *token,
568 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
569 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
575 char *enc_token_base64;
576 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
578 GNUNET_assert (GNUNET_OK == token_to_string (token,
582 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
587 GNUNET_STRINGS_base64_encode (enc_token,
590 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
591 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
592 GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64);
593 GNUNET_free (dh_key_str);
594 GNUNET_free (enc_token_base64);
595 GNUNET_free (enc_token);
596 GNUNET_free (token_str);
600 struct TokenTicketPayload*
601 ticket_payload_create (uint64_t nonce,
602 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
605 struct TokenTicketPayload* payload;
607 payload = GNUNET_malloc (sizeof (struct TokenTicketPayload));
608 payload->nonce = nonce;
609 payload->identity_key = *identity_pkey;
610 GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str));
615 ticket_payload_destroy (struct TokenTicketPayload* payload)
617 if (NULL != payload->label)
618 GNUNET_free (payload->label);
619 GNUNET_free (payload);
623 ticket_payload_serialize (struct TokenTicketPayload *payload,
626 char* identity_key_str;
628 identity_key_str = GNUNET_STRINGS_data_to_string_alloc (&payload->identity_key,
629 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
631 GNUNET_asprintf (result,
632 "{\"nonce\": \""SCNu64"\",\"identity\": \"%s\",\"label\": \"%s\"}",
633 payload->nonce, identity_key_str, payload->label);
634 GNUNET_free (identity_key_str);
640 * Create the token code
641 * The data is encrypted with a share ECDH derived secret using B (aud_key)
642 * and e (ecdh_privkey)
643 * The ticket also contains E (ecdh_pubkey) and a signature over the
647 ticket_create (uint64_t nonce,
648 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
650 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
652 struct TokenTicket *ticket;
653 struct TokenTicketPayload *code_payload;
655 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
656 code_payload = ticket_payload_create (nonce,
659 ticket->aud_key = *aud_key;
660 ticket->payload = code_payload;
667 ticket_destroy (struct TokenTicket *ticket)
669 ticket_payload_destroy (ticket->payload);
670 GNUNET_free (ticket);
674 ticket_serialize (struct TokenTicket *ticket,
675 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
678 char *code_payload_str;
679 char *enc_ticket_payload;
680 char *ticket_payload_str;
681 char *ticket_sig_str;
685 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
687 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
689 ticket_payload_serialize (ticket->payload,
692 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
696 &ticket->ecdh_pubkey));
698 GNUNET_free (ecdhe_privkey);
701 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
702 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
703 strlen (code_payload_str)); // E_K (code_str)
705 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
706 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
707 strlen (code_payload_str));
708 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
709 write_ptr = (char*) &purpose[1];
711 &ticket->ecdh_pubkey,
712 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
713 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
714 memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str));
715 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
717 &ticket->signature));
718 GNUNET_STRINGS_base64_encode (enc_ticket_payload,
719 strlen (code_payload_str),
720 &ticket_payload_str);
721 ticket_sig_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->signature,
722 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
724 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey,
725 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
726 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
727 GNUNET_asprintf (&ticket_str, "{\"data\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}",
728 ticket_payload_str, dh_key_str, ticket_sig_str);
729 GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result);
730 GNUNET_free (dh_key_str);
731 GNUNET_free (purpose);
732 GNUNET_free (ticket_str);
733 GNUNET_free (ticket_sig_str);
734 GNUNET_free (code_payload_str);
735 GNUNET_free (enc_ticket_payload);
736 GNUNET_free (ticket_payload_str);
741 ticket_payload_parse(const char *raw_data,
743 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
744 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
745 struct TokenTicketPayload **result)
747 const char* label_str;
748 const char* nonce_str;
749 const char* identity_key_str;
753 json_t *identity_json;
755 json_error_t err_json;
758 struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey;
760 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
766 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Data decryption failed\n");
767 return GNUNET_SYSERR;
770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data: %s\n", data_str);
771 root = json_loads (data_str, JSON_DECODE_ANY, &err_json);
774 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
775 "Error parsing data: %s\n", err_json.text);
776 GNUNET_free (data_str);
777 return GNUNET_SYSERR;
780 identity_json = json_object_get (root, "identity");
781 if (!json_is_string (identity_json))
783 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
784 "Error parsing data: %s\n", err_json.text);
786 GNUNET_free (data_str);
787 return GNUNET_SYSERR;
789 identity_key_str = json_string_value (identity_json);
790 GNUNET_STRINGS_string_to_data (identity_key_str,
791 strlen (identity_key_str),
793 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
796 label_json = json_object_get (root, "label");
797 if (!json_is_string (label_json))
799 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
800 "Error parsing data: %s\n", err_json.text);
802 GNUNET_free (data_str);
803 return GNUNET_SYSERR;
806 label_str = json_string_value (label_json);
807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str);
809 nonce_json = json_object_get (root, "nonce");
810 if (!json_is_string (label_json))
812 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
813 "Error parsing data: %s\n", err_json.text);
815 GNUNET_free (data_str);
816 return GNUNET_SYSERR;
819 nonce_str = json_string_value (nonce_json);
820 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str);
822 GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce));
824 *result = ticket_payload_create (nonce,
825 (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
827 GNUNET_free (data_str);
834 ticket_parse (const char *raw_data,
835 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
836 struct TokenTicket **result)
838 const char* enc_data_str;
839 const char* ecdh_enc_str;
840 const char* signature_enc_str;
843 json_t *signature_json;
845 json_t *enc_data_json;
846 json_error_t err_json;
848 char* ticket_decoded;
851 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
852 struct TokenTicket *ticket;
853 struct TokenTicketPayload *ticket_payload;
855 ticket_decoded = NULL;
856 GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded);
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded);
858 root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json);
861 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
862 "%s\n", err_json.text);
863 return GNUNET_SYSERR;
866 signature_json = json_object_get (root, "signature");
867 ecdh_json = json_object_get (root, "ecdh");
868 enc_data_json = json_object_get (root, "data");
870 signature_enc_str = json_string_value (signature_json);
871 ecdh_enc_str = json_string_value (ecdh_json);
872 enc_data_str = json_string_value (enc_data_json);
874 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
876 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
877 strlen (ecdh_enc_str),
878 &ticket->ecdh_pubkey,
879 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)))
881 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in data\n", ecdh_enc_str);
883 GNUNET_free (ticket);
884 return GNUNET_SYSERR;
886 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for data decryption\n", ecdh_enc_str);
887 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str,
888 strlen (signature_enc_str),
890 sizeof (struct GNUNET_CRYPTO_EcdsaSignature)))
893 GNUNET_free (ticket_decoded);
894 GNUNET_free (ticket);
895 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in data\n");
896 return GNUNET_SYSERR;
899 enc_data_len = GNUNET_STRINGS_base64_decode (enc_data_str,
900 strlen (enc_data_str),
904 if (GNUNET_OK != ticket_payload_parse (enc_data,
907 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
911 GNUNET_free (enc_data);
912 GNUNET_free (ticket_decoded);
913 GNUNET_free (ticket);
914 return GNUNET_SYSERR;
917 ticket->payload = ticket_payload;
919 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
920 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
921 enc_data_len); // E_K (code_str)
923 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
924 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
926 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
927 write_ptr = (char*) &purpose[1];
928 memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
929 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
930 memcpy (write_ptr, enc_data, enc_data_len);
932 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET,
935 &ticket_payload->identity_key))
937 ticket_destroy (ticket);
938 GNUNET_free (ticket_decoded);
940 GNUNET_free (purpose);
941 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
942 "Error verifying signature for ticket\n");
943 return GNUNET_SYSERR;
946 GNUNET_free (purpose);
948 GNUNET_free (enc_data);
949 GNUNET_free (ticket_decoded);
957 /* end of identity_token.c */