From cc838240da0d28fa1fc6d7a97da2808a7a622365 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Fri, 6 Oct 2017 16:50:32 +0200 Subject: [PATCH] -remove deprecated --- src/identity-provider/Makefile.am | 23 - src/identity-provider/gnunet-identity-token.c | 179 --- src/identity-provider/gnunet-idp.c | 8 +- .../gnunet-service-identity-provider.c | 1417 +++-------------- src/identity-provider/identity_provider.h | 140 -- src/identity-provider/identity_provider_api.c | 362 +---- src/identity-provider/identity_token.c | 1006 ------------ src/identity-provider/identity_token.h | 351 ---- .../plugin_identity_provider_sqlite.c | 6 +- .../plugin_rest_identity_provider.c | 1216 -------------- src/include/gnunet_identity_provider_plugin.h | 6 +- .../gnunet_identity_provider_service.h | 137 +- 12 files changed, 198 insertions(+), 4653 deletions(-) delete mode 100644 src/identity-provider/gnunet-identity-token.c delete mode 100644 src/identity-provider/identity_token.c delete mode 100644 src/identity-provider/identity_token.h delete mode 100644 src/identity-provider/plugin_rest_identity_provider.c diff --git a/src/identity-provider/Makefile.am b/src/identity-provider/Makefile.am index 1b35c6c04..0aabc2143 100644 --- a/src/identity-provider/Makefile.am +++ b/src/identity-provider/Makefile.am @@ -26,12 +26,10 @@ pkgcfg_DATA = \ lib_LTLIBRARIES = \ libgnunetidentityprovider.la plugin_LTLIBRARIES = \ - libgnunet_plugin_rest_identity_provider.la \ libgnunet_plugin_gnsrecord_identity_provider.la \ $(SQLITE_PLUGIN) bin_PROGRAMS = \ - gnunet-identity-token \ gnunet-idp libexec_PROGRAMS = \ @@ -60,7 +58,6 @@ libgnunet_plugin_identity_provider_sqlite_la_LDFLAGS = \ gnunet_service_identity_provider_SOURCES = \ gnunet-service-identity-provider.c \ - identity_token.c \ identity_attribute.h gnunet_service_identity_provider_LDADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ @@ -85,19 +82,6 @@ libgnunetidentityprovider_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ -version-info 0:0:0 -libgnunet_plugin_rest_identity_provider_la_SOURCES = \ - plugin_rest_identity_provider.c -libgnunet_plugin_rest_identity_provider_la_LIBADD = \ - $(top_builddir)/src/identity/libgnunetidentity.la \ - libgnunetidentityprovider.la \ - $(top_builddir)/src/rest/libgnunetrest.la \ - $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ - $(top_builddir)/src/namestore/libgnunetnamestore.la \ - $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ - $(LTLIBINTL) -ljansson -lmicrohttpd -libgnunet_plugin_rest_identity_provider_la_LDFLAGS = \ - $(GN_PLUGIN_LDFLAGS) - gnunet_idp_SOURCES = \ gnunet-idp.c gnunet_idp_LDADD = \ @@ -106,10 +90,3 @@ gnunet_idp_LDADD = \ $(top_builddir)/src/identity-provider/libgnunetidentityprovider.la \ $(top_builddir)/src/identity/libgnunetidentity.la \ $(GN_LIBINTL) - -gnunet_identity_token_SOURCES = \ - gnunet-identity-token.c -gnunet_identity_token_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - -ljansson -lmicrohttpd \ - $(GN_LIBINTL) diff --git a/src/identity-provider/gnunet-identity-token.c b/src/identity-provider/gnunet-identity-token.c deleted file mode 100644 index 30b63bfc4..000000000 --- a/src/identity-provider/gnunet-identity-token.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012-2015 GNUnet e.V. - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ -/** - * @author Martin Schanzenbach - * @file src/identity-provider/gnunet-service-identity-provider.c - * @brief Identity Token Service - * - */ - -#include "platform.h" -#include "gnunet_util_lib.h" -#include -#include "gnunet_signatures.h" - -/** - * The token - */ -static char* token; - -/** - * Weather to print the token - */ -static int print_token; - -static void -run (void *cls, - char *const *args, - const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *c) -{ - char *payload; - char *header; - //Get token parts - const char *header_b64; - const char *payload_b64; - const char *signature_b32; - const char *keystring; - char *data; - json_t *payload_json; - json_t *keystring_json; - json_error_t error; - struct GNUNET_CRYPTO_EcdsaPublicKey key; - struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - struct GNUNET_CRYPTO_EcdsaSignature sig; - - if (NULL == token) - { - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, - _("Option `-t' is required\n")); - return; - } - header_b64 = strtok (token, "."); - payload_b64 = strtok (NULL, "."); - signature_b32 = strtok (NULL, "."); - if ( (NULL == header_b64) || - (NULL == payload_b64) || - (NULL == signature_b32) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, - _("Token `%s' is malformed\n"), - token); - GNUNET_free (token); - token = NULL; - return; - } - - //Decode payload - GNUNET_STRINGS_base64_decode (payload_b64, - strlen (payload_b64), - &payload); - //Decode header - GNUNET_STRINGS_base64_decode (header_b64, - strlen (header_b64), - &header); - - - GNUNET_asprintf(&data, - "%s,%s", - header_b64, - payload_b64); - char *val = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + strlen (data)); - purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose*)val; - purpose->size = htonl(sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + strlen (data)); - purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); - GNUNET_memcpy (&purpose[1], data, strlen(data)); - GNUNET_free (data); - GNUNET_free (token); - token = NULL; - - if (print_token) - printf ("Token:\nHeader:\t\t%s\nPayload:\t%s\n", - header, - payload); - GNUNET_free (header); - - payload_json = json_loads (payload, 0, &error); - GNUNET_free (payload); - - if ((NULL == payload_json) || (! json_is_object (payload_json)) ) - { - GNUNET_free (val); - return; - } - keystring_json = json_object_get (payload_json, "iss"); - if (! json_is_string (keystring_json)) - { - GNUNET_free (val); - return; - } - keystring = json_string_value (keystring_json); - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (keystring, - strlen (keystring), - &key)) - { - GNUNET_free (val); - return; - } - GNUNET_STRINGS_string_to_data (signature_b32, - strlen (signature_b32), - &sig, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); - - if (print_token) - printf ("Signature:\t%s\n", - keystring); - - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN, - purpose, - &sig, - &key)) - printf("Signature not OK!\n"); - else - printf("Signature OK!\n"); - GNUNET_free (val); - return; -} - - -int -main(int argc, char *const argv[]) -{ - struct GNUNET_GETOPT_CommandLineOption options[] = { - - GNUNET_GETOPT_option_string ('t', - "token", - NULL, - gettext_noop ("GNUid token"), - &token), - - GNUNET_GETOPT_option_flag ('p', - "print", - gettext_noop ("Print token contents"), - &print_token), - - GNUNET_GETOPT_OPTION_END - }; - return GNUNET_PROGRAM_run (argc, argv, "ct", - "ct", options, - &run, NULL); -} diff --git a/src/identity-provider/gnunet-idp.c b/src/identity-provider/gnunet-idp.c index fbe1d9613..bc30a1148 100644 --- a/src/identity-provider/gnunet-idp.c +++ b/src/identity-provider/gnunet-idp.c @@ -104,7 +104,7 @@ static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key; /** * Ticket to consume */ -static struct GNUNET_IDENTITY_PROVIDER_Ticket2 ticket; +static struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; /** * Attribute list @@ -128,12 +128,12 @@ do_cleanup(void *cls) static void ticket_issue_cb (void* cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) { char* ticket_str; if (NULL != ticket) { ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket, - sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket2)); + sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); printf("%s\n", ticket_str); GNUNET_free (ticket_str); @@ -278,7 +278,7 @@ ego_cb (void *cls, GNUNET_STRINGS_string_to_data (consume_ticket, strlen (consume_ticket), &ticket, - sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket2)); + sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); attr_list = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index 8960ea162..9c03cdbd7 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c @@ -36,7 +36,6 @@ #include "gnunet_identity_provider_plugin.h" #include "gnunet_signatures.h" #include "identity_provider.h" -#include "identity_token.h" #include "identity_attribute.h" #include @@ -360,27 +359,8 @@ struct AttributeStoreHandle }; - -struct VerifiedAttributeEntry -{ - /** - * DLL - */ - struct VerifiedAttributeEntry *prev; - - /** - * DLL - */ - struct VerifiedAttributeEntry *next; - - /** - * Attribute Name - */ - char* name; -}; - +/* Prototype */ struct ParallelLookup; -struct ParallelLookup2; struct ConsumeTicketHandle { @@ -393,7 +373,7 @@ struct ConsumeTicketHandle /** * Ticket */ - struct GNUNET_IDENTITY_PROVIDER_Ticket2 ticket; + struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; /** * LookupRequest @@ -413,12 +393,12 @@ struct ConsumeTicketHandle /** * Lookup DLL */ - struct ParallelLookup2 *parallel_lookups_head; + struct ParallelLookup *parallel_lookups_head; /** * Lookup DLL */ - struct ParallelLookup2 *parallel_lookups_tail; + struct ParallelLookup *parallel_lookups_tail; /** * Kill task @@ -441,82 +421,30 @@ struct ConsumeTicketHandle uint32_t r_id; }; -struct ParallelLookup2 -{ - struct ParallelLookup2 *next; - - struct ParallelLookup2 *prev; - - struct GNUNET_GNS_LookupRequest *lookup_request; - - struct ConsumeTicketHandle *handle; - - char *label; -}; - - -struct ExchangeHandle -{ - - /** - * Client connection - */ - struct IdpClient *client; - - /** - * Ticket - */ - struct TokenTicket *ticket; - - /** - * Token returned - */ - struct IdentityToken *token; - - /** - * LookupRequest - */ - struct GNUNET_GNS_LookupRequest *lookup_request; - - /** - * Audience Key - */ - struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey; - - /** - * ParallelLookups DLL - */ - struct ParallelLookup *parallel_lookups_head; - struct ParallelLookup *parallel_lookups_tail; - - struct GNUNET_SCHEDULER_Task *kill_task; - struct GNUNET_CRYPTO_AbeKey *key; - - /** - * Label to return - */ - char *label; - - /** - * request id - */ - uint32_t r_id; -}; - +/** + * Handle for a parallel GNS lookup job + */ struct ParallelLookup { + /* DLL */ struct ParallelLookup *next; + /* DLL */ struct ParallelLookup *prev; + /* The GNS request */ struct GNUNET_GNS_LookupRequest *lookup_request; - struct ExchangeHandle *handle; + /* The handle the return to */ + struct ConsumeTicketHandle *handle; + /* The label to look up */ char *label; }; - +/** + * Ticket issue request handle + */ struct TicketIssueHandle { @@ -538,7 +466,7 @@ struct TicketIssueHandle /** * Ticket to issue */ - struct GNUNET_IDENTITY_PROVIDER_Ticket2 ticket; + struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; /** * QueueEntry @@ -552,103 +480,6 @@ struct TicketIssueHandle }; -/** - * DEPRECATED - */ -struct IssueHandle -{ - - /** - * Client connection - */ - struct IdpClient *client; - - /** - * Issuer Key - */ - struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key; - - /** - * Issue pubkey - */ - struct GNUNET_CRYPTO_EcdsaPublicKey iss_pkey; - - /** - * Audience Key - */ - struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; - - /** - * The issuer egos ABE master key - */ - struct GNUNET_CRYPTO_AbeMasterKey *abe_key; - - /** - * Expiration - */ - struct GNUNET_TIME_Absolute expiration; - - /** - * Scopes - */ - char *scopes; - - /** - * DLL - */ - struct VerifiedAttributeEntry *v_attr_head; - - /** - * DLL - */ - struct VerifiedAttributeEntry *v_attr_tail; - - /** - * nonce - */ - uint64_t nonce; - - /** - * NS iterator - */ - struct GNUNET_NAMESTORE_ZoneIterator *ns_it; - - /** - * Cred request - */ - struct GNUNET_CREDENTIAL_Request *credential_request; - - /** - * Attribute map - */ - struct GNUNET_CONTAINER_MultiHashMap *attr_map; - - /** - * Token - */ - struct IdentityToken *token; - - /** - * Ticket - */ - struct TokenTicket *ticket; - - /** - * QueueEntry - */ - struct GNUNET_NAMESTORE_QueueEntry *ns_qe; - - /** - * The label the token is stored under - */ - char *label; - - /** - * request id - */ - uint32_t r_id; -}; - /** * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format * @@ -667,1088 +498,206 @@ struct EgoEntry /** * Ego handle - */ - struct GNUNET_IDENTITY_Ego *ego; - - /** - * Attribute map. Contains the attributes as json_t - */ - struct GNUNET_CONTAINER_MultiHashMap *attr_map; - -}; - -/** - * Cleanup task - */ -static void -cleanup() -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Cleaning up\n"); - if (NULL != stats) - { - GNUNET_STATISTICS_destroy (stats, GNUNET_NO); - stats = NULL; - } - GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, - TKT_database)); - GNUNET_free (db_lib_name); - db_lib_name = NULL; - if (NULL != timeout_task) - GNUNET_SCHEDULER_cancel (timeout_task); - if (NULL != update_task) - GNUNET_SCHEDULER_cancel (update_task); - if (NULL != identity_handle) - GNUNET_IDENTITY_disconnect (identity_handle); - if (NULL != gns_handle) - GNUNET_GNS_disconnect (gns_handle); - if (NULL != credential_handle) - GNUNET_CREDENTIAL_disconnect (credential_handle); - if (NULL != ns_it) - GNUNET_NAMESTORE_zone_iteration_stop (ns_it); - if (NULL != ns_qe) - GNUNET_NAMESTORE_cancel (ns_qe); - if (NULL != ns_handle) - GNUNET_NAMESTORE_disconnect (ns_handle); - if (NULL != token) - GNUNET_free (token); - if (NULL != label) - GNUNET_free (label); - -} - -/** - * Shutdown task - * - * @param cls NULL - * @param tc task context - */ -static void -do_shutdown (void *cls) -{ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Shutting down...\n"); - cleanup(); -} - -/** - * Finished storing newly bootstrapped ABE key - */ -static void -bootstrap_store_cont (void *cls, - int32_t success, - const char *emsg) -{ - struct AbeBootstrapHandle *abh = cls; - if (GNUNET_SYSERR == success) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to bootstrap ABE master %s\n", - emsg); - abh->proc (abh->proc_cls, NULL); - GNUNET_free (abh->abe_key); - GNUNET_free (abh); - return; - } - abh->proc (abh->proc_cls, abh->abe_key); - GNUNET_free (abh); -} - -/** - * Generates and stores a new ABE key - */ -static void -bootstrap_store_task (void *cls) -{ - struct AbeBootstrapHandle *abh = cls; - struct GNUNET_GNSRECORD_Data rd[1]; - - rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key, - (void**)&rd[0].data); - rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER; - rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; - rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? - abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, - &abh->identity, - "+", - 1, - rd, - &bootstrap_store_cont, - abh); -} - -/** - * Error checking for ABE master - */ -static void -bootstrap_abe_error (void *cls) -{ - struct AbeBootstrapHandle *abh = cls; - GNUNET_free (abh); - abh->proc (abh->proc_cls, NULL); - GNUNET_free (abh); -} - - -/** - * Handle ABE lookup in namestore - */ -static void -bootstrap_abe_result (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - struct AbeBootstrapHandle *abh = cls; - struct GNUNET_CRYPTO_AbeMasterKey *abe_key; - int i; - - for (i=0;iproc (abh->proc_cls, abe_key); - GNUNET_free (abh); - return; - } - - //No ABE master found, bootstrapping... - abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key (); - GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh); -} - -/** - * Bootstrap ABE master if it does not yet exists. - * Will call the AbeBootstrapResult processor when done. - */ -static void -bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, - AbeBootstrapResult proc, - void* cls) -{ - struct AbeBootstrapHandle *abh; - - abh = GNUNET_new (struct AbeBootstrapHandle); - abh->proc = proc; - abh->proc_cls = cls; - abh->identity = *identity; - abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, - identity, - "+", - &bootstrap_abe_error, - abh, - &bootstrap_abe_result, - abh); - -} - - - -static struct GNUNET_MQ_Envelope* -create_exchange_result_message (const char* token, - const char* label, - uint64_t ticket_nonce, - uint64_t id) -{ - struct GNUNET_MQ_Envelope *env; - struct ExchangeResultMessage *erm; - uint16_t token_len = strlen (token) + 1; - - env = GNUNET_MQ_msg_extra (erm, - token_len, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT); - erm->ticket_nonce = htonl (ticket_nonce); - erm->id = id; - GNUNET_memcpy (&erm[1], token, token_len); - return env; -} - - -static struct GNUNET_MQ_Envelope* -create_issue_result_message (const char* label, - const char* ticket, - const char* token, - uint64_t id) -{ - struct GNUNET_MQ_Envelope *env; - struct IssueResultMessage *irm; - char *tmp_str; - size_t len; - - GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token); - len = strlen (tmp_str) + 1; - env = GNUNET_MQ_msg_extra (irm, - len, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT); - irm->id = id; - GNUNET_memcpy (&irm[1], tmp_str, strlen (tmp_str) + 1); - GNUNET_free (tmp_str); - return env; -} - -static void -cleanup_issue_handle (struct IssueHandle *handle) -{ - if (NULL != handle->attr_map) - GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map); - if (NULL != handle->scopes) - GNUNET_free (handle->scopes); - if (NULL != handle->token) - token_destroy (handle->token); - if (NULL != handle->ticket) - ticket_destroy (handle->ticket); - if (NULL != handle->label) - GNUNET_free (handle->label); - if (NULL != handle->ns_it) - GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it); - if (NULL != handle->credential_request) - GNUNET_CREDENTIAL_request_cancel (handle->credential_request); - GNUNET_free (handle); -} - -static void -store_record_issue_cont (void *cls, - int32_t success, - const char *emsg) -{ - struct IssueHandle *handle = cls; - struct GNUNET_MQ_Envelope *env; - char *ticket_str; - char *token_str; - - handle->ns_qe = NULL; - if (GNUNET_SYSERR == success) - { - cleanup_issue_handle (handle); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", - "Unknown Error\n"); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; - } - if (GNUNET_OK != ticket_serialize (handle->ticket, - &handle->iss_key, - &ticket_str)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", - "Error serializing ticket\n"); - cleanup_issue_handle (handle); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; - } - if (GNUNET_OK != token_to_string (handle->token, - &handle->iss_key, - &token_str)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", - "Error serializing token\n"); - GNUNET_free (ticket_str); - cleanup_issue_handle (handle); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; - } - env = create_issue_result_message (handle->label, - ticket_str, - token_str, - handle->r_id); - GNUNET_MQ_send (handle->client->mq, - env); - cleanup_issue_handle (handle); - GNUNET_free (ticket_str); - GNUNET_free (token_str); -} - -static int -create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, - struct GNUNET_CRYPTO_SymmetricSessionKey *skey, - struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) -{ - struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; - - GNUNET_CRYPTO_hash_to_enc (new_key_hash, - &new_key_hash_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); - static const char ctx_key[] = "gnuid-aes-ctx-key"; - GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), - new_key_hash, sizeof (struct GNUNET_HashCode), - ctx_key, strlen (ctx_key), - NULL, 0); - static const char ctx_iv[] = "gnuid-aes-ctx-iv"; - GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), - new_key_hash, sizeof (struct GNUNET_HashCode), - ctx_iv, strlen (ctx_iv), - NULL, 0); - return GNUNET_OK; -} - -int -serialize_abe_keyinfo (const struct IssueHandle *handle, - const struct GNUNET_CRYPTO_AbeKey *rp_key, - struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, - char **result) -{ - char *enc_keyinfo; - char *serialized_key; - char *buf; - struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; - ssize_t size; - - struct GNUNET_CRYPTO_SymmetricSessionKey skey; - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - struct GNUNET_HashCode new_key_hash; - ssize_t enc_size; - - size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key, - (void**)&serialized_key); - buf = GNUNET_malloc (strlen (handle->scopes) + 1 + size); - GNUNET_memcpy (buf, - handle->scopes, - strlen (handle->scopes) + 1); - GNUNET_memcpy (buf + strlen (handle->scopes) + 1, - serialized_key, - size); - // ECDH keypair E = eG - *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create(); - GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey, - &ecdh_pubkey); - enc_keyinfo = GNUNET_malloc (size + strlen (handle->scopes) + 1); - // Derived key K = H(eB) - GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, - &handle->aud_key, - &new_key_hash)); - create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); - enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf, - size + strlen (handle->scopes) + 1, - &skey, &iv, - enc_keyinfo); - *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+ - enc_size); - GNUNET_memcpy (*result, - &ecdh_pubkey, - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), - enc_keyinfo, - enc_size); - GNUNET_free (enc_keyinfo); - return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size; -} - -static void -cleanup_exchange_handle (struct ExchangeHandle *handle) -{ - if (NULL != handle->ticket) - ticket_destroy (handle->ticket); - if (NULL != handle->token) - token_destroy (handle->token); - GNUNET_free (handle); -} - - -/** - * Build a token and store it - * - * @param cls the IssueHandle - */ -static void -sign_and_return_token (void *cls) -{ - struct ExchangeHandle *handle = cls; - struct GNUNET_MQ_Envelope *env; - char *token_str; - uint64_t time; - uint64_t exp_time; - - time = GNUNET_TIME_absolute_get().abs_value_us; - exp_time = time + token_expiration_interval.rel_value_us; - - token_add_attr_int (handle->token, "nbf", time); - token_add_attr_int (handle->token, "iat", time); - token_add_attr_int (handle->token, "exp", exp_time); - - //Readable - GNUNET_assert (GNUNET_OK == token_to_string (handle->token, - &handle->aud_privkey, - &token_str)); - - env = create_exchange_result_message (token_str, - handle->label, - handle->ticket->payload->nonce, - handle->r_id); - GNUNET_MQ_send (handle->client->mq, - env); - cleanup_exchange_handle (handle); - GNUNET_free (token_str); - -} - -/** - * Build an ABE key and store it - * - * @param cls the IssueHandle - */ -static void -issue_ticket (void *cls) -{ - struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; - struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; - struct IssueHandle *handle = cls; - struct GNUNET_GNSRECORD_Data code_record[1]; - struct GNUNET_CRYPTO_AbeKey *rp_key; - char *nonce_str; - char *code_record_data; - char **attrs; - char *scope; - char *scopes_tmp; - int attrs_len; - int i; - uint64_t time; - uint64_t exp_time; - size_t code_record_len; - - //Remote nonce - nonce_str = NULL; - GNUNET_asprintf (&nonce_str, "%lu", handle->nonce); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str); - - GNUNET_CRYPTO_ecdsa_key_get_public (&handle->iss_key, - &pub_key); - handle->ticket = ticket_create (handle->nonce, - &pub_key, - handle->label, - &handle->aud_key); - - time = GNUNET_TIME_absolute_get().abs_value_us; - exp_time = time + token_expiration_interval.rel_value_us; - - token_add_attr_int (handle->token, "nbf", time); - token_add_attr_int (handle->token, "iat", time); - token_add_attr_int (handle->token, "exp", exp_time); - token_add_attr (handle->token, "nonce", nonce_str); - - //Create new ABE key for RP - attrs_len = (GNUNET_CONTAINER_multihashmap_size (handle->attr_map) + 1) * sizeof (char*); - attrs = GNUNET_malloc (attrs_len); - i = 0; - scopes_tmp = GNUNET_strdup (handle->scopes); - for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) { - attrs[i] = scope; - i++; - } - rp_key = GNUNET_CRYPTO_cpabe_create_key (handle->abe_key, - attrs); - code_record_len = serialize_abe_keyinfo (handle, - rp_key, - &ecdhe_privkey, - &code_record_data); - code_record[0].data = code_record_data; - code_record[0].data_size = code_record_len; - code_record[0].expiration_time = exp_time; - code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY; - code_record[0].flags = GNUNET_GNSRECORD_RF_NONE; - - - //Publish record - handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, - &handle->iss_key, - handle->label, - 1, - code_record, - &store_record_issue_cont, - handle); - GNUNET_free (ecdhe_privkey); - GNUNET_free (nonce_str); - GNUNET_free (code_record_data); -} - -/** - * Credential to JSON - * @param cred the credential - * @return the resulting json, NULL if failed - */ -static json_t* -credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred) -{ - char *issuer; - char *subject; - char *signature; - char attribute[cred->issuer_attribute_len + 1]; - json_t *cred_obj; - - issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key); - if (NULL == issuer) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer in credential malformed\n"); - return NULL; - } - subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); - if (NULL == subject) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Subject in credential malformed\n"); - GNUNET_free (issuer); - return NULL; - } - GNUNET_STRINGS_base64_encode ((char*)&cred->signature, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature), - &signature); - memcpy (attribute, - cred->issuer_attribute, - cred->issuer_attribute_len); - attribute[cred->issuer_attribute_len] = '\0'; - cred_obj = json_object (); - json_object_set_new (cred_obj, "issuer", json_string (issuer)); - json_object_set_new (cred_obj, "subject", json_string (subject)); - json_object_set_new (cred_obj, "attribute", json_string (attribute)); - json_object_set_new (cred_obj, "signature", json_string (signature)); - json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us)); - GNUNET_free (issuer); - GNUNET_free (subject); - GNUNET_free (signature); - return cred_obj; -} - - -static void -handle_vattr_collection (void* cls, - unsigned int d_count, - struct GNUNET_CREDENTIAL_Delegation *dc, - unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cred) -{ - struct IssueHandle *handle = cls; - struct VerifiedAttributeEntry *vattr; - json_t *cred_json; - json_t *cred_array; - int i; - handle->credential_request = NULL; - - if (NULL == cred) - { - GNUNET_SCHEDULER_add_now (&issue_ticket, handle); - return; - } - cred_array = json_array(); - for (i=0;itoken, - handle->v_attr_head->name, - cred_array); - } - json_decref (cred_array); - vattr = handle->v_attr_head; - - GNUNET_CONTAINER_DLL_remove (handle->v_attr_head, - handle->v_attr_tail, - vattr); - GNUNET_free (vattr->name); - GNUNET_free (vattr); - - if (NULL == handle->v_attr_head) - { - GNUNET_SCHEDULER_add_now (&issue_ticket, handle); - return; - } - handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle, - &handle->aud_key, - handle->v_attr_head->name, - &handle->iss_key, - &handle_vattr_collection, - handle); - -} - - -static void -attr_collect_error (void *cls) -{ - struct IssueHandle *handle = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute Error!\n"); - handle->ns_it = NULL; - GNUNET_SCHEDULER_add_now (&issue_ticket, handle); -} - - -static void -attr_collect_finished (void *cls) -{ - struct IssueHandle *handle = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n"); - handle->ns_it = NULL; - - if (NULL == handle->v_attr_head) - { - GNUNET_SCHEDULER_add_now (&issue_ticket, handle); - return; - } - handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle, - &handle->aud_key, - handle->v_attr_head->name, - &handle->iss_key, - &handle_vattr_collection, - handle); -} - -/** - * Collect attributes for token - */ -static void -attr_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - struct IssueHandle *handle = cls; - int i; - char* data; - struct GNUNET_HashCode key; - - GNUNET_CRYPTO_hash (label, - strlen (label), - &key); - - if (0 == rd_count || - ( (NULL != handle->attr_map) && - (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map, - &key)) - ) - ) - { - GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", label); - - if (1 == rd_count) - { - if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) - { - data = GNUNET_GNSRECORD_value_to_string (rd->record_type, - rd->data, - rd->data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data); - token_add_attr (handle->token, - label, - data); - GNUNET_free (data); - } - GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); - return; - } - - i = 0; - for (; i < rd_count; i++) - { - if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) - { - data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, - rd[i].data, - rd[i].data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data); - token_add_attr (handle->token, label, data); - GNUNET_free (data); - } - } - - GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); -} - -static void -process_parallel_lookup (void *cls, uint32_t rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Parallel lookup finished (count=%u)\n", rd_count); - struct ParallelLookup *parallel_lookup = cls; - struct ExchangeHandle *handle = parallel_lookup->handle; - char *data; - int i; - - GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head, - handle->parallel_lookups_tail, - parallel_lookup); - GNUNET_free (parallel_lookup); - if (1 == rd_count) - { - if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) - { - GNUNET_CRYPTO_cpabe_decrypt (rd->data, - rd->data_size, - handle->key, - (void**)&data); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data); - token_add_attr (handle->token, - parallel_lookup->label, - data); - GNUNET_free (data); - } - } else { - i = 0; - for (; i < rd_count; i++) - { - if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) - { - data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, - rd[i].data, - rd[i].data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data); - token_add_attr (handle->token, parallel_lookup->label, data); - GNUNET_free (data); - } - } - } - if (NULL != handle->parallel_lookups_head) - return; //Wait for more - //Else we are done - GNUNET_SCHEDULER_cancel (handle->kill_task); - GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); -} - -void -abort_parallel_lookups (void *cls) -{ - struct ExchangeHandle *handle = cls; - struct ParallelLookup *lu; - struct ParallelLookup *tmp; - - for (lu = handle->parallel_lookups_head; - NULL != lu;) { - GNUNET_GNS_lookup_cancel (lu->lookup_request); - GNUNET_free (lu->label); - tmp = lu->next; - GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head, - handle->parallel_lookups_tail, - lu); - GNUNET_free (lu); - lu = tmp; - } - GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); - -} - -static void -process_lookup_result (void *cls, uint32_t rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - struct ExchangeHandle *handle = cls; - struct GNUNET_HashCode new_key_hash; - struct GNUNET_CRYPTO_SymmetricSessionKey enc_key; - struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv; - struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key; - struct ParallelLookup *parallel_lookup; - size_t size; - char *buf; - char *scope; - char *lookup_query; - - handle->lookup_request = NULL; - if (1 != rd_count) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Number of keys %d != 1.", - rd_count); - cleanup_exchange_handle (handle); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; - } - - //Decrypt - ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data; - - buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - - //Calculate symmetric key from ecdh parameters - GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_ecdsa_ecdh (&handle->aud_privkey, - ecdh_key, - &new_key_hash)); - create_sym_key_from_ecdh (&new_key_hash, - &enc_key, - &enc_iv); - size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), - rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), - &enc_key, - &enc_iv, - buf); + */ + struct GNUNET_IDENTITY_Ego *ego; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Decrypted bytes: %zd Expected bytes: %zd\n", - size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); + /** + * Attribute map. Contains the attributes as json_t + */ + struct GNUNET_CONTAINER_MultiHashMap *attr_map; - scopes = GNUNET_strdup (buf); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Scopes %s\n", scopes); - handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1), - rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) - - strlen (scopes) - 1); +}; - for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ",")) +/** + * Cleanup task + */ +static void +cleanup() +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Cleaning up\n"); + if (NULL != stats) { - GNUNET_asprintf (&lookup_query, - "%s.gnu", - scope); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Looking up %s\n", lookup_query); - parallel_lookup = GNUNET_new (struct ParallelLookup); - parallel_lookup->handle = handle; - parallel_lookup->label = GNUNET_strdup (scope); - parallel_lookup->lookup_request - = GNUNET_GNS_lookup (gns_handle, - lookup_query, - &handle->ticket->payload->identity_key, - GNUNET_GNSRECORD_TYPE_ID_ATTR, - GNUNET_GNS_LO_LOCAL_MASTER, - &process_parallel_lookup, - parallel_lookup); - GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head, - handle->parallel_lookups_tail, - parallel_lookup); + GNUNET_STATISTICS_destroy (stats, GNUNET_NO); + stats = NULL; } - handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3), - &abort_parallel_lookups, - handle); + GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, + TKT_database)); + GNUNET_free (db_lib_name); + db_lib_name = NULL; + if (NULL != timeout_task) + GNUNET_SCHEDULER_cancel (timeout_task); + if (NULL != update_task) + GNUNET_SCHEDULER_cancel (update_task); + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + if (NULL != gns_handle) + GNUNET_GNS_disconnect (gns_handle); + if (NULL != credential_handle) + GNUNET_CREDENTIAL_disconnect (credential_handle); + if (NULL != ns_it) + GNUNET_NAMESTORE_zone_iteration_stop (ns_it); + if (NULL != ns_qe) + GNUNET_NAMESTORE_cancel (ns_qe); + if (NULL != ns_handle) + GNUNET_NAMESTORE_disconnect (ns_handle); + if (NULL != token) + GNUNET_free (token); + if (NULL != label) + GNUNET_free (label); + } /** - * Checks a exchange message + * Shutdown task * - * @param cls client sending the message - * @param xm message of type `struct ExchangeMessage` - * @return #GNUNET_OK if @a xm is well-formed + * @param cls NULL + * @param tc task context */ -static int -check_exchange_message (void *cls, - const struct ExchangeMessage *xm) +static void +do_shutdown (void *cls) { - uint16_t size; - - size = ntohs (xm->header.size); - if (size <= sizeof (struct ExchangeMessage)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Shutting down...\n"); + cleanup(); } /** - * - * Handler for exchange message - * - * @param cls unused - * @param client who sent the message - * @param message the message + * Finished storing newly bootstrapped ABE key */ static void -handle_exchange_message (void *cls, - const struct ExchangeMessage *xm) +bootstrap_store_cont (void *cls, + int32_t success, + const char *emsg) { - struct ExchangeHandle *xchange_handle; - struct IdpClient *idp = cls; - const char *ticket; - char *lookup_query; - - ticket = (const char *) &xm[1]; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received EXCHANGE of `%s' from client\n", - ticket); - xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle)); - xchange_handle->aud_privkey = xm->aud_privkey; - xchange_handle->r_id = xm->id; - if (GNUNET_SYSERR == ticket_parse (ticket, - &xchange_handle->aud_privkey, - &xchange_handle->ticket)) + struct AbeBootstrapHandle *abh = cls; + if (GNUNET_SYSERR == success) { - GNUNET_free (xchange_handle); - GNUNET_SERVICE_client_drop (idp->client); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to bootstrap ABE master %s\n", + emsg); + abh->proc (abh->proc_cls, NULL); + GNUNET_free (abh->abe_key); + GNUNET_free (abh); return; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for ABE key under %s\n", - xchange_handle->ticket->payload->label); - GNUNET_asprintf (&lookup_query, - "%s.gnu", - xchange_handle->ticket->payload->label); - GNUNET_SERVICE_client_continue (idp->client); - xchange_handle->client = idp; - xchange_handle->token = token_create (&xchange_handle->ticket->payload->identity_key, - &xchange_handle->ticket->payload->identity_key); - xchange_handle->lookup_request - = GNUNET_GNS_lookup (gns_handle, - lookup_query, - &xchange_handle->ticket->payload->identity_key, - GNUNET_GNSRECORD_TYPE_ABE_KEY, - GNUNET_GNS_LO_LOCAL_MASTER, - &process_lookup_result, - xchange_handle); - GNUNET_free (lookup_query); - + abh->proc (abh->proc_cls, abh->abe_key); + GNUNET_free (abh); } -void -attr_collect_task (void *cls) +/** + * Generates and stores a new ABE key + */ +static void +bootstrap_store_task (void *cls) { - struct IssueHandle *issue_handle = cls; - - issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, - &issue_handle->iss_key, - &attr_collect_error, - issue_handle, - &attr_collect, - issue_handle, - &attr_collect_finished, - issue_handle); + struct AbeBootstrapHandle *abh = cls; + struct GNUNET_GNSRECORD_Data rd[1]; + + rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key, + (void**)&rd[0].data); + rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER; + rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; + rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? + abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, + &abh->identity, + "+", + 1, + rd, + &bootstrap_store_cont, + abh); } -void -abe_key_lookup_error (void *cls) +/** + * Error checking for ABE master + */ +static void +bootstrap_abe_error (void *cls) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error looking for ABE master!\n"); - GNUNET_SCHEDULER_add_now (&do_shutdown, cls); + struct AbeBootstrapHandle *abh = cls; + GNUNET_free (abh); + abh->proc (abh->proc_cls, NULL); + GNUNET_free (abh); } -void -abe_key_lookup_result (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) + +/** + * Handle ABE lookup in namestore + */ +static void +bootstrap_abe_result (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd) { - struct IssueHandle *handle = cls; + struct AbeBootstrapHandle *abh = cls; + struct GNUNET_CRYPTO_AbeMasterKey *abe_key; int i; for (i=0;iabe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data, - rd[i].data_size); - GNUNET_SCHEDULER_add_now (&attr_collect_task, handle); + abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data, + rd[i].data_size); + abh->proc (abh->proc_cls, abe_key); + GNUNET_free (abh); return; } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No ABE master found!\n"); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - -} - - -/** - * Checks an issue message - * - * @param cls client sending the message - * @param im message of type `struct IssueMessage` - * @return #GNUNET_OK if @a im is well-formed - */ -static int -check_issue_message(void *cls, - const struct IssueMessage *im) -{ - uint16_t size; - size = ntohs (im->header.size); - if (size <= sizeof (struct IssueMessage)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - scopes = (char *) &im[1]; - if ('\0' != scopes[size - sizeof (struct IssueMessage) - 1]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Malformed scopes received!\n"); - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; + //No ABE master found, bootstrapping... + abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key (); + GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh); } - /** - * - * Handler for issue message - * - * @param cls unused - * @param client who sent the message - * @param message the message + * Bootstrap ABE master if it does not yet exists. + * Will call the AbeBootstrapResult processor when done. */ static void -handle_issue_message (void *cls, - const struct IssueMessage *im) +bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + AbeBootstrapResult proc, + void* cls) { - const char *scopes; - char *scopes_tmp; - char *scope; - uint64_t rnd_key; - struct GNUNET_HashCode key; - struct IssueHandle *issue_handle; - struct IdpClient *idp = cls; + struct AbeBootstrapHandle *abh; - scopes = (const char *) &im[1]; - //v_attrs = (const char *) &im[1] + ntohl(im->scope_len); - issue_handle = GNUNET_malloc (sizeof (struct IssueHandle)); - issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5, - GNUNET_NO); - scopes_tmp = GNUNET_strdup (scopes); + abh = GNUNET_new (struct AbeBootstrapHandle); + abh->proc = proc; + abh->proc_cls = cls; + abh->identity = *identity; + abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, + identity, + "+", + &bootstrap_abe_error, + abh, + &bootstrap_abe_result, + abh); - for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) - { - GNUNET_CRYPTO_hash (scope, - strlen (scope), - &key); - GNUNET_CONTAINER_multihashmap_put (issue_handle->attr_map, - &key, - scope, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); - } - GNUNET_free (scopes_tmp); - /*scopes_tmp = GNUNET_strdup (v_attrs); +} - for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) - { - vattr_entry = GNUNET_new (struct VerifiedAttributeEntry); - vattr_entry->name = GNUNET_strdup (scope); - GNUNET_CONTAINER_DLL_insert (issue_handle->v_attr_head, - issue_handle->v_attr_tail, - vattr_entry); - } - GNUNET_free (scopes_tmp);*/ +static int +create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, + struct GNUNET_CRYPTO_SymmetricSessionKey *skey, + struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) +{ + struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; - issue_handle->r_id = im->id; - issue_handle->aud_key = im->aud_key; - issue_handle->iss_key = im->iss_key; - GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key, - &issue_handle->iss_pkey); - issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration); - issue_handle->nonce = ntohl (im->nonce); - GNUNET_SERVICE_client_continue (idp->client); - issue_handle->client = idp; - issue_handle->scopes = GNUNET_strdup (scopes); - issue_handle->token = token_create (&issue_handle->iss_pkey, - &issue_handle->aud_key); - rnd_key = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, - UINT64_MAX); - GNUNET_STRINGS_base64_encode ((char*)&rnd_key, - sizeof (uint64_t), - &issue_handle->label); - issue_handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, - &issue_handle->iss_key, - "+", - &abe_key_lookup_error, - issue_handle, - &abe_key_lookup_result, - issue_handle); + GNUNET_CRYPTO_hash_to_enc (new_key_hash, + &new_key_hash_str); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); + static const char ctx_key[] = "gnuid-aes-ctx-key"; + GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), + new_key_hash, sizeof (struct GNUNET_HashCode), + ctx_key, strlen (ctx_key), + NULL, 0); + static const char ctx_iv[] = "gnuid-aes-ctx-iv"; + GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), + new_key_hash, sizeof (struct GNUNET_HashCode), + ctx_iv, strlen (ctx_iv), + NULL, 0); + return GNUNET_OK; } static void @@ -1765,11 +714,11 @@ cleanup_ticket_issue_handle (struct TicketIssueHandle *handle) static void send_ticket_result (struct IdpClient *client, uint32_t r_id, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) { struct TicketResultMessage *irm; struct GNUNET_MQ_Envelope *env; - struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket_buf; + struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf; /* store ticket in DB */ if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, @@ -1781,9 +730,9 @@ send_ticket_result (struct IdpClient *client, } env = GNUNET_MQ_msg_extra (irm, - sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket2), + sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket), GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT); - ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&irm[1]; + ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1]; *ticket_buf = *ticket; irm->id = htonl (r_id); GNUNET_MQ_send (client->mq, @@ -2043,7 +992,7 @@ process_parallel_lookup2 (void *cls, uint32_t rd_count, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n", rd_count); - struct ParallelLookup2 *parallel_lookup = cls; + struct ParallelLookup *parallel_lookup = cls; struct ConsumeTicketHandle *handle = parallel_lookup->handle; struct ConsumeTicketResultMessage *crm; struct GNUNET_MQ_Envelope *env; @@ -2105,8 +1054,8 @@ void abort_parallel_lookups2 (void *cls) { struct ConsumeTicketHandle *handle = cls; - struct ParallelLookup2 *lu; - struct ParallelLookup2 *tmp; + struct ParallelLookup *lu; + struct ParallelLookup *tmp; struct AttributeResultMessage *arm; struct GNUNET_MQ_Envelope *env; @@ -2147,7 +1096,7 @@ process_consume_abe_key (void *cls, uint32_t rd_count, struct GNUNET_CRYPTO_SymmetricSessionKey enc_key; struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv; struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key; - struct ParallelLookup2 *parallel_lookup; + struct ParallelLookup *parallel_lookup; size_t size; char *buf; char *scope; @@ -2201,7 +1150,7 @@ process_consume_abe_key (void *cls, uint32_t rd_count, scope); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up %s\n", lookup_query); - parallel_lookup = GNUNET_new (struct ParallelLookup2); + parallel_lookup = GNUNET_new (struct ParallelLookup); parallel_lookup->handle = handle; parallel_lookup->label = GNUNET_strdup (scope); parallel_lookup->lookup_request @@ -2247,7 +1196,7 @@ handle_consume_ticket_message (void *cls, ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity, &ch->identity_pub); - ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket2*)&cm[1]); + ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]); rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd, sizeof (uint64_t)); GNUNET_asprintf (&lookup_query, @@ -2660,7 +1609,7 @@ struct TicketIterationProcResult */ static void ticket_iterate_proc (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) { struct TicketIterationProcResult *proc = cls; @@ -2973,14 +1922,6 @@ GNUNET_SERVICE_MAIN &client_connect_cb, &client_disconnect_cb, NULL, - GNUNET_MQ_hd_var_size (issue_message, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE, - struct IssueMessage, - NULL), - GNUNET_MQ_hd_var_size (exchange_message, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE, - struct ExchangeMessage, - NULL), GNUNET_MQ_hd_var_size (attribute_store_message, GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE, struct AttributeStoreMessage, diff --git a/src/identity-provider/identity_provider.h b/src/identity-provider/identity_provider.h index 96bed18f4..9361854ad 100644 --- a/src/identity-provider/identity_provider.h +++ b/src/identity-provider/identity_provider.h @@ -33,146 +33,6 @@ GNUNET_NETWORK_STRUCT_BEGIN -/** - * The token - */ -struct GNUNET_IDENTITY_PROVIDER_Token -{ - /** - * The JWT representation of the identity token - */ - char *data; -}; - -/** - * The ticket DEPRECATED - */ -struct GNUNET_IDENTITY_PROVIDER_Ticket -{ - /** - * The Base64 representation of the ticket - */ - char *data; -}; - -/** - * Answer from service to client after issue operation - */ -struct IssueResultMessage -{ - /** - * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE - */ - struct GNUNET_MessageHeader header; - - /** - * Unique identifier for this request (for key collisions). - */ - uint32_t id GNUNET_PACKED; - - /* followed by 0-terminated label,ticket,token */ - -}; - - -/** - * Ticket exchange message. - */ -struct ExchangeResultMessage -{ - /** - * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE - */ - struct GNUNET_MessageHeader header; - - /** - * Unique identifier for this request (for key collisions). - */ - uint32_t id GNUNET_PACKED; - - /** - * Nonce found in ticket. NBO - * 0 on error. - */ - uint64_t ticket_nonce GNUNET_PACKED; - - /* followed by 0-terminated token */ - -}; - - - -/** - * Client requests IdP to issue token. - */ -struct IssueMessage -{ - /** - * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT - */ - struct GNUNET_MessageHeader header; - - /** - * Unique identifier for this request (for key collisions). - */ - uint32_t id GNUNET_PACKED; - - - /** - * Issuer identity private key - */ - struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key; - - /** - * Audience public key - */ - struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; - - /** - * Nonce - */ - uint64_t nonce; - - /** - * Length of scopes - */ - uint64_t scope_len; - - /** - * Expiration of token in NBO. - */ - struct GNUNET_TIME_AbsoluteNBO expiration; - - - /* followed by 0-terminated comma-separated scope list */ - -}; - - -/** - * Use to exchange a ticket for a token - */ -struct ExchangeMessage -{ - /** - * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT - */ - struct GNUNET_MessageHeader header; - - /** - * Unique identifier for this request (for key collisions). - */ - uint32_t id GNUNET_PACKED; - - /** - * Audience identity private key - */ - struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey; - - /* followed by 0-terminated ticket string */ - -}; - /** * Use to store an identity attribute */ diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c index 6ef1d470e..d623eaf3b 100644 --- a/src/identity-provider/identity_provider_api.c +++ b/src/identity-provider/identity_provider_api.c @@ -63,18 +63,6 @@ struct GNUNET_IDENTITY_PROVIDER_Operation */ const struct GNUNET_MessageHeader *msg; - /** - * Continuation to invoke with the result of the transmission; @e cb - * will be NULL in this case. - */ - GNUNET_IDENTITY_PROVIDER_ExchangeCallback ex_cb; - - /** - * Continuation to invoke with the result of the transmission for - * 'issue' operations (@e cont will be NULL in this case). - */ - GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb; - /** * Continuation to invoke after attribute store call */ @@ -403,151 +391,6 @@ mq_error_handler (void *cls, force_reconnect (handle); } -/** - * Check validity of message received from the service - * - * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` - * @param result_msg the incoming message - */ -static int -check_exchange_result (void *cls, - const struct ExchangeResultMessage *erm) -{ - char *str; - size_t size = ntohs (erm->header.size); - - - str = (char *) &erm[0]; - if ( (size > sizeof (struct ExchangeResultMessage)) && - ('\0' != str[size - 1]) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Check validity of message received from the service - * - * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` - * @param result_msg the incoming message - */ -static int -check_result (void *cls, - const struct IssueResultMessage *irm) -{ - char *str; - size_t size = ntohs (irm->header.size); - str = (char*) &irm[0]; - if ( (size > sizeof (struct IssueResultMessage)) && - ('\0' != str[size - 1]) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - -/** - * Handler for messages received from the GNS service - * - * @param cls the `struct GNUNET_GNS_Handle *` - * @param loookup_msg the incoming message - */ -static void -handle_exchange_result (void *cls, - const struct ExchangeResultMessage *erm) -{ - struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; - struct GNUNET_IDENTITY_PROVIDER_Operation *op; - struct GNUNET_IDENTITY_PROVIDER_Token token; - uint64_t ticket_nonce; - uint32_t r_id = ntohl (erm->id); - char *str; - - for (op = handle->op_head; NULL != op; op = op->next) - if (op->r_id == r_id) - break; - if (NULL == op) - return; - str = GNUNET_strdup ((char*)&erm[1]); - op = handle->op_head; - GNUNET_CONTAINER_DLL_remove (handle->op_head, - handle->op_tail, - op); - token.data = str; - ticket_nonce = ntohl (erm->ticket_nonce); - if (NULL != op->ex_cb) - op->ex_cb (op->cls, &token, ticket_nonce); - GNUNET_free (str); - GNUNET_free (op); - -} - -/** - * Handler for messages received from the GNS service - * - * @param cls the `struct GNUNET_GNS_Handle *` - * @param loookup_msg the incoming message - */ -static void -handle_result (void *cls, - const struct IssueResultMessage *irm) -{ - struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; - struct GNUNET_IDENTITY_PROVIDER_Operation *op; - struct GNUNET_IDENTITY_PROVIDER_Token token; - struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; - uint32_t r_id = ntohl (irm->id); - char *str; - char *label_str; - char *ticket_str; - char *token_str; - - for (op = handle->op_head; NULL != op; op = op->next) - if (op->r_id == r_id) - break; - if (NULL == op) - return; - str = GNUNET_strdup ((char*)&irm[1]); - label_str = strtok (str, ","); - - if (NULL == label_str) - { - GNUNET_free (str); - GNUNET_break (0); - return; - } - ticket_str = strtok (NULL, ","); - if (NULL == ticket_str) - { - GNUNET_free (str); - GNUNET_break (0); - return; - } - token_str = strtok (NULL, ","); - if (NULL == token_str) - { - GNUNET_free (str); - GNUNET_break (0); - return; - } - GNUNET_CONTAINER_DLL_remove (handle->op_head, - handle->op_tail, - op); - ticket.data = ticket_str; - token.data = token_str; - if (NULL != op->iss_cb) - op->iss_cb (op->cls, label_str, &ticket, &token); - GNUNET_free (str); - GNUNET_free (op); - -} - - - /** * Handle an incoming message of type * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE @@ -824,7 +667,7 @@ handle_ticket_result (void *cls, struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; struct GNUNET_IDENTITY_PROVIDER_Operation *op; struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it; - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket; + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket; uint32_t r_id = ntohl (msg->id); size_t msg_len; @@ -847,7 +690,7 @@ handle_ticket_result (void *cls, if (NULL != op->tr_cb) op->tr_cb (op->cls, NULL); } else { - ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&msg[1]; + ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1]; if (NULL != op->tr_cb) op->tr_cb (op->cls, ticket); } @@ -863,7 +706,7 @@ handle_ticket_result (void *cls, it->finish_cb (it->finish_cb_cls); } else { - ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&msg[1]; + ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1]; if (NULL != it->tr_cb) it->tr_cb (it->cls, ticket); } @@ -888,14 +731,6 @@ reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE, struct AttributeStoreResponseMessage, h), - GNUNET_MQ_hd_var_size (result, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT, - struct IssueResultMessage, - h), - GNUNET_MQ_hd_var_size (exchange_result, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT, - struct ExchangeResultMessage, - h), GNUNET_MQ_hd_var_size (attribute_result, GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT, struct AttributeResultMessage, @@ -952,117 +787,6 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) } -/** - * Issue an identity token - * - * @param id identity service to query - * @param service_name for which service is an identity wanted - * @param cb function to call with the result (will only be called once) - * @param cb_cls closure for @a cb - * @return handle to abort the operation - */ -struct GNUNET_IDENTITY_PROVIDER_Operation * -GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - const char* scopes, - const char* vattr, - struct GNUNET_TIME_Absolute expiration, - uint64_t nonce, - GNUNET_IDENTITY_PROVIDER_IssueCallback cb, - void *cb_cls) -{ - struct GNUNET_IDENTITY_PROVIDER_Operation *op; - struct IssueMessage *im; - size_t slen; - - slen = strlen (scopes) + 1; - if (NULL != vattr) - slen += strlen (vattr) + 1; - if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct IssueMessage)) - { - GNUNET_break (0); - return NULL; - } - op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); - op->h = id; - op->iss_cb = cb; - op->cls = cb_cls; - op->r_id = id->r_id_gen++; - op->env = GNUNET_MQ_msg_extra (im, - slen, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE); - im->id = op->r_id; - im->iss_key = *iss_key; - im->aud_key = *aud_key; - im->scope_len = htonl (strlen(scopes)+1); - im->nonce = htonl (nonce); - im->expiration = GNUNET_TIME_absolute_hton (expiration); - GNUNET_memcpy (&im[1], scopes, strlen(scopes)); - if (NULL != vattr) - GNUNET_memcpy ((char*)&im[1]+strlen(scopes)+1, vattr, strlen(vattr)); - GNUNET_CONTAINER_DLL_insert_tail (id->op_head, - id->op_tail, - op); - if (NULL != id->mq) - GNUNET_MQ_send_copy (id->mq, - op->env); - return op; -} - - -/** - * Exchange a token ticket for a token - * - * @param id identity provider service - * @param ticket ticket to exchange - * @param cont function to call once the operation finished - * @param cont_cls closure for @a cont - * @return handle to abort the operation - */ -struct GNUNET_IDENTITY_PROVIDER_Operation * -GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey, - GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, - void *cont_cls) -{ - struct GNUNET_IDENTITY_PROVIDER_Operation *op; - struct ExchangeMessage *em; - size_t slen; - char *ticket_str; - - ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); - - slen = strlen (ticket_str) + 1; - if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct ExchangeMessage)) - { - GNUNET_free (ticket_str); - GNUNET_break (0); - return NULL; - } - op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); - op->h = id; - op->ex_cb = cont; - op->cls = cont_cls; - op->r_id = id->r_id_gen++; - op->env = GNUNET_MQ_msg_extra (em, - slen, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE); - em->aud_privkey = *aud_privkey; - em->id = htonl (op->r_id); - GNUNET_memcpy (&em[1], ticket_str, slen); - GNUNET_free (ticket_str); - GNUNET_CONTAINER_DLL_insert_tail (id->op_head, - id->op_tail, - op); - if (NULL != id->mq) - GNUNET_MQ_send_copy (id->mq, - op->env); - return op; -} - - /** * Cancel an operation. Note that the operation MAY still * be executed; this merely cancels the continuation; if the request @@ -1107,80 +831,6 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) GNUNET_free (h); } -/** - * Convenience API - */ - - -/** - * Destroy token - * - * @param token the token - */ -void -GNUNET_IDENTITY_PROVIDER_token_destroy(struct GNUNET_IDENTITY_PROVIDER_Token *token) -{ - GNUNET_assert (NULL != token); - if (NULL != token->data) - GNUNET_free (token->data); - GNUNET_free (token); -} - -/** - * Returns string representation of token. A JSON-Web-Token. - * - * @param token the token - * @return The JWT (must be freed) - */ -char * -GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_Token *token) -{ - return GNUNET_strdup (token->data); -} - -/** - * Returns string representation of ticket. Base64-Encoded - * - * @param ticket the ticket - * @return the Base64-Encoded ticket - */ -char * -GNUNET_IDENTITY_PROVIDER_ticket_to_string (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) -{ - return GNUNET_strdup (ticket->data); -} - -/** - * Created a ticket from a string (Base64 encoded ticket) - * - * @param input Base64 encoded ticket - * @param ticket pointer where the ticket is stored - * @return GNUNET_OK - */ -int -GNUNET_IDENTITY_PROVIDER_string_to_ticket (const char* input, - struct GNUNET_IDENTITY_PROVIDER_Ticket **ticket) -{ - *ticket = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); - (*ticket)->data = GNUNET_strdup (input); - return GNUNET_OK; -} - - -/** - * Destroys a ticket - * - * @param ticket the ticket to destroy - */ -void -GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) -{ - GNUNET_assert (NULL != ticket); - if (NULL != ticket->data) - GNUNET_free (ticket->data); - GNUNET_free (ticket); -} - /** * Store an attribute. If the attribute is already present, * it is replaced with the new attribute. @@ -1428,7 +1078,7 @@ GNUNET_IDENTITY_PROVIDER_idp_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handl struct GNUNET_IDENTITY_PROVIDER_Operation * GNUNET_IDENTITY_PROVIDER_rp_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey * identity, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket, + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, GNUNET_IDENTITY_PROVIDER_AttributeResult cb, void *cb_cls) { @@ -1444,14 +1094,14 @@ GNUNET_IDENTITY_PROVIDER_rp_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Hand h->op_tail, op); op->env = GNUNET_MQ_msg_extra (ctm, - sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket2), + sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket), GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET); ctm->identity = *identity; ctm->id = htonl (op->r_id); GNUNET_memcpy ((char*)&ctm[1], ticket, - sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket2)); + sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket)); if (NULL != h->mq) GNUNET_MQ_send_copy (h->mq, diff --git a/src/identity-provider/identity_token.c b/src/identity-provider/identity_token.c deleted file mode 100644 index 6794e373c..000000000 --- a/src/identity-provider/identity_token.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2010-2015 GNUnet e.V. - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ - -/** - * @file identity-provider/identity_token.c - * @brief helper library to manage identity tokens - * @author Martin Schanzenbach - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_signatures.h" -#include "identity_token.h" -#include -#include - -#define JWT_ALG "alg" - -#define JWT_ALG_VALUE "ED512" - -#define JWT_TYP "typ" - -#define JWT_TYP_VALUE "jwt" - -/** - * Crypto helper functions - */ - -static int -create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, - struct GNUNET_CRYPTO_SymmetricSessionKey *skey, - struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) -{ - struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; - - GNUNET_CRYPTO_hash_to_enc (new_key_hash, - &new_key_hash_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); - static const char ctx_key[] = "gnuid-aes-ctx-key"; - GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), - new_key_hash, sizeof (struct GNUNET_HashCode), - ctx_key, strlen (ctx_key), - NULL, 0); - static const char ctx_iv[] = "gnuid-aes-ctx-iv"; - GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), - new_key_hash, sizeof (struct GNUNET_HashCode), - ctx_iv, strlen (ctx_iv), - NULL, 0); - return GNUNET_OK; -} - - - -/** - * Decrypts data part from a token code - */ -static int -decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key, - const char *cyphertext, - size_t cyphertext_len, - char **result_str) -{ - struct GNUNET_HashCode new_key_hash; - struct GNUNET_CRYPTO_SymmetricSessionKey enc_key; - struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv; - - char *str_buf = GNUNET_malloc (cyphertext_len); - size_t str_size; - - //Calculate symmetric key from ecdh parameters - GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key, - ecdh_key, - &new_key_hash)); - - create_sym_key_from_ecdh (&new_key_hash, - &enc_key, - &enc_iv); - - str_size = GNUNET_CRYPTO_symmetric_decrypt (cyphertext, - cyphertext_len, - &enc_key, - &enc_iv, - str_buf); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Decrypted bytes: %zd Expected bytes: %zd\n", - str_size, - cyphertext_len); - if (-1 == str_size) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n"); - GNUNET_free (str_buf); - return GNUNET_SYSERR; - } - *result_str = GNUNET_malloc (str_size+1); - GNUNET_memcpy (*result_str, str_buf, str_size); - (*result_str)[str_size] = '\0'; - GNUNET_free (str_buf); - return GNUNET_OK; - -} - -/** - * Decrypt string using pubkey and ECDHE -*/ -static int -decrypt_str_ecdhe2 (const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey, - const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - const char *ciphertext, - size_t ciphertext_len, - char **plaintext) -{ - struct GNUNET_CRYPTO_SymmetricSessionKey skey; - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - struct GNUNET_HashCode new_key_hash; - - //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt - *plaintext = GNUNET_malloc (ciphertext_len); - - // Derived key K = H(eB) - GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey, - aud_key, - &new_key_hash)); - create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); - GNUNET_CRYPTO_symmetric_decrypt (ciphertext, - ciphertext_len, - &skey, &iv, - *plaintext); - return GNUNET_OK; -} - - -/** - * Encrypt string using pubkey and ECDHE - * Returns ECDHE pubkey to be used for decryption - */ -static int -encrypt_str_ecdhe (const char *plaintext, - const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key, - char **cyphertext, - struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, - struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey) -{ - struct GNUNET_CRYPTO_SymmetricSessionKey skey; - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - struct GNUNET_HashCode new_key_hash; - ssize_t enc_size; - - // ECDH keypair E = eG - *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create(); - GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey, - ecdh_pubkey); - - //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt - *cyphertext = GNUNET_malloc (strlen (plaintext)); - - // Derived key K = H(eB) - GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, - pub_key, - &new_key_hash)); - create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%zd)", - plaintext, - strlen (plaintext)); - enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext, - strlen (plaintext), - &skey, &iv, - *cyphertext); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%zd)", enc_size); - return GNUNET_OK; -} - - -/** - * Identity Token API - */ - - -/** - * Create an Identity Token - * - * @param type the JSON API resource type - * @param id the JSON API resource id - * @return a new JSON API resource or NULL on error. - */ -struct IdentityToken* -token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss, - const struct GNUNET_CRYPTO_EcdsaPublicKey* aud) -{ - struct IdentityToken *token; - char* audience; - char* issuer; - - issuer = GNUNET_STRINGS_data_to_string_alloc (iss, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - audience = GNUNET_STRINGS_data_to_string_alloc (aud, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - - token = GNUNET_malloc (sizeof (struct IdentityToken)); - token_add_attr (token, "iss", issuer); - token_add_attr (token, "aud", audience); - token_add_attr (token, "sub", issuer); - token->aud_key = *aud; - GNUNET_free (issuer); - GNUNET_free (audience); - return token; -} - -void -token_destroy (struct IdentityToken *token) -{ - struct TokenAttr *attr; - struct TokenAttr *tmp_attr; - struct TokenAttrValue *val; - struct TokenAttrValue *tmp_val; - - for (attr = token->attr_head; NULL != attr;) - { - tmp_attr = attr->next; - GNUNET_CONTAINER_DLL_remove (token->attr_head, - token->attr_tail, - attr); - for (val = attr->val_head; NULL != val;) - { - tmp_val = val->next; - GNUNET_CONTAINER_DLL_remove (attr->val_head, - attr->val_tail, - val); - if (NULL != val->value) - GNUNET_free (val->value); - GNUNET_free (val); - val = tmp_val; - } - GNUNET_free (attr->name); - GNUNET_free (attr); - attr = tmp_attr; - } - - - GNUNET_free (token); -} - -void -token_add_attr_json (struct IdentityToken *token, - const char* key, - json_t* value) -{ - struct TokenAttr *attr; - struct TokenAttrValue *new_val; - GNUNET_assert (NULL != token); - - new_val = GNUNET_malloc (sizeof (struct TokenAttrValue)); - new_val->json_value = value; - json_incref(value); - for (attr = token->attr_head; NULL != attr; attr = attr->next) - { - if (0 == strcmp (key, attr->name)) - break; - } - - if (NULL == attr) - { - attr = GNUNET_malloc (sizeof (struct TokenAttr)); - attr->name = GNUNET_strdup (key); - GNUNET_CONTAINER_DLL_insert (token->attr_head, - token->attr_tail, - attr); - } - - GNUNET_CONTAINER_DLL_insert (attr->val_head, - attr->val_tail, - new_val); -} - -void -token_add_attr (struct IdentityToken *token, - const char* key, - const char* value) -{ - struct TokenAttr *attr; - struct TokenAttrValue *new_val; - GNUNET_assert (NULL != token); - - new_val = GNUNET_malloc (sizeof (struct TokenAttrValue)); - new_val->value = GNUNET_strdup (value); - for (attr = token->attr_head; NULL != attr; attr = attr->next) - { - if (0 == strcmp (key, attr->name)) - break; - } - - if (NULL == attr) - { - attr = GNUNET_malloc (sizeof (struct TokenAttr)); - attr->name = GNUNET_strdup (key); - GNUNET_CONTAINER_DLL_insert (token->attr_head, - token->attr_tail, - attr); - } - - GNUNET_CONTAINER_DLL_insert (attr->val_head, - attr->val_tail, - new_val); -} - -void -token_add_attr_int (struct IdentityToken *token, - const char* key, - uint64_t value) -{ - struct TokenAttr *attr; - struct TokenAttrValue *new_val; - GNUNET_assert (NULL != token); - - new_val = GNUNET_malloc (sizeof (struct TokenAttrValue)); - new_val->int_value = value; - for (attr = token->attr_head; NULL != attr; attr = attr->next) - { - if (0 == strcmp (key, attr->name)) - break; - } - - if (NULL == attr) - { - attr = GNUNET_malloc (sizeof (struct TokenAttr)); - attr->name = GNUNET_strdup (key); - GNUNET_CONTAINER_DLL_insert (token->attr_head, - token->attr_tail, - attr); - } - - GNUNET_CONTAINER_DLL_insert (attr->val_head, - attr->val_tail, - new_val); -} - -static void -parse_json_payload(const char* payload_base64, - struct IdentityToken *token) -{ - const char *key; - const json_t *value; - const json_t *arr_value; - char *payload; - int idx; - json_t *payload_json; - json_error_t err_json; - - GNUNET_STRINGS_base64_decode (payload_base64, - strlen (payload_base64), - &payload); - //TODO signature and aud key - payload_json = json_loads (payload, JSON_DECODE_ANY, &err_json); - - json_object_foreach (payload_json, key, value) - { - if (json_is_array (value)) - { - json_array_foreach (value, idx, arr_value) - { - if (json_is_integer (arr_value)) - token_add_attr_int (token, key, - json_integer_value (arr_value)); - else if (json_is_string (arr_value)) - token_add_attr (token, - key, - json_string_value (arr_value)); - else - token_add_attr_json (token, - key, - (json_t*)arr_value); - } - } else { - if (json_is_integer (value)) - token_add_attr_int (token, key, - json_integer_value (value)); - else if (json_is_string (value)) - token_add_attr (token, key, json_string_value (value)); - else - token_add_attr_json (token, key, (json_t*)value); - } - } - - json_decref (payload_json); - GNUNET_free (payload); -} - -int -token_parse2 (const char* raw_data, - const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - struct IdentityToken **result) -{ - char *enc_token_str; - char *tmp_buf; - char *token_str; - char *enc_token; - char *payload_base64; - size_t enc_token_len; - - GNUNET_asprintf (&tmp_buf, "%s", raw_data); - strtok (tmp_buf, ","); - enc_token_str = strtok (NULL, ","); - - enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str, - strlen (enc_token_str), - &enc_token); - if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key, - aud_key, - enc_token, - enc_token_len, - &token_str)) - { - GNUNET_free (tmp_buf); - GNUNET_free (enc_token); - return GNUNET_SYSERR; - } - - GNUNET_assert (NULL != strtok (token_str, ".")); - payload_base64 = strtok (NULL, "."); - - *result = GNUNET_malloc (sizeof (struct IdentityToken)); - parse_json_payload (payload_base64, *result); - - (*result)->aud_key = *aud_key; - GNUNET_free (enc_token); - GNUNET_free (token_str); - GNUNET_free (tmp_buf); - return GNUNET_OK; -} - -int -token_parse (const char* raw_data, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - struct IdentityToken **result) -{ - char *ecdh_pubkey_str; - char *enc_token_str; - char *tmp_buf; - char *token_str; - char *enc_token; - char *payload_base64; - size_t enc_token_len; - struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; - - GNUNET_asprintf (&tmp_buf, "%s", raw_data); - ecdh_pubkey_str = strtok (tmp_buf, ","); - enc_token_str = strtok (NULL, ","); - - GNUNET_assert (NULL != ecdh_pubkey_str); - GNUNET_assert (NULL != enc_token_str); - - GNUNET_STRINGS_string_to_data (ecdh_pubkey_str, - strlen (ecdh_pubkey_str), - &ecdh_pubkey, - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str, - strlen (enc_token_str), - &enc_token); - if (GNUNET_OK != decrypt_str_ecdhe (priv_key, - &ecdh_pubkey, - enc_token, - enc_token_len, - &token_str)) - { - GNUNET_free (tmp_buf); - GNUNET_free (enc_token); - return GNUNET_SYSERR; - } - - GNUNET_assert (NULL != strtok (token_str, ".")); - payload_base64 = strtok (NULL, "."); - - *result = GNUNET_malloc (sizeof (struct IdentityToken)); - parse_json_payload (payload_base64, *result); - - GNUNET_free (enc_token); - GNUNET_free (token_str); - GNUNET_free (tmp_buf); - return GNUNET_OK; -} - -static char* -create_json_payload (const struct IdentityToken *token) -{ - struct TokenAttr *attr; - struct TokenAttrValue *val; - json_t *root; - char *json_str; - - root = json_object(); - for (attr = token->attr_head; NULL != attr; attr = attr->next) - { - for (val = attr->val_head; NULL != val; val = val->next) - { - if (NULL != val->value) - { - json_object_set_new (root, - attr->name, - json_string (val->value)); - } else if (NULL != val->json_value) { - json_object_set (root, - attr->name, - val->json_value); - }else { - json_object_set_new (root, - attr->name, - json_integer (val->int_value)); - } - } - } - json_str = json_dumps (root, JSON_INDENT(1)); - json_decref (root); - return json_str; -} - -static char* -create_json_header(void) -{ - json_t *root; - char *json_str; - - root = json_object (); - json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE)); - json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE)); - - json_str = json_dumps (root, JSON_INDENT(1)); - json_decref (root); - return json_str; -} - -int -token_to_string (const struct IdentityToken *token, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - char **result) -{ - char *payload_str; - char *header_str; - char *payload_base64; - char *header_base64; - char *padding; - char *signature_target; - char *signature_str; - struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - header_str = create_json_header(); - GNUNET_STRINGS_base64_encode (header_str, - strlen (header_str), - &header_base64); - //Remove GNUNET padding of base64 - padding = strtok(header_base64, "="); - while (NULL != padding) - padding = strtok(NULL, "="); - - payload_str = create_json_payload (token); - GNUNET_STRINGS_base64_encode (payload_str, - strlen (payload_str), - &payload_base64); - - //Remove GNUNET padding of base64 - padding = strtok(payload_base64, "="); - while (NULL != padding) - padding = strtok(NULL, "="); - - GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64); - purpose = - GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - strlen (signature_target)); - purpose->size = - htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); - purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); - GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target)); - if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key, - purpose, - (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature)) - { - GNUNET_free (signature_target); - GNUNET_free (payload_str); - GNUNET_free (payload_base64); - GNUNET_free (header_base64); - GNUNET_free (purpose); - return GNUNET_SYSERR; - } - - GNUNET_STRINGS_base64_encode ((const char*)&token->signature, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature), - &signature_str); - GNUNET_asprintf (result, "%s.%s.%s", - header_base64, payload_base64, signature_str); - GNUNET_free (signature_target); - GNUNET_free (payload_str); - GNUNET_free (header_str); - GNUNET_free (signature_str); - GNUNET_free (payload_base64); - GNUNET_free (header_base64); - GNUNET_free (purpose); - return GNUNET_OK; -} - -int -token_serialize (const struct IdentityToken *token, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, - char **result) -{ - char *token_str; - char *enc_token; - char *dh_key_str; - char *enc_token_base64; - struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; - - GNUNET_assert (GNUNET_OK == token_to_string (token, - priv_key, - &token_str)); - - GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str, - &token->aud_key, - &enc_token, - ecdh_privkey, - &ecdh_pubkey)); - GNUNET_STRINGS_base64_encode (enc_token, - strlen (token_str), - &enc_token_base64); - dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey, - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64); - GNUNET_free (dh_key_str); - GNUNET_free (enc_token_base64); - GNUNET_free (enc_token); - GNUNET_free (token_str); - return GNUNET_OK; -} - -struct TokenTicketPayload* -ticket_payload_create (uint64_t nonce, - const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, - const char* lbl_str) -{ - struct TokenTicketPayload* payload; - - payload = GNUNET_malloc (sizeof (struct TokenTicketPayload)); - payload->nonce = nonce; - payload->identity_key = *identity_pkey; - GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str)); - return payload; -} - -void -ticket_payload_destroy (struct TokenTicketPayload* payload) -{ - if (NULL != payload->label) - GNUNET_free (payload->label); - GNUNET_free (payload); -} - -void -ticket_payload_serialize (struct TokenTicketPayload *payload, - char **result) -{ - char* identity_key_str; - - identity_key_str = GNUNET_STRINGS_data_to_string_alloc (&payload->identity_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - - GNUNET_asprintf (result, - "{\"nonce\": \"%"SCNu64"\",\"identity\": \"%s\",\"label\": \"%s\"}", - payload->nonce, identity_key_str, payload->label); - GNUNET_free (identity_key_str); - -} - - -/** - * Create the token code - * The data is encrypted with a share ECDH derived secret using B (aud_key) - * and e (ecdh_privkey) - * The ticket also contains E (ecdh_pubkey) and a signature over the - * data and E - */ -struct TokenTicket* -ticket_create (uint64_t nonce, - const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, - const char* lbl_str, - const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key) -{ - struct TokenTicket *ticket; - struct TokenTicketPayload *code_payload; - - ticket = GNUNET_malloc (sizeof (struct TokenTicket)); - code_payload = ticket_payload_create (nonce, - identity_pkey, - lbl_str); - ticket->aud_key = *aud_key; - ticket->payload = code_payload; - - - return ticket; -} - -void -ticket_destroy (struct TokenTicket *ticket) -{ - ticket_payload_destroy (ticket->payload); - GNUNET_free (ticket); -} - -int -ticket_serialize (struct TokenTicket *ticket, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - char **result) -{ - char *code_payload_str; - char *enc_ticket_payload; - char *ticket_payload_str; - char *ticket_sig_str; - char *ticket_str; - char *dh_key_str; - char *write_ptr; - struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; - - struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - - ticket_payload_serialize (ticket->payload, - &code_payload_str); - - GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str, - &ticket->aud_key, - &enc_ticket_payload, - &ecdhe_privkey, - &ticket->ecdh_pubkey)); - - GNUNET_free (ecdhe_privkey); - - purpose = - GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E - strlen (code_payload_str)); // E_K (code_str) - purpose->size = - htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + - strlen (code_payload_str)); - purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET); - write_ptr = (char*) &purpose[1]; - GNUNET_memcpy (write_ptr, - &ticket->ecdh_pubkey, - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); - GNUNET_memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str)); - GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key, - purpose, - &ticket->signature)); - GNUNET_STRINGS_base64_encode (enc_ticket_payload, - strlen (code_payload_str), - &ticket_payload_str); - ticket_sig_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->signature, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); - - dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey, - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str); - GNUNET_asprintf (&ticket_str, "{\"data\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}", - ticket_payload_str, dh_key_str, ticket_sig_str); - GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result); - GNUNET_free (dh_key_str); - GNUNET_free (purpose); - GNUNET_free (ticket_str); - GNUNET_free (ticket_sig_str); - GNUNET_free (code_payload_str); - GNUNET_free (enc_ticket_payload); - GNUNET_free (ticket_payload_str); - return GNUNET_OK; -} - -int -ticket_payload_parse(const char *raw_data, - ssize_t data_len, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey, - struct TokenTicketPayload **result) -{ - const char* label_str; - const char* nonce_str; - const char* identity_key_str; - - json_t *root; - json_t *label_json; - json_t *identity_json; - json_t *nonce_json; - json_error_t err_json; - char* data_str; - uint64_t nonce; - struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey; - - if (GNUNET_OK != decrypt_str_ecdhe (priv_key, - ecdhe_pkey, - raw_data, - data_len, - &data_str)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Data decryption failed\n"); - return GNUNET_SYSERR; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data: %s\n", data_str); - root = json_loads (data_str, JSON_DECODE_ANY, &err_json); - if (!root) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing data: %s\n", err_json.text); - GNUNET_free (data_str); - return GNUNET_SYSERR; - } - - identity_json = json_object_get (root, "identity"); - if (!json_is_string (identity_json)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing data: %s\n", err_json.text); - json_decref (root); - GNUNET_free (data_str); - return GNUNET_SYSERR; - } - identity_key_str = json_string_value (identity_json); - GNUNET_STRINGS_string_to_data (identity_key_str, - strlen (identity_key_str), - &id_pkey, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - - - label_json = json_object_get (root, "label"); - if (!json_is_string (label_json)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing data: %s\n", err_json.text); - json_decref (root); - GNUNET_free (data_str); - return GNUNET_SYSERR; - } - - label_str = json_string_value (label_json); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str); - - nonce_json = json_object_get (root, "nonce"); - if (!json_is_string (label_json)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing data: %s\n", err_json.text); - json_decref (root); - GNUNET_free (data_str); - return GNUNET_SYSERR; - } - - nonce_str = json_string_value (nonce_json); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str); - - GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce)); - - *result = ticket_payload_create (nonce, - (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey, - label_str); - GNUNET_free (data_str); - json_decref (root); - return GNUNET_OK; - -} - -int -ticket_parse (const char *raw_data, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - struct TokenTicket **result) -{ - const char* enc_data_str; - const char* ecdh_enc_str; - const char* signature_enc_str; - - json_t *root; - json_t *signature_json; - json_t *ecdh_json; - json_t *enc_data_json; - json_error_t err_json; - char* enc_data; - char* ticket_decoded; - char* write_ptr; - size_t enc_data_len; - struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - struct TokenTicket *ticket; - struct TokenTicketPayload *ticket_payload; - - ticket_decoded = NULL; - GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded); - root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json); - if (!root) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%s\n", err_json.text); - return GNUNET_SYSERR; - } - - signature_json = json_object_get (root, "signature"); - ecdh_json = json_object_get (root, "ecdh"); - enc_data_json = json_object_get (root, "data"); - - signature_enc_str = json_string_value (signature_json); - ecdh_enc_str = json_string_value (ecdh_json); - enc_data_str = json_string_value (enc_data_json); - - ticket = GNUNET_malloc (sizeof (struct TokenTicket)); - - if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str, - strlen (ecdh_enc_str), - &ticket->ecdh_pubkey, - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in data\n", ecdh_enc_str); - json_decref (root); - GNUNET_free (ticket); - return GNUNET_SYSERR; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for data decryption\n", ecdh_enc_str); - if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str, - strlen (signature_enc_str), - &ticket->signature, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature))) - { - json_decref (root); - GNUNET_free (ticket_decoded); - GNUNET_free (ticket); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in data\n"); - return GNUNET_SYSERR; - } - - enc_data_len = GNUNET_STRINGS_base64_decode (enc_data_str, - strlen (enc_data_str), - &enc_data); - - - if (GNUNET_OK != ticket_payload_parse (enc_data, - enc_data_len, - priv_key, - (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey, - &ticket_payload)) - { - json_decref (root); - GNUNET_free (enc_data); - GNUNET_free (ticket_decoded); - GNUNET_free (ticket); - return GNUNET_SYSERR; - } - - ticket->payload = ticket_payload; - purpose = - GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E - enc_data_len); // E_K (code_str) - purpose->size = - htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + - enc_data_len); - purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET); - write_ptr = (char*) &purpose[1]; - GNUNET_memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); - GNUNET_memcpy (write_ptr, enc_data, enc_data_len); - - if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET, - purpose, - &ticket->signature, - &ticket_payload->identity_key)) - { - ticket_destroy (ticket); - GNUNET_free (ticket_decoded); - json_decref (root); - GNUNET_free (purpose); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error verifying signature for ticket\n"); - return GNUNET_SYSERR; - } - *result = ticket; - GNUNET_free (purpose); - - GNUNET_free (enc_data); - GNUNET_free (ticket_decoded); - json_decref (root); - return GNUNET_OK; - -} - - - -/* end of identity_token.c */ diff --git a/src/identity-provider/identity_token.h b/src/identity-provider/identity_token.h deleted file mode 100644 index 5988bc668..000000000 --- a/src/identity-provider/identity_token.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012-2015 GNUnet e.V. - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ -/** - * @author Martin Schanzenbach - * @file identity-provider/identity_token.h - * @brief GNUnet Identity Provider library - * - */ -#ifndef IDENTITY_TOKEN_H -#define IDENTITY_TOKEN_H - -#include "gnunet_crypto_lib.h" -#include - -struct IdentityToken -{ - /** - * DLL - */ - struct TokenAttr *attr_head; - - /** - * DLL - */ - struct TokenAttr *attr_tail; - - /** - * Token Signature - */ - struct GNUNET_CRYPTO_EcdsaSignature signature; - - /** - * Audience Pubkey - */ - struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; -}; - -struct TokenAttr -{ - /** - * DLL - */ - struct TokenAttr *next; - - /** - * DLL - */ - struct TokenAttr *prev; - - /** - * Attribute name - */ - char *name; - - /** - * Attribute value DLL - */ - struct TokenAttrValue *val_head; - - /** - * Attribute value DLL - */ - struct TokenAttrValue *val_tail; - -}; - -struct TokenAttrValue -{ - /** - * DLL - */ - struct TokenAttrValue *next; - - /** - * DLL - */ - struct TokenAttrValue *prev; - - /** - * Attribute value - */ - char *value; - - /** - * Attribute int value - * used if NULL == value - */ - uint64_t int_value; - - /** - * Json value - */ - json_t *json_value; -}; - -struct TokenTicketPayload -{ - /** - * Nonce - */ - uint64_t nonce; - - /** - * Label - */ - char *label; - - /** - * Issuing Identity - */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity_key; -}; - - -struct TokenTicket -{ - /** - * Meta info - */ - struct TokenTicketPayload *payload; - - /** - * ECDH Pubkey - */ - struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; - - /** - * Signature - */ - struct GNUNET_CRYPTO_EcdsaSignature signature; - - /** - * Target identity - */ - struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; -}; - - - -/** - * Create an identity token - * - * @param iss the issuer string for the token - * @param aud the audience of the token - * - * @return a new token - */ -struct IdentityToken* -token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *iss, - const struct GNUNET_CRYPTO_EcdsaPublicKey* aud); - -/** - * Destroy an identity token - * - * @param token the token to destroy - */ -void -token_destroy (struct IdentityToken*token); - -/** - * Add a new key value pair to the token - * - * @param token the token to modify - * @param key the key - * @param value the value - */ -void -token_add_attr (struct IdentityToken *token, - const char* key, - const char* value); - -/** - * Add a new key value pair to the token - * - * @param token the token to modify - * @param key the key - * @param value the value - */ -void -token_add_attr_int (struct IdentityToken *token, - const char* key, - uint64_t value); - - - -/** - * Add a value to a TokenAttribute - * - * @param attr the token attribute - * @param value value to add - */ - void - token_attr_add_value (const struct TokenAttr *attr, - const char *value); - -/** - * Add a new key value pair to the token with the value as json - * - * @param the token to modify - * @param key the key - * @param value the value - * - */ -void -token_add_attr_json (struct IdentityToken *token, - const char* key, - json_t* value); - -/** - * Serialize a token. The token will be signed and base64 according to the - * JWT format. The signature is base32-encoded ECDSA. - * The resulting JWT is encrypted using - * ECDHE for the audience and Base64 - * encoded in result. The audience requires the ECDHE public key P - * to decrypt the token T. The key P is included in the result and prepended - * before the token - * - * @param token the token to serialize - * @param priv_key the private key used to sign the token - * @param ecdhe_privkey the ECDHE private key used to encrypt the token - * @param result P,Base64(E(T)) - * - * @return GNUNET_OK on success - */ -int -token_serialize (const struct IdentityToken*token, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - struct GNUNET_CRYPTO_EcdhePrivateKey **ecdhe_privkey, - char **result); - -/** - * Parses the serialized token and returns a token - * - * @param data the serialized token - * @param priv_key the private key of the audience - * @param result the token - * - * @return GNUNET_OK on success - */ -int -token_parse (const char* data, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - struct IdentityToken **result); - -/** - * Parses the serialized token and returns a token - * This variant is intended for the party that issued the token and also - * wants to decrypt the serialized token. - * - * @param data the serialized token - * @param priv_key the private (!) ECDHE key - * @param aud_key the identity of the audience - * @param result the token - * - * @return GNUNET_OK on success - */ -int -token_parse2 (const char* data, - const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - struct IdentityToken **result); - - -/** - * - * Returns a JWT-string representation of the token - * - * @param token the token - * @param priv_key the private key used to sign the JWT - * @param result the JWT - * - * @return GNUNET_OK on success - */ -int -token_to_string (const struct IdentityToken *token, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - char **result); - -/** - * - * Creates a ticket that can be exchanged by the audience for - * the token. The token must be placed under the label - * - * @param nonce nonce provided by the audience that requested the ticket - * @param iss_pkey the issuer pubkey used to sign the ticket - * @param label the label encoded in the ticket - * @param aud_ley the audience pubkey used to encrypt the ticket payload - * - * @return the ticket - */ -struct TokenTicket* -ticket_create (uint64_t nonce, - const struct GNUNET_CRYPTO_EcdsaPublicKey* iss_pkey, - const char* lbl_str, - const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key); - -/** - * Serialize a ticket. Returns the Base64 representation of the ticket. - * Format: Base64( { payload: E(Payload), ecdhe: K, signature: signature } ) - * - * @param ticket the ticket to serialize - * @param priv_key the issuer private key to sign the ticket payload - * @param result the serialized ticket - * - * @return GNUNET_OK on success - */ -int -ticket_serialize (struct TokenTicket *ticket, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - char **result); - -/** - * Destroys a ticket - * - * @param the ticket to destroy - */ -void -ticket_destroy (struct TokenTicket *ticket); - -/** - * Parses a serialized ticket - * - * @param data the serialized ticket - * @param priv_key the audience private key - * @param ticket the ticket - * - * @return GNUNET_OK on success - */ -int -ticket_parse (const char* raw_data, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, - struct TokenTicket **ticket); - -#endif diff --git a/src/identity-provider/plugin_identity_provider_sqlite.c b/src/identity-provider/plugin_identity_provider_sqlite.c index 7a19ba827..ff2d3a22e 100644 --- a/src/identity-provider/plugin_identity_provider_sqlite.c +++ b/src/identity-provider/plugin_identity_provider_sqlite.c @@ -358,7 +358,7 @@ database_shutdown (struct Plugin *plugin) */ static int identity_provider_sqlite_store_ticket (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) { struct Plugin *plugin = cls; int n; @@ -437,7 +437,7 @@ identity_provider_sqlite_store_ticket (void *cls, */ static int identity_provider_sqlite_delete_ticket (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) { struct Plugin *plugin = cls; int n; @@ -502,7 +502,7 @@ get_ticket_and_call_iterator (struct Plugin *plugin, GNUNET_IDENTITY_PROVIDER_TicketIterator iter, void *iter_cls) { - struct GNUNET_IDENTITY_PROVIDER_Ticket2 ticket; + struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; int ret; int sret; diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c deleted file mode 100644 index dfb935f5b..000000000 --- a/src/identity-provider/plugin_rest_identity_provider.c +++ /dev/null @@ -1,1216 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012-2015 GNUnet e.V. - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ -/** - * @author Martin Schanzenbach - * @file identity/plugin_rest_identity.c - * @brief GNUnet Namestore REST plugin - * - */ - -#include "platform.h" -#include "gnunet_rest_plugin.h" -#include "gnunet_identity_service.h" -#include "gnunet_gns_service.h" -#include "gnunet_gnsrecord_lib.h" -#include "gnunet_namestore_service.h" -#include "gnunet_rest_lib.h" -#include "gnunet_jsonapi_lib.h" -#include "gnunet_jsonapi_util.h" -#include "microhttpd.h" -#include -#include -#include "gnunet_signatures.h" -#include "gnunet_identity_provider_service.h" - -/** - * REST root namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_PROVIDER "/idp" - -/** - * Issue namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE "/idp/issue" - -/** - * Check namespace TODO - */ -#define GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK "/idp/check" - -/** - * Token namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN "/idp/token" - -/** - * The parameter name in which the ticket must be provided - */ -#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET "ticket" - -/** - * The parameter name in which the expected nonce must be provided - */ -#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE "expected_nonce" - -/** - * The parameter name in which the ticket must be provided - */ -#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN "token" - -/** - * The URL parameter name in which the nonce must be provided - */ -#define GNUNET_IDENTITY_TOKEN_REQUEST_NONCE "nonce" - -/** - * State while collecting all egos - */ -#define ID_REST_STATE_INIT 0 - -/** - * Done collecting egos - */ -#define ID_REST_STATE_POST_INIT 1 - -/** - * Resource type - */ -#define GNUNET_REST_JSONAPI_IDENTITY_TOKEN "token" - -/** - * URL parameter to create a GNUid token for a specific audience - */ -#define GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST "audience" - -/** - * URL parameter to create a GNUid token for a specific issuer (EGO) - */ -#define GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST "issuer" - -/** - * Attributes passed to issue request - */ -#define GNUNET_IDENTITY_TOKEN_ATTR_LIST "requested_attrs" - -/** - * Attributes passed to issue request - */ -#define GNUNET_IDENTITY_TOKEN_V_ATTR_LIST "requested_verified_attrs" - - -/** - * Token expiration string - */ -#define GNUNET_IDENTITY_TOKEN_EXP_STRING "expiration" - -/** - * Error messages - */ -#define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid" -#define GNUNET_REST_ERROR_NO_DATA "No data" - -/** - * GNUid token lifetime - */ -#define GNUNET_GNUID_TOKEN_EXPIRATION_MICROSECONDS 300000000 - -/** - * The configuration handle - */ -const struct GNUNET_CONFIGURATION_Handle *cfg; - -/** - * HTTP methods allows for this plugin - */ -static char* allow_methods; - -/** - * @brief struct returned by the initialization function of the plugin - */ -struct Plugin -{ - const struct GNUNET_CONFIGURATION_Handle *cfg; -}; - -/** - * The ego list - */ -struct EgoEntry -{ - /** - * DLL - */ - struct EgoEntry *next; - - /** - * DLL - */ - struct EgoEntry *prev; - - /** - * Ego Identifier - */ - char *identifier; - - /** - * Public key string - */ - char *keystring; - - /** - * The Ego - */ - struct GNUNET_IDENTITY_Ego *ego; -}; - - -struct RequestHandle -{ - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; - - /** - * Selected ego - */ - struct EgoEntry *ego_entry; - - /** - * Ptr to current ego private key - */ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - - /** - * Handle to the rest connection - */ - struct GNUNET_REST_RequestHandle *conndata_handle; - - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - - /** - * IDENTITY Operation - */ - struct GNUNET_IDENTITY_Operation *op; - - /** - * Identity Provider - */ - struct GNUNET_IDENTITY_PROVIDER_Handle *idp; - - /** - * Idp Operation - */ - struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op; - - /** - * Handle to NS service - */ - struct GNUNET_NAMESTORE_Handle *ns_handle; - - /** - * NS iterator - */ - struct GNUNET_NAMESTORE_ZoneIterator *ns_it; - - /** - * NS Handle - */ - struct GNUNET_NAMESTORE_QueueEntry *ns_qe; - - /** - * Desired timeout for the lookup (default is no timeout). - */ - struct GNUNET_TIME_Relative timeout; - - /** - * ID of a task associated with the resolution process. - */ - struct GNUNET_SCHEDULER_Task *timeout_task; - - /** - * The plugin result processor - */ - GNUNET_REST_ResultProcessor proc; - - /** - * The closure of the result processor - */ - void *proc_cls; - - /** - * The url - */ - char *url; - - /** - * Error response message - */ - char *emsg; - - /** - * Reponse code - */ - int response_code; - - /** - * Response object - */ - struct GNUNET_JSONAPI_Document *resp_object; - -}; - - -/** - * Cleanup lookup handle - * @param handle Handle to clean up - */ -static void -cleanup_handle (struct RequestHandle *handle) -{ - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Cleaning up\n"); - if (NULL != handle->resp_object) - GNUNET_JSONAPI_document_delete (handle->resp_object); - if (NULL != handle->timeout_task) - GNUNET_SCHEDULER_cancel (handle->timeout_task); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); - if (NULL != handle->idp) - GNUNET_IDENTITY_PROVIDER_disconnect (handle->idp); - if (NULL != handle->ns_it) - GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it); - if (NULL != handle->ns_qe) - GNUNET_NAMESTORE_cancel (handle->ns_qe); - if (NULL != handle->ns_handle) - GNUNET_NAMESTORE_disconnect (handle->ns_handle); - if (NULL != handle->url) - GNUNET_free (handle->url); - if (NULL != handle->emsg) - GNUNET_free (handle->emsg); - for (ego_entry = handle->ego_head; - NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } - GNUNET_free (handle); -} - - -/** - * Task run on error, sends error message. Cleans up everything. - * - * @param cls the `struct RequestHandle` - */ -static void -do_error (void *cls) -{ - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - char *json_error; - - GNUNET_asprintf (&json_error, - "{Error while processing request: %s}", - handle->emsg); - resp = GNUNET_REST_create_response (json_error); - handle->proc (handle->proc_cls, resp, handle->response_code); - cleanup_handle (handle); - GNUNET_free (json_error); -} - -/** - * Task run on timeout, sends error message. Cleans up everything. - * - * @param cls the `struct RequestHandle` - */ -static void -do_timeout (void *cls) -{ - struct RequestHandle *handle = cls; - - handle->timeout_task = NULL; - do_error (handle); -} - - -/** - * Task run on shutdown. Cleans up everything. - * - * @param cls unused - */ -static void -do_cleanup_handle_delayed (void *cls) -{ - struct RequestHandle *handle = cls; - - cleanup_handle (handle); -} - - -/** - * Get a ticket for identity - * @param cls the handle - * @param ticket the ticket returned from the idp - */ -static void -token_creat_cont (void *cls, - const char *label, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, - const struct GNUNET_IDENTITY_PROVIDER_Token *token) -{ - struct GNUNET_JSONAPI_Resource *json_resource; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - json_t *ticket_json; - json_t *token_json; - char *ticket_str; - char *token_str; - char *result_str; - - handle->idp_op = NULL; - - if (NULL == ticket) - { - handle->emsg = GNUNET_strdup ("Error in token issue"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - handle->resp_object = GNUNET_JSONAPI_document_new (); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, - label); - ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); - token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token); - ticket_json = json_string (ticket_str); - token_json = json_string (token_str); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, - ticket_json); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN, - token_json); - GNUNET_free (ticket_str); - GNUNET_free (token_str); - json_decref (ticket_json); - json_decref (token_json); - GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - - GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); - resp = GNUNET_REST_create_response (result_str); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result_str); - GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle); -} - - -/** - * Continueationf for token issue request - * - * @param con the Rest handle - * @param url the requested url - * @param cls the request handle - */ -static void -issue_token_cont (struct GNUNET_REST_RequestHandle *con, - const char *url, - void *cls) -{ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - const char *egoname; - - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct GNUNET_HashCode key; - struct MHD_Response *resp; - struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; - struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; - struct GNUNET_TIME_Relative etime_rel; - struct GNUNET_TIME_Absolute exp_time; - char *ego_val; - char *audience; - char *exp_str; - char *nonce_str; - char *scopes; - char *vattrs; - uint64_t time; - uint64_t nonce; - - if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, - GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "URL invalid: %s\n", handle->url); - resp = GNUNET_REST_create_response (NULL); - handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST); - cleanup_handle (handle); - return; - } - egoname = NULL; - ego_entry = NULL; - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, - strlen (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST), - &key); - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Issuer not found\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - ego_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - if (NULL == ego_val) - { - GNUNET_SCHEDULER_add_now (&do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Ego invalid: %s\n", - ego_val); - return; - } - for (ego_entry = handle->ego_head; - NULL != ego_entry; - ego_entry = ego_entry->next) - { - if (0 != strcmp (ego_val, ego_entry->identifier)) - continue; - egoname = ego_entry->identifier; - break; - } - if ( (NULL == egoname) || - (NULL == ego_entry) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Ego not found: %s\n", - ego_val); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Ego to issue token for: %s\n", - egoname); - - - //Meta info - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_ATTR_LIST, - strlen (GNUNET_IDENTITY_TOKEN_ATTR_LIST), - &key); - - scopes = NULL; - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("Scopes missing!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - - //vattrs - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST, - strlen (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST), - &key); - - vattrs = NULL; - if ( GNUNET_YES == - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - vattrs = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - } - - - - //Token audience - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST, - strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST), - &key); - audience = NULL; - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Audience missing!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Audience to issue token for: %s\n", - audience); - - priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, - &pub_key); - GNUNET_STRINGS_string_to_data (audience, - strlen (audience), - &aud_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - - //Remote nonce - nonce_str = NULL; - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE, - strlen (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE), - &key); - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("Request nonce missing!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_assert (NULL != nonce_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Request nonce: %s\n", - nonce_str); - GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &nonce)); - - //Get expiration for token from URL parameter - GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING, - strlen (GNUNET_IDENTITY_TOKEN_EXP_STRING), - &key); - - exp_str = NULL; - if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key)) - { - exp_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - } - if (NULL == exp_str) { - handle->emsg = GNUNET_strdup ("No expiration given!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - if (GNUNET_OK != - GNUNET_STRINGS_fancy_time_to_relative (exp_str, - &etime_rel)) - { - handle->emsg = GNUNET_strdup ("Expiration invalid!\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - time = GNUNET_TIME_absolute_get().abs_value_us; - exp_time.abs_value_us = time + etime_rel.rel_value_us; - - handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); - handle->idp_op = GNUNET_IDENTITY_PROVIDER_issue_token (handle->idp, - priv_key, - &aud_key, - scopes, - vattrs, - exp_time, - nonce, - &token_creat_cont, - handle); - -} - - -/** - * Build a GNUid token for identity - * - * @param cls the request handle - */ -static void -return_token_list (void *cls) -{ - char* result_str; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); - resp = GNUNET_REST_create_response (result_str); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result_str); - cleanup_handle (handle); -} - - -static void -token_collect_error_cb (void *cls) -{ - struct RequestHandle *handle = cls; - - do_error (handle); -} - - -/** - * Collect all tokens for an ego - * - * TODO move this into the identity-provider service - * - */ -static void -token_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd); - - -static void -token_collect_finished_cb (void *cls) -{ - struct RequestHandle *handle = cls; - struct EgoEntry *ego_tmp; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - - ego_tmp = handle->ego_head; - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - ego_tmp); - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - - if (NULL == handle->ego_head) - { - //Done - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token END\n"); - handle->ns_it = NULL; - GNUNET_SCHEDULER_add_now (&return_token_list, handle); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Next ego: %s\n", - handle->ego_head->identifier); - priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); - handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, - priv_key, - &token_collect_error_cb, - handle, - &token_collect, - handle, - &token_collect_finished_cb, - handle); -} - - -/** - * Collect all tokens for an ego - * - * TODO move this into the identity-provider service - * - */ -static void -token_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - struct RequestHandle *handle = cls; - int i; - char* data; - struct GNUNET_JSONAPI_Resource *json_resource; - json_t *issuer; - json_t *token; - - for (i = 0; i < rd_count; i++) - { - if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN) - { - data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, - rd[i].data, - rd[i].data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token: %s\n", data); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN, - label); - issuer = json_string (handle->ego_head->identifier); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, - issuer); - json_decref (issuer); - token = json_string (data); - GNUNET_JSONAPI_resource_add_attr (json_resource, - GNUNET_REST_JSONAPI_IDENTITY_TOKEN, - token); - json_decref (token); - - GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - GNUNET_free (data); - } - } - - GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); -} - - - -/** - * Respond to OPTIONS request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -list_token_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - char* ego_val; - struct GNUNET_HashCode key; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; - - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, - strlen (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST), - &key); - - if ( GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No issuer given.\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - ego_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_assert (NULL != ego_val); - //Remove non-matching egos - for (ego_entry = handle->ego_head; - NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - if (0 != strcmp (ego_val, ego_tmp->identifier)) - { - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - ego_tmp); - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } - } - handle->resp_object = GNUNET_JSONAPI_document_new (); - if (NULL == handle->ego_head) - { - //Done - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No results.\n"); - GNUNET_SCHEDULER_add_now (&return_token_list, handle); - return; - } - priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); - handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); - handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, - priv_key, - &token_collect_error_cb, - handle, - &token_collect, - handle, - &token_collect_finished_cb, - handle); - -} - -/** - * Return token to requestor - * - * @param cls request handle - * @param token the token - */ -static void -exchange_cont (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Token *token, - uint64_t ticket_nonce) -{ - json_t *root; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - struct GNUNET_HashCode key; - char* result; - char* token_str; - char* nonce_str; - uint64_t expected_nonce; - - //Get nonce - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE, - strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE), - &key); - - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("No nonce given."); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - GNUNET_assert (NULL != nonce_str); - GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &expected_nonce)); - - if (ticket_nonce != expected_nonce) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Ticket nonce %"SCNu64" does not match expected nonce %"SCNu64"\n", - ticket_nonce, expected_nonce); - handle->emsg = GNUNET_strdup ("Ticket nonce does not match expected nonce\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - root = json_object (); - token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token); - json_object_set_new (root, "token", json_string (token_str)); - json_object_set_new (root, "token_type", json_string ("jwt")); - GNUNET_free (token_str); - - result = json_dumps (root, JSON_INDENT(1)); - resp = GNUNET_REST_create_response (result); - GNUNET_free (result); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - cleanup_handle (handle); - json_decref (root); -} - - -/** - * - * Callback called when identity for token exchange has been found - * - * @param cls request handle - * @param ego the identity to use as issuer - * @param ctx user context - * @param name identity name - * - */ -static void -exchange_token_ticket_cb (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *name) -{ - struct RequestHandle *handle = cls; - struct GNUNET_HashCode key; - struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket; - char* ticket_str; - - handle->op = NULL; - - if (NULL == ego) - { - handle->emsg = GNUNET_strdup ("No identity found."); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - //Get ticket - GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, - strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET), - &key); - - if ( GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, - &key) ) - { - handle->emsg = GNUNET_strdup ("No ticket given."); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - ticket_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, - &key); - handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (ego); - GNUNET_IDENTITY_PROVIDER_string_to_ticket (ticket_str, - &ticket); - - handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); - handle->idp_op = GNUNET_IDENTITY_PROVIDER_exchange_ticket (handle->idp, - ticket, - handle->priv_key, - &exchange_cont, - handle); - GNUNET_IDENTITY_PROVIDER_ticket_destroy (ticket); - -} - - - -/** - * Respond to issue request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -exchange_token_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - struct RequestHandle *handle = cls; - - //Get token from GNS - handle->op = GNUNET_IDENTITY_get (handle->identity_handle, - "gns-master", - &exchange_token_ticket_cb, - handle); -} - -/** - * Respond to OPTIONS request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -options_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - struct MHD_Response *resp; - struct RequestHandle *handle = cls; - - //For now, independent of path return all options - resp = GNUNET_REST_create_response (NULL); - MHD_add_response_header (resp, - "Access-Control-Allow-Methods", - allow_methods); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - cleanup_handle (handle); - return; -} - -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = { - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE, &issue_token_cont}, - //{MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK, &check_token_cont}, - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PROVIDER, &list_token_cont}, - {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, &options_cont}, - {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN, &exchange_token_ticket_cont}, - GNUNET_REST_HANDLER_END - }; - - if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_handle, - handlers, - &err, - handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - -/** - * If listing is enabled, prints information about the egos. - * - * This function is initially called for all egos and then again - * whenever a ego's identifier changes or if it is deleted. At the - * end of the initial pass over all egos, the function is once called - * with 'NULL' for 'ego'. That does NOT mean that the callback won't - * be invoked in the future or that there was an error. - * - * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', - * this function is only called ONCE, and 'NULL' being passed in - * 'ego' does indicate an error (i.e. name is taken or no default - * value is known). If 'ego' is non-NULL and if '*ctx' - * is set in those callbacks, the value WILL be passed to a subsequent - * call to the identity callback of 'GNUNET_IDENTITY_connect' (if - * that one was not NULL). - * - * When an identity is renamed, this function is called with the - * (known) ego but the NEW identifier. - * - * When an identity is deleted, this function is called with the - * (known) ego and "NULL" for the 'identifier'. In this case, - * the 'ego' is henceforth invalid (and the 'ctx' should also be - * cleaned up). - * - * @param cls closure - * @param ego ego handle - * @param ctx context for application to store data for this ego - * (during the lifetime of this process, initially NULL) - * @param identifier identifier assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used - */ -static void -list_ego (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *identifier) -{ - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct GNUNET_CRYPTO_EcdsaPublicKey pk; - - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) - { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); - return; - } - if (ID_REST_STATE_INIT == handle->state) { - ego_entry = GNUNET_new (struct EgoEntry); - GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = - GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); - ego_entry->ego = ego; - ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry); - } - -} - -/** - * Function processing the REST call - * - * @param method HTTP method - * @param url URL of the HTTP request - * @param data body of the HTTP request (optional) - * @param data_size length of the body - * @param proc callback function for the result - * @param proc_cls closure for callback function - * @return GNUNET_OK if request accepted - */ -static void -rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, - GNUNET_REST_ResultProcessor proc, - void *proc_cls) -{ - struct RequestHandle *handle = GNUNET_new (struct RequestHandle); - - handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; - handle->proc_cls = proc_cls; - handle->proc = proc; - handle->state = ID_REST_STATE_INIT; - handle->conndata_handle = conndata_handle; - - - handle->url = GNUNET_strdup (conndata_handle->url); - if (handle->url[strlen (handle->url)-1] == '/') - handle->url[strlen (handle->url)-1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting...\n"); - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, - &list_ego, - handle); - handle->timeout_task = - GNUNET_SCHEDULER_add_delayed (handle->timeout, - &do_timeout, - handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected\n"); -} - -/** - * Entry point for the plugin. - * - * @param cls Config info - * @return NULL on error, otherwise the plugin context - */ -void * -libgnunet_plugin_rest_identity_provider_init (void *cls) -{ - static struct Plugin plugin; - struct GNUNET_REST_Plugin *api; - - cfg = cls; - if (NULL != plugin.cfg) - return NULL; /* can only initialize once! */ - memset (&plugin, 0, sizeof (struct Plugin)); - plugin.cfg = cfg; - api = GNUNET_new (struct GNUNET_REST_Plugin); - api->cls = &plugin; - api->name = GNUNET_REST_API_NS_IDENTITY_PROVIDER; - api->process_request = &rest_identity_process_request; - GNUNET_asprintf (&allow_methods, - "%s, %s, %s, %s, %s", - MHD_HTTP_METHOD_GET, - MHD_HTTP_METHOD_POST, - MHD_HTTP_METHOD_PUT, - MHD_HTTP_METHOD_DELETE, - MHD_HTTP_METHOD_OPTIONS); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Identity Token REST API initialized\n")); - return api; -} - - -/** - * Exit point from the plugin. - * - * @param cls the plugin context (as returned by "init") - * @return always NULL - */ -void * -libgnunet_plugin_rest_identity_provider_done (void *cls) -{ - struct GNUNET_REST_Plugin *api = cls; - struct Plugin *plugin = api->cls; - - plugin->cfg = NULL; - GNUNET_free_non_null (allow_methods); - GNUNET_free (api); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Identity Token REST plugin is finished\n"); - return NULL; -} - -/* end of plugin_rest_gns.c */ diff --git a/src/include/gnunet_identity_provider_plugin.h b/src/include/gnunet_identity_provider_plugin.h index 9e779bde7..27d7eb44f 100644 --- a/src/include/gnunet_identity_provider_plugin.h +++ b/src/include/gnunet_identity_provider_plugin.h @@ -50,7 +50,7 @@ extern "C" * @param ticket the ticket */ typedef void (*GNUNET_IDENTITY_PROVIDER_TicketIterator) (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket); + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); /** @@ -72,7 +72,7 @@ struct GNUNET_IDENTITY_PROVIDER_PluginFunctions * @return #GNUNET_OK on success, else #GNUNET_SYSERR */ int (*store_ticket) (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket); + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); /** * Delete a ticket from the database. @@ -82,7 +82,7 @@ struct GNUNET_IDENTITY_PROVIDER_PluginFunctions * @return #GNUNET_OK on success, else #GNUNET_SYSERR */ int (*delete_ticket) (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket); + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); diff --git a/src/include/gnunet_identity_provider_service.h b/src/include/gnunet_identity_provider_service.h index 198e2f918..fb5131567 100644 --- a/src/include/gnunet_identity_provider_service.h +++ b/src/include/gnunet_identity_provider_service.h @@ -56,15 +56,10 @@ struct GNUNET_IDENTITY_PROVIDER_Handle; */ struct GNUNET_IDENTITY_PROVIDER_Token; -/** - * Handle for a ticket DEPRECATED - */ -struct GNUNET_IDENTITY_PROVIDER_Ticket; - /** * The ticket */ -struct GNUNET_IDENTITY_PROVIDER_Ticket2 +struct GNUNET_IDENTITY_PROVIDER_Ticket { /** * The ticket issuer @@ -169,38 +164,6 @@ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute; }; -/** - * Method called when a token has been exchanged for a ticket. - * On success returns a token - * - * @param cls closure - * @param token the token - */ -typedef void -(*GNUNET_IDENTITY_PROVIDER_ExchangeCallback)(void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Token *token, - uint64_t ticket_nonce); - -/** TODO DEPRECATED - * Method called when a token has been issued. - * On success returns a ticket that can be given to the audience to retrive the - * token - * - * @param cls closure - * @param grant the label in GNS pointing to the token - * @param ticket the ticket - * @param token the issued token - * @param name name assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used - */ -typedef void -(*GNUNET_IDENTITY_PROVIDER_IssueCallback)(void *cls, - const char *grant, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, - const struct GNUNET_IDENTITY_PROVIDER_Token *token); - - /** * Connect to the identity provider service. * @@ -340,7 +303,7 @@ GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_At */ typedef void (*GNUNET_IDENTITY_PROVIDER_TicketCallback)(void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket); + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); /** * Issues a ticket to another identity. The identity may use @@ -397,7 +360,7 @@ GNUNET_IDENTITY_PROVIDER_idp_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Hand struct GNUNET_IDENTITY_PROVIDER_Operation * GNUNET_IDENTITY_PROVIDER_rp_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *id, const struct GNUNET_CRYPTO_EcdsaPrivateKey * identity, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket, + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, GNUNET_IDENTITY_PROVIDER_AttributeResult cb, void *cb_cls); @@ -474,50 +437,6 @@ GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_ void GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it); -/** TODO remove DEPRECATED - * Issue a token for a specific audience. - * - * @param id identity provider service to use - * @param iss issuer (identity) - * @param aud audience (identity) - * @param scope the identity attributes requested, comman separated - * @param expiration the token expiration - * @param nonce the nonce that will be included in token and ticket - * @param cb callback to call with result - * @param cb_cls closure - * @return handle to abort the operation - */ -struct GNUNET_IDENTITY_PROVIDER_Operation * -GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - const char* scope, - const char* vattr, - struct GNUNET_TIME_Absolute expiration, - uint64_t nonce, - GNUNET_IDENTITY_PROVIDER_IssueCallback cb, - void *cb_cls); - - -/** TODO remove DEPRECATED - * Exchange a ticket for a token. Intended to be used by audience that - * received a ticket. - * - * @param id identity provider service to use - * @param ticket the ticket to exchange - * @param aud_privkey the audience of the ticket - * @param cont function to call once the operation finished - * @param cont_cls closure for @a cont - * @return handle to abort the operation - */ -struct GNUNET_IDENTITY_PROVIDER_Operation * -GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey, - GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, - void *cont_cls); - - /** * Disconnect from identity provider service. * @@ -538,56 +457,6 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h); void GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op); - -/** - * Convenience API - */ - -/** - * Destroy token - * - * @param token the token - */ -void -GNUNET_IDENTITY_PROVIDER_token_destroy(struct GNUNET_IDENTITY_PROVIDER_Token *token); - -/** - * Returns string representation of token. A JSON-Web-Token. - * - * @param token the token - * @return The JWT (must be freed) - */ -char * -GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_Token *token); - -/** - * Returns string representation of ticket. Base64-Encoded - * - * @param ticket the ticket - * @return the Base64-Encoded ticket - */ -char * -GNUNET_IDENTITY_PROVIDER_ticket_to_string (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); - -/** - * Created a ticket from a string (Base64 encoded ticket) - * - * @param input Base64 encoded ticket - * @param ticket pointer where the ticket is stored - * @return GNUNET_OK - */ -int -GNUNET_IDENTITY_PROVIDER_string_to_ticket (const char* input, - struct GNUNET_IDENTITY_PROVIDER_Ticket **ticket); - -/** - * Destroys a ticket - * - * @param ticket the ticket to destroy - */ -void -GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); - #if 0 /* keep Emacsens' auto-indent happy */ { #endif -- 2.25.1