aboutsummaryrefslogtreecommitdiff
path: root/src/identity-provider
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-08 18:59:47 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-08 18:59:47 +0000
commit35262a0fe27afccb154122f113adcc75947ee45d (patch)
tree5b1259067c9da96e60c2a303415b222a4c383319 /src/identity-provider
parent1b67c9c5424c96ff4e30d12b8d58cec315f000a1 (diff)
downloadgnunet-35262a0fe27afccb154122f113adcc75947ee45d.tar.gz
gnunet-35262a0fe27afccb154122f113adcc75947ee45d.zip
- More heavy refactoring. Probably lots of broken things to see here.
Diffstat (limited to 'src/identity-provider')
-rw-r--r--src/identity-provider/Makefile.am20
-rw-r--r--src/identity-provider/gnunet-service-identity-provider.c (renamed from src/identity-provider/gnunet-service-identity-token.c)662
-rw-r--r--src/identity-provider/identity_provider.h164
-rw-r--r--src/identity-provider/identity_provider_api.c611
-rw-r--r--src/identity-provider/identity_token.c (renamed from src/identity-provider/identity-token.c)91
-rw-r--r--src/identity-provider/identity_token.h269
-rw-r--r--src/identity-provider/plugin_rest_identity_token.c554
7 files changed, 1866 insertions, 505 deletions
diff --git a/src/identity-provider/Makefile.am b/src/identity-provider/Makefile.am
index a9338ba59..edd9844c1 100644
--- a/src/identity-provider/Makefile.am
+++ b/src/identity-provider/Makefile.am
@@ -21,39 +21,31 @@ pkgcfg_DATA = \
21 21
22plugin_LTLIBRARIES = \ 22plugin_LTLIBRARIES = \
23 libgnunet_plugin_rest_identity_token.la 23 libgnunet_plugin_rest_identity_token.la
24lib_LTLIBRARIES = \
25 libgnunetidentityprovider.la
26 24
27bin_PROGRAMS = \ 25bin_PROGRAMS = \
28 gnunet-identity-token 26 gnunet-identity-token
29 27
30libexec_PROGRAMS = \ 28libexec_PROGRAMS = \
31 gnunet-service-identity-token 29 gnunet-service-identity-provider
32 30
33gnunet_service_identity_token_SOURCES = \ 31gnunet_service_identity_provider_SOURCES = \
34 gnunet-service-identity-token.c 32 gnunet-service-identity-provider.c \
35gnunet_service_identity_token_LDADD = \ 33 identity_token.c
36 libgnunetidentityprovider.la \ 34gnunet_service_identity_provider_LDADD = \
37 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ 35 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
38 $(top_builddir)/src/util/libgnunetutil.la \ 36 $(top_builddir)/src/util/libgnunetutil.la \
39 $(top_builddir)/src/namestore/libgnunetnamestore.la \ 37 $(top_builddir)/src/namestore/libgnunetnamestore.la \
40 $(top_builddir)/src/identity/libgnunetidentity.la \ 38 $(top_builddir)/src/identity/libgnunetidentity.la \
39 $(top_builddir)/src/gns/libgnunetgns.la \
41 $(GN_LIBINTL) \ 40 $(GN_LIBINTL) \
42 -ljansson 41 -ljansson
43 42
44libgnunetidentityprovider_la_SOURCES = \
45 identity-token.c
46libgnunetidentityprovider_la_LIBADD = \
47 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
48 $(LTLIBINTL) -ljansson
49
50libgnunet_plugin_rest_identity_token_la_SOURCES = \ 43libgnunet_plugin_rest_identity_token_la_SOURCES = \
51 plugin_rest_identity_token.c 44 plugin_rest_identity_token.c
52libgnunet_plugin_rest_identity_token_la_LIBADD = \ 45libgnunet_plugin_rest_identity_token_la_LIBADD = \
53 $(top_builddir)/src/identity/libgnunetidentity.la \ 46 $(top_builddir)/src/identity/libgnunetidentity.la \
54 $(top_builddir)/src/rest/libgnunetrest.la \ 47 $(top_builddir)/src/rest/libgnunetrest.la \
55 $(top_builddir)/src/namestore/libgnunetnamestore.la \ 48 $(top_builddir)/src/namestore/libgnunetnamestore.la \
56 $(top_builddir)/src/gns/libgnunetgns.la \
57 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ 49 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
58 $(LTLIBINTL) -ljansson -lmicrohttpd 50 $(LTLIBINTL) -ljansson -lmicrohttpd
59libgnunet_plugin_rest_identity_token_la_LDFLAGS = \ 51libgnunet_plugin_rest_identity_token_la_LDFLAGS = \
diff --git a/src/identity-provider/gnunet-service-identity-token.c b/src/identity-provider/gnunet-service-identity-provider.c
index 039d1c7e0..6cb8bf72f 100644
--- a/src/identity-provider/gnunet-service-identity-token.c
+++ b/src/identity-provider/gnunet-service-identity-provider.c
@@ -19,18 +19,23 @@
19 */ 19 */
20/** 20/**
21 * @author Martin Schanzenbach 21 * @author Martin Schanzenbach
22 * @file src/rest/gnunet-service-identity-token.c 22 * @file src/identity/gnunet-service-identity-provider.c
23 * @brief Identity Token Service 23 * @brief Identity Token Service
24 * 24 *
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h"
29#include "gnunet_protocols.h"
28#include "gnunet_identity_service.h" 30#include "gnunet_identity_service.h"
29#include "gnunet_gnsrecord_lib.h" 31#include "gnunet_gnsrecord_lib.h"
30#include "gnunet_namestore_service.h" 32#include "gnunet_namestore_service.h"
33#include "gnunet_statistics_service.h"
34#include "gnunet_gns_service.h"
31#include <jansson.h> 35#include <jansson.h>
32#include "gnunet_signatures.h" 36#include "gnunet_signatures.h"
33#include "gnunet_identity_provider_lib.h" 37#include "identity_provider.h"
38#include "identity_token.h"
34 39
35/** 40/**
36 * First pass state 41 * First pass state
@@ -73,6 +78,11 @@ static struct GNUNET_IDENTITY_Handle *identity_handle;
73static struct GNUNET_NAMESTORE_Handle *ns_handle; 78static struct GNUNET_NAMESTORE_Handle *ns_handle;
74 79
75/** 80/**
81 * GNS handle
82 */
83static struct GNUNET_GNS_Handle *gns_handle;
84
85/**
76 * Namestore qe 86 * Namestore qe
77 */ 87 */
78static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; 88static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
@@ -102,7 +112,7 @@ static struct GNUNET_TIME_Relative min_rel_exp;
102/** 112/**
103 * Currently processed token 113 * Currently processed token
104 */ 114 */
105static struct GNUNET_IDENTITY_PROVIDER_Token *token; 115static struct IdentityToken *token;
106 116
107/** 117/**
108 * Label for currently processed token 118 * Label for currently processed token
@@ -125,6 +135,114 @@ static uint64_t rd_exp;
125static struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_privkey; 135static struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_privkey;
126 136
127/** 137/**
138 * Handle to the statistics service.
139 */
140static struct GNUNET_STATISTICS_Handle *stats;
141
142/**
143 * Notification context, simplifies client broadcasts.
144 */
145static struct GNUNET_SERVER_NotificationContext *nc;
146
147struct ExchangeHandle
148{
149
150 /**
151 * Client connection
152 */
153 struct GNUNET_SERVER_Client *client;
154
155 /**
156 * Ticket
157 */
158 struct TokenTicket *ticket;
159
160 /**
161 * Token returned
162 */
163 struct IdentityToken *token;
164
165 /**
166 * LookupRequest
167 */
168 struct GNUNET_GNS_LookupRequest *lookup_request;
169
170 /**
171 * Audience Key
172 */
173 struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey;
174
175 /**
176 * Label to return
177 */
178 char *label;
179};
180
181struct IssueHandle
182{
183
184 /**
185 * Client connection
186 */
187 struct GNUNET_SERVER_Client *client;
188
189 /**
190 * Issuer Key
191 */
192 struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key;
193
194 /**
195 * Issue pubkey
196 */
197 struct GNUNET_CRYPTO_EcdsaPublicKey iss_pkey;
198
199 /**
200 * Audience Key
201 */
202 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
203
204 /**
205 * Expiration
206 */
207 struct GNUNET_TIME_Absolute expiration;
208
209 /**
210 * Scopes
211 */
212 char *scopes;
213
214 /**
215 * nonce
216 */
217 uint64_t nonce;
218
219 /**
220 * NS iterator
221 */
222 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
223
224 /**
225 * Attribute map
226 */
227 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
228
229 /**
230 * Token
231 */
232 struct IdentityToken *token;
233
234 /**
235 * Ticket
236 */
237 struct TokenTicket *ticket;
238
239 /**
240 * QueueEntry
241 */
242 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
243};
244
245/**
128 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format 246 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
129 * 247 *
130 */ 248 */
@@ -159,16 +277,16 @@ struct EgoEntry
159/** 277/**
160 * Our configuration. 278 * Our configuration.
161 */ 279 */
162static const struct GNUNET_CONFIGURATION_Handle *cfg; 280 static const struct GNUNET_CONFIGURATION_Handle *cfg;
163 281
164 282
165/** 283 /**
166 * Continuation for token store call 284 * Continuation for token store call
167 * 285 *
168 * @param cls NULL 286 * @param cls NULL
169 * @param success error code 287 * @param success error code
170 * @param emsg error message 288 * @param emsg error message
171 */ 289 */
172static void 290static void
173store_token_cont (void *cls, 291store_token_cont (void *cls,
174 int32_t success, 292 int32_t success,
@@ -214,7 +332,7 @@ handle_token_update (void *cls,
214 struct GNUNET_TIME_Absolute new_exp; 332 struct GNUNET_TIME_Absolute new_exp;
215 struct GNUNET_TIME_Absolute new_iat; 333 struct GNUNET_TIME_Absolute new_iat;
216 struct GNUNET_TIME_Absolute new_nbf; 334 struct GNUNET_TIME_Absolute new_nbf;
217 struct GNUNET_IDENTITY_PROVIDER_Token *new_token; 335 struct IdentityToken *new_token;
218 json_t *payload_json; 336 json_t *payload_json;
219 json_t *value; 337 json_t *value;
220 json_t *cur_value; 338 json_t *cur_value;
@@ -263,8 +381,8 @@ handle_token_update (void *cls,
263 } 381 }
264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 382 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
265 "Token is expired. Create a new one\n"); 383 "Token is expired. Create a new one\n");
266 new_token = GNUNET_IDENTITY_PROVIDER_token_create (&pub_key, 384 new_token = token_create (&pub_key,
267 &token->aud_key); 385 &token->aud_key);
268 new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp); 386 new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
269 new_nbf = GNUNET_TIME_absolute_get (); 387 new_nbf = GNUNET_TIME_absolute_get ();
270 new_iat = new_nbf; 388 new_iat = new_nbf;
@@ -272,15 +390,15 @@ handle_token_update (void *cls,
272 json_object_foreach(payload_json, key, value) { 390 json_object_foreach(payload_json, key, value) {
273 if (0 == strcmp (key, "exp")) 391 if (0 == strcmp (key, "exp"))
274 { 392 {
275 GNUNET_IDENTITY_PROVIDER_token_add_json (new_token, key, json_integer (new_exp.abs_value_us)); 393 token_add_json (new_token, key, json_integer (new_exp.abs_value_us));
276 } 394 }
277 else if (0 == strcmp (key, "nbf")) 395 else if (0 == strcmp (key, "nbf"))
278 { 396 {
279 GNUNET_IDENTITY_PROVIDER_token_add_json (new_token, key, json_integer (new_nbf.abs_value_us)); 397 token_add_json (new_token, key, json_integer (new_nbf.abs_value_us));
280 } 398 }
281 else if (0 == strcmp (key, "iat")) 399 else if (0 == strcmp (key, "iat"))
282 { 400 {
283 GNUNET_IDENTITY_PROVIDER_token_add_json (new_token, key, json_integer (new_iat.abs_value_us)); 401 token_add_json (new_token, key, json_integer (new_iat.abs_value_us));
284 } 402 }
285 else if ((0 == strcmp (key, "iss")) 403 else if ((0 == strcmp (key, "iss"))
286 || (0 == strcmp (key, "aud"))) 404 || (0 == strcmp (key, "aud")))
@@ -290,7 +408,7 @@ handle_token_update (void *cls,
290 else if ((0 == strcmp (key, "sub")) 408 else if ((0 == strcmp (key, "sub"))
291 || (0 == strcmp (key, "rnl"))) 409 || (0 == strcmp (key, "rnl")))
292 { 410 {
293 GNUNET_IDENTITY_PROVIDER_token_add_json (new_token, key, value); 411 token_add_json (new_token, key, value);
294 } 412 }
295 else { 413 else {
296 GNUNET_CRYPTO_hash (key, 414 GNUNET_CRYPTO_hash (key,
@@ -302,16 +420,16 @@ handle_token_update (void *cls,
302 { 420 {
303 cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map, 421 cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map,
304 &key_hash); 422 &key_hash);
305 GNUNET_IDENTITY_PROVIDER_token_add_json (new_token, key, cur_value); 423 token_add_json (new_token, key, cur_value);
306 } 424 }
307 } 425 }
308 } 426 }
309 427
310 // reassemble and set 428 // reassemble and set
311 GNUNET_assert (GNUNET_IDENTITY_PROVIDER_token_serialize (new_token, 429 GNUNET_assert (token_serialize (new_token,
312 priv_key, 430 priv_key,
313 &new_ecdhe_privkey, 431 &new_ecdhe_privkey,
314 &enc_token_str)); 432 &enc_token_str));
315 433
316 json_decref (payload_json); 434 json_decref (payload_json);
317 435
@@ -347,8 +465,8 @@ handle_token_update (void *cls,
347 &store_token_cont, 465 &store_token_cont,
348 ego_entry); 466 ego_entry);
349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token); 467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token);
350 GNUNET_IDENTITY_PROVIDER_token_destroy (new_token); 468 token_destroy (new_token);
351 GNUNET_IDENTITY_PROVIDER_token_destroy (token); 469 token_destroy (token);
352 GNUNET_free (new_ecdhe_privkey); 470 GNUNET_free (new_ecdhe_privkey);
353 GNUNET_free (enc_token_str); 471 GNUNET_free (enc_token_str);
354 token = NULL; 472 token = NULL;
@@ -444,10 +562,10 @@ token_collect (void *cls,
444 aud_key = (struct GNUNET_CRYPTO_EcdsaPublicKey *)&ecdhe_privkey+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey); 562 aud_key = (struct GNUNET_CRYPTO_EcdsaPublicKey *)&ecdhe_privkey+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey);
445 scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 563 scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
446 564
447 GNUNET_IDENTITY_PROVIDER_token_parse2 (token_record->data, 565 token_parse2 (token_record->data,
448 &ecdhe_privkey, 566 &ecdhe_privkey,
449 aud_key, 567 aud_key,
450 &token); 568 &token);
451 569
452 //token = GNUNET_GNSRECORD_value_to_string (rd->record_type, 570 //token = GNUNET_GNSRECORD_value_to_string (rd->record_type,
453 // rd->data, 571 // rd->data,
@@ -647,12 +765,25 @@ cleanup()
647 765
648 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
649 "Cleaning up\n"); 767 "Cleaning up\n");
768 if (NULL != nc)
769 {
770 GNUNET_SERVER_notification_context_destroy (nc);
771 nc = NULL;
772 }
773 if (NULL != stats)
774 {
775 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
776 stats = NULL;
777 }
778
650 if (NULL != timeout_task) 779 if (NULL != timeout_task)
651 GNUNET_SCHEDULER_cancel (timeout_task); 780 GNUNET_SCHEDULER_cancel (timeout_task);
652 if (NULL != update_task) 781 if (NULL != update_task)
653 GNUNET_SCHEDULER_cancel (update_task); 782 GNUNET_SCHEDULER_cancel (update_task);
654 if (NULL != identity_handle) 783 if (NULL != identity_handle)
655 GNUNET_IDENTITY_disconnect (identity_handle); 784 GNUNET_IDENTITY_disconnect (identity_handle);
785 if (NULL != gns_handle)
786 GNUNET_GNS_disconnect (gns_handle);
656 if (NULL != ns_it) 787 if (NULL != ns_it)
657 GNUNET_NAMESTORE_zone_iteration_stop (ns_it); 788 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
658 if (NULL != ns_qe) 789 if (NULL != ns_qe)
@@ -696,6 +827,437 @@ do_shutdown (void *cls,
696 cleanup(); 827 cleanup();
697} 828}
698 829
830
831static struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage*
832create_exchange_result_message (const char* token,
833 const char* label)
834{
835 struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm;
836 uint16_t token_len = strlen (token) + 1;
837 erm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)
838 + token_len);
839 erm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT);
840 erm->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)
841 + token_len);
842 memcpy (&erm[1], token, token_len);
843 return erm;
844}
845
846
847static struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage*
848create_issue_result_message (const char* ticket)
849{
850 struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
851
852 irm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) + strlen(ticket) + 1);
853 irm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT);
854 irm->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) + strlen (ticket) + 1);
855 memcpy (&irm[1], ticket, strlen (ticket) + 1);
856 return irm;
857}
858
859void
860store_token_issue_cont (void *cls,
861 int32_t success,
862 const char *emsg)
863{
864 struct IssueHandle *handle = cls;
865 struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
866 char* token_ticket_str;
867 handle->ns_qe = NULL;
868 if (GNUNET_SYSERR == success)
869 {
870 //TODO err msg
871 return;
872 }
873 if (GNUNET_OK != ticket_serialize (handle->ticket,
874 &handle->iss_key,
875 &token_ticket_str))
876 {
877 GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
878 ticket_destroy (handle->ticket);
879 GNUNET_free (handle);
880 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
881 return;
882 }
883 irm = create_issue_result_message (token_ticket_str);
884 GNUNET_SERVER_notification_context_unicast (nc,
885 handle->client,
886 &irm->header,
887 GNUNET_NO);
888 GNUNET_free (irm);
889 GNUNET_free (token_ticket_str);
890 GNUNET_SERVER_receive_done (handle->client, GNUNET_OK);
891}
892
893/**
894 * Build a GNUid token for identity
895 * @param handle the handle
896 * @param ego_entry the ego to build the token for
897 * @param name name of the ego
898 * @param token_aud token audience
899 * @param token the resulting gnuid token
900 * @return identifier string of token (label)
901 */
902static void
903sign_and_return_token (void *cls,
904 const struct GNUNET_SCHEDULER_TaskContext *tc)
905{
906 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
907 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
908 struct GNUNET_CRYPTO_EcdsaPublicKey aud_pkey;
909 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
910 struct IssueHandle *handle = cls;
911 struct GNUNET_GNSRECORD_Data token_record[2];
912 struct GNUNET_TIME_Relative etime_rel;
913 char *lbl_str;
914 char *nonce_str;
915 char *enc_token_str;
916 char *token_metadata;
917 char *scopes;
918 char* write_ptr;
919 uint64_t time;
920 uint64_t exp_time;
921 uint64_t rnd_key;
922 size_t token_metadata_len;
923
924 //Remote nonce
925 nonce_str = NULL;
926 GNUNET_asprintf (&nonce_str, "%d", handle->nonce);
927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
928
929 //Label
930 rnd_key = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
931 GNUNET_STRINGS_base64_encode ((char*)&rnd_key, sizeof (uint64_t), &lbl_str);
932 GNUNET_CRYPTO_ecdsa_key_get_public (&handle->iss_key,
933 &pub_key);
934
935 handle->ticket = ticket_create (nonce_str,
936 &pub_key,
937 lbl_str,
938 &aud_pkey);
939
940
941
942 if (GNUNET_OK !=
943 GNUNET_STRINGS_fancy_time_to_relative ("1d", //TODO
944 &etime_rel))
945 {
946 ticket_destroy (handle->ticket);
947 GNUNET_free (handle);
948 GNUNET_SCHEDULER_add_now (&do_shutdown, handle);
949 return;
950 }
951 time = GNUNET_TIME_absolute_get().abs_value_us;
952 exp_time = time + etime_rel.rel_value_us;
953
954 token_add_json (handle->token, "nbf", json_integer (time));
955 token_add_json (handle->token, "iat", json_integer (time));
956 token_add_json (handle->token, "exp", json_integer (exp_time));
957 token_add_attr (handle->token, "nonce", nonce_str);
958
959
960 //Token in a serialized encrypted format
961 GNUNET_assert (token_serialize (handle->token,
962 &handle->iss_key,
963 &ecdhe_privkey,
964 &enc_token_str));
965
966 //Token record E,E_K (Token)
967 token_record[0].data = enc_token_str;
968 token_record[0].data_size = strlen (enc_token_str) + 1;
969 token_record[0].expiration_time = exp_time;
970 token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
971 token_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
972
973
974 token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
975 + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)
976 + strlen (handle->scopes) + 1; //With 0-Terminator
977 token_metadata = GNUNET_malloc (token_metadata_len);
978 write_ptr = token_metadata;
979 memcpy (token_metadata, ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
980 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
981 memcpy (write_ptr, &handle->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
982 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
983 memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator;
984
985 GNUNET_free (ecdhe_privkey);
986
987 token_record[1].data = token_metadata;
988 token_record[1].data_size = token_metadata_len;
989 token_record[1].expiration_time = exp_time;
990 token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
991 token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
992
993 //Persist token
994 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
995 priv_key,
996 lbl_str,
997 2,
998 token_record,
999 &store_token_issue_cont,
1000 handle);
1001 GNUNET_free (lbl_str);
1002 GNUNET_free (enc_token_str);
1003}
1004
1005/**
1006 * Collect attributes for token
1007 */
1008static void
1009attr_collect (void *cls,
1010 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1011 const char *label,
1012 unsigned int rd_count,
1013 const struct GNUNET_GNSRECORD_Data *rd)
1014{
1015 int i;
1016 char* data;
1017 json_t *attr_arr;
1018 struct IssueHandle *handle = cls;
1019 struct GNUNET_HashCode key;
1020
1021 if (NULL == label)
1022 {
1023 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n");
1024 handle->ns_it = NULL;
1025 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1026 return;
1027 }
1028
1029 GNUNET_CRYPTO_hash (label,
1030 strlen (label),
1031 &key);
1032
1033 if (0 == rd_count ||
1034 ( (NULL != handle->attr_map) &&
1035 (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map,
1036 &key))
1037 )
1038 )
1039 {
1040 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1041 return;
1042 }
1043
1044 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", label);
1045
1046 if (1 == rd_count)
1047 {
1048 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1049 {
1050 data = GNUNET_GNSRECORD_value_to_string (rd->record_type,
1051 rd->data,
1052 rd->data_size);
1053 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1054 token_add_json (handle->token,
1055 label,
1056 json_string (data));
1057 GNUNET_free (data);
1058 }
1059 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1060 return;
1061 }
1062
1063 i = 0;
1064 attr_arr = json_array();
1065 for (; i < rd_count; i++)
1066 {
1067 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1068 {
1069 data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
1070 rd[i].data,
1071 rd[i].data_size);
1072 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1073 json_array_append_new (attr_arr, json_string (data));
1074 GNUNET_free (data);
1075 }
1076 }
1077
1078 if (0 < json_array_size (attr_arr))
1079 {
1080 token_add_json (handle->token, label, attr_arr);
1081 }
1082 json_decref (attr_arr);
1083 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1084}
1085
1086static void
1087process_lookup_result (void *cls, uint32_t rd_count,
1088 const struct GNUNET_GNSRECORD_Data *rd)
1089{
1090 struct ExchangeHandle *handle = cls;
1091 struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm;
1092 char* token_str;
1093 char* record_str;
1094
1095 handle->lookup_request = NULL;
1096 if (2 != rd_count)
1097 {
1098 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1099 "Number of tokens %d != 2.",
1100 rd_count);
1101 GNUNET_free (handle->label);
1102 GNUNET_free (handle);
1103 GNUNET_SCHEDULER_add_now (&do_shutdown, handle);
1104 return;
1105 }
1106
1107 record_str =
1108 GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN,
1109 rd->data,
1110 rd->data_size);
1111
1112 //Decrypt and parse
1113 GNUNET_assert (GNUNET_OK == token_parse (record_str,
1114 &handle->aud_privkey,
1115 &handle->token));
1116
1117 //Readable
1118 GNUNET_assert (GNUNET_OK == token_to_string (handle->token,
1119 &handle->aud_privkey,
1120 &token_str));
1121
1122 erm = create_exchange_result_message (token_str,
1123 handle->label);
1124 GNUNET_SERVER_notification_context_unicast (nc,
1125 handle->client,
1126 &erm->header,
1127 GNUNET_NO);
1128 GNUNET_free (erm);
1129 GNUNET_SERVER_receive_done (handle->client, GNUNET_OK);
1130
1131}
1132
1133/**
1134 *
1135 * Handler for exchange message
1136 *
1137 * @param cls unused
1138 * @param client who sent the message
1139 * @param message the message
1140 */
1141static void
1142handle_exchange_message (void *cls,
1143 struct GNUNET_SERVER_Client *client,
1144 const struct GNUNET_MessageHeader *message)
1145{
1146 const struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *em;
1147 struct ExchangeHandle *xchange_handle;
1148 uint16_t size;
1149 const char *ticket;
1150 char *lookup_query;
1151
1152 size = ntohs (message->size);
1153 if (size <= sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage))
1154 {
1155 GNUNET_break (0);
1156 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1157 return;
1158 }
1159 em = (const struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *) message;
1160 ticket = (const char *) &em[1];
1161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1162 "Received EXCHANGE of `%s' from client\n",
1163 ticket);
1164 xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle));
1165 xchange_handle->aud_privkey = em->aud_privkey;
1166 if (GNUNET_SYSERR == ticket_parse (ticket,
1167 &xchange_handle->aud_privkey,
1168 &xchange_handle->ticket))
1169 {
1170 GNUNET_free (xchange_handle);
1171 GNUNET_break (0);
1172 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1173 return;
1174 }
1175 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for token under %s\n",
1176 xchange_handle->ticket->payload->label);
1177 GNUNET_asprintf (&lookup_query,
1178 "%s.gnu",
1179 xchange_handle->ticket->payload->label);
1180 xchange_handle->lookup_request = GNUNET_GNS_lookup (gns_handle,
1181 lookup_query,
1182 &xchange_handle->ticket->payload->identity_key,
1183 GNUNET_GNSRECORD_TYPE_ID_TOKEN,
1184 GNUNET_GNS_LO_LOCAL_MASTER,
1185 NULL,
1186 &process_lookup_result,
1187 xchange_handle);
1188 GNUNET_free (lookup_query);
1189
1190}
1191
1192/**
1193 *
1194 * Handler for issue message
1195 *
1196 * @param cls unused
1197 * @param client who sent the message
1198 * @param message the message
1199 */
1200static void
1201handle_issue_message (void *cls,
1202 struct GNUNET_SERVER_Client *client,
1203 const struct GNUNET_MessageHeader *message)
1204{
1205 const struct GNUNET_IDENTITY_PROVIDER_IssueMessage *im;
1206 uint16_t size;
1207 const char *scopes;
1208 char *scopes_tmp;
1209 char *scope;
1210 char *attr_list_tmp;
1211 struct GNUNET_HashCode key;
1212 struct IssueHandle *issue_handle;
1213
1214 size = ntohs (message->size);
1215 if (size <= sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage))
1216 {
1217 GNUNET_break (0);
1218 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1219 return;
1220 }
1221 im = (const struct GNUNET_IDENTITY_PROVIDER_IssueMessage *) message;
1222 scopes = (const char *) &im[1];
1223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1224 "Received ISSUE of `%s' from client\n",
1225 scope);
1226 issue_handle = GNUNET_malloc (sizeof (struct IssueHandle));
1227 issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
1228 GNUNET_NO);
1229 scopes_tmp = GNUNET_strdup (scopes);
1230 scope = strtok(attr_list_tmp, ",");
1231 for (; NULL != scope; scope = strtok (NULL, ","))
1232 {
1233 GNUNET_CRYPTO_hash (scope,
1234 strlen (scope),
1235 &key);
1236 GNUNET_CONTAINER_multihashmap_put (issue_handle->attr_map,
1237 &key,
1238 scope,
1239 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1240 }
1241 GNUNET_free (scopes_tmp);
1242
1243 issue_handle->aud_key = im->aud_key;
1244 issue_handle->iss_key = im->iss_key;
1245 issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration);
1246 issue_handle->nonce = im->nonce;
1247 GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key,
1248 &issue_handle->iss_pkey);
1249 issue_handle->token = token_create (&issue_handle->iss_pkey,
1250 &im->aud_key);
1251
1252 issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1253 &im->iss_key,
1254 &attr_collect,
1255 issue_handle);
1256 GNUNET_SERVER_receive_done (client, GNUNET_OK); //TODO here?
1257
1258
1259}
1260
699/** 1261/**
700 * Main function that will be run 1262 * Main function that will be run
701 * 1263 *
@@ -706,12 +1268,22 @@ do_shutdown (void *cls,
706 */ 1268 */
707static void 1269static void
708run (void *cls, 1270run (void *cls,
709 char *const *args, 1271 struct GNUNET_SERVER_Handle *server,
710 const char *cfgfile,
711 const struct GNUNET_CONFIGURATION_Handle *c) 1272 const struct GNUNET_CONFIGURATION_Handle *c)
712{ 1273{
1274 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
1275 {&handle_issue_message, NULL,
1276 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE, 0},
1277 {&handle_exchange_message, NULL,
1278 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE, 0},
1279 {NULL, NULL, 0, 0}
1280 };
1281
713 cfg = c; 1282 cfg = c;
714 1283
1284 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
1285 GNUNET_SERVER_add_handlers (server, handlers);
1286 nc = GNUNET_SERVER_notification_context_create (server, 1);
715 1287
716 //Connect to identity and namestore services 1288 //Connect to identity and namestore services
717 ns_handle = GNUNET_NAMESTORE_connect (cfg); 1289 ns_handle = GNUNET_NAMESTORE_connect (cfg);
@@ -720,6 +1292,12 @@ run (void *cls,
720 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore"); 1292 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
721 } 1293 }
722 1294
1295 gns_handle = GNUNET_GNS_connect (cfg);
1296 if (NULL == gns_handle)
1297 {
1298 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1299 }
1300
723 identity_handle = GNUNET_IDENTITY_connect (cfg, 1301 identity_handle = GNUNET_IDENTITY_connect (cfg,
724 &list_ego, 1302 &list_ego,
725 NULL); 1303 NULL);
@@ -731,7 +1309,7 @@ run (void *cls,
731 1309
732/** 1310/**
733 * 1311 *
734 * The main function for gnunet-service-identity-token 1312 * The main function
735 * 1313 *
736 * @param argc number of arguments from the cli 1314 * @param argc number of arguments from the cli
737 * @param argv command line arguments 1315 * @param argv command line arguments
@@ -741,22 +1319,10 @@ run (void *cls,
741int 1319int
742main (int argc, char *const *argv) 1320main (int argc, char *const *argv)
743{ 1321{
744 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 1322 return (GNUNET_OK ==
745 GNUNET_GETOPT_OPTION_END 1323 GNUNET_SERVICE_run (argc, argv, "identity-provider",
746 }; 1324 GNUNET_SERVICE_OPTION_NONE,
747 int ret; 1325 &run, NULL)) ? 0 : 1;
748
749 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
750 return 2;
751 GNUNET_log_setup ("gnunet-service-identity-token", "WARNING", NULL);
752 ret =
753 (GNUNET_OK ==
754 GNUNET_PROGRAM_run (argc, argv, "gnunet-service-identity-token",
755 _("GNUnet identity token service"),
756 options,
757 &run, NULL)) ? 0: 1;
758 GNUNET_free_non_null ((char *) argv);
759 return ret;
760} 1326}
761 1327
762/* end of gnunet-rest-server.c */ 1328/* end of gnunet-rest-server.c */
diff --git a/src/identity-provider/identity_provider.h b/src/identity-provider/identity_provider.h
new file mode 100644
index 000000000..63e362117
--- /dev/null
+++ b/src/identity-provider/identity_provider.h
@@ -0,0 +1,164 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2016 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public Liceidentity as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public Liceidentity for more details.
14
15 You should have received a copy of the GNU General Public Liceidentity
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @author Martin Schanzenbach
23 * @file identity-provider/identity_provider.h
24 *
25 * @brief Common type definitions for the identity provider
26 * service and API.
27 */
28#ifndef IDENTITY_PROVIDER_H
29#define IDENTITY_PROVIDER_H
30
31#include "gnunet_common.h"
32
33
34GNUNET_NETWORK_STRUCT_BEGIN
35
36/**
37 * The token
38 */
39struct GNUNET_IDENTITY_PROVIDER_Token
40{
41 /**
42 * The JWT representation of the identity token
43 */
44 char *data;
45};
46
47/**
48 * The ticket
49 */
50struct GNUNET_IDENTITY_PROVIDER_Ticket
51{
52 /**
53 * The Base64 representation of the ticket
54 */
55 char *data;
56};
57
58/**
59 * Answer from service to client after issue operation
60 */
61struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage
62{
63 /**
64 * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE
65 */
66 struct GNUNET_MessageHeader header;
67
68 /* followed by 0-terminated ticket */
69
70};
71
72
73/**
74 * Ticket exchange message.
75 */
76struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage
77{
78 /**
79 * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE
80 */
81 struct GNUNET_MessageHeader header;
82
83 /**
84 * Number of bytes in token string including 0-termination, in NBO;
85 * 0 on error.
86 */
87 uint16_t name_len GNUNET_PACKED;
88
89 /* followed by 0-terminated token */
90
91};
92
93
94
95/**
96 * Client requests IdP to issue token.
97 */
98struct GNUNET_IDENTITY_PROVIDER_IssueMessage
99{
100 /**
101 * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT
102 */
103 struct GNUNET_MessageHeader header;
104
105 /**
106 * Issuer identity private key
107 */
108 struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key;
109
110 /**
111 * Audience public key
112 */
113 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
114
115 /**
116 * Nonce
117 */
118 uint64_t nonce;
119
120 /**
121 * Expiration of token in NBO.
122 */
123 struct GNUNET_TIME_AbsoluteNBO expiration;
124
125
126 /* followed by 0-terminated comma-separated scope list */
127
128};
129
130
131/**
132 * Use to exchange a ticket for a token
133 */
134struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage
135{
136 /**
137 * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT
138 */
139 struct GNUNET_MessageHeader header;
140
141 /**
142 * Audience identity private key
143 */
144 struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey;
145
146
147 /**
148 * Number of bytes in ticket string including 0-termination, in NBO.
149 */
150 uint16_t name_len GNUNET_PACKED;
151
152 /**
153 * Always zero.
154 */
155 uint16_t reserved GNUNET_PACKED;
156
157 /* followed by 0-terminated ticket string */
158
159};
160
161
162GNUNET_NETWORK_STRUCT_END
163
164#endif
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c
new file mode 100644
index 000000000..c22151534
--- /dev/null
+++ b/src/identity-provider/identity_provider_api.c
@@ -0,0 +1,611 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2016 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public Liceidentity as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public Liceidentity for more details.
14
15 You should have received a copy of the GNU General Public Liceidentity
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file identity-provider/identity_provider_api.c
23 * @brief api to interact with the identity provider service
24 * @author Martin Schanzenbach
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h"
29#include "gnunet_protocols.h"
30#include "gnunet_identity_provider_service.h"
31#include "identity_provider.h"
32
33#define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__)
34
35
36
37/**
38 * Handle for an operation with the service.
39 */
40struct GNUNET_IDENTITY_PROVIDER_Operation
41{
42
43 /**
44 * Main handle.
45 */
46 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
47
48 /**
49 * We keep operations in a DLL.
50 */
51 struct GNUNET_IDENTITY_PROVIDER_Operation *next;
52
53 /**
54 * We keep operations in a DLL.
55 */
56 struct GNUNET_IDENTITY_PROVIDER_Operation *prev;
57
58 /**
59 * Message to send to the service.
60 * Allocated at the end of this struct.
61 */
62 const struct GNUNET_MessageHeader *msg;
63
64 /**
65 * Continuation to invoke with the result of the transmission; @e cb
66 * will be NULL in this case.
67 */
68 GNUNET_IDENTITY_PROVIDER_ExchangeCallback ex_cb;
69
70 /**
71 * Continuation to invoke with the result of the transmission for
72 * 'issue' operations (@e cont will be NULL in this case).
73 */
74 GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb;
75
76 /**
77 * Closure for @e cont or @e cb.
78 */
79 void *cls;
80
81};
82
83
84/**
85 * Handle for the service.
86 */
87struct GNUNET_IDENTITY_PROVIDER_Handle
88{
89 /**
90 * Configuration to use.
91 */
92 const struct GNUNET_CONFIGURATION_Handle *cfg;
93
94 /**
95 * Socket (if available).
96 */
97 struct GNUNET_CLIENT_Connection *client;
98
99 /**
100 * Function to call when we receive updates.
101 */
102 GNUNET_IDENTITY_PROVIDER_Callback cb;
103
104 /**
105 * Closure for 'cb'.
106 */
107 void *cb_cls;
108
109 /**
110 * Head of active operations.
111 */
112 struct GNUNET_IDENTITY_PROVIDER_Operation *op_head;
113
114 /**
115 * Tail of active operations.
116 */
117 struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail;
118
119 /**
120 * Currently pending transmission request, or NULL for none.
121 */
122 struct GNUNET_CLIENT_TransmitHandle *th;
123
124 /**
125 * Task doing exponential back-off trying to reconnect.
126 */
127 struct GNUNET_SCHEDULER_Task * reconnect_task;
128
129 /**
130 * Time for next connect retry.
131 */
132 struct GNUNET_TIME_Relative reconnect_delay;
133
134 /**
135 * Are we polling for incoming messages right now?
136 */
137 int in_receive;
138
139};
140
141
142/**
143 * Try again to connect to the service.
144 *
145 * @param cls handle to the service.
146 * @param tc scheduler context
147 */
148static void
149reconnect (void *cls,
150 const struct GNUNET_SCHEDULER_TaskContext *tc);
151
152
153/**
154 * Reschedule a connect attempt to the service.
155 *
156 * @param h transport service to reconnect
157 */
158static void
159reschedule_connect (struct GNUNET_IDENTITY_Handle *h)
160{
161 GNUNET_assert (h->reconnect_task == NULL);
162
163 if (NULL != h->th)
164 {
165 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
166 h->th = NULL;
167 }
168 if (NULL != h->client)
169 {
170 GNUNET_CLIENT_disconnect (h->client);
171 h->client = NULL;
172 }
173 h->in_receive = GNUNET_NO;
174 LOG (GNUNET_ERROR_TYPE_DEBUG,
175 "Scheduling task to reconnect to identity provider service in %s.\n",
176 GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, GNUNET_YES));
177 h->reconnect_task =
178 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
179 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
180}
181
182
183/**
184 * Type of a function to call when we receive a message
185 * from the service.
186 *
187 * @param cls closure
188 * @param msg message received, NULL on timeout or fatal error
189 */
190static void
191message_handler (void *cls,
192 const struct GNUNET_MessageHeader *msg)
193{
194 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
195 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
196 struct GNUNET_IDENTITY_PROVIDER_Token token;
197 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
198 const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
199 const struct GNUNET_IDENTITY_ExchangeResultMessage *erm;
200 struct GNUNET_CRYPTO_EcdsaPublicKey pub;
201 struct GNUNET_HashCode id;
202 const char *str;
203 uint16_t size;
204 uint16_t name_len;
205
206 if (NULL == msg)
207 {
208 reschedule_connect (h);
209 return;
210 }
211 LOG (GNUNET_ERROR_TYPE_DEBUG,
212 "Received message of type %d from identity provider service\n",
213 ntohs (msg->type));
214 size = ntohs (msg->size);
215 switch (ntohs (msg->type))
216 {
217 case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT:
218 if (size < sizeof (struct GNUNET_IDENTITY_IssueResultMessage))
219 {
220 GNUNET_break (0);
221 reschedule_connect (h);
222 return;
223 }
224 irm = (const struct GNUNET_IDENTITY_IssueResultMessage *) msg;
225 str = (const char *) &irm[1];
226 if ( (size > sizeof (struct GNUNET_IDENTITY_IssueResultMessage)) &&
227 ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_IssueResultMessage) - 1]) )
228 {
229 GNUNET_break (0);
230 reschedule_connect (h);
231 return;
232 }
233 if (size == sizeof (struct GNUNET_IDENTITY_IssueResultMessage))
234 str = NULL;
235
236 op = h->op_head;
237 GNUNET_CONTAINER_DLL_remove (h->op_head,
238 h->op_tail,
239 op);
240 GNUNET_CLIENT_receive (h->client, &message_handler, h,
241 GNUNET_TIME_UNIT_FOREVER_REL);
242 ticket->data = str;
243 if (NULL != op->iss_cb)
244 op->iss_cb (op->cls, &ticket);
245 GNUNET_free (op);
246 break;
247 case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT:
248 if (size < sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage))
249 {
250 GNUNET_break (0);
251 reschedule_connect (h);
252 return;
253 }
254 erm = (const struct GNUNET_IDENTITY_ExchangeResultMessage *) msg;
255 str = (const char *) &erm[1];
256 if ( (size > sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage)) &&
257 ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage) - 1]) )
258 {
259 GNUNET_break (0);
260 reschedule_connect (h);
261 return;
262 }
263 if (size == sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage))
264 str = NULL;
265
266 op = h->op_head;
267 GNUNET_CONTAINER_DLL_remove (h->op_head,
268 h->op_tail,
269 op);
270 GNUNET_CLIENT_receive (h->client, &message_handler, h,
271 GNUNET_TIME_UNIT_FOREVER_REL);
272 token->data = str;
273 if (NULL != op->ex_cb)
274 op->ex_cb (op->cls, token);
275 GNUNET_free (op);
276 break;
277
278 default:
279 GNUNET_break (0);
280 reschedule_connect (h);
281 return;
282 }
283}
284
285
286/**
287 * Schedule transmission of the next message from our queue.
288 *
289 * @param h identity handle
290 */
291static void
292transmit_next (struct GNUNET_IDENTITY_PROVIDER_Handle *h);
293
294
295/**
296 * Transmit next message to service.
297 *
298 * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle`.
299 * @param size number of bytes available in @a buf
300 * @param buf where to copy the message
301 * @return number of bytes copied to buf
302 */
303static size_t
304send_next_message (void *cls,
305 size_t size,
306 void *buf)
307{
308 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
309 struct GNUNET_IDENTITY_PROVIDER_Operation *op = h->op_head;
310 size_t ret;
311
312 h->th = NULL;
313 if (NULL == op)
314 return 0;
315 ret = ntohs (op->msg->size);
316 if (ret > size)
317 {
318 reschedule_connect (h);
319 return 0;
320 }
321 LOG (GNUNET_ERROR_TYPE_DEBUG,
322 "Sending message of type %d to identity provider service\n",
323 ntohs (op->msg->type));
324 memcpy (buf, op->msg, ret);
325 if ( (NULL == op->cont) &&
326 (NULL == op->cb) )
327 {
328 GNUNET_CONTAINER_DLL_remove (h->op_head,
329 h->op_tail,
330 op);
331 GNUNET_free (op);
332 transmit_next (h);
333 }
334 if (GNUNET_NO == h->in_receive)
335 {
336 h->in_receive = GNUNET_YES;
337 GNUNET_CLIENT_receive (h->client,
338 &message_handler, h,
339 GNUNET_TIME_UNIT_FOREVER_REL);
340 }
341 return ret;
342}
343
344
345/**
346 * Schedule transmission of the next message from our queue.
347 *
348 * @param h identity provider handle
349 */
350static void
351transmit_next (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
352{
353 struct GNUNET_IDENTITY_PROVIDER_Operation *op = h->op_head;
354
355 GNUNET_assert (NULL == h->th);
356 if (NULL == op)
357 return;
358 if (NULL == h->client)
359 return;
360 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
361 ntohs (op->msg->size),
362 GNUNET_TIME_UNIT_FOREVER_REL,
363 GNUNET_NO,
364 &send_next_message,
365 h);
366}
367
368
369/**
370 * Try again to connect to the service.
371 *
372 * @param cls handle to the identity provider service.
373 * @param tc scheduler context
374 */
375static void
376reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
377{
378 struct GNUNET_IDENTITY_Handle *h = cls;
379 struct GNUNET_IDENTITY_Operation *op;
380 struct GNUNET_MessageHeader msg;
381
382 h->reconnect_task = NULL;
383 LOG (GNUNET_ERROR_TYPE_DEBUG,
384 "Connecting to identity provider service.\n");
385 GNUNET_assert (NULL == h->client);
386 h->client = GNUNET_CLIENT_connect ("identity-provider", h->cfg);
387 GNUNET_assert (NULL != h->client);
388 if ( (NULL == h->op_head) ||
389 (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_START != ntohs (h->op_head->msg->type)) )
390 {
391 op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) +
392 sizeof (struct GNUNET_MessageHeader));
393 op->h = h;
394 op->msg = (const struct GNUNET_MessageHeader *) &op[1];
395 msg.size = htons (sizeof (msg));
396 msg.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_START);
397 memcpy (&op[1], &msg, sizeof (msg));
398 GNUNET_CONTAINER_DLL_insert (h->op_head,
399 h->op_tail,
400 op);
401 }
402 transmit_next (h);
403 GNUNET_assert (NULL != h->th);
404}
405
406
407/**
408 * Connect to the identity provider service.
409 *
410 * @param cfg the configuration to use
411 * @return handle to use
412 */
413struct GNUNET_IDENTITY_PROVIDER_Handle *
414GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
415{
416 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
417
418 h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle);
419 h->cfg = cfg;
420 h->cb = cb;
421 h->cb_cls = cb_cls;
422 h->egos = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES);
423 h->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
424 h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, h);
425 return h;
426}
427
428
429/**
430 * Issue an identity token
431 *
432 * @param id identity service to query
433 * @param service_name for which service is an identity wanted
434 * @param cb function to call with the result (will only be called once)
435 * @param cb_cls closure for @a cb
436 * @return handle to abort the operation
437 */
438struct GNUNET_IDENTITY_PROVIDER_Operation *
439GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
440 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key,
441 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
442 const char* scopes,
443 const struct GNUNET_TIME_Absolute exp,
444 GNUNET_IDENTITY_PROVIDER_IssueCallback cb,
445 void *cb_cls)
446{
447 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
448 struct GNUNET_IDENTITY_PROVIDER_IssueMessage *im;
449 size_t slen;
450
451 slen = strlen (scopes) + 1;
452 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage))
453 {
454 GNUNET_break (0);
455 return NULL;
456 }
457 op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) +
458 sizeof (struct GNUNET_IDENTITY_IssueMessage) +
459 slen);
460 op->h = id;
461 op->cb = cb;
462 op->cls = cb_cls;
463 im = (struct GNUNET_IDENTITY_GetDefaultMessage *) &op[1];
464 im->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE);
465 im->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) +
466 slen);
467 im->iss_key = *iss_key;
468 im->aud_key = *aud_ley;
469 im->exp = exp.abs_value_ul;
470 memcpy (&im[1], scopes, slen);
471 op->msg = &im->header;
472 GNUNET_CONTAINER_DLL_insert_tail (id->op_head,
473 id->op_tail,
474 op);
475 if (NULL == id->th)
476 transmit_next (id);
477 return op;
478}
479
480
481/**
482 * Exchange a token ticket for a token
483 *
484 * @param id identity provider service
485 * @param ticket ticket to exchange
486 * @param cont function to call once the operation finished
487 * @param cont_cls closure for @a cont
488 * @return handle to abort the operation
489 */
490struct GNUNET_IDENTITY_PROVIDER_Operation *
491GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_Handle *id,
492 const char *ticket,
493 GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont,
494 void *cont_cls)
495{
496 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
497 struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *em;
498 size_t slen;
499
500 slen = strlen (ticket) + 1;
501 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_ExchangeMessage))
502 {
503 GNUNET_break (0);
504 return NULL;
505 }
506 op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) +
507 sizeof (struct GNUNET_IDENTITY_ExchangeMessage) +
508 slen);
509 op->h = id;
510 op->cont = cont;
511 op->cls = cont_cls;
512 em = (struct GNUNET_IDENTITY_ExchangeMessage *) &op[1];
513 em->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE);
514 em->header.size = htons (sizeof (struct GNUNET_IDENTITY_ExchangeMessage) +
515 slen);
516 memcpy (&em[1], ticket, slen);
517 op->msg = &em->header;
518 GNUNET_CONTAINER_DLL_insert_tail (id->op_head,
519 id->op_tail,
520 op);
521 if (NULL == id->th)
522 transmit_next (id);
523 return op;
524}
525
526
527/**
528 * Cancel an operation. Note that the operation MAY still
529 * be executed; this merely cancels the continuation; if the request
530 * was already transmitted, the service may still choose to complete
531 * the operation.
532 *
533 * @param op operation to cancel
534 */
535void
536GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
537{
538 struct GNUNET_IDENTITY_Handle *h = op->h;
539
540 if ( (h->op_head != op) ||
541 (NULL == h->client) )
542 {
543 /* request not active, can simply remove */
544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
545 "Client aborted non-head operation, simply removing it\n");
546 GNUNET_CONTAINER_DLL_remove (h->op_head,
547 h->op_tail,
548 op);
549 GNUNET_free (op);
550 return;
551 }
552 if (NULL != h->th)
553 {
554 /* request active but not yet with service, can still abort */
555 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
556 "Client aborted head operation prior to transmission, aborting it\n");
557 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
558 h->th = NULL;
559 GNUNET_CONTAINER_DLL_remove (h->op_head,
560 h->op_tail,
561 op);
562 GNUNET_free (op);
563 transmit_next (h);
564 return;
565 }
566 /* request active with service, simply ensure continuations are not called */
567 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
568 "Client aborted active request, NULLing continuation\n");
569 op->ex_cb = NULL;
570 op->iss_cb = NULL;
571}
572
573
574/**
575 * Disconnect from service
576 *
577 * @param h handle to destroy
578 */
579void
580GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
581{
582 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
583
584 GNUNET_assert (NULL != h);
585 if (h->reconnect_task != NULL)
586 {
587 GNUNET_SCHEDULER_cancel (h->reconnect_task);
588 h->reconnect_task = NULL;
589 }
590 if (NULL != h->th)
591 {
592 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
593 h->th = NULL;
594 }
595 while (NULL != (op = h->op_head))
596 {
597 GNUNET_break (NULL == op->cont);
598 GNUNET_CONTAINER_DLL_remove (h->op_head,
599 h->op_tail,
600 op);
601 GNUNET_free (op);
602 }
603 if (NULL != h->client)
604 {
605 GNUNET_CLIENT_disconnect (h->client);
606 h->client = NULL;
607 }
608 GNUNET_free (h);
609}
610
611/* end of identity_provider_api.c */
diff --git a/src/identity-provider/identity-token.c b/src/identity-provider/identity_token.c
index a9f210b14..10e142ca0 100644
--- a/src/identity-provider/identity-token.c
+++ b/src/identity-provider/identity_token.c
@@ -19,14 +19,14 @@
19 */ 19 */
20 20
21/** 21/**
22 * @file identity-token/identity-token.c 22 * @file identity-token/identity_token.c
23 * @brief helper library to manage identity tokens 23 * @brief helper library to manage identity tokens
24 * @author Martin Schanzenbach 24 * @author Martin Schanzenbach
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h" 28#include "gnunet_signatures.h"
29#include "gnunet_identity_provider_lib.h" 29#include "identity_token.h"
30#include <jansson.h> 30#include <jansson.h>
31 31
32 32
@@ -189,11 +189,11 @@ encrypt_str_ecdhe (const char *plaintext,
189 * @param id the JSON API resource id 189 * @param id the JSON API resource id
190 * @return a new JSON API resource or NULL on error. 190 * @return a new JSON API resource or NULL on error.
191 */ 191 */
192struct GNUNET_IDENTITY_PROVIDER_Token* 192struct IdentityToken*
193GNUNET_IDENTITY_PROVIDER_token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss, 193token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss,
194 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud) 194 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud)
195{ 195{
196 struct GNUNET_IDENTITY_PROVIDER_Token *token; 196 struct IdentityToken *token;
197 char* audience; 197 char* audience;
198 char* issuer; 198 char* issuer;
199 199
@@ -204,7 +204,7 @@ GNUNET_IDENTITY_PROVIDER_token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey
204 204
205 205
206 206
207 token = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Token)); 207 token = GNUNET_malloc (sizeof (struct IdentityToken));
208 208
209 token->header = json_object(); 209 token->header = json_object();
210 token->payload = json_object(); 210 token->payload = json_object();
@@ -214,6 +214,7 @@ GNUNET_IDENTITY_PROVIDER_token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey
214 214
215 json_object_set_new (token->payload, "iss", json_string (issuer)); 215 json_object_set_new (token->payload, "iss", json_string (issuer));
216 json_object_set_new (token->payload, "aud", json_string (audience)); 216 json_object_set_new (token->payload, "aud", json_string (audience));
217 json_object_set_new (token->payload, "sub", json_string (issuer));
217 218
218 token->aud_key = *aud; 219 token->aud_key = *aud;
219 GNUNET_free (issuer); 220 GNUNET_free (issuer);
@@ -222,7 +223,7 @@ GNUNET_IDENTITY_PROVIDER_token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey
222} 223}
223 224
224void 225void
225GNUNET_IDENTITY_PROVIDER_token_destroy (struct GNUNET_IDENTITY_PROVIDER_Token *token) 226token_destroy (struct IdentityToken *token)
226{ 227{
227 json_decref (token->header); 228 json_decref (token->header);
228 json_decref (token->payload); 229 json_decref (token->payload);
@@ -230,7 +231,7 @@ GNUNET_IDENTITY_PROVIDER_token_destroy (struct GNUNET_IDENTITY_PROVIDER_Token *t
230} 231}
231 232
232void 233void
233GNUNET_IDENTITY_PROVIDER_token_add_attr (const struct GNUNET_IDENTITY_PROVIDER_Token *token, 234token_add_attr (const struct IdentityToken *token,
234 const char* key, 235 const char* key,
235 const char* value) 236 const char* value)
236{ 237{
@@ -241,7 +242,7 @@ GNUNET_IDENTITY_PROVIDER_token_add_attr (const struct GNUNET_IDENTITY_PROVIDER_T
241} 242}
242 243
243void 244void
244GNUNET_IDENTITY_PROVIDER_token_add_json (const struct GNUNET_IDENTITY_PROVIDER_Token *token, 245token_add_json (const struct IdentityToken *token,
245 const char* key, 246 const char* key,
246 json_t* value) 247 json_t* value)
247{ 248{
@@ -253,10 +254,10 @@ GNUNET_IDENTITY_PROVIDER_token_add_json (const struct GNUNET_IDENTITY_PROVIDER_T
253 254
254 255
255int 256int
256GNUNET_IDENTITY_PROVIDER_token_parse2 (const char* raw_data, 257token_parse2 (const char* raw_data,
257 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key, 258 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
258 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 259 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
259 struct GNUNET_IDENTITY_PROVIDER_Token **result) 260 struct IdentityToken **result)
260{ 261{
261 char *enc_token_str; 262 char *enc_token_str;
262 char *tmp_buf; 263 char *tmp_buf;
@@ -299,7 +300,7 @@ GNUNET_IDENTITY_PROVIDER_token_parse2 (const char* raw_data,
299 //TODO signature 300 //TODO signature
300 301
301 302
302 *result = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Token)); 303 *result = GNUNET_malloc (sizeof (struct IdentityToken));
303 (*result)->aud_key = *aud_key; 304 (*result)->aud_key = *aud_key;
304 (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json); 305 (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json);
305 (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json); 306 (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json);
@@ -312,9 +313,9 @@ GNUNET_IDENTITY_PROVIDER_token_parse2 (const char* raw_data,
312} 313}
313 314
314int 315int
315GNUNET_IDENTITY_PROVIDER_token_parse (const char* raw_data, 316token_parse (const char* raw_data,
316 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 317 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
317 struct GNUNET_IDENTITY_PROVIDER_Token **result) 318 struct IdentityToken **result)
318{ 319{
319 char *ecdh_pubkey_str; 320 char *ecdh_pubkey_str;
320 char *enc_token_str; 321 char *enc_token_str;
@@ -363,7 +364,7 @@ GNUNET_IDENTITY_PROVIDER_token_parse (const char* raw_data,
363 //TODO signature and aud key 364 //TODO signature and aud key
364 365
365 366
366 *result = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Token)); 367 *result = GNUNET_malloc (sizeof (struct IdentityToken));
367 (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json); 368 (*result)->header = json_loads (header, JSON_DECODE_ANY, &err_json);
368 (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json); 369 (*result)->payload = json_loads (payload, JSON_DECODE_ANY, &err_json);
369 GNUNET_free (enc_token); 370 GNUNET_free (enc_token);
@@ -375,7 +376,7 @@ GNUNET_IDENTITY_PROVIDER_token_parse (const char* raw_data,
375} 376}
376 377
377int 378int
378GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_Token *token, 379token_to_string (const struct IdentityToken *token,
379 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 380 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
380 char **result) 381 char **result)
381{ 382{
@@ -443,7 +444,7 @@ GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_
443} 444}
444 445
445int 446int
446GNUNET_IDENTITY_PROVIDER_token_serialize (const struct GNUNET_IDENTITY_PROVIDER_Token *token, 447token_serialize (const struct IdentityToken *token,
447 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 448 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
448 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, 449 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
449 char **result) 450 char **result)
@@ -454,7 +455,7 @@ GNUNET_IDENTITY_PROVIDER_token_serialize (const struct GNUNET_IDENTITY_PROVIDER_
454 char *enc_token_base64; 455 char *enc_token_base64;
455 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; 456 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
456 457
457 GNUNET_assert (GNUNET_OK == GNUNET_IDENTITY_PROVIDER_token_to_string (token, 458 GNUNET_assert (GNUNET_OK == token_to_string (token,
458 priv_key, 459 priv_key,
459 &token_str)); 460 &token_str));
460 461
@@ -476,14 +477,14 @@ GNUNET_IDENTITY_PROVIDER_token_serialize (const struct GNUNET_IDENTITY_PROVIDER_
476 return GNUNET_OK; 477 return GNUNET_OK;
477} 478}
478 479
479struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload* 480struct TokenTicketPayload*
480GNUNET_IDENTITY_PROVIDER_ticket_payload_create (const char* nonce, 481ticket_payload_create (const char* nonce,
481 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, 482 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
482 const char* lbl_str) 483 const char* lbl_str)
483{ 484{
484 struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload* payload; 485 struct TokenTicketPayload* payload;
485 486
486 payload = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload)); 487 payload = GNUNET_malloc (sizeof (struct TokenTicketPayload));
487 GNUNET_asprintf (&payload->nonce, nonce, strlen (nonce)); 488 GNUNET_asprintf (&payload->nonce, nonce, strlen (nonce));
488 payload->identity_key = *identity_pkey; 489 payload->identity_key = *identity_pkey;
489 GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str)); 490 GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str));
@@ -491,7 +492,7 @@ GNUNET_IDENTITY_PROVIDER_ticket_payload_create (const char* nonce,
491} 492}
492 493
493void 494void
494GNUNET_IDENTITY_PROVIDER_ticket_payload_destroy (struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload* payload) 495ticket_payload_destroy (struct TokenTicketPayload* payload)
495{ 496{
496 GNUNET_free (payload->nonce); 497 GNUNET_free (payload->nonce);
497 GNUNET_free (payload->label); 498 GNUNET_free (payload->label);
@@ -499,7 +500,7 @@ GNUNET_IDENTITY_PROVIDER_ticket_payload_destroy (struct GNUNET_IDENTITY_PROVIDER
499} 500}
500 501
501void 502void
502GNUNET_IDENTITY_PROVIDER_ticket_payload_serialize (struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload *payload, 503ticket_payload_serialize (struct TokenTicketPayload *payload,
503 char **result) 504 char **result)
504{ 505{
505 char* identity_key_str; 506 char* identity_key_str;
@@ -522,17 +523,17 @@ GNUNET_IDENTITY_PROVIDER_ticket_payload_serialize (struct GNUNET_IDENTITY_PROVID
522 * The ticket also contains E (ecdh_pubkey) and a signature over the 523 * The ticket also contains E (ecdh_pubkey) and a signature over the
523 * metadata and E 524 * metadata and E
524 */ 525 */
525struct GNUNET_IDENTITY_PROVIDER_TokenTicket* 526struct TokenTicket*
526GNUNET_IDENTITY_PROVIDER_ticket_create (const char* nonce_str, 527ticket_create (const char* nonce_str,
527 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, 528 const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey,
528 const char* lbl_str, 529 const char* lbl_str,
529 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key) 530 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key)
530{ 531{
531 struct GNUNET_IDENTITY_PROVIDER_TokenTicket *ticket; 532 struct TokenTicket *ticket;
532 struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload *code_payload; 533 struct TokenTicketPayload *code_payload;
533 534
534 ticket = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_TokenTicket)); 535 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
535 code_payload = GNUNET_IDENTITY_PROVIDER_ticket_payload_create (nonce_str, 536 code_payload = ticket_payload_create (nonce_str,
536 identity_pkey, 537 identity_pkey,
537 lbl_str); 538 lbl_str);
538 ticket->aud_key = *aud_key; 539 ticket->aud_key = *aud_key;
@@ -543,14 +544,14 @@ GNUNET_IDENTITY_PROVIDER_ticket_create (const char* nonce_str,
543} 544}
544 545
545void 546void
546GNUNET_IDENTITY_PROVIDER_ticket_destroy (struct GNUNET_IDENTITY_PROVIDER_TokenTicket *ticket) 547ticket_destroy (struct TokenTicket *ticket)
547{ 548{
548 GNUNET_IDENTITY_PROVIDER_ticket_payload_destroy (ticket->payload); 549 ticket_payload_destroy (ticket->payload);
549 GNUNET_free (ticket); 550 GNUNET_free (ticket);
550} 551}
551 552
552int 553int
553GNUNET_IDENTITY_PROVIDER_ticket_serialize (struct GNUNET_IDENTITY_PROVIDER_TokenTicket *ticket, 554ticket_serialize (struct TokenTicket *ticket,
554 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 555 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
555 char **result) 556 char **result)
556{ 557{
@@ -565,7 +566,7 @@ GNUNET_IDENTITY_PROVIDER_ticket_serialize (struct GNUNET_IDENTITY_PROVIDER_Token
565 566
566 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 567 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
567 568
568 GNUNET_IDENTITY_PROVIDER_ticket_payload_serialize (ticket->payload, 569 ticket_payload_serialize (ticket->payload,
569 &code_payload_str); 570 &code_payload_str);
570 571
571 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str, 572 GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str,
@@ -617,11 +618,11 @@ GNUNET_IDENTITY_PROVIDER_ticket_serialize (struct GNUNET_IDENTITY_PROVIDER_Token
617} 618}
618 619
619int 620int
620GNUNET_IDENTITY_PROVIDER_ticket_payload_parse(const char *raw_data, 621ticket_payload_parse(const char *raw_data,
621 ssize_t data_len, 622 ssize_t data_len,
622 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 623 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
623 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey, 624 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
624 struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload **result) 625 struct TokenTicketPayload **result)
625{ 626{
626 const char* label_str; 627 const char* label_str;
627 const char* nonce_str; 628 const char* nonce_str;
@@ -697,7 +698,7 @@ GNUNET_IDENTITY_PROVIDER_ticket_payload_parse(const char *raw_data,
697 nonce_str = json_string_value (nonce_json); 698 nonce_str = json_string_value (nonce_json);
698 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found nonce: %s\n", nonce_str); 699 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found nonce: %s\n", nonce_str);
699 700
700 *result = GNUNET_IDENTITY_PROVIDER_ticket_payload_create (nonce_str, 701 *result = ticket_payload_create (nonce_str,
701 (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey, 702 (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey,
702 label_str); 703 label_str);
703 GNUNET_free (meta_str); 704 GNUNET_free (meta_str);
@@ -707,9 +708,9 @@ GNUNET_IDENTITY_PROVIDER_ticket_payload_parse(const char *raw_data,
707} 708}
708 709
709int 710int
710GNUNET_IDENTITY_PROVIDER_ticket_parse (const char *raw_data, 711ticket_parse (const char *raw_data,
711 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 712 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
712 struct GNUNET_IDENTITY_PROVIDER_TokenTicket **result) 713 struct TokenTicket **result)
713{ 714{
714 const char* enc_meta_str; 715 const char* enc_meta_str;
715 const char* ecdh_enc_str; 716 const char* ecdh_enc_str;
@@ -725,8 +726,8 @@ GNUNET_IDENTITY_PROVIDER_ticket_parse (const char *raw_data,
725 char* write_ptr; 726 char* write_ptr;
726 size_t enc_meta_len; 727 size_t enc_meta_len;
727 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 728 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
728 struct GNUNET_IDENTITY_PROVIDER_TokenTicket *ticket; 729 struct TokenTicket *ticket;
729 struct GNUNET_IDENTITY_PROVIDER_TokenTicketPayload *ticket_payload; 730 struct TokenTicketPayload *ticket_payload;
730 731
731 ticket_decoded = NULL; 732 ticket_decoded = NULL;
732 GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded); 733 GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded);
@@ -747,7 +748,7 @@ GNUNET_IDENTITY_PROVIDER_ticket_parse (const char *raw_data,
747 ecdh_enc_str = json_string_value (ecdh_json); 748 ecdh_enc_str = json_string_value (ecdh_json);
748 enc_meta_str = json_string_value (enc_meta_json); 749 enc_meta_str = json_string_value (enc_meta_json);
749 750
750 ticket = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_TokenTicket)); 751 ticket = GNUNET_malloc (sizeof (struct TokenTicket));
751 752
752 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str, 753 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
753 strlen (ecdh_enc_str), 754 strlen (ecdh_enc_str),
@@ -777,7 +778,7 @@ GNUNET_IDENTITY_PROVIDER_ticket_parse (const char *raw_data,
777 &enc_meta); 778 &enc_meta);
778 779
779 780
780 GNUNET_IDENTITY_PROVIDER_ticket_payload_parse (enc_meta, 781 ticket_payload_parse (enc_meta,
781 enc_meta_len, 782 enc_meta_len,
782 priv_key, 783 priv_key,
783 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey, 784 (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey,
@@ -804,7 +805,7 @@ GNUNET_IDENTITY_PROVIDER_ticket_parse (const char *raw_data,
804 &ticket->signature, 805 &ticket->signature,
805 &ticket_payload->identity_key)) 806 &ticket_payload->identity_key))
806 { 807 {
807 GNUNET_IDENTITY_PROVIDER_ticket_destroy (ticket); 808 ticket_destroy (ticket);
808 GNUNET_free (ticket_decoded); 809 GNUNET_free (ticket_decoded);
809 json_decref (root); 810 json_decref (root);
810 GNUNET_free (purpose); 811 GNUNET_free (purpose);
@@ -824,4 +825,4 @@ GNUNET_IDENTITY_PROVIDER_ticket_parse (const char *raw_data,
824 825
825 826
826 827
827/* end of identity-token.c */ 828/* end of identity_token.c */
diff --git a/src/identity-provider/identity_token.h b/src/identity-provider/identity_token.h
new file mode 100644
index 000000000..a51f8ca84
--- /dev/null
+++ b/src/identity-provider/identity_token.h
@@ -0,0 +1,269 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
20/**
21 * @author Martin Schanzenbach
22 * @file include/gnunet_identity_provider_lib.h
23 * @brief GNUnet Identity Provider library
24 *
25 */
26#ifndef IDENTITY_TOKEN_H
27#define IDENTITY_TOKEN_H
28
29#include "gnunet_crypto_lib.h"
30#include <jansson.h>
31
32struct IdentityToken
33{
34 /**
35 * JSON header
36 */
37 json_t *header;
38
39 /**
40 * JSON Payload
41 */
42 json_t *payload;
43
44 /**
45 * Token Signature
46 */
47 struct GNUNET_CRYPTO_EcdsaSignature signature;
48
49 /**
50 * Audience Pubkey
51 */
52 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
53};
54
55struct TokenTicketPayload
56{
57 /**
58 * Nonce
59 */
60 char* nonce;
61
62 /**
63 * Label
64 */
65 char *label;
66
67 /**
68 * Issuing Identity
69 */
70 struct GNUNET_CRYPTO_EcdsaPublicKey identity_key;
71};
72
73
74struct TokenTicket
75{
76 /**
77 * Meta info
78 */
79 struct TokenTicketPayload *payload;
80
81 /**
82 * ECDH Pubkey
83 */
84 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
85
86 /**
87 * Signature
88 */
89 struct GNUNET_CRYPTO_EcdsaSignature signature;
90
91 /**
92 * Target identity
93 */
94 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
95};
96
97
98
99/**
100 * Create an identity token
101 *
102 * @param iss the issuer string for the token
103 * @param aud the audience of the token
104 *
105 * @return a new token
106 */
107struct IdentityToken*
108token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *iss,
109 const struct GNUNET_CRYPTO_EcdsaPublicKey* aud);
110
111/**
112 * Destroy an identity token
113 *
114 * @param token the token to destroy
115 */
116void
117token_destroy (struct IdentityToken*token);
118
119/**
120 * Add a new key value pair to the token
121 *
122 * @param token the token to modify
123 * @param key the key
124 * @param value the value
125 */
126void
127token_add_attr (const struct IdentityToken *token,
128 const char* key,
129 const char* value);
130
131/**
132 * Add a new key value pair to the token with the value as json
133 *
134 * @param the token to modify
135 * @param key the key
136 * @param value the value
137 *
138 */
139void
140token_add_json (const struct IdentityToken *token,
141 const char* key,
142 json_t* value);
143
144/**
145 * Serialize a token. The token will be signed and base64 according to the
146 * JWT format. The signature is base32-encoded ECDSA.
147 * The resulting JWT is encrypted using
148 * ECDHE for the audience and Base64
149 * encoded in result. The audience requires the ECDHE public key P
150 * to decrypt the token T. The key P is included in the result and prepended
151 * before the token
152 *
153 * @param token the token to serialize
154 * @param priv_key the private key used to sign the token
155 * @param ecdhe_privkey the ECDHE private key used to encrypt the token
156 * @param result P,Base64(E(T))
157 *
158 * @return GNUNET_OK on success
159 */
160int
161token_serialize (const struct IdentityToken*token,
162 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
163 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdhe_privkey,
164 char **result);
165
166/**
167 * Parses the serialized token and returns a token
168 *
169 * @param data the serialized token
170 * @param priv_key the private key of the audience
171 * @param result the token
172 *
173 * @return GNUNET_OK on success
174 */
175int
176token_parse (const char* data,
177 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
178 struct IdentityToken **result);
179
180/**
181 * Parses the serialized token and returns a token
182 * This variant is intended for the party that issued the token and also
183 * wants to decrypt the serialized token.
184 *
185 * @param data the serialized token
186 * @param priv_key the private (!) ECDHE key
187 * @param aud_key the identity of the audience
188 * @param result the token
189 *
190 * @return GNUNET_OK on success
191 */
192 int
193 token_parse2 (const char* data,
194 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key,
195 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
196 struct IdentityToken **result);
197
198
199/**
200 *
201 * Returns a JWT-string representation of the token
202 *
203 * @param token the token
204 * @param priv_key the private key used to sign the JWT
205 * @param result the JWT
206 *
207 * @return GNUNET_OK on success
208 */
209 int
210 token_to_string (const struct IdentityToken *token,
211 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
212 char **result);
213
214/**
215 *
216 * Creates a ticket that can be exchanged by the audience for
217 * the token. The token must be placed under the label
218 *
219 * @param nonce_str nonce provided by the audience that requested the ticket
220 * @param iss_pkey the issuer pubkey used to sign the ticket
221 * @param label the label encoded in the ticket
222 * @param aud_ley the audience pubkey used to encrypt the ticket payload
223 *
224 * @return the ticket
225 */
226struct TokenTicket*
227ticket_create (const char* nonce_str,
228 const struct GNUNET_CRYPTO_EcdsaPublicKey* iss_pkey,
229 const char* lbl_str,
230 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key);
231
232/**
233 * Serialize a ticket. Returns the Base64 representation of the ticket.
234 * Format: Base64( { payload: E(Payload), ecdhe: K, signature: signature } )
235 *
236 * @param ticket the ticket to serialize
237 * @param priv_key the issuer private key to sign the ticket payload
238 * @param result the serialized ticket
239 *
240 * @return GNUNET_OK on success
241 */
242int
243ticket_serialize (struct TokenTicket *ticket,
244 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
245 char **result);
246
247/**
248 * Destroys a ticket
249 *
250 * @param the ticket to destroy
251 */
252void
253ticket_destroy (struct TokenTicket *ticket);
254
255/**
256 * Parses a serialized ticket
257 *
258 * @param data the serialized ticket
259 * @param priv_key the audience private key
260 * @param ticket the ticket
261 *
262 * @return GNUNET_OK on success
263 */
264 int
265 ticket_parse (const char* raw_data,
266 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
267 struct TokenTicket **ticket);
268
269#endif
diff --git a/src/identity-provider/plugin_rest_identity_token.c b/src/identity-provider/plugin_rest_identity_token.c
index d2c1b6c5d..fedee8b0e 100644
--- a/src/identity-provider/plugin_rest_identity_token.c
+++ b/src/identity-provider/plugin_rest_identity_token.c
@@ -34,7 +34,7 @@
34#include "microhttpd.h" 34#include "microhttpd.h"
35#include <jansson.h> 35#include <jansson.h>
36#include "gnunet_signatures.h" 36#include "gnunet_signatures.h"
37#include "gnunet_identity_provider_lib.h" 37#include "gnunet_identity_provider_service.h"
38 38
39/** 39/**
40 * REST root namespace 40 * REST root namespace
@@ -61,7 +61,7 @@
61 */ 61 */
62#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_AUTHORIZE "/gnuid/authorize" 62#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_AUTHORIZE "/gnuid/authorize"
63 63
64#define GNUNET_REST_JSONAPI_IDENTITY_token_ticket "code" 64#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET "ticket"
65 65
66#define GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_GRANT_TYPE_CODE "authorization_code" 66#define GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_GRANT_TYPE_CODE "authorization_code"
67 67
@@ -213,14 +213,19 @@ struct RequestHandle
213 struct GNUNET_IDENTITY_Operation *op; 213 struct GNUNET_IDENTITY_Operation *op;
214 214
215 /** 215 /**
216 * Handle to NS service 216 * Identity Provider
217 */ 217 */
218 struct GNUNET_NAMESTORE_Handle *ns_handle; 218 struct GNUNET_IDENTITY_PROVIDER_Handle *idp;
219 219
220 /** 220 /**
221 * Handle to GNS service 221 * Idp Operation
222 */ 222 */
223 struct GNUNET_GNS_Handle *gns_handle; 223 struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op;
224
225 /**
226 * Handle to NS service
227 */
228 struct GNUNET_NAMESTORE_Handle *ns_handle;
224 229
225 /** 230 /**
226 * NS iterator 231 * NS iterator
@@ -243,11 +248,6 @@ struct RequestHandle
243 struct GNUNET_SCHEDULER_Task * timeout_task; 248 struct GNUNET_SCHEDULER_Task * timeout_task;
244 249
245 /** 250 /**
246 * GNS lookup
247 */
248 struct GNUNET_GNS_LookupRequest *lookup_request;
249
250 /**
251 * The plugin result processor 251 * The plugin result processor
252 */ 252 */
253 GNUNET_REST_ResultProcessor proc; 253 GNUNET_REST_ResultProcessor proc;
@@ -288,16 +288,6 @@ struct RequestHandle
288 char *emsg; 288 char *emsg;
289 289
290 /** 290 /**
291 * Identity Token
292 */
293 struct GNUNET_IDENTITY_PROVIDER_Token *token;
294
295 /**
296 * Identity Token Code
297 */
298 struct GNUNET_IDENTITY_PROVIDER_TokenTicket *token_ticket;
299
300 /**
301 * Response object 291 * Response object
302 */ 292 */
303 struct JsonApiObject *resp_object; 293 struct JsonApiObject *resp_object;
@@ -330,8 +320,6 @@ cleanup_handle (struct RequestHandle *handle)
330 GNUNET_SCHEDULER_cancel (handle->timeout_task); 320 GNUNET_SCHEDULER_cancel (handle->timeout_task);
331 if (NULL != handle->identity_handle) 321 if (NULL != handle->identity_handle)
332 GNUNET_IDENTITY_disconnect (handle->identity_handle); 322 GNUNET_IDENTITY_disconnect (handle->identity_handle);
333 if (NULL != handle->gns_handle)
334 GNUNET_GNS_disconnect (handle->gns_handle);
335 if (NULL != handle->ns_it) 323 if (NULL != handle->ns_it)
336 GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it); 324 GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it);
337 if (NULL != handle->ns_qe) 325 if (NULL != handle->ns_qe)
@@ -340,10 +328,6 @@ cleanup_handle (struct RequestHandle *handle)
340 GNUNET_NAMESTORE_disconnect (handle->ns_handle); 328 GNUNET_NAMESTORE_disconnect (handle->ns_handle);
341 if (NULL != handle->attr_map) 329 if (NULL != handle->attr_map)
342 GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map); 330 GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
343 if (NULL != handle->token)
344 GNUNET_IDENTITY_PROVIDER_token_destroy (handle->token);
345 if (NULL != handle->token_ticket)
346 GNUNET_IDENTITY_PROVIDER_ticket_destroy (handle->token_ticket);
347 if (NULL != handle->url) 331 if (NULL != handle->url)
348 GNUNET_free (handle->url); 332 GNUNET_free (handle->url);
349 if (NULL != handle->emsg) 333 if (NULL != handle->emsg)
@@ -404,24 +388,7 @@ store_token_cont (void *cls,
404 int32_t success, 388 int32_t success,
405 const char *emsg) 389 const char *emsg)
406{ 390{
407 char *result_str;
408 struct MHD_Response *resp;
409 struct RequestHandle *handle = cls;
410
411 handle->ns_qe = NULL;
412 if (GNUNET_SYSERR == success)
413 {
414 handle->emsg = GNUNET_strdup (emsg);
415 GNUNET_SCHEDULER_add_now (&do_error, handle);
416 return;
417 } 391 }
418 GNUNET_REST_jsonapi_data_serialize (handle->resp_object, &result_str);
419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
420 resp = GNUNET_REST_create_json_response (result_str);
421 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
422 GNUNET_free (result_str);
423 GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle);
424}
425 392
426 393
427 394
@@ -441,299 +408,45 @@ store_token_cont (void *cls,
441 * @return identifier string of token (label) 408 * @return identifier string of token (label)
442 */ 409 */
443static void 410static void
444sign_and_return_token (void *cls, 411token_creat_cont (void *cls,
445 const struct GNUNET_SCHEDULER_TaskContext *tc) 412 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
446{ 413{
447 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
448 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
449 struct GNUNET_CRYPTO_EcdsaPublicKey aud_pkey;
450 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
451 struct JsonApiResource *json_resource; 414 struct JsonApiResource *json_resource;
452 struct RequestHandle *handle = cls; 415 struct RequestHandle *handle = cls;
453 struct GNUNET_GNSRECORD_Data token_record[2];
454 struct GNUNET_HashCode key;
455 struct GNUNET_TIME_Relative etime_rel;
456 json_t *token_str;
457 json_t *name_str;
458 json_t *token_ticket_json; 416 json_t *token_ticket_json;
459 char *lbl_str; 417 char *ticket_str;
460 char *exp_str; 418 char *result_str;
461 char *token_ticket_str; 419 struct MHD_Response *resp;
462 char *audience; 420
463 char *nonce_str; 421 if (NULL == ticket)
464 char *enc_token_str;
465 char *token_metadata;
466 char *scopes;
467 char* write_ptr;
468 uint64_t time;
469 uint64_t exp_time;
470 uint64_t rnd_key;
471 size_t token_metadata_len;
472
473 //Remote nonce
474 nonce_str = NULL;
475 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE,
476 strlen (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE),
477 &key);
478 if ( GNUNET_YES !=
479 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
480 &key) )
481 {
482 handle->emsg = GNUNET_strdup ("Request nonce missing!\n");
483 GNUNET_SCHEDULER_add_now (&do_error, handle);
484 return;
485 }
486 nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
487 &key);
488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
489 //Token audience
490 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST,
491 strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST),
492 &key);
493 audience = NULL;
494 if ( GNUNET_YES !=
495 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
496 &key) )
497 {
498 handle->emsg = GNUNET_strdup ("Audience missing!\n");
499 GNUNET_SCHEDULER_add_now (&do_error, handle);
500 return;
501 }
502 audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
503 &key);
504 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Audience to issue token for: %s\n", audience);
505
506 //Audience pubkey (B = bG)
507 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (audience,
508 strlen (audience),
509 &aud_pkey))
510 {
511 handle->emsg = GNUNET_strdup ("Client PKEY invalid!\n");
512 GNUNET_SCHEDULER_add_now (&do_error, handle);
513 return;
514 }
515
516
517 rnd_key = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
518 GNUNET_STRINGS_base64_encode ((char*)&rnd_key, sizeof (uint64_t), &lbl_str);
519 priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
520 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key,
521 &pub_key);
522
523 handle->token_ticket = GNUNET_IDENTITY_PROVIDER_ticket_create (nonce_str,
524 &pub_key,
525 lbl_str,
526 &aud_pkey);
527
528 if (GNUNET_OK != GNUNET_IDENTITY_PROVIDER_ticket_serialize (handle->token_ticket,
529 priv_key,
530 &token_ticket_str))
531 {
532 handle->emsg = GNUNET_strdup ("Unable to create ref token!\n");
533 GNUNET_SCHEDULER_add_now (&do_error, handle);
534 return;
535 }
536
537 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING,
538 strlen (GNUNET_IDENTITY_TOKEN_EXP_STRING),
539 &key);
540 //Get expiration for token from URL parameter
541 exp_str = NULL;
542 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
543 &key))
544 {
545 exp_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
546 &key);
547 }
548 if (NULL == exp_str) {
549 handle->emsg = GNUNET_strdup ("No expiration given!\n");
550 GNUNET_SCHEDULER_add_now (&do_error, handle);
551 return;
552 }
553
554 if (GNUNET_OK !=
555 GNUNET_STRINGS_fancy_time_to_relative (exp_str,
556 &etime_rel))
557 { 422 {
558 handle->emsg = GNUNET_strdup ("Expiration invalid!\n"); 423 handle->emsg = GNUNET_strdup ("Error in token issue");
559 GNUNET_SCHEDULER_add_now (&do_error, handle); 424 GNUNET_SCHEDULER_add_now (&do_error, handle);
560 return; 425 return;
561 } 426 }
562 time = GNUNET_TIME_absolute_get().abs_value_us; 427
563 exp_time = time + etime_rel.rel_value_us;
564
565 //json_object_set_new (handle->payload, "lbl", json_string (lbl_str));
566 GNUNET_IDENTITY_PROVIDER_token_add_attr (handle->token, "sub", handle->ego_entry->identifier);
567 GNUNET_IDENTITY_PROVIDER_token_add_json (handle->token, "nbf", json_integer (time));
568 GNUNET_IDENTITY_PROVIDER_token_add_json (handle->token, "iat", json_integer (time));
569 GNUNET_IDENTITY_PROVIDER_token_add_json (handle->token, "exp", json_integer (exp_time));
570 GNUNET_IDENTITY_PROVIDER_token_add_attr (handle->token, "nonce", nonce_str);
571
572
573 handle->resp_object = GNUNET_REST_jsonapi_object_new (); 428 handle->resp_object = GNUNET_REST_jsonapi_object_new ();
574 429
575 json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN, 430 json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
576 lbl_str); 431 "tmpid");
577 name_str = json_string (handle->ego_entry->identifier); 432 ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket);
578 GNUNET_REST_jsonapi_resource_add_attr (json_resource, 433 token_ticket_json = json_string (ticket_str);
579 GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
580 name_str);
581 json_decref (name_str);
582 token_str = json_string (enc_token_str);
583 GNUNET_REST_jsonapi_resource_add_attr (json_resource,
584 GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
585 token_str);
586 token_ticket_json = json_string (token_ticket_str);
587 GNUNET_REST_jsonapi_resource_add_attr (json_resource, 434 GNUNET_REST_jsonapi_resource_add_attr (json_resource,
588 GNUNET_REST_JSONAPI_IDENTITY_token_ticket, 435 GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
589 token_ticket_json); 436 token_ticket_json);
590 GNUNET_free (token_ticket_str); 437 GNUNET_free (ticket_str);
591 json_decref (token_ticket_json); 438 json_decref (token_ticket_json);
592 GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource); 439 GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
593 //Token in a serialized encrypted format 440 GNUNET_REST_jsonapi_data_serialize (handle->resp_object, &result_str);
594 GNUNET_assert (GNUNET_IDENTITY_PROVIDER_token_serialize (handle->token, 441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
595 priv_key, 442 resp = GNUNET_REST_create_json_response (result_str);
596 &ecdhe_privkey, 443 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
597 &enc_token_str)); 444 GNUNET_free (result_str);
598 445 GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle);
599 //Token record E,E_K (Token)
600 token_record[0].data = enc_token_str;
601 token_record[0].data_size = strlen (enc_token_str) + 1;
602 token_record[0].expiration_time = exp_time;
603 token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
604 token_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
605
606
607 //Meta info
608 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_ATTR_LIST,
609 strlen (GNUNET_IDENTITY_TOKEN_ATTR_LIST),
610 &key);
611
612 scopes = NULL;
613 if ( GNUNET_YES !=
614 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
615 &key) )
616 {
617 handle->emsg = GNUNET_strdup ("Scopes missing!\n");
618 GNUNET_SCHEDULER_add_now (&do_error, handle);
619 return;
620 }
621 scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
622 &key);
623
624 token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
625 + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)
626 + strlen (scopes) + 1; //With 0-Terminator
627 token_metadata = GNUNET_malloc (token_metadata_len);
628 write_ptr = token_metadata;
629 memcpy (token_metadata, ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
630 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
631 memcpy (write_ptr, &aud_pkey, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
632 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
633 memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator;
634
635 GNUNET_free (ecdhe_privkey);
636
637 token_record[1].data = token_metadata;
638 token_record[1].data_size = token_metadata_len;
639 token_record[1].expiration_time = exp_time;
640 token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
641 token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
642
643 //Persist token
644 handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
645 priv_key,
646 lbl_str,
647 2,
648 token_record,
649 &store_token_cont,
650 handle);
651 GNUNET_free (lbl_str);
652 GNUNET_free (enc_token_str);
653 json_decref (token_str);
654}
655
656
657
658
659
660static void
661attr_collect (void *cls,
662 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
663 const char *label,
664 unsigned int rd_count,
665 const struct GNUNET_GNSRECORD_Data *rd)
666{
667 int i;
668 char* data;
669 json_t *attr_arr;
670 struct RequestHandle *handle = cls;
671 struct GNUNET_HashCode key;
672
673 if (NULL == label)
674 {
675 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n");
676 handle->ns_it = NULL;
677 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
678 return;
679 }
680
681 GNUNET_CRYPTO_hash (label,
682 strlen (label),
683 &key);
684
685 if (0 == rd_count ||
686 ( (NULL != handle->attr_map) &&
687 (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map,
688 &key))
689 )
690 )
691 {
692 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
693 return;
694 }
695
696 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", label);
697 446
698 if (1 == rd_count)
699 {
700 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
701 {
702 data = GNUNET_GNSRECORD_value_to_string (rd->record_type,
703 rd->data,
704 rd->data_size);
705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
706 GNUNET_IDENTITY_PROVIDER_token_add_attr (handle->token, label, data);
707 GNUNET_free (data);
708 }
709 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
710 return;
711 }
712 447
713 i = 0;
714 attr_arr = json_array();
715 for (; i < rd_count; i++)
716 {
717 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
718 {
719 data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
720 rd[i].data,
721 rd[i].data_size);
722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
723 json_array_append_new (attr_arr, json_string (data));
724 GNUNET_free (data);
725 }
726 }
727
728 if (0 < json_array_size (attr_arr))
729 {
730 GNUNET_IDENTITY_PROVIDER_token_add_json (handle->token, label, attr_arr);
731 }
732 json_decref (attr_arr);
733 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
734} 448}
735 449
736
737/** 450/**
738 * Create a response with requested ego(s) 451 * Create a response with requested ego(s)
739 * 452 *
@@ -749,6 +462,9 @@ issue_token_cont (struct RestConnectionDataHandle *con,
749 const char *egoname; 462 const char *egoname;
750 char *ego_val; 463 char *ego_val;
751 char *audience; 464 char *audience;
465 char *exp_str;
466 char *nonce_str;
467 char *scopes;
752 struct RequestHandle *handle = cls; 468 struct RequestHandle *handle = cls;
753 struct EgoEntry *ego_entry; 469 struct EgoEntry *ego_entry;
754 struct GNUNET_HashCode key; 470 struct GNUNET_HashCode key;
@@ -756,6 +472,10 @@ issue_token_cont (struct RestConnectionDataHandle *con,
756 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; 472 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
757 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; 473 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
758 struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key; 474 struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key;
475 struct GNUNET_TIME_Relative etime_rel;
476 struct GNUNET_TIME_Absolute exp_time;
477 uint64_t time;
478 uint64_t nonce;
759 479
760 if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, 480 if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url,
761 GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE)) 481 GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE))
@@ -806,6 +526,24 @@ issue_token_cont (struct RestConnectionDataHandle *con,
806 strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST), 526 strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST),
807 &key); 527 &key);
808 528
529 //Meta info
530 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_ATTR_LIST,
531 strlen (GNUNET_IDENTITY_TOKEN_ATTR_LIST),
532 &key);
533
534 scopes = NULL;
535 if ( GNUNET_YES !=
536 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
537 &key) )
538 {
539 handle->emsg = GNUNET_strdup ("Scopes missing!\n");
540 GNUNET_SCHEDULER_add_now (&do_error, handle);
541 return;
542 }
543 scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
544 &key);
545
546
809 //Token audience 547 //Token audience
810 audience = NULL; 548 audience = NULL;
811 if ( GNUNET_YES != 549 if ( GNUNET_YES !=
@@ -829,18 +567,79 @@ issue_token_cont (struct RestConnectionDataHandle *con,
829 strlen (audience), 567 strlen (audience),
830 &aud_key, 568 &aud_key,
831 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 569 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
832 handle->token = GNUNET_IDENTITY_PROVIDER_token_create (&pub_key,
833 aud_key);
834 GNUNET_free (aud_key);
835 570
571 //Remote nonce
572 nonce_str = NULL;
573 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE,
574 strlen (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE),
575 &key);
576 if ( GNUNET_YES !=
577 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
578 &key) )
579 {
580 handle->emsg = GNUNET_strdup ("Request nonce missing!\n");
581 GNUNET_SCHEDULER_add_now (&do_error, handle);
582 return;
583 }
584 nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
585 &key);
586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
587 sscanf (nonce_str, "%lu", &nonce);
836 588
837 //Get identity attributes 589 //Get expiration for token from URL parameter
838 handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); 590 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING,
839 handle->ego_entry = ego_entry; 591 strlen (GNUNET_IDENTITY_TOKEN_EXP_STRING),
840 handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, 592 &key);
593
594 exp_str = NULL;
595 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
596 &key))
597 {
598 exp_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
599 &key);
600 }
601 if (NULL == exp_str) {
602 handle->emsg = GNUNET_strdup ("No expiration given!\n");
603 GNUNET_SCHEDULER_add_now (&do_error, handle);
604 return;
605 }
606
607 if (GNUNET_OK !=
608 GNUNET_STRINGS_fancy_time_to_relative (exp_str,
609 &etime_rel))
610 {
611 handle->emsg = GNUNET_strdup ("Expiration invalid!\n");
612 GNUNET_SCHEDULER_add_now (&do_error, handle);
613 return;
614 }
615 time = GNUNET_TIME_absolute_get().abs_value_us;
616 exp_time.abs_value_us = time + etime_rel.rel_value_us;
617
618 handle->idp_op = GNUNET_IDENTITY_PROVIDER_issue_token (handle->idp,
841 priv_key, 619 priv_key,
842 &attr_collect, 620 aud_key,
621 scopes,
622 &exp_time,
623 nonce,
624 &token_creat_cont,
843 handle); 625 handle);
626 /*handle->token_handle = GNUNET_IDENTITY_PROVIDER_token_issue (&pub_key,
627 aud_key,
628 handle->attr_map,
629 &token_creat_cont,
630 handle);
631 handle->token = GNUNET_IDENTITY_PROVIDER_token_create (&pub_key,
632 aud_key);*/
633 GNUNET_free (aud_key);
634
635
636 //Get identity attributes
637 /*handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
638 handle->ego_entry = ego_entry;
639 handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
640 priv_key,
641 &attr_collect,
642 handle);*/
844} 643}
845 644
846 645
@@ -1010,51 +809,21 @@ list_token_cont (struct RestConnectionDataHandle *con_handle,
1010 809
1011} 810}
1012 811
1013
1014
1015
1016static void 812static void
1017process_lookup_result (void *cls, uint32_t rd_count, 813exchange_cont (void *cls,
1018 const struct GNUNET_GNSRECORD_Data *rd) 814 const struct GNUNET_IDENTITY_PROVIDER_Token *token)
1019{ 815{
1020 struct RequestHandle *handle = cls;
1021 json_t *root; 816 json_t *root;
817 struct RequestHandle *handle = cls;
1022 struct MHD_Response *resp; 818 struct MHD_Response *resp;
1023 char *result; 819 char* result;
1024 char* token_str; 820 char* token_str;
1025 char* record_str; 821
1026 822 root = json_object ();
1027 handle->lookup_request = NULL; 823 token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token);
1028 if (2 != rd_count)
1029 {
1030 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1031 "Number of tokens %d != 2.",
1032 rd_count);
1033 handle->emsg = GNUNET_strdup ("Number of tokens != 2.");
1034 GNUNET_SCHEDULER_add_now (&do_error, handle);
1035 return;
1036 }
1037
1038 root = json_object();
1039 record_str =
1040 GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN,
1041 rd->data,
1042 rd->data_size);
1043
1044 //Decrypt and parse
1045 GNUNET_assert (GNUNET_OK == GNUNET_IDENTITY_PROVIDER_token_parse (record_str,
1046 handle->priv_key,
1047 &handle->token));
1048
1049 //Readable
1050 GNUNET_assert (GNUNET_OK == GNUNET_IDENTITY_PROVIDER_token_to_string (handle->token,
1051 handle->priv_key,
1052 &token_str));
1053
1054 json_object_set_new (root, "access_token", json_string (token_str)); 824 json_object_set_new (root, "access_token", json_string (token_str));
1055 json_object_set_new (root, "token_type", json_string ("gnuid")); 825 json_object_set_new (root, "token_type", json_string ("gnuid"));
1056 GNUNET_free (token_str); 826 GNUNET_free (token_str);
1057 GNUNET_free (record_str);
1058 827
1059 result = json_dumps (root, JSON_INDENT(1)); 828 result = json_dumps (root, JSON_INDENT(1));
1060 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", result); 829 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", result);
@@ -1062,70 +831,59 @@ process_lookup_result (void *cls, uint32_t rd_count,
1062 GNUNET_free (result); 831 GNUNET_free (result);
1063 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 832 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1064 cleanup_handle (handle); 833 cleanup_handle (handle);
1065 json_decref (root); 834 json_decref (root);
1066} 835}
1067 836
1068
1069static void 837static void
1070exchange_token_ticket_cb (void *cls, 838exchange_token_ticket_cb (void *cls,
1071 struct GNUNET_IDENTITY_Ego *ego, 839 struct GNUNET_IDENTITY_Ego *ego,
1072 void **ctx, 840 void **ctx,
1073 const char *name) 841 const char *name)
1074{ 842{
1075 struct RequestHandle *handle = cls; 843 struct RequestHandle *handle = cls;
1076 struct GNUNET_HashCode key; 844 struct GNUNET_HashCode key;
1077 char* code; 845 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
1078 char* lookup_query; 846 char* ticket_str;
1079 847
1080 handle->op = NULL; 848 handle->op = NULL;
1081 849
1082 if (NULL == ego) 850 if (NULL == ego)
1083 { 851 {
1084 handle->emsg = GNUNET_strdup ("No GNS identity found."); 852 handle->emsg = GNUNET_strdup ("No identity found.");
1085 GNUNET_SCHEDULER_add_now (&do_error, handle); 853 GNUNET_SCHEDULER_add_now (&do_error, handle);
1086 return; 854 return;
1087 } 855 }
1088 856
1089 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_token_ticket, 857 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
1090 strlen (GNUNET_REST_JSONAPI_IDENTITY_token_ticket), 858 strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET),
1091 &key); 859 &key);
1092 860
1093 if ( GNUNET_NO == 861 if ( GNUNET_NO ==
1094 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, 862 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
1095 &key) ) 863 &key) )
1096 { 864 {
1097 handle->emsg = GNUNET_strdup ("No code given."); 865 handle->emsg = GNUNET_strdup ("No ticket given.");
1098 GNUNET_SCHEDULER_add_now (&do_error, handle); 866 GNUNET_SCHEDULER_add_now (&do_error, handle);
1099 return; 867 return;
1100 } 868 }
1101 code = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, 869 ticket_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
1102 &key); 870 &key);
1103 871
1104 handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (ego); 872 handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (ego);
873 GNUNET_IDENTITY_PROVIDER_string_to_ticket (ticket_str,
874 &ticket);
875
876 handle->idp_op = GNUNET_IDENTITY_PROVIDER_exchange_ticket (handle->idp,
877 ticket,
878 handle->priv_key,
879 &exchange_cont,
880 handle);
881 GNUNET_free (ticket);
1105 882
1106 if (GNUNET_SYSERR == GNUNET_IDENTITY_PROVIDER_ticket_parse (code,
1107 handle->priv_key,
1108 &handle->token_ticket))
1109 {
1110 handle->emsg = GNUNET_strdup ("Error extracting values from token code.");
1111 GNUNET_SCHEDULER_add_now (&do_error, handle);
1112 return;
1113 }
1114 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for token under %s\n",
1115 handle->token_ticket->payload->label);
1116 handle->gns_handle = GNUNET_GNS_connect (cfg);
1117 GNUNET_asprintf (&lookup_query, "%s.gnu", handle->token_ticket->payload->label);
1118 handle->lookup_request = GNUNET_GNS_lookup (handle->gns_handle,
1119 lookup_query,
1120 &handle->token_ticket->payload->identity_key,
1121 GNUNET_GNSRECORD_TYPE_ID_TOKEN,
1122 GNUNET_GNS_LO_LOCAL_MASTER,
1123 NULL,
1124 &process_lookup_result,
1125 handle);
1126 GNUNET_free (lookup_query);
1127} 883}
1128 884
885
886
1129/** 887/**
1130 * Respond to OAuth2 /token request 888 * Respond to OAuth2 /token request
1131 * 889 *
@@ -1135,8 +893,8 @@ exchange_token_ticket_cb (void *cls,
1135 */ 893 */
1136static void 894static void
1137exchange_token_ticket_cont (struct RestConnectionDataHandle *con_handle, 895exchange_token_ticket_cont (struct RestConnectionDataHandle *con_handle,
1138 const char* url, 896 const char* url,
1139 void *cls) 897 void *cls)
1140{ 898{
1141 struct RequestHandle *handle = cls; 899 struct RequestHandle *handle = cls;
1142 char* grant_type; 900 char* grant_type;