2 This file is part of GNUnet
3 Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors)
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 * Crypto helper functions
38 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
39 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
40 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
42 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
44 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
46 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
47 static const char ctx_key[] = "gnuid-aes-ctx-key";
48 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
49 new_key_hash, sizeof (struct GNUNET_HashCode),
50 ctx_key, strlen (ctx_key),
52 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
53 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
54 new_key_hash, sizeof (struct GNUNET_HashCode),
55 ctx_iv, strlen (ctx_iv),
63 * Decrypts metainfo part from a token code
66 decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
67 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key,
68 const char *cyphertext,
69 size_t cyphertext_len,
72 struct GNUNET_HashCode new_key_hash;
73 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
74 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
76 char *str_buf = GNUNET_malloc (cyphertext_len);
79 //Calculate symmetric key from ecdh parameters
80 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key,
84 create_sym_key_from_ecdh (&new_key_hash,
88 str_size = GNUNET_CRYPTO_symmetric_decrypt (cyphertext,
93 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decrypted bytes: %d Expected bytes: %d\n", str_size, cyphertext_len);
96 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n");
97 GNUNET_free (str_buf);
100 *result_str = GNUNET_malloc (str_size+1);
101 memcpy (*result_str, str_buf, str_size);
102 (*result_str)[str_size] = '\0';
103 GNUNET_free (str_buf);
109 * Decrypt string using pubkey and ECDHE
112 decrypt_str_ecdhe2 (const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey,
113 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
114 const char *ciphertext,
115 size_t ciphertext_len,
118 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
119 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
120 struct GNUNET_HashCode new_key_hash;
122 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
123 *plaintext = GNUNET_malloc (ciphertext_len);
125 // Derived key K = H(eB)
126 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
129 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
130 GNUNET_CRYPTO_symmetric_decrypt (ciphertext,
139 * Encrypt string using pubkey and ECDHE
140 * Returns ECDHE pubkey to be used for decryption
143 encrypt_str_ecdhe (const char *plaintext,
144 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key,
146 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
147 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey)
149 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
150 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
151 struct GNUNET_HashCode new_key_hash;
154 // ECDH keypair E = eG
155 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
156 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
159 //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt
160 *cyphertext = GNUNET_malloc (strlen (plaintext));
162 // Derived key K = H(eB)
163 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
166 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
167 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypting string %s\n (len=%d)",
170 enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext, strlen (plaintext),
173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypted (len=%d)", enc_size);
186 * Create an Identity Token
188 * @param type the JSON API resource type
189 * @param id the JSON API resource id
190 * @return a new JSON API resource or NULL on error.
192 struct IdentityToken*
193 token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
194 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud)
196 struct IdentityToken *token;
200 issuer = GNUNET_STRINGS_data_to_string_alloc (iss,
201 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
202 audience = GNUNET_STRINGS_data_to_string_alloc (aud,
203 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
207 token = GNUNET_malloc (sizeof (struct IdentityToken));
209 token->header = json_object();
210 token->payload = json_object();
212 json_object_set_new (token->header, "alg", json_string ("ED512"));
213 json_object_set_new (token->header, "typ", json_string ("JWT"));
215 json_object_set_new (token->payload, "iss", json_string (issuer));
216 json_object_set_new (token->payload, "aud", json_string (audience));
217 json_object_set_new (token->payload, "sub", json_string (issuer));
219 token->aud_key = *aud;
220 GNUNET_free (issuer);
221 GNUNET_free (audience);
226 token_destroy (struct IdentityToken *token)
228 json_decref (token->header);
229 json_decref (token->payload);
234 token_add_attr (const struct IdentityToken *token,
238 GNUNET_assert (NULL != token);
239 GNUNET_assert (NULL != token->payload);
241 json_object_set_new (token->payload, key, json_string (value));
245 token_add_json (const struct IdentityToken *token,
249 GNUNET_assert (NULL != token);
250 GNUNET_assert (NULL != token->payload);
252 json_object_set_new (token->payload, key, value);
257 token_parse2 (const char* raw_data,
258 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
259 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
260 struct IdentityToken **result)
269 char *payload_base64;
270 size_t enc_token_len;
271 json_error_t err_json;
273 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
274 strtok (tmp_buf, ",");
275 enc_token_str = strtok (NULL, ",");
277 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
278 strlen (enc_token_str),
280 if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key,
286 GNUNET_free (tmp_buf);
287 GNUNET_free (enc_token);
288 return GNUNET_SYSERR;
291 header_base64 = strtok (token_str, ".");
292 payload_base64 = strtok (NULL, ".");
294 GNUNET_STRINGS_base64_decode (header_base64,
295 strlen (header_base64),
297 GNUNET_STRINGS_base64_decode (payload_base64,
298 strlen (payload_base64),
303 *result = GNUNET_malloc (sizeof (struct IdentityToken));
304 (*result)->aud_key = *aud_key;
305 (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json);
306 (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json);
307 GNUNET_free (enc_token);
308 GNUNET_free (token_str);
309 GNUNET_free (tmp_buf);
310 GNUNET_free (payload);
311 GNUNET_free (header);
316 token_parse (const char* raw_data,
317 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
318 struct IdentityToken **result)
320 char *ecdh_pubkey_str;
328 char *payload_base64;
329 size_t enc_token_len;
330 json_error_t err_json;
331 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
333 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
334 ecdh_pubkey_str = strtok (tmp_buf, ",");
335 enc_token_str = strtok (NULL, ",");
337 GNUNET_STRINGS_string_to_data (ecdh_pubkey_str,
338 strlen (ecdh_pubkey_str),
340 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
341 enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str,
342 strlen (enc_token_str),
344 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
350 GNUNET_free (tmp_buf);
351 GNUNET_free (enc_token);
352 return GNUNET_SYSERR;
355 header_base64 = strtok (token_str, ".");
356 payload_base64 = strtok (NULL, ".");
358 GNUNET_STRINGS_base64_decode (header_base64,
359 strlen (header_base64),
361 GNUNET_STRINGS_base64_decode (payload_base64,
362 strlen (payload_base64),
364 //TODO signature and aud key
367 *result = GNUNET_malloc (sizeof (struct IdentityToken));
368 (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json);
369 (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json);
370 GNUNET_free (enc_token);
371 GNUNET_free (token_str);
372 GNUNET_free (tmp_buf);
373 GNUNET_free (payload);
374 GNUNET_free (header);
379 token_to_string (const struct IdentityToken *token,
380 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
385 char *payload_base64;
388 char *signature_target;
390 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
391 header_str = json_dumps (token->header, JSON_COMPACT);
392 GNUNET_STRINGS_base64_encode (header_str,
395 //Remove GNUNET padding of base64
396 padding = strtok(header_base64, "=");
397 while (NULL != padding)
398 padding = strtok(NULL, "=");
400 payload_str = json_dumps (token->payload, JSON_COMPACT);
401 GNUNET_STRINGS_base64_encode (payload_str,
402 strlen (payload_str),
405 //Remove GNUNET padding of base64
406 padding = strtok(payload_base64, "=");
407 while (NULL != padding)
408 padding = strtok(NULL, "=");
410 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64);
412 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
413 strlen (signature_target));
415 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
416 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
417 memcpy (&purpose[1], signature_target, strlen (signature_target));
418 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
420 (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature))
422 GNUNET_free (signature_target);
423 GNUNET_free (payload_str);
424 GNUNET_free (header_str);
425 GNUNET_free (payload_base64);
426 GNUNET_free (header_base64);
427 GNUNET_free (purpose);
428 return GNUNET_SYSERR;
431 GNUNET_STRINGS_base64_encode ((const char*)&token->signature,
432 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
434 GNUNET_asprintf (result, "%s.%s.%s",
435 header_base64, payload_base64, signature_str);
436 GNUNET_free (signature_target);
437 GNUNET_free (payload_str);
438 GNUNET_free (header_str);
439 GNUNET_free (signature_str);
440 GNUNET_free (payload_base64);
441 GNUNET_free (header_base64);
442 GNUNET_free (purpose);
447 token_serialize (const struct IdentityToken *token,
448 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
449 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
455 char *enc_token_base64;
456 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
458 GNUNET_assert (GNUNET_OK == token_to_string (token,
462 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str,
467 GNUNET_STRINGS_base64_encode (enc_token,
470 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
471 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
472 GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64);
473 GNUNET_free (dh_key_str);
474 GNUNET_free (enc_token_base64);
475 GNUNET_free (enc_token);
476 GNUNET_free (token_str);
480 struct TokenTicketPayload*
481 ticket_payload_create (const char* nonce,
482 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
485 struct TokenTicketPayload* payload;
487 payload = GNUNET_malloc (sizeof (struct TokenTicketPayload));
488 GNUNET_asprintf (&payload->nonce, nonce, strlen (nonce));
489 payload->identity_key = *identity_pkey;
490 GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str));
495 ticket_payload_destroy (struct TokenTicketPayload* payload)
497 GNUNET_free (payload->nonce);
498 GNUNET_free (payload->label);
499 GNUNET_free (payload);
503 ticket_payload_serialize (struct TokenTicketPayload *payload,
506 char* identity_key_str;
508 identity_key_str = GNUNET_STRINGS_data_to_string_alloc (&payload->identity_key,
509 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
511 GNUNET_asprintf (result,
512 "{\"nonce\": \"%u\",\"identity\": \"%s\",\"label\": \"%s\"}",
513 payload->nonce, identity_key_str, payload->label);
514 GNUNET_free (identity_key_str);
520 * Create the token code
521 * The metadata is encrypted with a share ECDH derived secret using B (aud_key)
522 * and e (ecdh_privkey)
523 * The ticket also contains E (ecdh_pubkey) and a signature over the
527 ticket_create (const char* nonce_str,
528 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
530 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
532 struct TokenTicket *ticket;
533 struct TokenTicketPayload *code_payload;
535 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
536 code_payload = ticket_payload_create (nonce_str,
539 ticket->aud_key = *aud_key;
540 ticket->payload = code_payload;
547 ticket_destroy (struct TokenTicket *ticket)
549 ticket_payload_destroy (ticket->payload);
550 GNUNET_free (ticket);
554 ticket_serialize (struct TokenTicket *ticket,
555 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
558 char *code_payload_str;
559 char *enc_ticket_payload;
560 char *ticket_payload_str;
561 char *ticket_sig_str;
565 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
567 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
569 ticket_payload_serialize (ticket->payload,
572 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
576 &ticket->ecdh_pubkey));
578 GNUNET_free (ecdhe_privkey);
581 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
582 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
583 strlen (code_payload_str)); // E_K (code_str)
585 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
586 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
587 strlen (code_payload_str));
588 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
589 write_ptr = (char*) &purpose[1];
591 &ticket->ecdh_pubkey,
592 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
593 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
594 memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str));
595 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
597 &ticket->signature));
598 GNUNET_STRINGS_base64_encode (enc_ticket_payload,
599 strlen (code_payload_str),
600 &ticket_payload_str);
601 ticket_sig_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->signature,
602 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
604 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey,
605 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
606 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
607 GNUNET_asprintf (&ticket_str, "{\"meta\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}",
608 ticket_payload_str, dh_key_str, ticket_sig_str);
609 GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result);
610 GNUNET_free (dh_key_str);
611 GNUNET_free (purpose);
612 GNUNET_free (ticket_str);
613 GNUNET_free (ticket_sig_str);
614 GNUNET_free (code_payload_str);
615 GNUNET_free (enc_ticket_payload);
616 GNUNET_free (ticket_payload_str);
621 ticket_payload_parse(const char *raw_data,
623 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
624 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
625 struct TokenTicketPayload **result)
627 const char* label_str;
628 const char* nonce_str;
629 const char* identity_key_str;
633 json_t *identity_json;
635 json_error_t err_json;
637 struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey;
639 if (GNUNET_OK != decrypt_str_ecdhe (priv_key,
645 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata decryption failed\n");
646 return GNUNET_SYSERR;
649 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata: %s\n", meta_str);
650 root = json_loads (meta_str, JSON_DECODE_ANY, &err_json);
653 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
654 "Error parsing metadata: %s\n", err_json.text);
655 GNUNET_free (meta_str);
656 return GNUNET_SYSERR;
659 identity_json = json_object_get (root, "identity");
660 if (!json_is_string (identity_json))
662 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
663 "Error parsing metadata: %s\n", err_json.text);
665 GNUNET_free (meta_str);
666 return GNUNET_SYSERR;
668 identity_key_str = json_string_value (identity_json);
669 GNUNET_STRINGS_string_to_data (identity_key_str,
670 strlen (identity_key_str),
672 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
675 label_json = json_object_get (root, "label");
676 if (!json_is_string (label_json))
678 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
679 "Error parsing metadata: %s\n", err_json.text);
681 GNUNET_free (meta_str);
682 return GNUNET_SYSERR;
685 label_str = json_string_value (label_json);
686 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found label: %s\n", label_str);
688 nonce_json = json_object_get (root, "nonce");
689 if (!json_is_string (label_json))
691 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
692 "Error parsing metadata: %s\n", err_json.text);
694 GNUNET_free (meta_str);
695 return GNUNET_SYSERR;
698 nonce_str = json_string_value (nonce_json);
699 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found nonce: %s\n", nonce_str);
701 *result = ticket_payload_create (nonce_str,
702 (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
704 GNUNET_free (meta_str);
711 ticket_parse (const char *raw_data,
712 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
713 struct TokenTicket **result)
715 const char* enc_meta_str;
716 const char* ecdh_enc_str;
717 const char* signature_enc_str;
720 json_t *signature_json;
722 json_t *enc_meta_json;
723 json_error_t err_json;
725 char* ticket_decoded;
728 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
729 struct TokenTicket *ticket;
730 struct TokenTicketPayload *ticket_payload;
732 ticket_decoded = NULL;
733 GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded);
734 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Token Code: %s\n", ticket_decoded);
735 root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json);
738 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
739 "%s\n", err_json.text);
740 return GNUNET_SYSERR;
743 signature_json = json_object_get (root, "signature");
744 ecdh_json = json_object_get (root, "ecdh");
745 enc_meta_json = json_object_get (root, "meta");
747 signature_enc_str = json_string_value (signature_json);
748 ecdh_enc_str = json_string_value (ecdh_json);
749 enc_meta_str = json_string_value (enc_meta_json);
751 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
753 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
754 strlen (ecdh_enc_str),
755 &ticket->ecdh_pubkey,
756 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)))
758 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in metadata\n", ecdh_enc_str);
760 GNUNET_free (ticket);
761 return GNUNET_SYSERR;
763 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s for metadata decryption\n", ecdh_enc_str);
764 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str,
765 strlen (signature_enc_str),
767 sizeof (struct GNUNET_CRYPTO_EcdsaSignature)))
770 GNUNET_free (ticket_decoded);
771 GNUNET_free (ticket);
772 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in metadata\n");
773 return GNUNET_SYSERR;
776 enc_meta_len = GNUNET_STRINGS_base64_decode (enc_meta_str,
777 strlen (enc_meta_str),
781 ticket_payload_parse (enc_meta,
784 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
787 ticket->payload = ticket_payload;
788 //TODO: check signature here
790 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
791 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
792 enc_meta_len); // E_K (code_str)
794 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
795 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
797 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
798 write_ptr = (char*) &purpose[1];
799 memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
800 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
801 memcpy (write_ptr, enc_meta, enc_meta_len);
803 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET,
806 &ticket_payload->identity_key))
808 ticket_destroy (ticket);
809 GNUNET_free (ticket_decoded);
811 GNUNET_free (purpose);
812 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
813 "Error verifying signature for token code\n");
814 return GNUNET_SYSERR;
817 GNUNET_free (purpose);
819 GNUNET_free (enc_meta);
820 GNUNET_free (ticket_decoded);
828 /* end of identity_token.c */