aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/curl/curl.c2
-rw-r--r--src/gns/gns.h8
-rw-r--r--src/gns/gns_api.c68
-rw-r--r--src/gns/gnunet-service-gns.c1
-rw-r--r--src/gns/gnunet-service-gns_interceptor.c7
-rw-r--r--src/gns/gnunet-service-gns_resolver.c23
-rw-r--r--src/gns/gnunet-service-gns_resolver.h5
-rw-r--r--src/include/Makefile.am16
-rw-r--r--src/include/gnunet_buffer_lib.h176
-rw-r--r--src/include/gnunet_curl_lib.h2
-rw-r--r--src/include/gnunet_gns_service.h25
-rw-r--r--src/include/gnunet_gnsrecord_lib.h11
-rw-r--r--src/include/gnunet_protocols.h11
-rw-r--r--src/include/gnunet_reclaim_attribute_lib.h245
-rw-r--r--src/include/gnunet_reclaim_attribute_plugin.h27
-rw-r--r--src/include/gnunet_reclaim_service.h82
-rw-r--r--src/include/gnunet_util_taler_wallet_lib.h56
-rw-r--r--src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c109
-rw-r--r--src/reclaim-attribute/reclaim_attribute.c587
-rw-r--r--src/reclaim-attribute/reclaim_attribute.h62
-rw-r--r--src/reclaim/gnunet-reclaim.c14
-rw-r--r--src/reclaim/gnunet-service-reclaim.c903
-rw-r--r--src/reclaim/gnunet-service-reclaim_tickets.c260
-rw-r--r--src/reclaim/json_reclaim.c221
-rw-r--r--src/reclaim/json_reclaim.h19
-rw-r--r--src/reclaim/oidc_helper.c126
-rw-r--r--src/reclaim/oidc_helper.h2
-rw-r--r--src/reclaim/plugin_gnsrecord_reclaim.c6
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c236
-rw-r--r--src/reclaim/plugin_rest_reclaim.c867
-rw-r--r--src/reclaim/reclaim.h39
-rw-r--r--src/reclaim/reclaim_api.c418
-rw-r--r--src/transport/Makefile.am24
-rw-r--r--src/transport/test_communicator_unix_basic_peer1.conf (renamed from src/transport/test_communicator_unix_peer1.conf)0
-rw-r--r--src/util/.gitignore2
-rw-r--r--src/util/Makefile.am47
-rw-r--r--src/util/buffer.c226
-rw-r--r--src/util/common_logging.c8
-rw-r--r--src/util/crypto_ecc.c109
-rw-r--r--src/util/gnunet-crypto-tvg.c278
-rw-r--r--src/util/test_crypto_ecdh_ecdsa.c97
-rw-r--r--src/util/tweetnacl-gnunet.c20
-rw-r--r--src/util/tweetnacl-gnunet.h4
-rw-r--r--src/vpn/gnunet-service-vpn.c17
45 files changed, 5008 insertions, 466 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 1bcc1ae7b..7b73a4bb8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -66,12 +66,6 @@ endif
66endif 66endif
67 67
68 68
69if TALER_ONLY
70SUBDIRS = \
71 include \
72 util
73else
74
75SUBDIRS = \ 69SUBDIRS = \
76 include $(INTLEMU_SUBDIRS) \ 70 include $(INTLEMU_SUBDIRS) \
77 util \ 71 util \
@@ -128,5 +122,3 @@ SUBDIRS = \
128 $(RECLAIM_DIR) \ 122 $(RECLAIM_DIR) \
129 $(EXP_DIR) \ 123 $(EXP_DIR) \
130 integration-tests 124 integration-tests
131
132endif
diff --git a/src/curl/curl.c b/src/curl/curl.c
index dcbb43f58..82eb28ed9 100644
--- a/src/curl/curl.c
+++ b/src/curl/curl.c
@@ -680,7 +680,7 @@ do_benchmark (CURLMsg *cmsg)
680 680
681 681
682/** 682/**
683 * Run the main event loop for the Taler interaction. 683 * Run the main event loop for the HTTP interaction.
684 * 684 *
685 * @param ctx the library context 685 * @param ctx the library context
686 * @param rp parses the raw response returned from 686 * @param rp parses the raw response returned from
diff --git a/src/gns/gns.h b/src/gns/gns.h
index 1fa812c23..5f51b7108 100644
--- a/src/gns/gns.h
+++ b/src/gns/gns.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2012-2013 GNUnet e.V. 3 Copyright (C) 2012-2020 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -57,9 +57,11 @@ struct LookupMessage
57 int16_t options GNUNET_PACKED; 57 int16_t options GNUNET_PACKED;
58 58
59 /** 59 /**
60 * Always 0. 60 * Recursion depth limit, i.e. how many more
61 * GNS zones may be traversed during the resolution
62 * of this name.
61 */ 63 */
62 int16_t reserved GNUNET_PACKED; 64 uint16_t recursion_depth_limit GNUNET_PACKED;
63 65
64 /** 66 /**
65 * the type of record to look up 67 * the type of record to look up
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c
index 4a4003b2a..0d99d822e 100644
--- a/src/gns/gns_api.c
+++ b/src/gns/gns_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016, 2018 GNUnet e.V. 3 Copyright (C) 2009-2020 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -37,6 +37,12 @@
37#define LOG(kind, ...) GNUNET_log_from (kind, "gns-api", __VA_ARGS__) 37#define LOG(kind, ...) GNUNET_log_from (kind, "gns-api", __VA_ARGS__)
38 38
39/** 39/**
40 * Default recursion depth limit to apply if
41 * the application does not specify any.
42 */
43#define DEFAULT_LIMIT 128
44
45/**
40 * Handle to a lookup request 46 * Handle to a lookup request
41 */ 47 */
42struct GNUNET_GNS_LookupRequest 48struct GNUNET_GNS_LookupRequest
@@ -325,21 +331,24 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr)
325 * 331 *
326 * @param handle handle to the GNS service 332 * @param handle handle to the GNS service
327 * @param name the name to look up (in UTF-8 encoding) 333 * @param name the name to look up (in UTF-8 encoding)
328 * @param zone the zone to start the resolution in 334 * @param zone zone to look in
329 * @param type the record type to look up 335 * @param type the GNS record type to look for
330 * @param options local options for the lookup 336 * @param options local options for the lookup
331 * @param proc processor to call on result 337 * @param recursion_depth_limit maximum number of zones
338 * that the lookup may (still) traverse
339 * @param proc function to call on result
332 * @param proc_cls closure for @a proc 340 * @param proc_cls closure for @a proc
333 * @return handle to the get request 341 * @return handle to the queued request
334 */ 342 */
335struct GNUNET_GNS_LookupRequest* 343struct GNUNET_GNS_LookupRequest *
336GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, 344GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle,
337 const char *name, 345 const char *name,
338 const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, 346 const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
339 uint32_t type, 347 uint32_t type,
340 enum GNUNET_GNS_LocalOptions options, 348 enum GNUNET_GNS_LocalOptions options,
341 GNUNET_GNS_LookupResultProcessor proc, 349 uint16_t recursion_depth_limit,
342 void *proc_cls) 350 GNUNET_GNS_LookupResultProcessor proc,
351 void *proc_cls)
343{ 352{
344 /* IPC to shorten gns names, return shorten_handle */ 353 /* IPC to shorten gns names, return shorten_handle */
345 struct LookupMessage *lookup_msg; 354 struct LookupMessage *lookup_msg;
@@ -370,6 +379,8 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
370 GNUNET_MESSAGE_TYPE_GNS_LOOKUP); 379 GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
371 lookup_msg->id = htonl (lr->r_id); 380 lookup_msg->id = htonl (lr->r_id);
372 lookup_msg->options = htons ((uint16_t) options); 381 lookup_msg->options = htons ((uint16_t) options);
382 lookup_msg->recursion_depth_limit
383 = htons (recursion_depth_limit);
373 lookup_msg->zone = *zone; 384 lookup_msg->zone = *zone;
374 lookup_msg->type = htonl (type); 385 lookup_msg->type = htonl (type);
375 GNUNET_memcpy (&lookup_msg[1], 386 GNUNET_memcpy (&lookup_msg[1],
@@ -385,4 +396,35 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
385} 396}
386 397
387 398
399/**
400 * Perform an asynchronous lookup operation on the GNS.
401 *
402 * @param handle handle to the GNS service
403 * @param name the name to look up (in UTF-8 encoding)
404 * @param zone the zone to start the resolution in
405 * @param type the record type to look up
406 * @param options local options for the lookup
407 * @param proc processor to call on result
408 * @param proc_cls closure for @a proc
409 * @return handle to the get request
410 */
411struct GNUNET_GNS_LookupRequest*
412GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
413 const char *name,
414 const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
415 uint32_t type,
416 enum GNUNET_GNS_LocalOptions options,
417 GNUNET_GNS_LookupResultProcessor proc,
418 void *proc_cls)
419{
420 return GNUNET_GNS_lookup_limited (handle,
421 name,
422 zone,
423 type,
424 options,
425 DEFAULT_LIMIT,
426 proc,
427 proc_cls);
428}
429
388/* end of gns_api.c */ 430/* end of gns_api.c */
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c
index 99cdbfe4e..8c5b2d6c4 100644
--- a/src/gns/gnunet-service-gns.c
+++ b/src/gns/gnunet-service-gns.c
@@ -463,6 +463,7 @@ handle_lookup (void *cls,
463 name, 463 name,
464 (enum GNUNET_GNS_LocalOptions) ntohs ( 464 (enum GNUNET_GNS_LocalOptions) ntohs (
465 sh_msg->options), 465 sh_msg->options),
466 ntohs (sh_msg->recursion_depth_limit),
466 &send_lookup_response, clh); 467 &send_lookup_response, clh);
467 GNUNET_STATISTICS_update (statistics, 468 GNUNET_STATISTICS_update (statistics,
468 "Lookup attempts", 469 "Lookup attempts",
diff --git a/src/gns/gnunet-service-gns_interceptor.c b/src/gns/gnunet-service-gns_interceptor.c
index dd97782ae..9d6636e84 100644
--- a/src/gns/gnunet-service-gns_interceptor.c
+++ b/src/gns/gnunet-service-gns_interceptor.c
@@ -34,6 +34,12 @@
34 34
35 35
36/** 36/**
37 * How deep do we allow recursions to go before we abort?
38 */
39#define MAX_RECURSION 256
40
41
42/**
37 * Handle to a DNS intercepted 43 * Handle to a DNS intercepted
38 * reslution request 44 * reslution request
39 */ 45 */
@@ -347,6 +353,7 @@ handle_dns_request (void *cls,
347 p->queries[0].type, 353 p->queries[0].type,
348 p->queries[0].name, 354 p->queries[0].name,
349 GNUNET_NO, 355 GNUNET_NO,
356 MAX_RECURSION,
350 &reply_to_dns, ilh); 357 &reply_to_dns, ilh);
351 return; 358 return;
352 } 359 }
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c
index 2c2263e58..735742283 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -77,11 +77,6 @@
77 */ 77 */
78#define DHT_GNS_REPLICATION_LEVEL 10 78#define DHT_GNS_REPLICATION_LEVEL 10
79 79
80/**
81 * How deep do we allow recursions to go before we abort?
82 */
83#define MAX_RECURSION 256
84
85 80
86/** 81/**
87 * DLL to hold the authority chain we had to pass in the resolution 82 * DLL to hold the authority chain we had to pass in the resolution
@@ -320,7 +315,7 @@ struct GNS_ResolverHandle
320 /** 315 /**
321 * closure passed to @e proc 316 * closure passed to @e proc
322 */ 317 */
323 void*proc_cls; 318 void *proc_cls;
324 319
325 /** 320 /**
326 * Handle for DHT lookups. should be NULL if no lookups are in progress 321 * Handle for DHT lookups. should be NULL if no lookups are in progress
@@ -395,7 +390,7 @@ struct GNS_ResolverHandle
395 struct DnsResult *dns_result_tail; 390 struct DnsResult *dns_result_tail;
396 391
397 /** 392 /**
398 * Current offset in 'name' where we are resolving. 393 * Current offset in @e name where we are resolving.
399 */ 394 */
400 size_t name_resolution_pos; 395 size_t name_resolution_pos;
401 396
@@ -423,12 +418,17 @@ struct GNS_ResolverHandle
423 418
424 /** 419 /**
425 * We increment the loop limiter for each step in a recursive 420 * We increment the loop limiter for each step in a recursive
426 * resolution. If it passes our threshold (i.e. due to 421 * resolution. If it passes our @e loop_threshold (i.e. due to
427 * self-recursion in the resolution, i.e CNAME fun), we stop. 422 * self-recursion in the resolution, i.e CNAME fun), we stop.
428 */ 423 */
429 unsigned int loop_limiter; 424 unsigned int loop_limiter;
430 425
431 /** 426 /**
427 * Maximum value of @e loop_limiter allowed by client.
428 */
429 unsigned int loop_threshold;
430
431 /**
432 * 16 bit random ID we used in the @e dns_request. 432 * 16 bit random ID we used in the @e dns_request.
433 */ 433 */
434 uint16_t original_dns_id; 434 uint16_t original_dns_id;
@@ -1856,6 +1856,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
1856 gp->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY; 1856 gp->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY;
1857 gp->rh->options = GNUNET_GNS_LO_DEFAULT; 1857 gp->rh->options = GNUNET_GNS_LO_DEFAULT;
1858 gp->rh->loop_limiter = rh->loop_limiter + 1; 1858 gp->rh->loop_limiter = rh->loop_limiter + 1;
1859 gp->rh->loop_threshold = rh->loop_threshold;
1859 gp->rh->task_id 1860 gp->rh->task_id
1860 = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, 1861 = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
1861 gp->rh); 1862 gp->rh);
@@ -2744,7 +2745,7 @@ recursive_resolution (void *cls)
2744 struct GNS_ResolverHandle *rh = cls; 2745 struct GNS_ResolverHandle *rh = cls;
2745 2746
2746 rh->task_id = NULL; 2747 rh->task_id = NULL;
2747 if (MAX_RECURSION < rh->loop_limiter++) 2748 if (rh->loop_threshold < rh->loop_limiter++)
2748 { 2749 {
2749 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2750 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2750 "Encountered unbounded recursion resolving `%s'\n", 2751 "Encountered unbounded recursion resolving `%s'\n",
@@ -2840,6 +2841,8 @@ start_resolver_lookup (void *cls)
2840 * @param record_type the record type to look up 2841 * @param record_type the record type to look up
2841 * @param name the name to look up 2842 * @param name the name to look up
2842 * @param options local options to control local lookup 2843 * @param options local options to control local lookup
2844 * @param recursion_depth_limit how many zones to traverse
2845 * at most
2843 * @param proc the processor to call on result 2846 * @param proc the processor to call on result
2844 * @param proc_cls the closure to pass to @a proc 2847 * @param proc_cls the closure to pass to @a proc
2845 * @return handle to cancel operation 2848 * @return handle to cancel operation
@@ -2849,6 +2852,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
2849 uint32_t record_type, 2852 uint32_t record_type,
2850 const char *name, 2853 const char *name,
2851 enum GNUNET_GNS_LocalOptions options, 2854 enum GNUNET_GNS_LocalOptions options,
2855 uint16_t recursion_depth_limit,
2852 GNS_ResultProcessor proc, 2856 GNS_ResultProcessor proc,
2853 void *proc_cls) 2857 void *proc_cls)
2854{ 2858{
@@ -2868,6 +2872,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
2868 rh->record_type = record_type; 2872 rh->record_type = record_type;
2869 rh->name = GNUNET_strdup (name); 2873 rh->name = GNUNET_strdup (name);
2870 rh->name_resolution_pos = strlen (name); 2874 rh->name_resolution_pos = strlen (name);
2875 rh->loop_threshold = recursion_depth_limit;
2871 rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, 2876 rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
2872 rh); 2877 rh);
2873 return rh; 2878 return rh;
diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h
index cc918fd90..3dab3c91a 100644
--- a/src/gns/gnunet-service-gns_resolver.h
+++ b/src/gns/gnunet-service-gns_resolver.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V. 3 Copyright (C) 2009-2020 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -79,6 +79,8 @@ typedef void
79 * @param record_type the record type to look up 79 * @param record_type the record type to look up
80 * @param name the name to look up 80 * @param name the name to look up
81 * @param options options set to control local lookup 81 * @param options options set to control local lookup
82 * @param recursion_depth_limit how many zones to traverse
83 * at most
82 * @param proc the processor to call 84 * @param proc the processor to call
83 * @param proc_cls the closure to pass to @a proc 85 * @param proc_cls the closure to pass to @a proc
84 * @return handle to cancel operation 86 * @return handle to cancel operation
@@ -88,6 +90,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
88 uint32_t record_type, 90 uint32_t record_type,
89 const char *name, 91 const char *name,
90 enum GNUNET_GNS_LocalOptions options, 92 enum GNUNET_GNS_LocalOptions options,
93 uint16_t recursion_depth_limit,
91 GNS_ResultProcessor proc, 94 GNS_ResultProcessor proc,
92 void *proc_cls); 95 void *proc_cls);
93 96
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index c81f8e7d8..b53f2420d 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -9,17 +9,6 @@ EXTRA_DIST = \
9 block_dns.h \ 9 block_dns.h \
10 block_regex.h 10 block_regex.h
11 11
12if TALER_ONLY
13gnunetinclude_HEADERS = \
14 platform.h gettext.h \
15 gnunet_common.h \
16 gnunet_container_lib.h \
17 gnunet_crypto_lib.h \
18 gnunet_strings_lib.h \
19 gnunet_time_lib.h \
20 gnunet_util_taler_wallet_lib.h
21else
22
23gnunetinclude_HEADERS = \ 12gnunetinclude_HEADERS = \
24 platform.h gettext.h \ 13 platform.h gettext.h \
25 compat.h \ 14 compat.h \
@@ -35,6 +24,7 @@ gnunetinclude_HEADERS = \
35 gnunet_block_lib.h \ 24 gnunet_block_lib.h \
36 gnunet_block_group_lib.h \ 25 gnunet_block_group_lib.h \
37 gnunet_block_plugin.h \ 26 gnunet_block_plugin.h \
27 gnunet_buffer_lib.h \
38 gnunet_client_lib.h \ 28 gnunet_client_lib.h \
39 gnunet_common.h \ 29 gnunet_common.h \
40 gnunet_constants.h \ 30 gnunet_constants.h \
@@ -101,7 +91,7 @@ gnunetinclude_HEADERS = \
101 gnunet_regex_service.h \ 91 gnunet_regex_service.h \
102 gnunet_rest_lib.h \ 92 gnunet_rest_lib.h \
103 gnunet_rest_plugin.h \ 93 gnunet_rest_plugin.h \
104 gnunet_rps_service.h \ 94 gnunet_rps_service.h \
105 gnunet_revocation_service.h \ 95 gnunet_revocation_service.h \
106 gnunet_scalarproduct_service.h \ 96 gnunet_scalarproduct_service.h \
107 gnunet_scheduler_lib.h \ 97 gnunet_scheduler_lib.h \
@@ -130,5 +120,3 @@ gnunetinclude_HEADERS = \
130 gnunet_tun_lib.h \ 120 gnunet_tun_lib.h \
131 gnunet_util_lib.h \ 121 gnunet_util_lib.h \
132 gnunet_vpn_service.h 122 gnunet_vpn_service.h
133
134endif
diff --git a/src/include/gnunet_buffer_lib.h b/src/include/gnunet_buffer_lib.h
new file mode 100644
index 000000000..c0ae06d77
--- /dev/null
+++ b/src/include/gnunet_buffer_lib.h
@@ -0,0 +1,176 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * Common buffer management functions.
23 *
24 * @author Florian Dold
25 */
26
27#ifndef GNUNET_BUFFER_LIB_H
28#define GNUNET_BUFFER_LIB_H
29
30/**
31 * Dynamically growing buffer. Can be used to construct
32 * strings and other objects with dynamic size.
33 *
34 * This structure should, in most cases, be stack-allocated and
35 * zero-initialized, like:
36 *
37 * struct GNUNET_Buffer my_buffer = { 0 };
38 */
39struct GNUNET_Buffer
40{
41 /**
42 * Capacity of the buffer.
43 */
44 size_t capacity;
45
46 /**
47 * Current write position.
48 */
49 size_t position;
50
51 /**
52 * Backing memory.
53 */
54 char *mem;
55
56 /**
57 * Log a warning if the buffer is grown over its initially allocated capacity.
58 */
59 int warn_grow;
60};
61
62
63/**
64 * Initialize a buffer with the given capacity.
65 *
66 * When a buffer is allocated with this function, a warning is logged
67 * when the buffer exceeds the initial capacity.
68 *
69 * @param buf the buffer to initialize
70 * @param capacity the capacity (in bytes) to allocate for @a buf
71 */
72void
73GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity);
74
75
76/**
77 * Make sure that at least @a n bytes remaining in the buffer.
78 *
79 * @param buf buffer to potentially grow
80 * @param n number of bytes that should be available to write
81 */
82void
83GNUNET_buffer_ensure_remaining (struct GNUNET_Buffer *buf, size_t n);
84
85
86/**
87 * Write bytes to the buffer.
88 *
89 * Grows the buffer if necessary.
90 *
91 * @param buf buffer to write to
92 * @param data data to read from
93 * @param len number of bytes to copy from @a data to @a buf
94 *
95 */
96void
97GNUNET_buffer_write (struct GNUNET_Buffer *buf, const char *data, size_t len);
98
99
100/**
101 * Write a 0-terminated string to a buffer, excluding the 0-terminator.
102 *
103 * Grows the buffer if necessary.
104 *
105 * @param buf the buffer to write to
106 * @param str the string to write to @a buf
107 */
108void
109GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str);
110
111
112/**
113 * Write a path component to a buffer, ensuring that
114 * there is exactly one slash between the previous contents
115 * of the buffer and the new string.
116 *
117 * @param buf buffer to write to
118 * @param str string containing the new path component
119 */
120void
121GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str);
122
123
124/**
125 * Write a 0-terminated formatted string to a buffer, excluding the
126 * 0-terminator.
127 *
128 * Grows the buffer if necessary.
129 *
130 * @param buf the buffer to write to
131 * @param fmt format string
132 * @param ... format arguments
133 */
134void
135GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...);
136
137
138/**
139 * Write a 0-terminated formatted string to a buffer, excluding the
140 * 0-terminator.
141 *
142 * Grows the buffer if necessary.
143 *
144 * @param buf the buffer to write to
145 * @param fmt format string
146 * @param args format argument list
147 */
148void
149GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf, const char *fmt, va_list
150 args);
151
152
153/**
154 * Clear the buffer and return the string it contained.
155 * The caller is responsible to eventually #GNUNET_free
156 * the returned string.
157 *
158 * The returned string is always 0-terminated.
159 *
160 * @param buf the buffer to reap the string from
161 * @returns the buffer contained in the string
162 */
163char *
164GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf);
165
166
167/**
168 * Free the backing memory of the given buffer.
169 * Does not free the memory of the buffer control structure,
170 * which is typically stack-allocated.
171 */
172void
173GNUNET_buffer_clear (struct GNUNET_Buffer *buf);
174
175
176#endif
diff --git a/src/include/gnunet_curl_lib.h b/src/include/gnunet_curl_lib.h
index 48eb7e490..8e981e91e 100644
--- a/src/include/gnunet_curl_lib.h
+++ b/src/include/gnunet_curl_lib.h
@@ -164,7 +164,7 @@ GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx);
164 164
165 165
166/** 166/**
167 * Run the main event loop for the Taler interaction. 167 * Run the main event loop for the HTTP interaction.
168 * 168 *
169 * @param ctx the library context 169 * @param ctx the library context
170 * @param rp parses the raw response returned from 170 * @param rp parses the raw response returned from
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h
index 5d2b7246a..ef81e9a88 100644
--- a/src/include/gnunet_gns_service.h
+++ b/src/include/gnunet_gns_service.h
@@ -147,6 +147,31 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
147 147
148 148
149/** 149/**
150 * Perform an asynchronous lookup operation on the GNS.
151 *
152 * @param handle handle to the GNS service
153 * @param name the name to look up (in UTF-8 encoding)
154 * @param zone zone to look in
155 * @param type the GNS record type to look for
156 * @param options local options for the lookup
157 * @param recursion_depth_limit maximum number of zones
158 * that the lookup may (still) traverse
159 * @param proc function to call on result
160 * @param proc_cls closure for @a proc
161 * @return handle to the queued request
162 */
163struct GNUNET_GNS_LookupRequest *
164GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle,
165 const char *name,
166 const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
167 uint32_t type,
168 enum GNUNET_GNS_LocalOptions options,
169 uint16_t recursion_depth_limit,
170 GNUNET_GNS_LookupResultProcessor proc,
171 void *proc_cls);
172
173
174/**
150 * Cancel pending lookup request 175 * Cancel pending lookup request
151 * 176 *
152 * @param lr the lookup request to cancel 177 * @param lr the lookup request to cancel
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h
index 3a49d98b9..797c71380 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -141,6 +141,17 @@ extern "C" {
141#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT 65553 141#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT 65553
142 142
143/** 143/**
144 * Record type for reclaim identity attestation
145 */
146#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR 65554
147
148/**
149 * Record type for reclaim identity references
150 */
151#define GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE 65555
152
153
154/**
144 * Flags that can be set for a record. 155 * Flags that can be set for a record.
145 */ 156 */
146enum GNUNET_GNSRECORD_Flags 157enum GNUNET_GNSRECORD_Flags
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index cd7cb50de..8091fb367 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2714,6 +2714,14 @@ extern "C" {
2714 2714
2715#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE 976 2715#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE 976
2716 2716
2717#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE 977
2718
2719#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE 978
2720
2721#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT 979
2722
2723#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE 980
2724
2717/************************************************** 2725/**************************************************
2718 * 2726 *
2719 * ABD MESSAGE TYPES 2727 * ABD MESSAGE TYPES
@@ -3301,6 +3309,9 @@ extern "C" {
3301/** 3309/**
3302 * Next available: 1500 3310 * Next available: 1500
3303 */ 3311 */
3312#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE 1500
3313
3314#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT 1501
3304 3315
3305 3316
3306/** 3317/**
diff --git a/src/include/gnunet_reclaim_attribute_lib.h b/src/include/gnunet_reclaim_attribute_lib.h
index 4563a5f67..004f2bd10 100644
--- a/src/include/gnunet_reclaim_attribute_lib.h
+++ b/src/include/gnunet_reclaim_attribute_lib.h
@@ -50,6 +50,15 @@ extern "C" {
50 */ 50 */
51#define GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING 1 51#define GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING 1
52 52
53/**
54* No value attestation.
55*/
56#define GNUNET_RECLAIM_ATTESTATION_TYPE_NONE 10
57
58/**
59* A JSON Web Token attestation.
60*/
61#define GNUNET_RECLAIM_ATTESTATION_TYPE_JWT 11
53 62
54/** 63/**
55 * An attribute. 64 * An attribute.
@@ -67,9 +76,48 @@ struct GNUNET_RECLAIM_ATTRIBUTE_Claim
67 uint32_t type; 76 uint32_t type;
68 77
69 /** 78 /**
79 * Flags
80 */
81 uint32_t flag;
82 /**
83 * The name of the attribute. Note "name" must never be individually
84 * free'd
85 */
86 const char *name;
87
88 /**
89 * Number of bytes in @e data.
90 */
91 size_t data_size;
92
93 /**
94 * Binary value stored as attribute value. Note: "data" must never
95 * be individually 'malloc'ed, but instead always points into some
96 * existing data area.
97 */
98 const void *data;
99};
100
101/**
102 * An attestation.
103 */
104struct GNUNET_RECLAIM_ATTESTATION_Claim
105{
106 /**
107 * ID
108 */
109 uint64_t id;
110
111 /**
112 * Type/Format of Claim
113 */
114 uint32_t type;
115
116 /**
70 * Version 117 * Version
71 */ 118 */
72 uint32_t version; 119 uint32_t version;
120
73 /** 121 /**
74 * The name of the attribute. Note "name" must never be individually 122 * The name of the attribute. Note "name" must never be individually
75 * free'd 123 * free'd
@@ -89,6 +137,33 @@ struct GNUNET_RECLAIM_ATTRIBUTE_Claim
89 const void *data; 137 const void *data;
90}; 138};
91 139
140/**
141 * A reference to an Attestatiom.
142 */
143struct GNUNET_RECLAIM_ATTESTATION_REFERENCE
144{
145 /**
146 * ID
147 */
148 uint64_t id;
149
150 /**
151 * Referenced ID of Attestation
152 */
153 uint64_t id_attest;
154
155 /**
156 * The name of the attribute/attestation reference value. Note "name" must never be individually
157 * free'd
158 */
159 const char *name;
160
161 /**
162 * The name of the attribute/attestation reference value. Note "name" must never be individually
163 * free'd
164 */
165 const char *reference_value;
166};
92 167
93/** 168/**
94 * A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures. 169 * A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
@@ -123,6 +198,20 @@ struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry
123 * The attribute claim 198 * The attribute claim
124 */ 199 */
125 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; 200 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
201 /**
202 * The attestation claim
203 */
204 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
205
206 /**
207 * The reference
208 */
209 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
210};
211
212struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType
213{
214 uint32_t type;
126}; 215};
127 216
128 217
@@ -203,6 +292,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
203struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * 292struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
204GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size); 293GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size);
205 294
295/**
296 * Count attestations in claim list
297 *
298 * @param attrs list
299 */
300int
301GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (
302 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
206 303
207/** 304/**
208 * Get required size for serialization buffer 305 * Get required size for serialization buffer
@@ -299,6 +396,154 @@ GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
299const char * 396const char *
300GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type); 397GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type);
301 398
399/**
400 * Get required size for serialization buffer
401 * FIXME:
402 * 1. The naming convention is violated here.
403 * It should GNUNET_RECLAIM_ATTRIBUTE_<lowercase from here>.
404 * It might make sense to refactor attestations into a separate folder.
405 * 2. The struct should be called GNUNET_RECLAIM_ATTESTATION_Data or
406 * GNUNET_RECLAIM_ATTRIBUTE_Attestation depending on location in source.
407 *
408 * @param attr the attestation to serialize
409 * @return the required buffer size
410 */
411size_t
412GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
413 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr);
414
415
416/**
417 * Serialize an attestation
418 *
419 * @param attr the attestation to serialize
420 * @param result the serialized attestation
421 * @return length of serialized data
422 */
423size_t
424GNUNET_RECLAIM_ATTESTATION_serialize (
425 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
426 char *result);
427
428
429/**
430 * Deserialize an attestation
431 *
432 * @param data the serialized attestation
433 * @param data_size the length of the serialized data
434 *
435 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
436 */
437struct GNUNET_RECLAIM_ATTESTATION_Claim *
438GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size);
439
440
441/**
442 * Create a new attestation.
443 *
444 * @param attr_name the attestation name
445 * @param type the attestation type
446 * @param data the attestation value
447 * @param data_size the attestation value size
448 * @return the new attestation
449 */
450struct GNUNET_RECLAIM_ATTESTATION_Claim *
451GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
452 uint32_t type,
453 const void *data,
454 size_t data_size);
455
456/**
457 * Convert the 'claim' of an attestation to a string
458 *
459 * @param type the type of attestation
460 * @param data claim in binary encoding
461 * @param data_size number of bytes in @a data
462 * @return NULL on error, otherwise human-readable representation of the claim
463 */
464char *
465GNUNET_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
466 const void *data,
467 size_t data_size);
468
469/**
470 * Convert human-readable version of a 'claim' of an attestation to the binary
471 * representation
472 *
473 * @param type type of the claim
474 * @param s human-readable string
475 * @param data set to value in binary encoding (will be allocated)
476 * @param data_size set to number of bytes in @a data
477 * @return #GNUNET_OK on success
478 */
479int
480GNUNET_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
481 const char *s,
482 void **data,
483 size_t *data_size);
484
485/**
486 * Convert an attestation type number to the corresponding attestation type string
487 *
488 * @param type number of a type
489 * @return corresponding typestring, NULL on error
490 */
491const char *
492GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type);
493
494/**
495 * Convert an attestation type name to the corresponding number
496 *
497 * @param typename name to convert
498 * @return corresponding number, UINT32_MAX on error
499 */
500uint32_t
501GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename);
502
503/**
504 * Create a new attestation reference.
505 *
506 * @param attr_name the referenced claim name
507 * @param ref_value the claim name in the attestation
508 * @return the new reference
509 */
510struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
511GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
512 const char *ref_value);
513
514
515/**
516 * Get required size for serialization buffer
517 *
518 * @param attr the reference to serialize
519 * @return the required buffer size
520 */
521size_t
522GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
523 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr);
524
525/**
526 * Serialize a reference
527 *
528 * @param attr the reference to serialize
529 * @param result the serialized reference
530 * @return length of serialized data
531 */
532size_t
533GNUNET_RECLAIM_ATTESTATION_REF_serialize (
534 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
535 char *result);
536
537/**
538 * Deserialize a reference
539 *
540 * @param data the serialized reference
541 * @param data_size the length of the serialized data
542 *
543 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
544 */
545struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
546GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t data_size);
302 547
303#if 0 /* keep Emacsens' auto-indent happy */ 548#if 0 /* keep Emacsens' auto-indent happy */
304{ 549{
diff --git a/src/include/gnunet_reclaim_attribute_plugin.h b/src/include/gnunet_reclaim_attribute_plugin.h
index 26a4bb4f2..e61cca5b2 100644
--- a/src/include/gnunet_reclaim_attribute_plugin.h
+++ b/src/include/gnunet_reclaim_attribute_plugin.h
@@ -134,6 +134,33 @@ struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions
134 * Number to typename. 134 * Number to typename.
135 */ 135 */
136 GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename; 136 GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename;
137
138 /**
139 * FIXME: It is odd that attestation functions are withing the attribute
140 * plugin. An attribute type may be backed by an attestation, but not
141 * necessarily.
142 * Maybe it would make more sense to refactor this into an attestation
143 * plugin?
144 *
145 * Attestation Conversion to string.
146 */
147 GNUNET_RECLAIM_ATTRIBUTE_ValueToStringFunction value_to_string_attest;
148
149 /**
150 * Attestation Conversion to binary.
151 */
152 GNUNET_RECLAIM_ATTRIBUTE_StringToValueFunction string_to_value_attest;
153
154 /**
155 * Attestation Typename to number.
156 */
157 GNUNET_RECLAIM_ATTRIBUTE_TypenameToNumberFunction typename_to_number_attest;
158
159 /**
160 * Attestation Number to typename.
161 */
162 GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename_attest;
163
137}; 164};
138 165
139 166
diff --git a/src/include/gnunet_reclaim_service.h b/src/include/gnunet_reclaim_service.h
index 237d791d9..214cdba69 100644
--- a/src/include/gnunet_reclaim_service.h
+++ b/src/include/gnunet_reclaim_service.h
@@ -117,7 +117,9 @@ typedef void (*GNUNET_RECLAIM_ContinuationWithStatus) (void *cls,
117 */ 117 */
118typedef void (*GNUNET_RECLAIM_AttributeResult) ( 118typedef void (*GNUNET_RECLAIM_AttributeResult) (
119 void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 119 void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
120 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr); 120 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
121 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
122 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference);
121 123
122 124
123/** 125/**
@@ -152,6 +154,28 @@ GNUNET_RECLAIM_attribute_store (
152 154
153 155
154/** 156/**
157 * Store an attestation. If the attestation is already present,
158 * it is replaced with the new attestation.
159 *
160 * @param h handle to the re:claimID service
161 * @param pkey private key of the identity
162 * @param attr the attestation value
163 * @param exp_interval the relative expiration interval for the attestation
164 * @param cont continuation to call when done
165 * @param cont_cls closure for @a cont
166 * @return handle to abort the request
167 */
168struct GNUNET_RECLAIM_Operation *
169GNUNET_RECLAIM_attestation_store (
170 struct GNUNET_RECLAIM_Handle *h,
171 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
172 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
173 const struct GNUNET_TIME_Relative *exp_interval,
174 GNUNET_RECLAIM_ContinuationWithStatus cont,
175 void *cont_cls);
176
177
178/**
155 * Delete an attribute. Tickets used to share this attribute are updated 179 * Delete an attribute. Tickets used to share this attribute are updated
156 * accordingly. 180 * accordingly.
157 * 181 *
@@ -169,8 +193,44 @@ GNUNET_RECLAIM_attribute_delete (
169 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, 193 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
170 GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls); 194 GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls);
171 195
196/**
197 * Delete an attestation. Tickets used to share this attestation are updated
198 * accordingly.
199 *
200 * @param h handle to the re:claimID service
201 * @param pkey Private key of the identity to add an attribute to
202 * @param attr The attestation
203 * @param cont Continuation to call when done
204 * @param cont_cls Closure for @a cont
205 * @return handle Used to to abort the request
206 */
207struct GNUNET_RECLAIM_Operation *
208GNUNET_RECLAIM_attestation_delete (
209 struct GNUNET_RECLAIM_Handle *h,
210 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
211 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
212 GNUNET_RECLAIM_ContinuationWithStatus cont,
213 void *cont_cls);
172 214
173/** 215/**
216 * Delete an attestation reference. Tickets used to share this reference are updated
217 * accordingly.
218 *
219 * @param h handle to the re:claimID service
220 * @param pkey Private key of the identity to delete the reference from
221 * @param attr The reference
222 * @param cont Continuation to call when done
223 * @param cont_cls Closure for @a cont
224 * @return handle Used to to abort the request
225 */
226struct GNUNET_RECLAIM_Operation *
227GNUNET_RECLAIM_attestation_reference_delete (
228 struct GNUNET_RECLAIM_Handle *h,
229 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
230 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
231 GNUNET_RECLAIM_ContinuationWithStatus cont,
232 void *cont_cls);
233/**
174 * List all attributes for a local identity. 234 * List all attributes for a local identity.
175 * This MUST lock the `struct GNUNET_RECLAIM_Handle` 235 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
176 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and 236 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
@@ -202,6 +262,26 @@ GNUNET_RECLAIM_get_attributes_start (
202 GNUNET_RECLAIM_AttributeResult proc, void *proc_cls, 262 GNUNET_RECLAIM_AttributeResult proc, void *proc_cls,
203 GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls); 263 GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls);
204 264
265/**
266 * Store an attestation reference. If the reference is already present,
267 * it is replaced with the new reference.
268 *
269 * @param h handle to the re:claimID service
270 * @param pkey private key of the identity
271 * @param attr the reference value
272 * @param exp_interval the relative expiration interval for the reference
273 * @param cont continuation to call when done
274 * @param cont_cls closure for @a cont
275 * @return handle to abort the request
276 */
277struct GNUNET_RECLAIM_Operation *
278GNUNET_RECLAIM_attestation_reference_store (
279 struct GNUNET_RECLAIM_Handle *h,
280 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
281 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
282 const struct GNUNET_TIME_Relative *exp_interval,
283 GNUNET_RECLAIM_ContinuationWithStatus cont,
284 void *cont_cls);
205 285
206/** 286/**
207 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start 287 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
diff --git a/src/include/gnunet_util_taler_wallet_lib.h b/src/include/gnunet_util_taler_wallet_lib.h
deleted file mode 100644
index a036824f6..000000000
--- a/src/include/gnunet_util_taler_wallet_lib.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2009, 2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @author Christian Grothoff
23 *
24 * @file
25 * Convenience header including all headers of subsystems in
26 * gnunet_util_taler_wallet library. Note that (due to the structure of the
27 * original headers), not all symbols declared by the included headers are
28 * actually included in the gnunet_util_taler_wallet library! The library
29 * excludes anything relating to the GNUnet installation location, scheduler,
30 * networking or OS-specific logic that would not apply to Apps/Browser
31 * extensions.
32 */
33
34#ifndef GNUNET_UTIL_TALER_WALLET_LIB_H
35#define GNUNET_UTIL_TALER_WALLET_LIB_H
36
37#ifdef __cplusplus
38extern "C"
39{
40#if 0 /* keep Emacsens' auto-indent happy */
41}
42#endif
43#endif
44
45#include "gnunet_crypto_lib.h"
46#include "gnunet_container_lib.h"
47#include "gnunet_strings_lib.h"
48
49#if 0 /* keep Emacsens' auto-indent happy */
50{
51#endif
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c b/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
index bb60909d9..ade2a27bb 100644
--- a/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
+++ b/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
@@ -90,6 +90,63 @@ gnuid_string_to_value (void *cls,
90 } 90 }
91} 91}
92 92
93/**
94 * Convert the 'value' of an attestation to a string.
95 *
96 * @param cls closure, unused
97 * @param type type of the attestation
98 * @param data value in binary encoding
99 * @param data_size number of bytes in @a data
100 * @return NULL on error, otherwise human-readable representation of the value
101 */
102static char *
103gnuid_value_to_string_attest (void *cls,
104 uint32_t type,
105 const void *data,
106 size_t data_size)
107{
108 switch (type)
109 {
110 case GNUNET_RECLAIM_ATTESTATION_TYPE_JWT:
111 return GNUNET_strndup (data, data_size);
112
113 default:
114 return NULL;
115 }
116}
117
118
119/**
120 * Convert human-readable version of a 'value' of an attestation to the binary
121 * representation.
122 *
123 * @param cls closure, unused
124 * @param type type of the attestation
125 * @param s human-readable string
126 * @param data set to value in binary encoding (will be allocated)
127 * @param data_size set to number of bytes in @a data
128 * @return #GNUNET_OK on success
129 */
130static int
131gnuid_string_to_value_attest (void *cls,
132 uint32_t type,
133 const char *s,
134 void **data,
135 size_t *data_size)
136{
137 if (NULL == s)
138 return GNUNET_SYSERR;
139 switch (type)
140 {
141 case GNUNET_RECLAIM_ATTESTATION_TYPE_JWT:
142 *data = GNUNET_strdup (s);
143 *data_size = strlen (s);
144 return GNUNET_OK;
145
146 default:
147 return GNUNET_SYSERR;
148 }
149}
93 150
94/** 151/**
95 * Mapping of attribute type numbers to human-readable 152 * Mapping of attribute type numbers to human-readable
@@ -102,6 +159,16 @@ static struct
102} gnuid_name_map[] = { { "STRING", GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING }, 159} gnuid_name_map[] = { { "STRING", GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING },
103 { NULL, UINT32_MAX } }; 160 { NULL, UINT32_MAX } };
104 161
162/**
163 * Mapping of attestation type numbers to human-readable
164 * attestation type names.
165 */
166static struct
167{
168 const char *name;
169 uint32_t number;
170} gnuid_attest_name_map[] = { { "JWT", GNUNET_RECLAIM_ATTESTATION_TYPE_JWT },
171 { NULL, UINT32_MAX } };
105 172
106/** 173/**
107 * Convert a type name to the corresponding number. 174 * Convert a type name to the corresponding number.
@@ -141,6 +208,44 @@ gnuid_number_to_typename (void *cls, uint32_t type)
141 return gnuid_name_map[i].name; 208 return gnuid_name_map[i].name;
142} 209}
143 210
211/**
212 * Convert a type name to the corresponding number.
213 *
214 * @param cls closure, unused
215 * @param gnuid_typename name to convert
216 * @return corresponding number, UINT32_MAX on error
217 */
218static uint32_t
219gnuid_typename_to_number_attest (void *cls, const char *gnuid_typename)
220{
221 unsigned int i;
222
223 i = 0;
224 while ((NULL != gnuid_attest_name_map[i].name) &&
225 (0 != strcasecmp (gnuid_typename, gnuid_attest_name_map[i].name)))
226 i++;
227 return gnuid_attest_name_map[i].number;
228}
229
230/**
231 * Convert a type number (i.e. 1) to the corresponding type string
232 *
233 * @param cls closure, unused
234 * @param type number of a type to convert
235 * @return corresponding typestring, NULL on error
236 */
237static const char *
238gnuid_number_to_typename_attest (void *cls, uint32_t type)
239{
240 unsigned int i;
241
242 i = 0;
243 while ((NULL != gnuid_attest_name_map[i].name) && (type !=
244 gnuid_attest_name_map[i].
245 number))
246 i++;
247 return gnuid_attest_name_map[i].name;
248}
144 249
145/** 250/**
146 * Entry point for the plugin. 251 * Entry point for the plugin.
@@ -158,6 +263,10 @@ libgnunet_plugin_reclaim_attribute_gnuid_init (void *cls)
158 api->string_to_value = &gnuid_string_to_value; 263 api->string_to_value = &gnuid_string_to_value;
159 api->typename_to_number = &gnuid_typename_to_number; 264 api->typename_to_number = &gnuid_typename_to_number;
160 api->number_to_typename = &gnuid_number_to_typename; 265 api->number_to_typename = &gnuid_number_to_typename;
266 api->value_to_string_attest = &gnuid_value_to_string_attest;
267 api->string_to_value_attest = &gnuid_string_to_value_attest;
268 api->typename_to_number_attest = &gnuid_typename_to_number_attest;
269 api->number_to_typename_attest = &gnuid_number_to_typename_attest;
161 return api; 270 return api;
162} 271}
163 272
diff --git a/src/reclaim-attribute/reclaim_attribute.c b/src/reclaim-attribute/reclaim_attribute.c
index b81394ad2..43199c108 100644
--- a/src/reclaim-attribute/reclaim_attribute.c
+++ b/src/reclaim-attribute/reclaim_attribute.c
@@ -217,6 +217,116 @@ GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
217 return NULL; 217 return NULL;
218} 218}
219 219
220/**
221 * Convert an attestation type name to the corresponding number
222 *
223 * @param typename name to convert
224 * @return corresponding number, UINT32_MAX on error
225 */
226uint32_t
227GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename)
228{
229 unsigned int i;
230 struct Plugin *plugin;
231 uint32_t ret;
232 init ();
233 for (i = 0; i < num_plugins; i++)
234 {
235 plugin = attr_plugins[i];
236 if (UINT32_MAX !=
237 (ret = plugin->api->typename_to_number_attest (plugin->api->cls,
238 typename)))
239 return ret;
240 }
241 return UINT32_MAX;
242}
243
244/**
245 * Convert an attestation type number to the corresponding attestation type string
246 *
247 * @param type number of a type
248 * @return corresponding typestring, NULL on error
249 */
250const char *
251GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type)
252{
253 unsigned int i;
254 struct Plugin *plugin;
255 const char *ret;
256
257 init ();
258 for (i = 0; i < num_plugins; i++)
259 {
260 plugin = attr_plugins[i];
261 if (NULL !=
262 (ret = plugin->api->number_to_typename_attest (plugin->api->cls, type)))
263 return ret;
264 }
265 return NULL;
266}
267/**
268 * Convert human-readable version of a 'claim' of an attestation to the binary
269 * representation
270 *
271 * @param type type of the claim
272 * @param s human-readable string
273 * @param data set to value in binary encoding (will be allocated)
274 * @param data_size set to number of bytes in @a data
275 * @return #GNUNET_OK on success
276 */
277int
278GNUNET_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
279 const char *s,
280 void **data,
281 size_t *data_size)
282{
283 unsigned int i;
284 struct Plugin *plugin;
285
286 init ();
287 for (i = 0; i < num_plugins; i++)
288 {
289 plugin = attr_plugins[i];
290 if (GNUNET_OK == plugin->api->string_to_value_attest (plugin->api->cls,
291 type,
292 s,
293 data,
294 data_size))
295 return GNUNET_OK;
296 }
297 return GNUNET_SYSERR;
298}
299
300
301/**
302 * Convert the 'claim' of an attestation to a string
303 *
304 * @param type the type of attestation
305 * @param data claim in binary encoding
306 * @param data_size number of bytes in @a data
307 * @return NULL on error, otherwise human-readable representation of the claim
308 */
309char *
310GNUNET_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
311 const void *data,
312 size_t data_size)
313{
314 unsigned int i;
315 struct Plugin *plugin;
316 char *ret;
317
318 init ();
319 for (i = 0; i < num_plugins; i++)
320 {
321 plugin = attr_plugins[i];
322 if (NULL != (ret = plugin->api->value_to_string_attest (plugin->api->cls,
323 type,
324 data,
325 data_size)))
326 return ret;
327 }
328 return NULL;
329}
220 330
221/** 331/**
222 * Create a new attribute. 332 * Create a new attribute.
@@ -243,6 +353,42 @@ GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
243 + strlen (attr_name_tmp) + 1 + data_size); 353 + strlen (attr_name_tmp) + 1 + data_size);
244 attr->type = type; 354 attr->type = type;
245 attr->data_size = data_size; 355 attr->data_size = data_size;
356 attr->flag = 0;
357 write_ptr = (char *) &attr[1];
358 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
359 attr->name = write_ptr;
360 write_ptr += strlen (attr->name) + 1;
361 GNUNET_memcpy (write_ptr, data, data_size);
362 attr->data = write_ptr;
363 GNUNET_free (attr_name_tmp);
364 return attr;
365}
366
367/**
368 * Create a new attestation.
369 *
370 * @param attr_name the attestation name
371 * @param type the attestation type
372 * @param data the attestation value
373 * @param data_size the attestation value size
374 * @return the new attestation
375 */
376struct GNUNET_RECLAIM_ATTESTATION_Claim *
377GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
378 uint32_t type,
379 const void *data,
380 size_t data_size)
381{
382 struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
383 char *write_ptr;
384 char *attr_name_tmp = GNUNET_strdup (attr_name);
385
386 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
387
388 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
389 + strlen (attr_name_tmp) + 1 + data_size);
390 attr->type = type;
391 attr->data_size = data_size;
246 attr->version = 0; 392 attr->version = 0;
247 write_ptr = (char *) &attr[1]; 393 write_ptr = (char *) &attr[1];
248 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1); 394 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
@@ -254,6 +400,40 @@ GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
254 return attr; 400 return attr;
255} 401}
256 402
403/**
404 * Create a new attestation reference.
405 *
406 * @param attr_name the referenced claim name
407 * @param ref_value the claim name in the attestation
408 * @return the new reference
409 */
410struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
411GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
412 const char *ref_value)
413{
414 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
415 char *write_ptr;
416 char *attr_name_tmp = GNUNET_strdup (attr_name);
417 char *ref_value_tmp = GNUNET_strdup (ref_value);
418
419 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
420 GNUNET_STRINGS_utf8_tolower (ref_value, ref_value_tmp);
421
422 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE)
423 + strlen (attr_name_tmp) + strlen (ref_value_tmp) + 2);
424
425 write_ptr = (char *) &attr[1];
426 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
427 attr->name = write_ptr;
428
429 write_ptr += strlen (attr_name) + 1;
430 GNUNET_memcpy (write_ptr, ref_value_tmp, strlen (ref_value_tmp) + 1);
431 attr->reference_value = write_ptr;
432
433 GNUNET_free (attr_name_tmp);
434 GNUNET_free (ref_value_tmp);
435 return attr;
436}
257 437
258/** 438/**
259 * Add a new attribute to a claim list 439 * Add a new attribute to a claim list
@@ -296,7 +476,30 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (
296 size_t len = 0; 476 size_t len = 0;
297 477
298 for (le = attrs->list_head; NULL != le; le = le->next) 478 for (le = attrs->list_head; NULL != le; le = le->next)
299 len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim); 479 {
480 if (NULL != le->claim)
481 {
482 len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
483 len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
484 }
485 else if (NULL != le->attest )
486 {
487 len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
488 len += GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest);
489 }
490 else if (NULL != le->reference)
491 {
492 len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
493 len += GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (le->reference);
494 }
495 else
496 {
497 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
498 "Unserialized Claim List Entry Type for size not known.\n");
499 break;
500 }
501 len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
502 }
300 return len; 503 return len;
301} 504}
302 505
@@ -317,14 +520,50 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
317 size_t len; 520 size_t len;
318 size_t total_len; 521 size_t total_len;
319 char *write_ptr; 522 char *write_ptr;
320
321 write_ptr = result; 523 write_ptr = result;
322 total_len = 0; 524 total_len = 0;
323 for (le = attrs->list_head; NULL != le; le = le->next) 525 for (le = attrs->list_head; NULL != le; le = le->next)
324 { 526 {
325 len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr); 527 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type;
326 total_len += len; 528 if (NULL != le->claim)
327 write_ptr += len; 529 {
530 list_type = (struct
531 GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
532 list_type->type = htons (1);
533 total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
534 write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
535 len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr);
536 total_len += len;
537 write_ptr += len;
538 }
539 else if (NULL != le->attest )
540 {
541 list_type = (struct
542 GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
543 list_type->type = htons (2);
544 total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
545 write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
546 len = GNUNET_RECLAIM_ATTESTATION_serialize (le->attest, write_ptr);
547 total_len += len;
548 write_ptr += len;
549 }
550 else if (NULL != le->reference)
551 {
552 list_type = (struct
553 GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
554 list_type->type = htons (3);
555 total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
556 write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
557 len = GNUNET_RECLAIM_ATTESTATION_REF_serialize (le->reference, write_ptr);
558 total_len += len;
559 write_ptr += len;
560 }
561 else
562 {
563 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
564 "Unserialized Claim List Entry Type not known.\n");
565 continue;
566 }
328 } 567 }
329 return total_len; 568 return total_len;
330} 569}
@@ -345,23 +584,75 @@ GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size)
345 size_t attr_len; 584 size_t attr_len;
346 const char *read_ptr; 585 const char *read_ptr;
347 586
348 if (data_size < sizeof(struct Attribute)) 587 if ((data_size < sizeof(struct Attribute) + sizeof(struct
588 GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry))
589 && (data_size < sizeof(struct
590 Attestation)
591 + sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) &&
592 (data_size < sizeof(struct Attestation_Reference) + sizeof(struct
593 GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) )
349 return NULL; 594 return NULL;
350 595
351 attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); 596 attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
352 read_ptr = data; 597 read_ptr = data;
353 while (((data + data_size) - read_ptr) >= sizeof(struct Attribute)) 598 while (((data + data_size) - read_ptr) >= sizeof(struct Attribute))
354 { 599 {
355 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); 600 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type;
356 le->claim = 601 list_type = (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) read_ptr;
357 GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr, 602 if (1 == ntohs (list_type->type))
358 data_size - (read_ptr - data)); 603 {
359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 604 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
360 "Deserialized attribute %s\n", 605 read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
361 le->claim->name); 606 if (((data + data_size) - read_ptr) < sizeof(struct Attribute))
362 GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le); 607 break;
363 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim); 608 le->attest = NULL;
364 read_ptr += attr_len; 609 le->reference = NULL;
610 le->claim =
611 GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
612 data_size - (read_ptr - data));
613 GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
614 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
615 read_ptr += attr_len;
616 }
617 else if (2 == ntohs (list_type->type))
618 {
619 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
620 read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
621 if (((data + data_size) - read_ptr) < sizeof(struct Attestation))
622 break;
623 le->claim = NULL;
624 le->reference = NULL;
625 le->attest =
626 GNUNET_RECLAIM_ATTESTATION_deserialize (read_ptr,
627 data_size - (read_ptr - data));
628 GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
629 attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest);
630 read_ptr += attr_len;
631 }
632 else if (3 == ntohs (list_type->type))
633 {
634 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
635 read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
636 if (((data + data_size) - read_ptr) < sizeof(struct
637 Attestation_Reference))
638 break;
639 le->claim = NULL;
640 le->attest = NULL;
641 le->reference =
642 GNUNET_RECLAIM_ATTESTATION_REF_deserialize (read_ptr,
643 data_size - (read_ptr
644 - data));
645 GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
646 attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
647 le->reference);
648 read_ptr += attr_len;
649 }
650 else
651 {
652 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
653 "Serialized Claim List Entry Type not known.\n");
654 break;
655 }
365 } 656 }
366 return attrs; 657 return attrs;
367} 658}
@@ -381,16 +672,45 @@ GNUNET_RECLAIM_ATTRIBUTE_list_dup (
381 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result; 672 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result;
382 673
383 result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); 674 result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
675 if (NULL == attrs->list_head)
676 {
677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Duplicating empty List\n");
678 }
384 for (le = attrs->list_head; NULL != le; le = le->next) 679 for (le = attrs->list_head; NULL != le; le = le->next)
385 { 680 {
386 result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); 681 result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
387 result_le->claim = 682 result_le->claim = NULL;
388 GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name, 683 result_le->attest = NULL;
389 le->claim->type, 684 result_le->reference = NULL;
390 le->claim->data, 685 if (NULL != le->claim)
391 le->claim->data_size); 686 {
392 result_le->claim->version = le->claim->version; 687 result_le->claim =
393 result_le->claim->id = le->claim->id; 688 GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
689 le->claim->type,
690 le->claim->data,
691 le->claim->data_size);
692
693 result_le->claim->id = le->claim->id;
694 result_le->claim->flag = le->claim->flag;
695 }
696 if ( NULL != le->attest)
697 {
698 result_le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (
699 le->attest->name,
700 le->attest->type,
701 le->attest->data,
702 le->attest->
703 data_size);
704 result_le->attest->id = le->attest->id;
705 }
706 if (NULL !=le->reference)
707 {
708 result_le->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (
709 le->reference->name,
710 le->reference->reference_value);
711 result_le->reference->id = le->reference->id;
712 result_le->reference->id_attest = le->reference->id_attest;
713 }
394 GNUNET_CONTAINER_DLL_insert (result->list_head, 714 GNUNET_CONTAINER_DLL_insert (result->list_head,
395 result->list_tail, 715 result->list_tail,
396 result_le); 716 result_le);
@@ -411,9 +731,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
411 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; 731 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
412 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le; 732 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le;
413 733
414 for (le = attrs->list_head; NULL != le;) 734 for (le = attrs->list_head; NULL != le; le = le->next)
415 { 735 {
416 GNUNET_free (le->claim); 736 if (NULL != le->claim)
737 GNUNET_free (le->claim);
738 if (NULL != le->attest)
739 GNUNET_free (le->attest);
740 if (NULL != le->reference)
741 GNUNET_free (le->reference);
417 tmp_le = le; 742 tmp_le = le;
418 le = le->next; 743 le = le->next;
419 GNUNET_free (tmp_le); 744 GNUNET_free (tmp_le);
@@ -421,7 +746,24 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
421 GNUNET_free (attrs); 746 GNUNET_free (attrs);
422} 747}
423 748
424 749/**
750 * Count attestations in claim list
751 *
752 * @param attrs list
753 */
754int
755GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (
756 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
757{
758 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
759 int i = 0;
760 for (le = attrs->list_head; NULL != le; le = le->next)
761 {
762 if (NULL != le->attest)
763 i++;
764 }
765 return i;
766}
425/** 767/**
426 * Get required size for serialization buffer 768 * Get required size for serialization buffer
427 * 769 *
@@ -455,7 +797,7 @@ GNUNET_RECLAIM_ATTRIBUTE_serialize (
455 797
456 attr_ser = (struct Attribute *) result; 798 attr_ser = (struct Attribute *) result;
457 attr_ser->attribute_type = htons (attr->type); 799 attr_ser->attribute_type = htons (attr->type);
458 attr_ser->attribute_version = htonl (attr->version); 800 attr_ser->attribute_version = htonl (attr->flag);
459 attr_ser->attribute_id = GNUNET_htonll (attr->id); 801 attr_ser->attribute_id = GNUNET_htonll (attr->id);
460 name_len = strlen (attr->name); 802 name_len = strlen (attr->name);
461 attr_ser->name_len = htons (name_len); 803 attr_ser->name_len = htons (name_len);
@@ -505,7 +847,7 @@ GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, size_t data_size)
505 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim) 847 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim)
506 + data_len + name_len + 1); 848 + data_len + name_len + 1);
507 attr->type = ntohs (attr_ser->attribute_type); 849 attr->type = ntohs (attr_ser->attribute_type);
508 attr->version = ntohl (attr_ser->attribute_version); 850 attr->flag = ntohl (attr_ser->attribute_version);
509 attr->id = GNUNET_ntohll (attr_ser->attribute_id); 851 attr->id = GNUNET_ntohll (attr_ser->attribute_id);
510 attr->data_size = data_len; 852 attr->data_size = data_len;
511 853
@@ -521,4 +863,193 @@ GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, size_t data_size)
521} 863}
522 864
523 865
866/**
867 * Get required size for serialization buffer
868 *
869 * @param attr the attestation to serialize
870 * @return the required buffer size
871 */
872size_t
873GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
874 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr)
875{
876 return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
877}
878
879/**
880 * Serialize an attestation
881 *
882 * @param attr the attestation to serialize
883 * @param result the serialized attestation
884 * @return length of serialized data
885 */
886size_t
887GNUNET_RECLAIM_ATTESTATION_serialize (
888 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
889 char *result)
890{
891 size_t data_len_ser;
892 size_t name_len;
893 struct Attestation *attr_ser;
894 char *write_ptr;
895
896 attr_ser = (struct Attestation *) result;
897 attr_ser->attestation_type = htons (attr->type);
898 attr_ser->attestation_version = htonl (attr->version);
899 attr_ser->attestation_id = GNUNET_htonll (attr->id);
900 name_len = strlen (attr->name);
901 attr_ser->name_len = htons (name_len);
902 write_ptr = (char *) &attr_ser[1];
903 GNUNET_memcpy (write_ptr, attr->name, name_len);
904 write_ptr += name_len;
905 // TODO plugin-ize
906 // data_len_ser = plugin->serialize_attribute_value (attr,
907 // &attr_ser[1]);
908 data_len_ser = attr->data_size;
909 GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
910 attr_ser->data_size = htons (data_len_ser);
911
912 return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
913}
914
915/**
916 * Deserialize an attestation
917 *
918 * @param data the serialized attestation
919 * @param data_size the length of the serialized data
920 *
921 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
922 */
923struct GNUNET_RECLAIM_ATTESTATION_Claim *
924GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size)
925{
926 struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
927 struct Attestation *attr_ser;
928 size_t data_len;
929 size_t name_len;
930 char *write_ptr;
931
932 if (data_size < sizeof(struct Attestation))
933 return NULL;
934
935 attr_ser = (struct Attestation *) data;
936 data_len = ntohs (attr_ser->data_size);
937 name_len = ntohs (attr_ser->name_len);
938 if (data_size < sizeof(struct Attestation) + data_len + name_len)
939 {
940 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
941 "Buffer too small to deserialize\n");
942 return NULL;
943 }
944 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
945 + data_len + name_len + 1);
946 attr->type = ntohs (attr_ser->attestation_type);
947 attr->version = ntohl (attr_ser->attestation_version);
948 attr->id = GNUNET_ntohll (attr_ser->attestation_id);
949 attr->data_size = data_len;
950
951 write_ptr = (char *) &attr[1];
952 GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
953 write_ptr[name_len] = '\0';
954 attr->name = write_ptr;
955
956 write_ptr += name_len + 1;
957 GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, attr->data_size);
958 attr->data = write_ptr;
959 return attr;
960}
961
962/**
963 * Get required size for serialization buffer
964 *
965 * @param attr the reference to serialize
966 * @return the required buffer size
967 */
968size_t
969GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
970 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr)
971{
972 return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
973 attr->reference_value);
974}
975
976
977/**
978 * Serialize a reference
979 *
980 * @param attr the reference to serialize
981 * @param result the serialized reference
982 * @return length of serialized data
983 */
984size_t
985GNUNET_RECLAIM_ATTESTATION_REF_serialize (
986 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
987 char *result)
988{
989 size_t name_len;
990 size_t refval_len;
991 struct Attestation_Reference *attr_ser;
992 char *write_ptr;
993 attr_ser = (struct Attestation_Reference *) result;
994 attr_ser->reference_id = GNUNET_htonll (attr->id);
995 attr_ser->attestation_id = GNUNET_htonll (attr->id_attest);
996 name_len = strlen (attr->name);
997 refval_len = strlen (attr->reference_value);
998 attr_ser->name_len = htons (name_len);
999 attr_ser->ref_value_len = htons (refval_len);
1000 write_ptr = (char *) &attr_ser[1];
1001 GNUNET_memcpy (write_ptr, attr->name, name_len);
1002 write_ptr += name_len;
1003 GNUNET_memcpy (write_ptr, attr->reference_value, refval_len);
1004
1005 return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
1006 attr->reference_value);
1007}
1008
1009
1010/**
1011 * Deserialize a reference
1012 *
1013 * @param data the serialized reference
1014 * @param data_size the length of the serialized data
1015 *
1016 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
1017 */
1018struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
1019GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t data_size)
1020{
1021 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
1022 struct Attestation_Reference *attr_ser;
1023 size_t name_len;
1024 size_t refval_len;
1025 char *write_ptr;
1026
1027 if (data_size < sizeof(struct Attestation_Reference))
1028 return NULL;
1029 attr_ser = (struct Attestation_Reference *) data;
1030 name_len = ntohs (attr_ser->name_len);
1031 refval_len = ntohs (attr_ser->ref_value_len);
1032 if (data_size < sizeof(struct Attestation_Reference) + refval_len + name_len)
1033 {
1034 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1035 "Buffer too small to deserialize\n");
1036 return NULL;
1037 }
1038 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE)
1039 + refval_len + name_len + 2);
1040
1041 attr->id = GNUNET_ntohll (attr_ser->reference_id);
1042 attr->id_attest = GNUNET_ntohll (attr_ser->attestation_id);
1043
1044 write_ptr = (char *) &attr[1];
1045 GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
1046 write_ptr[name_len] = '\0';
1047 attr->name = write_ptr;
1048
1049 write_ptr += name_len + 1;
1050 GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, refval_len);
1051 write_ptr[refval_len] = '\0';
1052 attr->reference_value = write_ptr;
1053 return attr;
1054}
524/* end of reclaim_attribute.c */ 1055/* end of reclaim_attribute.c */
diff --git a/src/reclaim-attribute/reclaim_attribute.h b/src/reclaim-attribute/reclaim_attribute.h
index d7358847e..80f1e5aac 100644
--- a/src/reclaim-attribute/reclaim_attribute.h
+++ b/src/reclaim-attribute/reclaim_attribute.h
@@ -61,4 +61,66 @@ struct Attribute
61 // followed by data_size Attribute value data 61 // followed by data_size Attribute value data
62}; 62};
63 63
64/**
65 * Serialized attestation claim
66 */
67struct Attestation
68{
69 /**
70 * Attestation type
71 */
72 uint32_t attestation_type;
73
74 /**
75 * Attestation version
76 */
77 uint32_t attestation_version;
78
79 /**
80 * Attestation ID
81 */
82 uint64_t attestation_id;
83
84 /**
85 * Name length
86 */
87 uint32_t name_len;
88
89 /**
90 * Data size
91 */
92 uint32_t data_size;
93
94 // followed by data_size Attestation value data
95};
96
97/**
98 * Serialized attestation reference
99 */
100struct Attestation_Reference
101{
102 /**
103 * Reference ID
104 */
105 uint64_t reference_id;
106
107 /**
108 * The ID of the referenced attestation
109 */
110 uint64_t attestation_id;
111
112 /**
113 * Claim Name length
114 */
115 uint32_t name_len;
116
117 /**
118 * Length of the referenced value
119 */
120 uint32_t ref_value_len;
121
122
123 // followed by the name and referenced value
124};
125
64#endif 126#endif
diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c
index 58f8cd6e2..5f9170f05 100644
--- a/src/reclaim/gnunet-reclaim.c
+++ b/src/reclaim/gnunet-reclaim.c
@@ -226,7 +226,9 @@ store_attr_cont (void *cls, int32_t success, const char *emsg)
226static void 226static void
227process_attrs (void *cls, 227process_attrs (void *cls,
228 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 228 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
229 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 229 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
230 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
231 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
230{ 232{
231 char *value_str; 233 char *value_str;
232 char *id; 234 char *id;
@@ -253,7 +255,7 @@ process_attrs (void *cls,
253 attr->name, 255 attr->name,
254 value_str, 256 value_str,
255 attr_type, 257 attr_type,
256 attr->version, 258 attr->flag,
257 id); 259 id);
258 GNUNET_free (id); 260 GNUNET_free (id);
259} 261}
@@ -445,7 +447,9 @@ iter_finished (void *cls)
445static void 447static void
446iter_cb (void *cls, 448iter_cb (void *cls,
447 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 449 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
448 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 450 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
451 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
452 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
449{ 453{
450 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; 454 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
451 char *attrs_tmp; 455 char *attrs_tmp;
@@ -480,7 +484,7 @@ iter_cb (void *cls,
480 attr->type, 484 attr->type,
481 attr->data, 485 attr->data,
482 attr->data_size); 486 attr->data_size);
483 le->claim->version = attr->version; 487 le->claim->flag = attr->flag;
484 le->claim->id = attr->id; 488 le->claim->id = attr->id;
485 GNUNET_CONTAINER_DLL_insert (attr_list->list_head, 489 GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
486 attr_list->list_tail, 490 attr_list->list_tail,
@@ -514,7 +518,7 @@ iter_cb (void *cls,
514 attr->name, 518 attr->name,
515 attr_str, 519 attr_str,
516 attr_type, 520 attr_type,
517 attr->version, 521 attr->flag,
518 id); 522 id);
519 GNUNET_free (id); 523 GNUNET_free (id);
520 } 524 }
diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c
index a83ea05a6..556006af0 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -266,6 +266,15 @@ struct AttributeDeleteHandle
266 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; 266 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
267 267
268 /** 268 /**
269 * The attestation to delete
270 */
271 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
272
273 /**
274 * The reference to delete
275 */
276 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
277 /**
269 * Tickets to update 278 * Tickets to update
270 */ 279 */
271 struct TicketRecordsEntry *tickets_to_update_head; 280 struct TicketRecordsEntry *tickets_to_update_head;
@@ -328,6 +337,16 @@ struct AttributeStoreHandle
328 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; 337 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
329 338
330 /** 339 /**
340 * The attestation to store
341 */
342 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
343
344 /**
345 * The reference to store
346 */
347 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
348
349 /**
331 * The attribute expiration interval 350 * The attribute expiration interval
332 */ 351 */
333 struct GNUNET_TIME_Relative exp; 352 struct GNUNET_TIME_Relative exp;
@@ -459,6 +478,10 @@ cleanup_adh (struct AttributeDeleteHandle *adh)
459 GNUNET_free (adh->label); 478 GNUNET_free (adh->label);
460 if (NULL != adh->claim) 479 if (NULL != adh->claim)
461 GNUNET_free (adh->claim); 480 GNUNET_free (adh->claim);
481 if (NULL != adh->attest)
482 GNUNET_free (adh->attest);
483 if (NULL != adh->reference)
484 GNUNET_free (adh->reference);
462 while (NULL != (le = adh->tickets_to_update_head)) 485 while (NULL != (le = adh->tickets_to_update_head))
463 { 486 {
464 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head, 487 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
@@ -486,6 +509,10 @@ cleanup_as_handle (struct AttributeStoreHandle *ash)
486 GNUNET_NAMESTORE_cancel (ash->ns_qe); 509 GNUNET_NAMESTORE_cancel (ash->ns_qe);
487 if (NULL != ash->claim) 510 if (NULL != ash->claim)
488 GNUNET_free (ash->claim); 511 GNUNET_free (ash->claim);
512 if (NULL != ash->attest)
513 GNUNET_free (ash->attest);
514 if (NULL != ash->reference)
515 GNUNET_free (ash->reference);
489 GNUNET_free (ash); 516 GNUNET_free (ash);
490} 517}
491 518
@@ -1023,6 +1050,478 @@ handle_attribute_store_message (void *cls,
1023 1050
1024 1051
1025/** 1052/**
1053 * Attestation store result handler
1054 *
1055 * @param cls our attribute store handle
1056 * @param success GNUNET_OK if successful
1057 * @param emsg error message (NULL if success=GNUNET_OK)
1058 */
1059static void
1060attest_store_cont (void *cls, int32_t success, const char *emsg)
1061{
1062 struct AttributeStoreHandle *ash = cls;
1063 struct GNUNET_MQ_Envelope *env;
1064 struct SuccessResultMessage *acr_msg;
1065
1066 ash->ns_qe = NULL;
1067 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1068 ash->client->store_op_tail,
1069 ash);
1070
1071 if (GNUNET_SYSERR == success)
1072 {
1073 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1074 "Failed to store attestation %s\n",
1075 emsg);
1076 cleanup_as_handle (ash);
1077 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1078 return;
1079 }
1080
1081 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1082 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1083 acr_msg->id = htonl (ash->r_id);
1084 acr_msg->op_result = htonl (GNUNET_OK);
1085 GNUNET_MQ_send (ash->client->mq, env);
1086 cleanup_as_handle (ash);
1087}
1088
1089/**
1090 * Send a reference error response
1091 *
1092 * @param ash our attribute store handle
1093 * @param success the success status
1094 */
1095static void
1096send_ref_error (struct AttributeStoreHandle *ash)
1097{
1098 struct GNUNET_MQ_Envelope *env;
1099 struct SuccessResultMessage *acr_msg;
1100
1101 ash->ns_qe = NULL;
1102 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1103 ash->client->store_op_tail,
1104 ash);
1105
1106 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1107 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1108 acr_msg->id = htonl (ash->r_id);
1109 acr_msg->op_result = htonl (GNUNET_SYSERR);
1110 GNUNET_MQ_send (ash->client->mq, env);
1111 cleanup_as_handle (ash);
1112}
1113
1114/**
1115 * Error looking up potential attestation. Abort.
1116 *
1117 * @param cls our attribute store handle
1118 */
1119static void
1120attest_error (void *cls)
1121{
1122 struct AttributeStoreHandle *ash = cls;
1123 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1124 "Failed to check for existing Attestation\n");
1125 cleanup_as_handle (ash);
1126 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1127 return;
1128}
1129
1130/**
1131* Check for existing record before storing reference
1132*
1133* @param cls our attribute store handle
1134* @param zone zone we are iterating
1135* @param label label of the records
1136* @param rd_count record count
1137* @param rd records
1138*/
1139static void
1140attest_add_cb (void *cls,
1141 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1142 const char *label,
1143 unsigned int rd_count,
1144 const struct GNUNET_GNSRECORD_Data *rd)
1145{
1146 struct AttributeStoreHandle *ash = cls;
1147 char *buf;
1148 size_t buf_size;
1149 buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
1150 buf = GNUNET_malloc (buf_size);
1151 GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
1152 if (0 == rd_count )
1153 {
1154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1155 "Storing new Attestation\n");
1156 struct GNUNET_GNSRECORD_Data rd_new[1];
1157 rd_new[0].data_size = buf_size;
1158 rd_new[0].data = buf;
1159 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
1160 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1161 rd_new[0].expiration_time = ash->exp.rel_value_us;
1162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1163 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1164 &ash->identity,
1165 label,
1166 1,
1167 rd_new,
1168 &attest_store_cont,
1169 ash);
1170 GNUNET_free (buf);
1171 return;
1172 }
1173 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1174 {
1175 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1176 "Existing Attestation location is not an Attestation\n");
1177 send_ref_error (ash);
1178 return;
1179 }
1180 struct GNUNET_GNSRECORD_Data rd_new[rd_count];
1181 for (int i = 0; i<rd_count; i++)
1182 {
1183 rd_new[i] = rd[i];
1184 }
1185 rd_new[0].data_size = buf_size;
1186 rd_new[0].data = buf;
1187 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
1188 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1189 rd_new[0].expiration_time = ash->exp.rel_value_us;
1190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1191 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1192 &ash->identity,
1193 label,
1194 rd_count,
1195 rd_new,
1196 &attest_store_cont,
1197 ash);
1198 GNUNET_free (buf);
1199}
1200
1201/**
1202 * Add a new attestation
1203 *
1204 * @param cls the AttributeStoreHandle
1205 */
1206static void
1207attest_store_task (void *cls)
1208{
1209 struct AttributeStoreHandle *ash = cls;
1210 char *label;
1211
1212 // Give the ash a new id if unset
1213 if (0 == ash->attest->id)
1214 ash->attest->id
1215 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
1216 label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
1217 sizeof(uint64_t));
1218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1219 "Looking up existing data under label %s\n", label);
1220// Test for the content of the existing ID
1221 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1222 &ash->identity,
1223 label,
1224 &attest_error,
1225 ash,
1226 &attest_add_cb,
1227 ash);
1228 GNUNET_free (label);
1229}
1230
1231/**
1232 * Check an attestation store message
1233 *
1234 * @param cls unused
1235 * @param sam the message to check
1236 */
1237static int
1238check_attestation_store_message (void *cls,
1239 const struct AttributeStoreMessage *sam)
1240{
1241 uint16_t size;
1242
1243 size = ntohs (sam->header.size);
1244 if (size <= sizeof(struct AttributeStoreMessage))
1245 {
1246 GNUNET_break (0);
1247 return GNUNET_SYSERR;
1248 }
1249 return GNUNET_OK;
1250}
1251
1252/**
1253* Handle an attestation store message
1254*
1255* @param cls our client
1256* @param sam the message to handle
1257*/
1258static void
1259handle_attestation_store_message (void *cls,
1260 const struct AttributeStoreMessage *sam)
1261{
1262 struct AttributeStoreHandle *ash;
1263 struct IdpClient *idp = cls;
1264 size_t data_len;
1265
1266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
1267
1268 data_len = ntohs (sam->attr_len);
1269
1270 ash = GNUNET_new (struct AttributeStoreHandle);
1271 ash->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &sam[1],
1272 data_len);
1273
1274 ash->r_id = ntohl (sam->id);
1275 ash->identity = sam->identity;
1276 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1277 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1278
1279 GNUNET_SERVICE_client_continue (idp->client);
1280 ash->client = idp;
1281 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1282 GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
1283}
1284
1285/**
1286 * Error looking up potential reference value. Abort.
1287 *
1288 * @param cls our attribute store handle
1289 */
1290static void
1291ref_error (void *cls)
1292{
1293 struct AttributeStoreHandle *ash = cls;
1294 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1295 "Failed to find Attestation entry for Attestation reference\n");
1296 cleanup_as_handle (ash);
1297 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1298 return;
1299}
1300
1301/**
1302 * Error looking up potential reference value. Abort.
1303 *
1304 * @param cls our attribute delete handle
1305 */
1306static void
1307ref_del_error (void *cls)
1308{
1309 struct AttributeDeleteHandle *adh = cls;
1310 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1311 "Failed to find Attestation entry for Attestation reference\n");
1312 cleanup_adh (adh);
1313 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1314 return;
1315}
1316/**
1317* Reference store result handler
1318*
1319* @param cls our attribute store handle
1320* @param success GNUNET_OK if successful
1321* @param emsg error message (NULL if success=GNUNET_OK)
1322*/
1323static void
1324reference_store_cont (void *cls, int32_t success, const char *emsg)
1325{
1326 struct AttributeStoreHandle *ash = cls;
1327 struct GNUNET_MQ_Envelope *env;
1328 struct SuccessResultMessage *acr_msg;
1329
1330 ash->ns_qe = NULL;
1331 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1332 ash->client->store_op_tail,
1333 ash);
1334
1335 if (GNUNET_SYSERR == success)
1336 {
1337 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1338 "Failed to store reference %s\n",
1339 emsg);
1340 cleanup_as_handle (ash);
1341 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1342 return;
1343 }
1344
1345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1346 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1347 acr_msg->id = htonl (ash->r_id);
1348 acr_msg->op_result = htonl (GNUNET_OK);
1349 GNUNET_MQ_send (ash->client->mq, env);
1350 cleanup_as_handle (ash);
1351}
1352
1353
1354/**
1355* Check for existing record before storing reference
1356*
1357* @param cls our attribute store handle
1358* @param zone zone we are iterating
1359* @param label label of the records
1360* @param rd_count record count
1361* @param rd records
1362*/
1363static void
1364ref_add_cb (void *cls,
1365 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1366 const char *label,
1367 unsigned int rd_count,
1368 const struct GNUNET_GNSRECORD_Data *rd)
1369{
1370 struct AttributeStoreHandle *ash = cls;
1371 char *buf;
1372 size_t buf_size;
1373 buf_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (ash->reference);
1374 buf = GNUNET_malloc (buf_size);
1375 GNUNET_RECLAIM_ATTESTATION_REF_serialize (ash->reference, buf);
1376 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
1377 char *data_tmp;
1378 if (0 == rd_count )
1379 {
1380 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1381 "Failed to find Attestation entry for Attestation reference\n");
1382 send_ref_error (ash);
1383 return;
1384 }
1385 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1386 {
1387 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1388 "Intended Reference storage location is not an attestation\n");
1389 send_ref_error (ash);
1390 return;
1391 }
1392 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
1393 int i;
1394 for (i = 0; i<rd_count; i++)
1395 {
1396 data_tmp = GNUNET_malloc (rd[i].data_size);
1397 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
1398 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, htons (
1399 rd[i].data_size));
1400 rd_new[i] = rd[i];
1401 if ((strcmp (ash->reference->name,ref->name) == 0)&&
1402 (strcmp (ash->reference->reference_value,ref->reference_value)==0) )
1403 {
1404 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1405 "Reference already stored\n");
1406 reference_store_cont (ash,GNUNET_OK, NULL);
1407 return;
1408 }
1409 }
1410 rd_new[rd_count].data_size = buf_size;
1411 rd_new[rd_count].data = buf;
1412 rd_new[rd_count].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE;
1413 rd_new[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1414 rd_new[rd_count].expiration_time = ash->exp.rel_value_us;
1415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1416 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1417 &ash->identity,
1418 label,
1419 rd_count + 1,
1420 rd_new,
1421 &reference_store_cont,
1422 ash);
1423 GNUNET_free (buf);
1424}
1425
1426/**
1427 * Add a new reference
1428 *
1429 * @param cls the AttributeStoreHandle
1430 */
1431static void
1432reference_store_task (void *cls)
1433{
1434 struct AttributeStoreHandle *ash = cls;
1435 char *label;
1436
1437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing reference\n");
1438
1439 // Give the ash a new id if unset
1440 if (0 == ash->reference->id)
1441 {
1442 if (0 == ash->reference->id_attest)
1443 {
1444 ash->reference->id = GNUNET_CRYPTO_random_u64 (
1445 GNUNET_CRYPTO_QUALITY_STRONG,
1446 UINT64_MAX);
1447 }
1448 else
1449 {
1450 ash->reference->id = ash->reference->id_attest;
1451 }
1452 }
1453
1454 label = GNUNET_STRINGS_data_to_string_alloc (&ash->reference->id,
1455 sizeof(uint64_t));
1456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1457 "Looking up existing data under label %s\n", label);
1458// Test for the content of the existing ID
1459
1460 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1461 &ash->identity,
1462 label,
1463 &ref_error,
1464 ash,
1465 &ref_add_cb,
1466 ash);
1467 GNUNET_free (label);
1468}
1469
1470/**
1471 * Check an attestation reference store message
1472 *
1473 * @param cls unused
1474 * @param sam the message to check
1475 */
1476static int
1477check_reference_store_message (void *cls,
1478 const struct
1479 AttributeStoreMessage *sam)
1480{
1481 uint16_t size;
1482
1483 size = ntohs (sam->header.size);
1484 if (size <= sizeof(struct AttributeStoreMessage))
1485 {
1486 GNUNET_break (0);
1487 return GNUNET_SYSERR;
1488 }
1489 return GNUNET_OK;
1490}
1491
1492
1493/**
1494 * Handle an attestation reference store message
1495 *
1496 * @param cls our client
1497 * @param sam the message to handle
1498 */
1499static void
1500handle_reference_store_message (void *cls,
1501 const struct AttributeStoreMessage *sam)
1502{
1503 struct AttributeStoreHandle *ash;
1504 struct IdpClient *idp = cls;
1505 size_t data_len;
1506
1507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_STORE message\n");
1508
1509 data_len = ntohs (sam->attr_len);
1510 ash = GNUNET_new (struct AttributeStoreHandle);
1511 ash->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &sam[1],
1512 data_len);
1513 ash->r_id = ntohl (sam->id);
1514 ash->identity = sam->identity;
1515 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1516 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1517
1518
1519 GNUNET_SERVICE_client_continue (idp->client);
1520 ash->client = idp;
1521 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1522 GNUNET_SCHEDULER_add_now (&reference_store_task, ash);
1523}
1524/**
1026 * Send a deletion success response 1525 * Send a deletion success response
1027 * 1526 *
1028 * @param adh our attribute deletion handle 1527 * @param adh our attribute deletion handle
@@ -1066,15 +1565,21 @@ ticket_iter (void *cls,
1066 struct AttributeDeleteHandle *adh = cls; 1565 struct AttributeDeleteHandle *adh = cls;
1067 struct TicketRecordsEntry *le; 1566 struct TicketRecordsEntry *le;
1068 int has_changed = GNUNET_NO; 1567 int has_changed = GNUNET_NO;
1069
1070 for (int i = 0; i < rd_count; i++) 1568 for (int i = 0; i < rd_count; i++)
1071 { 1569 {
1072 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) 1570 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
1073 continue; 1571 continue;
1074 if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))) 1572 if (adh->claim != NULL)
1075 continue; 1573 if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
1574 continue;
1575 if (adh->attest != NULL)
1576 if (0 != memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t)))
1577 continue;
1578 if (adh->reference != NULL)
1579 if (0 != memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t)))
1580 continue;
1076 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1581 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1077 "Attribute to delete found (%s)\n", 1582 "Attribute or Attestation/Reference to delete found (%s)\n",
1078 adh->label); 1583 adh->label);
1079 has_changed = GNUNET_YES; 1584 has_changed = GNUNET_YES;
1080 break; 1585 break;
@@ -1136,7 +1641,7 @@ update_tickets (void *cls)
1136 if (NULL == adh->tickets_to_update_head) 1641 if (NULL == adh->tickets_to_update_head)
1137 { 1642 {
1138 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1643 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1139 "Finished updatding tickets, success\n"); 1644 "Finished updating tickets, success\n");
1140 send_delete_response (adh, GNUNET_OK); 1645 send_delete_response (adh, GNUNET_OK);
1141 cleanup_adh (adh); 1646 cleanup_adh (adh);
1142 return; 1647 return;
@@ -1164,9 +1669,18 @@ update_tickets (void *cls)
1164 int j = 0; 1669 int j = 0;
1165 for (int i = 0; i < le->rd_count; i++) 1670 for (int i = 0; i < le->rd_count; i++)
1166 { 1671 {
1167 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) 1672 if (adh->claim != NULL)
1168 && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))) 1673 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1169 continue; 1674 && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))))
1675 continue;
1676 if (adh->attest != NULL)
1677 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1678 && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t))))
1679 continue;
1680 if (adh->reference != NULL)
1681 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
1682 && (0 == memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t))))
1683 continue;
1170 rd_new[j] = rd[i]; 1684 rd_new[j] = rd[i];
1171 j++; 1685 j++;
1172 } 1686 }
@@ -1192,7 +1706,6 @@ static void
1192ticket_iter_fin (void *cls) 1706ticket_iter_fin (void *cls)
1193{ 1707{
1194 struct AttributeDeleteHandle *adh = cls; 1708 struct AttributeDeleteHandle *adh = cls;
1195
1196 adh->ns_it = NULL; 1709 adh->ns_it = NULL;
1197 GNUNET_SCHEDULER_add_now (&update_tickets, adh); 1710 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1198} 1711}
@@ -1309,6 +1822,8 @@ handle_attribute_delete_message (void *cls,
1309 adh = GNUNET_new (struct AttributeDeleteHandle); 1822 adh = GNUNET_new (struct AttributeDeleteHandle);
1310 adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &dam[1], 1823 adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &dam[1],
1311 data_len); 1824 data_len);
1825 adh->reference = NULL;
1826 adh->attest = NULL;
1312 1827
1313 adh->r_id = ntohl (dam->id); 1828 adh->r_id = ntohl (dam->id);
1314 adh->identity = dam->identity; 1829 adh->identity = dam->identity;
@@ -1326,6 +1841,256 @@ handle_attribute_delete_message (void *cls,
1326 adh); 1841 adh);
1327} 1842}
1328 1843
1844/**
1845 * Attestation deleted callback
1846 *
1847 * @param cls our handle
1848 * @param success success status
1849 * @param emsg error message (NULL if success=GNUNET_OK)
1850 */
1851static void
1852attest_delete_cont (void *cls, int32_t success, const char *emsg)
1853{
1854 struct AttributeDeleteHandle *adh = cls;
1855
1856 adh->ns_qe = NULL;
1857 if (GNUNET_SYSERR == success)
1858 {
1859 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1860 "Error deleting attestation %s\n",
1861 adh->label);
1862 send_delete_response (adh, GNUNET_SYSERR);
1863 cleanup_adh (adh);
1864 return;
1865 }
1866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1867 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1868}
1869
1870/**
1871 * Check attestation delete message format
1872 *
1873 * @cls unused
1874 * @dam message to check
1875 */
1876static int
1877check_attestation_delete_message (void *cls,
1878 const struct AttributeDeleteMessage *dam)
1879{
1880 uint16_t size;
1881
1882 size = ntohs (dam->header.size);
1883 if (size <= sizeof(struct AttributeDeleteMessage))
1884 {
1885 GNUNET_break (0);
1886 return GNUNET_SYSERR;
1887 }
1888 return GNUNET_OK;
1889}
1890
1891
1892/**
1893 * Handle attestation deletion
1894 *
1895 * @param cls our client
1896 * @param dam deletion message
1897 */
1898static void
1899handle_attestation_delete_message (void *cls,
1900 const struct AttributeDeleteMessage *dam)
1901{
1902 struct AttributeDeleteHandle *adh;
1903 struct IdpClient *idp = cls;
1904 size_t data_len;
1905
1906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE message\n");
1907
1908 data_len = ntohs (dam->attr_len);
1909
1910 adh = GNUNET_new (struct AttributeDeleteHandle);
1911 adh->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &dam[1],
1912 data_len);
1913 adh->reference = NULL;
1914 adh->claim = NULL;
1915
1916 adh->r_id = ntohl (dam->id);
1917 adh->identity = dam->identity;
1918 adh->label
1919 = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id, sizeof(uint64_t));
1920 GNUNET_SERVICE_client_continue (idp->client);
1921 adh->client = idp;
1922 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1923 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1924 &adh->identity,
1925 adh->label,
1926 0,
1927 NULL,
1928 &attest_delete_cont,
1929 adh);
1930}
1931
1932
1933
1934/**
1935* Reference deleted callback
1936*
1937* @param cls our handle
1938* @param success success status
1939* @param emsg error message (NULL if success=GNUNET_OK)
1940*/
1941static void
1942reference_delete_cont (void *cls, int32_t success, const char *emsg)
1943{
1944 struct AttributeDeleteHandle *adh = cls;
1945
1946 adh->ns_qe = NULL;
1947 if (GNUNET_SYSERR == success)
1948 {
1949 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1950 "Error deleting reference %s\n",
1951 adh->label);
1952 send_delete_response (adh, GNUNET_SYSERR);
1953 cleanup_adh (adh);
1954 return;
1955 }
1956 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1957 //GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1958 send_delete_response (adh, GNUNET_OK);
1959 cleanup_adh (adh);
1960 return;
1961}
1962
1963static void
1964ref_del_cb (void *cls,
1965 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1966 const char *label,
1967 unsigned int rd_count,
1968 const struct GNUNET_GNSRECORD_Data *rd)
1969{
1970
1971 struct AttributeDeleteHandle *adh = cls;
1972 char *data_tmp;
1973 struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
1974 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
1975 size_t attr_len;
1976
1977 if (0 == rd_count )
1978 {
1979 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1980 "Failed to find Attestation entry for Attestation reference\n");
1981 cleanup_adh (adh);
1982 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1983 return;
1984 }
1985 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
1986 {
1987 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1988 "Intended Reference location is not an attestation\n");
1989 cleanup_adh (adh);
1990 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1991 return;
1992 }
1993 rd_new[0] = rd[0];
1994 int i;
1995 int j = 1;
1996 for (i = 1; i<rd_count; i++)
1997 {
1998 data_tmp = GNUNET_malloc (rd[i].data_size);
1999 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2000 attr_len = htons (rd[i].data_size);
2001 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len);
2002 if (NULL == ref )
2003 {
2004 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2005 "Unable to parse attestation reference from %s\n",
2006 data_tmp);
2007 rd_new[j] = rd[i];
2008 j += 1;
2009 continue;
2010 }
2011 if ((strcmp (adh->reference->name,ref->name) == 0)&&
2012 (strcmp (adh->reference->reference_value,ref->reference_value)==0) )
2013 {
2014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2015 "Found reference to delete.\n");
2016 }
2017 else
2018 {
2019 rd_new[j] = rd[i];
2020 j += 1;
2021 }
2022 GNUNET_free (data_tmp);
2023 }
2024 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
2025 &adh->identity,
2026 label,
2027 j,
2028 rd_new,
2029 &reference_delete_cont,
2030 adh);
2031}
2032
2033/**
2034 * Check an attestation reference delete message
2035 *
2036 * @param cls unused
2037 * @param sam the message to check
2038 */
2039static int
2040check_reference_delete_message (void *cls,
2041 const struct AttributeDeleteMessage *dam)
2042{
2043 uint16_t size;
2044
2045 size = ntohs (dam->header.size);
2046 if (size <= sizeof(struct AttributeDeleteMessage))
2047 {
2048 GNUNET_break (0);
2049 return GNUNET_SYSERR;
2050 }
2051 return GNUNET_OK;
2052}
2053
2054/**
2055 * Handle reference deletion
2056 *
2057 * @param cls our client
2058 * @param dam deletion message
2059 */
2060static void
2061handle_reference_delete_message (void *cls,
2062 const struct AttributeDeleteMessage *dam)
2063{
2064 struct AttributeDeleteHandle *adh;
2065 struct IdpClient *idp = cls;
2066 size_t data_len;
2067
2068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_DELETE message\n");
2069 data_len = ntohs (dam->attr_len);
2070 adh = GNUNET_new (struct AttributeDeleteHandle);
2071 adh->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &dam[1],
2072 data_len);
2073 adh->attest = NULL;
2074 adh->claim = NULL;
2075
2076 adh->r_id = ntohl (dam->id);
2077 adh->identity = dam->identity;
2078 adh->label
2079 = GNUNET_STRINGS_data_to_string_alloc (&adh->reference->id,
2080 sizeof(uint64_t));
2081 GNUNET_SERVICE_client_continue (idp->client);
2082 adh->client = idp;
2083 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
2084 adh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
2085 &adh->identity,
2086 adh->label,
2087 &ref_del_error,
2088 adh,
2089 &ref_del_cb,
2090 adh);
2091}
2092
2093
1329 2094
1330/************************************************* 2095/*************************************************
1331* Attrubute iteration 2096* Attrubute iteration
@@ -1372,7 +2137,7 @@ attr_iter_error (void *cls)
1372 2137
1373 2138
1374/** 2139/**
1375 * Got record. Return if it is an attribute. 2140 * Got record. Return if it is an attribute or attestation/reference.
1376 * 2141 *
1377 * @param cls our attribute iterator 2142 * @param cls our attribute iterator
1378 * @param zone zone we are iterating 2143 * @param zone zone we are iterating
@@ -1388,35 +2153,103 @@ attr_iter_cb (void *cls,
1388 const struct GNUNET_GNSRECORD_Data *rd) 2153 const struct GNUNET_GNSRECORD_Data *rd)
1389{ 2154{
1390 struct AttributeIterator *ai = cls; 2155 struct AttributeIterator *ai = cls;
1391 struct AttributeResultMessage *arm;
1392 struct GNUNET_MQ_Envelope *env; 2156 struct GNUNET_MQ_Envelope *env;
1393 char *data_tmp; 2157 char *data_tmp;
1394 2158
1395 if (rd_count != 1) 2159 if (rd_count == 0)
1396 { 2160 {
1397 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1); 2161 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1398 return; 2162 return;
1399 } 2163 }
2164 if (rd_count > 1)
2165 {
2166 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[0].record_type)
2167 {
2168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2169 "Found Ticket. Ignoring.\n");
2170 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2171 return;
2172 }
2173 else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
2174 {
2175 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2176 "Non-Attestation record with multiple entries found: %u\n",
2177 rd[0].record_type);
2178 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2179 return;
2180 }
2181 }
1400 2182
1401 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type) 2183 for (int i = 0; i<rd_count; i++)
1402 { 2184 {
1403 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1); 2185 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd[i].record_type) &&
1404 return; 2186 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type) &&
2187 (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE != rd[i].record_type))
2188 {
2189 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2190 return;
2191 }
2192
2193 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type )
2194 {
2195 struct AttributeResultMessage *arm;
2196 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
2197 label);
2198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2199 "Sending ATTRIBUTE_RESULT message\n");
2200 env = GNUNET_MQ_msg_extra (arm,
2201 rd[i].data_size,
2202 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2203 arm->id = htonl (ai->request_id);
2204 arm->attr_len = htons (rd[i].data_size);
2205 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
2206 data_tmp = (char *) &arm[1];
2207 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2208 GNUNET_MQ_send (ai->client->mq, env);
2209 }
2210 else
2211 {
2212 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type )
2213 {
2214 struct AttributeResultMessage *arm;
2215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
2216 label);
2217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2218 "Sending ATTESTATION_RESULT message\n");
2219 env = GNUNET_MQ_msg_extra (arm,
2220 rd[i].data_size,
2221 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
2222 arm->id = htonl (ai->request_id);
2223 arm->attr_len = htons (rd[i].data_size);
2224 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
2225 data_tmp = (char *) &arm[1];
2226 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2227 GNUNET_MQ_send (ai->client->mq, env);
2228 }
2229 else
2230 {
2231 struct ReferenceResultMessage *rrm;
2232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found reference under: %s\n",
2233 label);
2234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2235 "Sending REFERENCE_RESULT message\n");
2236 env = GNUNET_MQ_msg_extra (rrm,
2237 rd[i].data_size + rd[0].data_size,
2238 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT);
2239 rrm->id = htonl (ai->request_id);
2240 rrm->attest_len = htons (rd[0].data_size);
2241 rrm->ref_len = htons (rd[i].data_size);
2242 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &rrm->identity);
2243 data_tmp = (char *) &rrm[1];
2244 GNUNET_memcpy (data_tmp, rd[0].data, rd[0].data_size);
2245 data_tmp += rd[0].data_size;
2246 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
2247 GNUNET_MQ_send (ai->client->mq, env);
2248 }
2249 }
1405 } 2250 }
1406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label);
1407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
1408 env = GNUNET_MQ_msg_extra (arm,
1409 rd->data_size,
1410 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1411 arm->id = htonl (ai->request_id);
1412 arm->attr_len = htons (rd->data_size);
1413 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1414 data_tmp = (char *) &arm[1];
1415 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1416 GNUNET_MQ_send (ai->client->mq, env);
1417} 2251}
1418 2252
1419
1420/** 2253/**
1421 * Iterate over zone to get attributes 2254 * Iterate over zone to get attributes
1422 * 2255 *
@@ -1742,10 +2575,26 @@ GNUNET_SERVICE_MAIN (
1742 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE, 2575 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
1743 struct AttributeStoreMessage, 2576 struct AttributeStoreMessage,
1744 NULL), 2577 NULL),
2578 GNUNET_MQ_hd_var_size (attestation_store_message,
2579 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
2580 struct AttributeStoreMessage,
2581 NULL),
1745 GNUNET_MQ_hd_var_size (attribute_delete_message, 2582 GNUNET_MQ_hd_var_size (attribute_delete_message,
1746 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE, 2583 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
1747 struct AttributeDeleteMessage, 2584 struct AttributeDeleteMessage,
1748 NULL), 2585 NULL),
2586 GNUNET_MQ_hd_var_size (attestation_delete_message,
2587 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
2588 struct AttributeDeleteMessage,
2589 NULL),
2590 GNUNET_MQ_hd_var_size (reference_store_message,
2591 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE,
2592 struct AttributeStoreMessage,
2593 NULL),
2594 GNUNET_MQ_hd_var_size (reference_delete_message,
2595 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE,
2596 struct AttributeDeleteMessage,
2597 NULL),
1749 GNUNET_MQ_hd_fixed_size ( 2598 GNUNET_MQ_hd_fixed_size (
1750 iteration_start, 2599 iteration_start,
1751 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START, 2600 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c
index 4d1a26333..b022225b8 100644
--- a/src/reclaim/gnunet-service-reclaim_tickets.c
+++ b/src/reclaim/gnunet-service-reclaim_tickets.c
@@ -667,8 +667,7 @@ rvk_move_attr_cb (void *cls,
667 const struct GNUNET_GNSRECORD_Data *rd) 667 const struct GNUNET_GNSRECORD_Data *rd)
668{ 668{
669 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls; 669 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
670 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; 670 struct GNUNET_GNSRECORD_Data new_rd[rd_count];
671 struct GNUNET_GNSRECORD_Data new_rd;
672 struct RevokedAttributeEntry *le; 671 struct RevokedAttributeEntry *le;
673 char *new_label; 672 char *new_label;
674 char *attr_data; 673 char *attr_data;
@@ -677,7 +676,7 @@ rvk_move_attr_cb (void *cls,
677 if (0 == rd_count) 676 if (0 == rd_count)
678 { 677 {
679 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 678 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
680 "The attribute %s no longer exists!\n", 679 "The claim %s no longer exists!\n",
681 label); 680 label);
682 le = rvk->move_attr; 681 le = rvk->move_attr;
683 rvk->move_attr = le->next; 682 rvk->move_attr = le->next;
@@ -686,32 +685,82 @@ rvk_move_attr_cb (void *cls,
686 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk); 685 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
687 return; 686 return;
688 } 687 }
689 /** find a new place for this attribute **/ 688 rvk->move_attr->new_id =GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
690 rvk->move_attr->new_id = 689 new_label=NULL;
691 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); 690 attr_data=NULL;
692 new_rd = *rd; 691 //new_rd = *rd;
693 claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size); 692 for (int i = 0; i < rd_count; i++)
694 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 693 {
695 "Attribute to update: Name=%s, ID=%" PRIu64 "\n", 694 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type)
696 claim->name, 695 {
697 claim->id); 696 /** find a new place for this attribute **/
698 claim->id = rvk->move_attr->new_id; 697 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
699 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim); 698 claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, rd[i].data_size);
700 attr_data = GNUNET_malloc (rd->data_size); 699 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
701 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data); 700 "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
702 new_rd.data = attr_data; 701 claim->name,
703 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, 702 claim->id);
704 sizeof(uint64_t)); 703 claim->id = rvk->move_attr->new_id;
705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label); 704 new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
705 attr_data = GNUNET_malloc (rd[i].data_size);
706 new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
707 new_rd[i].data = attr_data;
708 new_rd[i].record_type = rd[i].record_type;
709 new_rd[i].flags = rd[i].flags;
710 new_rd[i].expiration_time = rd[i].expiration_time;
711 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
712 sizeof(uint64_t));
713 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
714 GNUNET_free (claim);
715 } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type)
716 {
717 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
718 attest=GNUNET_RECLAIM_ATTESTATION_deserialize(rd[i].data, rd[i].data_size);
719 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
720 "Attestation to update: Name=%s, ID=%" PRIu64 "\n",
721 attest->name,
722 attest->id);
723 attest->id = rvk->move_attr->new_id;
724 new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attest);
725 attr_data = GNUNET_malloc (rd[i].data_size);
726 new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize (attest, attr_data);
727 new_rd[i].data = attr_data;
728 new_rd[i].record_type = rd[i].record_type;
729 new_rd[i].flags = rd[i].flags;
730 new_rd[i].expiration_time = rd[i].expiration_time;
731 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, sizeof(uint64_t));
732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation %s\n", new_label);
733 GNUNET_free (attest);
734 } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type)
735 {
736 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
737 reference=GNUNET_RECLAIM_ATTESTATION_REF_deserialize(rd[i].data, rd[i].data_size);
738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
739 "Reference to update: Name=%s, ID=%" PRIu64 "\n",
740 reference->name,
741 reference->id);
742 reference->id = rvk->move_attr->new_id;
743 reference->id_attest = rvk->move_attr->new_id;
744 new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (reference);
745 attr_data = GNUNET_malloc (rd[i].data_size);
746 new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize (reference, attr_data);
747 new_rd[i].data = attr_data;
748 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, sizeof(uint64_t));
749 new_rd[i].record_type = rd[i].record_type;
750 new_rd[i].flags = rd[i].flags;
751 new_rd[i].expiration_time = rd[i].expiration_time;
752 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference %s\n", new_label);
753 GNUNET_free (reference);
754 }
755 }
706 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, 756 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
707 &rvk->identity, 757 &rvk->identity,
708 new_label, 758 new_label,
709 1, 759 rd_count,
710 &new_rd, 760 new_rd,
711 &move_attr_finished, 761 &move_attr_finished,
712 rvk); 762 rvk);
713 GNUNET_free (new_label); 763 GNUNET_free (new_label);
714 GNUNET_free (claim);
715 GNUNET_free (attr_data); 764 GNUNET_free (attr_data);
716} 765}
717 766
@@ -745,7 +794,7 @@ move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
745 } 794 }
746 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id, 795 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
747 sizeof(uint64_t)); 796 sizeof(uint64_t));
748 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label); 797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving claim %s\n", label);
749 798
750 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, 799 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
751 &rvk->identity, 800 &rvk->identity,
@@ -982,21 +1031,70 @@ process_parallel_lookup_result (void *cls,
982 1031
983 1032
984 GNUNET_free (parallel_lookup); 1033 GNUNET_free (parallel_lookup);
985 if (1 != rd_count) 1034 if (0 == rd_count)
986 GNUNET_break (0); // FIXME: We should never find this. 1035 GNUNET_break (0);
987 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR) 1036 // REMARK: It is possible now to find rd_count > 1
1037 for (int i = 0; i < rd_count; i++)
988 { 1038 {
989 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); 1039 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type)
990 attr_le->claim = 1040 {
991 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size); 1041 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
992 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, 1042 attr_le->claim =
993 cth->attrs->list_tail, 1043 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, rd[i].data_size);
994 attr_le); 1044 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
995 } 1045 cth->attrs->list_tail,
1046 attr_le);
1047 attr_le->reference = NULL;
1048 attr_le->attest = NULL;
1049 }
1050 else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type)
1051 {
1052 /**Ignore all plain attestations
1053 *attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1054 *attr_le->attest =
1055 * GNUNET_RECLAIM_ATTESTATION_deserialize (rd[i].data, rd[i].data_size);
1056 *GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
1057 * cth->attrs->list_tail,
1058 * attr_le);
1059 */
1060 continue;
1061 }
1062 else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type)
1063 {
1064 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le2;
1065 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1066 attr_le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1067 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[0].record_type)
1068 {
1069 attr_le->attest = GNUNET_RECLAIM_ATTESTATION_deserialize (rd[0].data,
1070 rd[0].
1071 data_size);
1072 attr_le2->reference =
1073 GNUNET_RECLAIM_ATTESTATION_REF_deserialize (rd[i].data,
1074 rd[i].data_size);
1075 attr_le->claim = NULL;
1076 attr_le->reference = NULL;
1077 attr_le2->claim = NULL;
1078 attr_le2->attest = NULL;
1079 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
1080 cth->attrs->list_tail,
1081 attr_le);
1082 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
1083 cth->attrs->list_tail,
1084 attr_le2);
1085 }
1086 else
1087 {
1088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1089 "Parallel Lookup of Reference without Attestation");
1090 continue;
1091 }
996 1092
1093
1094 }
1095 }
997 if (NULL != cth->parallel_lookups_head) 1096 if (NULL != cth->parallel_lookups_head)
998 return; // Wait for more 1097 return; // Wait for more
999
1000 /* Else we are done */ 1098 /* Else we are done */
1001 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL); 1099 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
1002 cleanup_cth (cth); 1100 cleanup_cth (cth);
@@ -1076,7 +1174,7 @@ lookup_authz_cb (void *cls,
1076 GNUNET_GNS_lookup (gns, 1174 GNUNET_GNS_lookup (gns,
1077 lbl, 1175 lbl,
1078 &cth->ticket.identity, 1176 &cth->ticket.identity,
1079 GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR, 1177 GNUNET_GNSRECORD_TYPE_ANY,
1080 GNUNET_GNS_LO_DEFAULT, 1178 GNUNET_GNS_LO_DEFAULT,
1081 &process_parallel_lookup_result, 1179 &process_parallel_lookup_result,
1082 parallel_lookup); 1180 parallel_lookup);
@@ -1223,6 +1321,7 @@ issue_ticket (struct TicketIssueHandle *ih)
1223 char *label; 1321 char *label;
1224 size_t list_len = 1; 1322 size_t list_len = 1;
1225 int i; 1323 int i;
1324 char *attest_string;
1226 1325
1227 for (le = ih->attrs->list_head; NULL != le; le = le->next) 1326 for (le = ih->attrs->list_head; NULL != le; le = le->next)
1228 list_len++; 1327 list_len++;
@@ -1232,8 +1331,51 @@ issue_ticket (struct TicketIssueHandle *ih)
1232 i = 0; 1331 i = 0;
1233 for (le = ih->attrs->list_head; NULL != le; le = le->next) 1332 for (le = ih->attrs->list_head; NULL != le; le = le->next)
1234 { 1333 {
1235 attrs_record[i].data = &le->claim->id; 1334 if (NULL != le->claim)
1236 attrs_record[i].data_size = sizeof(le->claim->id); 1335 {
1336 attrs_record[i].data = &le->claim->id;
1337 attrs_record[i].data_size = sizeof(le->claim->id);
1338 }
1339 else if (NULL != le->attest)
1340 {
1341 // REMARK: Since we only store IDs, the references are irrelevant
1342 int j = 0;
1343 GNUNET_asprintf (&attest_string,"%d",le->attest->id);
1344 while (j<i)
1345 {
1346 if (0 == strcmp (attest_string,GNUNET_STRINGS_data_to_string_alloc (
1347 attrs_record[j].data, attrs_record[j].data_size)))
1348 break;
1349 j++;
1350 }
1351 if (j < i)
1352 {
1353 list_len--;
1354 continue;
1355 }
1356 attrs_record[i].data = &le->attest->id;
1357 attrs_record[i].data_size = sizeof(le->attest->id);
1358 }
1359 else if (NULL != le->reference)
1360 {
1361 list_len--;
1362 continue;
1363 /*
1364 int j = 0;
1365 GNUNET_asprintf (&attest_string,"%d",le->attest->id);
1366 while (j<i)
1367 {
1368 if (strcmp(attest_string, GNUNET_STRINGS_data_to_string_alloc (
1369 attrs_record[j].data, attrs_record[j].data_size)))
1370 break;
1371 j++;
1372 }
1373 if (j < i)
1374 continue;
1375 attrs_record[i].data = &le->reference->id;
1376 attrs_record[i].data_size = sizeof(le->reference->id);
1377 */
1378 }
1237 /** 1379 /**
1238 * FIXME: Should this be the attribute expiration time or ticket 1380 * FIXME: Should this be the attribute expiration time or ticket
1239 * refresh interval? Probably min(attrs.expiration) 1381 * refresh interval? Probably min(attrs.expiration)
@@ -1344,14 +1486,34 @@ filter_tickets_cb (void *cls,
1344 for (le = tih->attrs->list_head; NULL != le; le = le->next) 1486 for (le = tih->attrs->list_head; NULL != le; le = le->next)
1345 { 1487 {
1346 // cmp attr_ref id with requested attr id 1488 // cmp attr_ref id with requested attr id
1347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1489 if (NULL !=le->claim)
1348 " %" PRIu64 "\n %" PRIu64 "\n", 1490 {
1349 *((uint64_t *) rd[i].data), 1491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1350 le->claim->id); 1492 " %" PRIu64 "\n %" PRIu64 "\n",
1351 1493 *((uint64_t *) rd[i].data),
1494 le->claim->id);
1495 if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t)))
1496 found_attrs_cnt++;
1497 }
1498 else if (NULL !=le->attest)
1499 {
1500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1501 " %" PRIu64 "\n %" PRIu64 "\n",
1502 *((uint64_t *) rd[i].data),
1503 le->attest->id);
1504 if (0 == memcmp (rd[i].data, &le->attest->id, sizeof(uint64_t)))
1505 found_attrs_cnt++;
1506 }
1507 else if (NULL != le->reference)
1508 {
1509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1510 " %" PRIu64 "\n %" PRIu64 "\n",
1511 *((uint64_t *) rd[i].data),
1512 le->reference->id);
1513 if (0 == memcmp (rd[i].data, &le->reference->id, sizeof(uint64_t)))
1514 found_attrs_cnt++;
1515 }
1352 1516
1353 if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t)))
1354 found_attrs_cnt++;
1355 } 1517 }
1356 } 1518 }
1357 1519
diff --git a/src/reclaim/json_reclaim.c b/src/reclaim/json_reclaim.c
index e029fdfb6..a464a9088 100644
--- a/src/reclaim/json_reclaim.c
+++ b/src/reclaim/json_reclaim.c
@@ -48,6 +48,7 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
48 const char *val_str = NULL; 48 const char *val_str = NULL;
49 const char *type_str = NULL; 49 const char *type_str = NULL;
50 const char *id_str = NULL; 50 const char *id_str = NULL;
51 const char *flag_str = NULL;
51 char *data; 52 char *data;
52 int unpack_state; 53 int unpack_state;
53 uint32_t type; 54 uint32_t type;
@@ -63,7 +64,7 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
63 } 64 }
64 // interpret single attribute 65 // interpret single attribute
65 unpack_state = json_unpack (root, 66 unpack_state = json_unpack (root,
66 "{s:s, s?s, s:s, s:s!}", 67 "{s:s, s?s, s:s, s:s, s?s!}",
67 "name", 68 "name",
68 &name_str, 69 &name_str,
69 "id", 70 "id",
@@ -71,7 +72,9 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
71 "type", 72 "type",
72 &type_str, 73 &type_str,
73 "value", 74 "value",
74 &val_str); 75 &val_str,
76 "flag",
77 &flag_str);
75 if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) || 78 if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
76 (NULL == type_str)) 79 (NULL == type_str))
77 { 80 {
@@ -264,3 +267,217 @@ GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
264 *ticket = NULL; 267 *ticket = NULL;
265 return ret; 268 return ret;
266} 269}
270
271/**
272 * Parse given JSON object to an attestation claim
273 *
274 * @param cls closure, NULL
275 * @param root the json object representing data
276 * @param spec where to write the data
277 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
278 */
279static int
280parse_attest (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
281{
282 struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
283 const char *name_str = NULL;
284 const char *val_str = NULL;
285 const char *type_str = NULL;
286 const char *id_str = NULL;
287 char *data;
288 int unpack_state;
289 uint32_t type;
290 size_t data_size;
291
292 GNUNET_assert (NULL != root);
293
294 if (! json_is_object (root))
295 {
296 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
297 "Error json is not array nor object!\n");
298 return GNUNET_SYSERR;
299 }
300 // interpret single attribute
301 unpack_state = json_unpack (root,
302 "{s:s, s?s, s:s, s:s!}",
303 "name",
304 &name_str,
305 "id",
306 &id_str,
307 "type",
308 &type_str,
309 "value",
310 &val_str);
311 if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
312 (NULL == type_str))
313 {
314 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
315 "Error json object has a wrong format!\n");
316 return GNUNET_SYSERR;
317 }
318 type = GNUNET_RECLAIM_ATTESTATION_typename_to_number (type_str);
319 if (GNUNET_SYSERR ==
320 (GNUNET_RECLAIM_ATTESTATION_string_to_value (type,
321 val_str,
322 (void **) &data,
323 &data_size)))
324 {
325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attestation value invalid!\n");
326 return GNUNET_SYSERR;
327 }
328 attr = GNUNET_RECLAIM_ATTESTATION_claim_new (name_str, type, data, data_size);
329 if ((NULL == id_str) || (0 == strlen (id_str)))
330 attr->id = 0;
331 else
332 GNUNET_STRINGS_string_to_data (id_str,
333 strlen (id_str),
334 &attr->id,
335 sizeof(uint64_t));
336
337 *(struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr = attr;
338 return GNUNET_OK;
339}
340
341/**
342 * Cleanup data left from parsing RSA public key.
343 *
344 * @param cls closure, NULL
345 * @param[out] spec where to free the data
346 */
347static void
348clean_attest (void *cls, struct GNUNET_JSON_Specification *spec)
349{
350 struct GNUNET_RECLAIM_ATTESTATION_Claim **attr;
351
352 attr = (struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr;
353 if (NULL != *attr)
354 {
355 GNUNET_free (*attr);
356 *attr = NULL;
357 }
358}
359/**
360 * JSON Specification for Reclaim attestation claims.
361 *
362 * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
363 * @return JSON Specification
364 */
365struct GNUNET_JSON_Specification
366GNUNET_RECLAIM_JSON_spec_claim_attest (struct
367 GNUNET_RECLAIM_ATTESTATION_Claim **attr)
368{
369 struct GNUNET_JSON_Specification ret = { .parser = &parse_attest,
370 .cleaner = &clean_attest,
371 .cls = NULL,
372 .field = NULL,
373 .ptr = attr,
374 .ptr_size = 0,
375 .size_ptr = NULL };
376
377 *attr = NULL;
378 return ret;
379}
380
381/**
382 * Parse given JSON object to an attestation claim
383 *
384 * @param cls closure, NULL
385 * @param root the json object representing data
386 * @param spec where to write the data
387 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
388 */
389static int
390parse_attest_ref (void *cls, json_t *root, struct
391 GNUNET_JSON_Specification *spec)
392{
393 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
394 const char *name_str = NULL;
395 const char *ref_val_str = NULL;
396 const char *ref_id_str = NULL;
397 const char *id_str = NULL;
398 int unpack_state;
399
400 GNUNET_assert (NULL != root);
401
402 if (! json_is_object (root))
403 {
404 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
405 "Error json is not array nor object!\n");
406 return GNUNET_SYSERR;
407 }
408 // interpret single reference
409 unpack_state = json_unpack (root,
410 "{s:s, s?s, s:s, s:s!}",
411 "name",
412 &name_str,
413 "id",
414 &id_str,
415 "ref_id",
416 &ref_id_str,
417 "ref_value",
418 &ref_val_str);
419 if ((0 != unpack_state) || (NULL == name_str) || (NULL == ref_val_str) ||
420 (NULL == ref_id_str))
421 {
422 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
423 "Error json object has a wrong format!\n");
424 return GNUNET_SYSERR;
425 }
426
427 attr = GNUNET_RECLAIM_ATTESTATION_reference_new (name_str, ref_val_str);
428
429 attr->id = 0;
430
431 if ((NULL == ref_id_str) || (0 == strlen (ref_id_str)))
432 attr->id_attest = 0;
433 else
434 GNUNET_STRINGS_string_to_data (ref_id_str,
435 strlen (ref_id_str),
436 &attr->id_attest,
437 sizeof(uint64_t));
438
439 *(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr = attr;
440 return GNUNET_OK;
441}
442
443/**
444 * Cleanup data left from parsing RSA public key.
445 *
446 * @param cls closure, NULL
447 * @param[out] spec where to free the data
448 */
449static void
450clean_attest_ref (void *cls, struct GNUNET_JSON_Specification *spec)
451{
452 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr;
453
454 attr = (struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr;
455 if (NULL != *attr)
456 {
457 GNUNET_free (*attr);
458 *attr = NULL;
459 }
460}
461
462/**
463 * JSON Specification for Reclaim attestation references.
464 *
465 * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
466 * @return JSON Specification
467 */
468struct GNUNET_JSON_Specification
469GNUNET_RECLAIM_JSON_spec_claim_attest_ref (struct
470 GNUNET_RECLAIM_ATTESTATION_REFERENCE
471 **attr)
472{
473 struct GNUNET_JSON_Specification ret = { .parser = &parse_attest_ref,
474 .cleaner = &clean_attest_ref,
475 .cls = NULL,
476 .field = NULL,
477 .ptr = attr,
478 .ptr_size = 0,
479 .size_ptr = NULL };
480
481 *attr = NULL;
482 return ret;
483} \ No newline at end of file
diff --git a/src/reclaim/json_reclaim.h b/src/reclaim/json_reclaim.h
index 3fd26167f..9e6479e5e 100644
--- a/src/reclaim/json_reclaim.h
+++ b/src/reclaim/json_reclaim.h
@@ -46,3 +46,22 @@ GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr);
46 */ 46 */
47struct GNUNET_JSON_Specification 47struct GNUNET_JSON_Specification
48GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket); 48GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket);
49
50/**
51 * JSON Specification for Reclaim attestation claims.
52 *
53 * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
54 * @return JSON Specification
55 */
56struct GNUNET_JSON_Specification
57GNUNET_RECLAIM_JSON_spec_claim_attest (struct
58 GNUNET_RECLAIM_ATTESTATION_Claim **attr);
59
60 /**
61 * JSON Specification for Reclaim attestation references.
62 *
63 * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
64 * @return JSON Specification
65 */
66 struct GNUNET_JSON_Specification
67 GNUNET_RECLAIM_JSON_spec_claim_attest_ref(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr);
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index 1c3d65f35..2ce462854 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -118,7 +118,7 @@ fix_base64 (char *str)
118char * 118char *
119OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 119OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
120 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, 120 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
121 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, 121 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
122 const struct GNUNET_TIME_Relative *expiration_time, 122 const struct GNUNET_TIME_Relative *expiration_time,
123 const char *nonce, 123 const char *nonce,
124 const char *secret_key) 124 const char *secret_key)
@@ -131,13 +131,22 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
131 char *subject; 131 char *subject;
132 char *header; 132 char *header;
133 char *body_str; 133 char *body_str;
134 char *aggr_names_str;
135 char *aggr_sources_str;
136 char *aggr_sources_jwt_str;
137 char *source_name;
134 char *result; 138 char *result;
135 char *header_base64; 139 char *header_base64;
136 char *body_base64; 140 char *body_base64;
137 char *signature_target; 141 char *signature_target;
138 char *signature_base64; 142 char *signature_base64;
139 char *attr_val_str; 143 char *attr_val_str;
144 char *attest_val_str;
140 json_t *body; 145 json_t *body;
146 json_t *aggr_names;
147 json_t *aggr_sources;
148 json_t *aggr_sources_jwt;
149 uint64_t attest_arr[GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (attrs)];
141 150
142 // iat REQUIRED time now 151 // iat REQUIRED time now
143 time_now = GNUNET_TIME_absolute_get (); 152 time_now = GNUNET_TIME_absolute_get ();
@@ -156,6 +165,8 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
156 GNUNET_CRYPTO_EcdsaPublicKey)); 165 GNUNET_CRYPTO_EcdsaPublicKey));
157 header = create_jwt_header (); 166 header = create_jwt_header ();
158 body = json_object (); 167 body = json_object ();
168 aggr_names = json_object ();
169 aggr_sources = json_object ();
159 170
160 // iss REQUIRED case sensitive server uri with https 171 // iss REQUIRED case sensitive server uri with https
161 // The issuer is the local reclaim instance (e.g. 172 // The issuer is the local reclaim instance (e.g.
@@ -180,18 +191,111 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
180 // nonce 191 // nonce
181 if (NULL != nonce) 192 if (NULL != nonce)
182 json_object_set_new (body, "nonce", json_string (nonce)); 193 json_object_set_new (body, "nonce", json_string (nonce));
183 194 int i = 0;
195 attest_val_str = NULL;
196 aggr_names_str = NULL;
197 aggr_sources_str = NULL;
198 aggr_sources_jwt_str = NULL;
199 source_name = NULL;
184 for (le = attrs->list_head; NULL != le; le = le->next) 200 for (le = attrs->list_head; NULL != le; le = le->next)
185 { 201 {
186 attr_val_str = 202
187 GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type, 203 if (le->claim != NULL)
188 le->claim->data, 204 {
189 le->claim->data_size); 205
190 json_object_set_new (body, le->claim->name, json_string (attr_val_str)); 206 attr_val_str =
191 GNUNET_free (attr_val_str); 207 GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type,
208 le->claim->data,
209 le->claim->data_size);
210 json_object_set_new (body, le->claim->name, json_string (attr_val_str));
211 GNUNET_free (attr_val_str);
212 }
213 else if (NULL != le->reference)
214 {
215 // Check if attest is there
216 int j = 0;
217 while (j<i)
218 {
219 if (attest_arr[j] == le->reference->id_attest)
220 break;
221 j++;
222 }
223 if (j==i)
224 {
225 // Attest not yet existent. Append to the end of the list
226 GNUNET_CONTAINER_DLL_remove (attrs->list_head, attrs->list_tail, le);
227 GNUNET_CONTAINER_DLL_insert_tail (attrs->list_head, attrs->list_tail,
228 le);
229 continue;
230 }
231 else
232 {
233 // Attestation is existing, hence take the respective source str
234 GNUNET_asprintf (&source_name,
235 "src%d",
236 j);
237 json_object_set_new (aggr_names, le->reference->name, json_string (
238 source_name));
239 }
240
241 }
242 else if (NULL != le->attest)
243 {
244 // We assume that at max 99 different attestations
245 int j = 0;
246 while (j<i)
247 {
248 if (attest_arr[j] == le->attest->id)
249 break;
250 j++;
251 }
252 if (j==i)
253 {
254 // New Attestation
255 attest_arr[i] = le->attest->id;
256 GNUNET_asprintf (&source_name,
257 "src%d",
258 i);
259 aggr_sources_jwt = json_object ();
260 attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (
261 le->attest->type, le->attest->data, le->attest->data_size);
262 json_object_set_new (aggr_sources_jwt, "JWT",json_string (
263 attest_val_str) );
264 aggr_sources_jwt_str = json_dumps (aggr_sources_jwt, JSON_INDENT (0)
265 | JSON_COMPACT);
266 json_object_set_new (aggr_sources, source_name,json_string (
267 aggr_sources_jwt_str));
268 i++;
269 }
270 else
271 {
272 // Attestation already existent. Ignore
273 continue;
274 }
275
276 }
277 }
278 if (NULL != attest_val_str)
279 GNUNET_free (attest_val_str);
280 if (NULL != source_name)
281 GNUNET_free (source_name);
282 if (0!=i)
283 {
284 aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT);
285 aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0)
286 | JSON_COMPACT);
287 json_object_set_new (body, "_claim_names", json_string (aggr_names_str));
288 json_object_set_new (body, "_claim_sources", json_string (
289 aggr_sources_str));
192 } 290 }
291
292 json_decref (aggr_names);
293 json_decref (aggr_sources);
294 json_decref (aggr_sources_jwt);
295
193 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); 296 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
194 json_decref (body); 297 json_decref (body);
298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str);
195 299
196 GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64); 300 GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64);
197 fix_base64 (header_base64); 301 fix_base64 (header_base64);
@@ -226,6 +330,12 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
226 GNUNET_free (signature_target); 330 GNUNET_free (signature_target);
227 GNUNET_free (header); 331 GNUNET_free (header);
228 GNUNET_free (body_str); 332 GNUNET_free (body_str);
333 if (NULL != aggr_sources_str)
334 GNUNET_free (aggr_sources_str);
335 if (NULL != aggr_names_str)
336 GNUNET_free (aggr_names_str);
337 if (NULL != aggr_sources_jwt_str)
338 GNUNET_free (aggr_sources_jwt_str);
229 GNUNET_free (signature_base64); 339 GNUNET_free (signature_base64);
230 GNUNET_free (body_base64); 340 GNUNET_free (body_base64);
231 GNUNET_free (header_base64); 341 GNUNET_free (header_base64);
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h
index 1774618e8..a7072755b 100644
--- a/src/reclaim/oidc_helper.h
+++ b/src/reclaim/oidc_helper.h
@@ -51,7 +51,7 @@
51char* 51char*
52OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 52OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
53 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, 53 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
54 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, 54 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
55 const struct GNUNET_TIME_Relative *expiration_time, 55 const struct GNUNET_TIME_Relative *expiration_time,
56 const char *nonce, 56 const char *nonce,
57 const char *secret_key); 57 const char *secret_key);
diff --git a/src/reclaim/plugin_gnsrecord_reclaim.c b/src/reclaim/plugin_gnsrecord_reclaim.c
index d530ef01d..f7145a272 100644
--- a/src/reclaim/plugin_gnsrecord_reclaim.c
+++ b/src/reclaim/plugin_gnsrecord_reclaim.c
@@ -54,6 +54,8 @@ value_to_string (void *cls, uint32_t type, const void *data, size_t data_size)
54 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF: 54 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF:
55 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: 55 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
56 case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER: 56 case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
57 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
58 case GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE:
57 return GNUNET_STRINGS_data_to_string_alloc (data, data_size); 59 return GNUNET_STRINGS_data_to_string_alloc (data, data_size);
58 60
59 default: 61 default:
@@ -93,6 +95,8 @@ string_to_value (void *cls, uint32_t type, const char *s, void **data,
93 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF: 95 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF:
94 case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER: 96 case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
95 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: 97 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
98 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
99 case GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE:
96 return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size); 100 return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size);
97 101
98 default: 102 default:
@@ -112,10 +116,12 @@ static struct
112} name_map[] = { 116} name_map[] = {
113 { "RECLAIM_ATTR", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR }, 117 { "RECLAIM_ATTR", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR },
114 { "RECLAIM_ATTR_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF }, 118 { "RECLAIM_ATTR_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF },
119 { "RECLAIM_ATTEST", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR },
115 { "RECLAIM_MASTER", GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER }, 120 { "RECLAIM_MASTER", GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER },
116 { "RECLAIM_OIDC_CLIENT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT }, 121 { "RECLAIM_OIDC_CLIENT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT },
117 { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT }, 122 { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT },
118 { "RECLAIM_TICKET", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET }, 123 { "RECLAIM_TICKET", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET },
124 { "RECLAIM_REFERENCE", GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE },
119 { NULL, UINT32_MAX } 125 { NULL, UINT32_MAX }
120}; 126};
121 127
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index 92a1de621..741094f21 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -120,6 +120,11 @@
120#define OIDC_NONCE_KEY "nonce" 120#define OIDC_NONCE_KEY "nonce"
121 121
122/** 122/**
123 * OIDC claims key
124 */
125#define OIDC_CLAIMS_KEY "claims"
126
127/**
123 * OIDC PKCE code challenge 128 * OIDC PKCE code challenge
124 */ 129 */
125#define OIDC_CODE_CHALLENGE_KEY "code_challenge" 130#define OIDC_CODE_CHALLENGE_KEY "code_challenge"
@@ -291,6 +296,11 @@ struct OIDC_Variables
291 char *nonce; 296 char *nonce;
292 297
293 /** 298 /**
299 * The OIDC claims
300 */
301 char *claims;
302
303 /**
294 * The OIDC response type 304 * The OIDC response type
295 */ 305 */
296 char *response_type; 306 char *response_type;
@@ -560,7 +570,12 @@ cleanup_handle (struct RequestHandle *handle)
560 { 570 {
561 claim_tmp = claim_entry; 571 claim_tmp = claim_entry;
562 claim_entry = claim_entry->next; 572 claim_entry = claim_entry->next;
563 GNUNET_free (claim_tmp->claim); 573 if (NULL != claim_tmp->claim)
574 GNUNET_free (claim_tmp->claim);
575 if (NULL != claim_tmp->attest)
576 GNUNET_free (claim_tmp->attest);
577 if (NULL != claim_tmp->reference)
578 GNUNET_free (claim_tmp->reference);
564 GNUNET_free (claim_tmp); 579 GNUNET_free (claim_tmp);
565 } 580 }
566 GNUNET_free (handle->attr_list); 581 GNUNET_free (handle->attr_list);
@@ -697,7 +712,7 @@ return_userinfo_response (void *cls)
697 struct MHD_Response *resp; 712 struct MHD_Response *resp;
698 713
699 result_str = json_dumps (handle->oidc->response, 0); 714 result_str = json_dumps (handle->oidc->response, 0);
700 715 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str);
701 resp = GNUNET_REST_create_response (result_str); 716 resp = GNUNET_REST_create_response (result_str);
702 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 717 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
703 GNUNET_free (result_str); 718 GNUNET_free (result_str);
@@ -838,7 +853,7 @@ login_redirect (void *cls)
838 &login_base_url)) 853 &login_base_url))
839 { 854 {
840 GNUNET_asprintf (&new_redirect, 855 GNUNET_asprintf (&new_redirect,
841 "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", 856 "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
842 login_base_url, 857 login_base_url,
843 OIDC_RESPONSE_TYPE_KEY, 858 OIDC_RESPONSE_TYPE_KEY,
844 handle->oidc->response_type, 859 handle->oidc->response_type,
@@ -854,7 +869,10 @@ login_redirect (void *cls)
854 (NULL != handle->oidc->code_challenge) ? 869 (NULL != handle->oidc->code_challenge) ?
855 handle->oidc->code_challenge : "", 870 handle->oidc->code_challenge : "",
856 OIDC_NONCE_KEY, 871 OIDC_NONCE_KEY,
857 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); 872 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "",
873 OIDC_CLAIMS_KEY,
874 (NULL != handle->oidc->claims) ? handle->oidc->claims :
875 "");
858 resp = GNUNET_REST_create_response (""); 876 resp = GNUNET_REST_create_response ("");
859 MHD_add_response_header (resp, "Location", new_redirect); 877 MHD_add_response_header (resp, "Location", new_redirect);
860 GNUNET_free (login_base_url); 878 GNUNET_free (login_base_url);
@@ -973,12 +991,14 @@ oidc_collect_finished_cb (void *cls)
973 991
974 992
975/** 993/**
976 * Collects all attributes for an ego if in scope parameter 994 * Collects all attributes/references for an ego if in scope parameter
977 */ 995 */
978static void 996static void
979oidc_attr_collect (void *cls, 997oidc_attr_collect (void *cls,
980 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 998 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
981 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 999 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1000 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1001 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
982{ 1002{
983 struct RequestHandle *handle = cls; 1003 struct RequestHandle *handle = cls;
984 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; 1004 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
@@ -986,39 +1006,92 @@ oidc_attr_collect (void *cls,
986 char *scope_variable; 1006 char *scope_variable;
987 char delimiter[] = " "; 1007 char delimiter[] = " ";
988 1008
989 if ((NULL == attr->name) || (NULL == attr->data)) 1009 if ((NULL == attr) && (NULL == reference))
990 { 1010 {
991 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1011 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
992 return; 1012 return;
993 } 1013 }
994 1014 if (NULL != reference)
995 scope_variables = GNUNET_strdup (handle->oidc->scope);
996 scope_variable = strtok (scope_variables, delimiter);
997 while (NULL != scope_variable)
998 {
999 if (0 == strcmp (attr->name, scope_variable))
1000 break;
1001 scope_variable = strtok (NULL, delimiter);
1002 }
1003 if (NULL == scope_variable)
1004 { 1015 {
1005 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1016 if ((NULL == reference->name) || (NULL == reference->reference_value))
1017 {
1018 return;
1019 }
1020 scope_variables = GNUNET_strdup (handle->oidc->scope);
1021 scope_variable = strtok (scope_variables, delimiter);
1022 while (NULL != scope_variable)
1023 {
1024 if (0 == strcmp (reference->name, scope_variable))
1025 break;
1026 scope_variable = strtok (NULL, delimiter);
1027 }
1028 if (NULL == scope_variable)
1029 {
1030 GNUNET_free (scope_variables);
1031 return;
1032 }
1006 GNUNET_free (scope_variables); 1033 GNUNET_free (scope_variables);
1007 return; 1034 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
1035 le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1036 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1037 le->claim = NULL;
1038 le->reference = NULL;
1039 le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (attest->name,
1040 attest->type,
1041 attest->data,
1042 attest->data_size);
1043 le->attest->id = attest->id;
1044 le2->attest = NULL;
1045 le2->claim = NULL;
1046 le2->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (reference->name,
1047 reference->
1048 reference_value);
1049 le2->reference->id = reference->id;
1050 le2->reference->id_attest = reference->id_attest;
1051 GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
1052 handle->attr_list->list_tail,
1053 le);
1054 GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
1055 handle->attr_list->list_tail,
1056 le2);
1057 }
1058 else if (NULL != attr)
1059 {
1060 if ((NULL == attr->name) || (NULL == attr->data))
1061 {
1062 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1063 return;
1064 }
1065 scope_variables = GNUNET_strdup (handle->oidc->scope);
1066 scope_variable = strtok (scope_variables, delimiter);
1067 while (NULL != scope_variable)
1068 {
1069 if (0 == strcmp (attr->name, scope_variable))
1070 break;
1071 scope_variable = strtok (NULL, delimiter);
1072 }
1073 if (NULL == scope_variable)
1074 {
1075 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1076 GNUNET_free (scope_variables);
1077 return;
1078 }
1079 GNUNET_free (scope_variables);
1080 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1081 le->reference = NULL;
1082 le->attest = NULL;
1083 le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
1084 attr->type,
1085 attr->data,
1086 attr->data_size);
1087 le->claim->id = attr->id;
1088 le->claim->flag = attr->flag;
1089
1090 GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
1091 handle->attr_list->list_tail,
1092 le);
1093 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1008 } 1094 }
1009 GNUNET_free (scope_variables);
1010
1011 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1012 le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
1013 attr->type,
1014 attr->data,
1015 attr->data_size);
1016 le->claim->id = attr->id;
1017 le->claim->version = attr->version;
1018 GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
1019 handle->attr_list->list_tail,
1020 le);
1021 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1022} 1095}
1023 1096
1024 1097
@@ -1304,6 +1377,9 @@ build_authz_response (void *cls)
1304 // OPTIONAL value: nonce 1377 // OPTIONAL value: nonce
1305 handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY); 1378 handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
1306 1379
1380 // OPTIONAL value: claims
1381 handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY);
1382
1307 // TODO check other values if needed 1383 // TODO check other values if needed
1308 number_of_ignored_parameter = 1384 number_of_ignored_parameter =
1309 sizeof(OIDC_ignored_parameter_array) / sizeof(char *); 1385 sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
@@ -1454,6 +1530,9 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1454 handle->ego_entry = handle->ego_tail; 1530 handle->ego_entry = handle->ego_tail;
1455 } 1531 }
1456 } 1532 }
1533 handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1534 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scope: %s\n",GNUNET_strdup (
1535 handle->oidc->scope));
1457 if (NULL == handle->tld) 1536 if (NULL == handle->tld)
1458 GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle); 1537 GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle);
1459 if (NULL == handle->tld) 1538 if (NULL == handle->tld)
@@ -1857,28 +1936,97 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1857 1936
1858 1937
1859/** 1938/**
1860 * Collects claims and stores them in handle 1939 * Collects claims and stores them in handle
1861 */ 1940 */
1862static void 1941static void
1863consume_ticket (void *cls, 1942consume_ticket (void *cls,
1864 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 1943 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1865 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 1944 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1945 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1946 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
1866{ 1947{
1867 struct RequestHandle *handle = cls; 1948 struct RequestHandle *handle = cls;
1868 char *tmp_value;
1869 json_t *value;
1870
1871 if (NULL == identity) 1949 if (NULL == identity)
1872 { 1950 {
1873 GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); 1951 GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle);
1874 return; 1952 return;
1875 } 1953 }
1876 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, 1954 if (NULL != attr)
1877 attr->data, 1955 {
1878 attr->data_size); 1956 char *tmp_value;
1879 value = json_string (tmp_value); 1957 json_t *value;
1880 json_object_set_new (handle->oidc->response, attr->name, value); 1958 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
1881 GNUNET_free (tmp_value); 1959 attr->data,
1960 attr->data_size);
1961 value = json_string (tmp_value);
1962 json_object_set_new (handle->oidc->response, attr->name, value);
1963 GNUNET_free (tmp_value);
1964 }
1965 else if ((NULL != attest) && (NULL != reference))
1966 {
1967 json_t *claim_sources;
1968 json_t *claim_sources_jwt;
1969 json_t *claim_names;
1970 char *attest_val_str;
1971 claim_sources=json_object_get(handle->oidc->response,"_claim_sources");
1972 claim_names=json_object_get(handle->oidc->response,"_claim_names");
1973 attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
1974 attest->data,
1975 attest->
1976 data_size);
1977 if ((NULL == claim_sources) && (NULL == claim_names) )
1978 {
1979 claim_sources = json_object ();
1980 claim_names = json_object ();
1981 }
1982 char *source_name;
1983 int i = 0;
1984 GNUNET_asprintf (&source_name,"src%d",i);
1985 while (NULL != (claim_sources_jwt = json_object_get (claim_sources,
1986 source_name)))
1987 {
1988 if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt,
1989 "JWT")),
1990 attest_val_str))
1991 {
1992 // Adapt only the claim names
1993 json_object_set_new (claim_names, reference->name, json_string (
1994 source_name));
1995 json_object_set (handle->oidc->response, "_claim_names",claim_names);
1996 handle->oidc->response = json_deep_copy(handle->oidc->response);
1997 break;
1998 }
1999 i++;
2000 GNUNET_asprintf (&source_name,"src%d",i);
2001 }
2002
2003 // Create new one
2004 if (NULL == claim_sources_jwt)
2005 {
2006 claim_sources_jwt = json_object ();
2007 // Set the JWT for names
2008 json_object_set_new (claim_names, reference->name, json_string (
2009 source_name));
2010 // Set the JWT for the inner source
2011 json_object_set_new (claim_sources_jwt, "JWT", json_string (
2012 attest_val_str));
2013 // Set the JWT for the source
2014 json_object_set_new (claim_sources, source_name,claim_sources_jwt);
2015 // Set as claims
2016 json_object_set (handle->oidc->response, "_claim_names", claim_names);
2017 json_object_set (handle->oidc->response, "_claim_sources",claim_sources);
2018 handle->oidc->response = json_deep_copy(handle->oidc->response);
2019 }
2020
2021 json_decref (claim_sources);
2022 json_decref (claim_names);
2023 json_decref (claim_sources_jwt);
2024 GNUNET_free (attest_val_str);
2025 }
2026 else
2027 {
2028 // REMARK: We should not find any claim, one of attest/ref is NULL
2029 }
1882} 2030}
1883 2031
1884 2032
diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c
index 9a75b2d16..dcda75b65 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -37,7 +37,6 @@
37#include "gnunet_rest_plugin.h" 37#include "gnunet_rest_plugin.h"
38#include "gnunet_signatures.h" 38#include "gnunet_signatures.h"
39#include "json_reclaim.h" 39#include "json_reclaim.h"
40
41/** 40/**
42 * REST root namespace 41 * REST root namespace
43 */ 42 */
@@ -49,6 +48,11 @@
49#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes" 48#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
50 49
51/** 50/**
51 * Attestation namespace
52 */
53#define GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE "/reclaim/attestation"
54
55/**
52 * Ticket namespace 56 * Ticket namespace
53 */ 57 */
54#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets" 58#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets"
@@ -272,6 +276,8 @@ cleanup_handle (struct RequestHandle *handle)
272 claim_tmp = claim_entry; 276 claim_tmp = claim_entry;
273 claim_entry = claim_entry->next; 277 claim_entry = claim_entry->next;
274 GNUNET_free (claim_tmp->claim); 278 GNUNET_free (claim_tmp->claim);
279 GNUNET_free (claim_tmp->attest);
280 GNUNET_free (claim_tmp->reference);
275 GNUNET_free (claim_tmp); 281 GNUNET_free (claim_tmp);
276 } 282 }
277 GNUNET_free (handle->attr_list); 283 GNUNET_free (handle->attr_list);
@@ -360,6 +366,21 @@ finished_cont (void *cls, int32_t success, const char *emsg)
360 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 366 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
361} 367}
362 368
369static void
370delete_finished_cb (void *cls, int32_t success, const char *emsg)
371{
372 struct RequestHandle *handle = cls;
373 struct MHD_Response *resp;
374
375 resp = GNUNET_REST_create_response (emsg);
376 if (GNUNET_OK != success)
377 {
378 GNUNET_SCHEDULER_add_now (&do_error, handle);
379 return;
380 }
381 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
382 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
383}
363 384
364/** 385/**
365 * Return attributes for identity 386 * Return attributes for identity
@@ -434,6 +455,661 @@ ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
434} 455}
435 456
436 457
458static void
459add_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
460 const char *url,
461 void *cls)
462{
463 struct RequestHandle *handle = cls;
464 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
465 const char *identity;
466 struct EgoEntry *ego_entry;
467 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attribute;
468 struct GNUNET_TIME_Relative exp;
469 char term_data[handle->rest_handle->data_size + 1];
470 json_t *data_json;
471 json_error_t err;
472 struct GNUNET_JSON_Specification attrspec[] =
473 { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attribute),
474 GNUNET_JSON_spec_end () };
475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
476 "Adding an attestation reference for %s.\n",
477 handle->url);
478 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
479 "reference/") + 1 >= strlen (
480 handle->url))
481 {
482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
483 GNUNET_SCHEDULER_add_now (&do_error, handle);
484 return;
485 }
486 identity = handle->url + strlen (
487 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
488 + 1;
489 for (ego_entry = handle->ego_head; NULL != ego_entry;
490 ego_entry = ego_entry->next)
491 if (0 == strcmp (identity, ego_entry->identifier))
492 break;
493 if (NULL == ego_entry)
494 {
495 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
496 return;
497 }
498 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
499 if (0 >= handle->rest_handle->data_size)
500 {
501 GNUNET_SCHEDULER_add_now (&do_error, handle);
502 return;
503 }
504
505 term_data[handle->rest_handle->data_size] = '\0';
506 GNUNET_memcpy (term_data,
507 handle->rest_handle->data,
508 handle->rest_handle->data_size);
509 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
510 GNUNET_assert (GNUNET_OK ==
511 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
512 json_decref (data_json);
513 if (NULL == attribute)
514 {
515 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
516 "Unable to parse attestation reference from %s\n",
517 term_data);
518 GNUNET_SCHEDULER_add_now (&do_error, handle);
519 return;
520 }
521 /**
522 * New ID for attribute
523 */
524 if (0 == attribute->id)
525 attribute->id = attribute->id_attest;
526 handle->idp = GNUNET_RECLAIM_connect (cfg);
527 exp = GNUNET_TIME_UNIT_HOURS;
528 handle->idp_op = GNUNET_RECLAIM_attestation_reference_store (handle->idp,
529 identity_priv,
530 attribute,
531 &exp,
532 &finished_cont,
533 handle);
534 GNUNET_JSON_parse_free (attrspec);
535}
536
537static void
538parse_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
539 const char *url,
540 void *cls)
541{
542 struct RequestHandle *handle = cls;
543
544 char term_data[handle->rest_handle->data_size + 1];
545 json_t *data_json;
546 json_error_t err;
547 int unpack_state;
548 struct MHD_Response *resp;
549 char *val_str = NULL;
550 const char *type_str = NULL;
551 term_data[handle->rest_handle->data_size] = '\0';
552 GNUNET_memcpy (term_data,
553 handle->rest_handle->data,
554 handle->rest_handle->data_size);
555 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
556 GNUNET_assert (NULL != data_json);
557 if (! json_is_object (data_json))
558 {
559 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
560 "Error json is not array nor object!\n");
561 GNUNET_SCHEDULER_add_now (&do_error, handle);
562 return;
563 }
564 unpack_state = json_unpack (data_json,
565 "{s:s, s:s!}",
566 "value",
567 &val_str,
568 "type",
569 &type_str);
570 if ((0 != unpack_state) || (NULL == val_str) || (NULL == type_str))
571 {
572 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
573 "Error json object has a wrong format!\n");
574 GNUNET_SCHEDULER_add_now (&do_error, handle);
575 return;
576 }
577 if (0 == strcmp (type_str, "JWT"))
578 {
579 // The value is a JWT
580 char *decoded_jwt;
581 char delim[] = ".";
582 char *jwt_body = strtok (val_str, delim);
583 jwt_body = strtok (NULL, delim);
584 GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
585 (void **) &decoded_jwt);
586 resp = GNUNET_REST_create_response (decoded_jwt);
587 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
588 GNUNET_free (decoded_jwt);
589 }
590 else
591 {
592 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
593 "Error requested parsing type not supported!\n");
594 GNUNET_SCHEDULER_add_now (&do_error, handle);
595 return;
596 }
597 cleanup_handle (handle);
598 json_decref (data_json);
599}
600
601static void
602add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
603 const char *url,
604 void *cls)
605{
606 struct RequestHandle *handle = cls;
607 /* Check for substring "reference" */
608 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
609 handle->url))
610 {
611 if ( strncmp ("reference/", (handle->url + strlen (
612 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
613 + 1), strlen (
614 "reference/")) == 0)
615 {
616 add_attestation_ref_cont (con_handle,url,cls);
617 return;
618 }
619 }
620 /* Check for substring "parse" */
621 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
622 handle->url))
623 {
624 if ( strncmp ("parse", (handle->url + strlen (
625 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
626 + 1), strlen (
627 "parse")) == 0)
628 {
629 parse_attestation_cont (con_handle,url,cls);
630 return;
631 }
632 }
633 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
634 const char *identity;
635 struct EgoEntry *ego_entry;
636 struct GNUNET_RECLAIM_ATTESTATION_Claim *attribute;
637 struct GNUNET_TIME_Relative exp;
638 char term_data[handle->rest_handle->data_size + 1];
639 json_t *data_json;
640 json_error_t err;
641 struct GNUNET_JSON_Specification attrspec[] =
642 { GNUNET_RECLAIM_JSON_spec_claim_attest (&attribute),
643 GNUNET_JSON_spec_end () };
644
645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
646 "Adding an attestation for %s.\n",
647 handle->url);
648 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
649 handle->url))
650 {
651 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
652 GNUNET_SCHEDULER_add_now (&do_error, handle);
653 return;
654 }
655 identity = handle->url + strlen (
656 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
657
658 for (ego_entry = handle->ego_head; NULL != ego_entry;
659 ego_entry = ego_entry->next)
660 if (0 == strcmp (identity, ego_entry->identifier))
661 break;
662
663 if (NULL == ego_entry)
664 {
665 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
666 return;
667 }
668 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
669
670 if (0 >= handle->rest_handle->data_size)
671 {
672 GNUNET_SCHEDULER_add_now (&do_error, handle);
673 return;
674 }
675
676 term_data[handle->rest_handle->data_size] = '\0';
677 GNUNET_memcpy (term_data,
678 handle->rest_handle->data,
679 handle->rest_handle->data_size);
680 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
681 GNUNET_assert (GNUNET_OK ==
682 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
683 json_decref (data_json);
684 if (NULL == attribute)
685 {
686 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
687 "Unable to parse attestation from %s\n",
688 term_data);
689 GNUNET_SCHEDULER_add_now (&do_error, handle);
690 return;
691 }
692 /**
693 * New ID for attribute
694 */
695 if (0 == attribute->id)
696 attribute->id =
697 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
698 handle->idp = GNUNET_RECLAIM_connect (cfg);
699 exp = GNUNET_TIME_UNIT_HOURS;
700 handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp,
701 identity_priv,
702 attribute,
703 &exp,
704 &finished_cont,
705 handle);
706 GNUNET_JSON_parse_free (attrspec);
707}
708
709/**
710 * Collect all references for an ego
711 *
712 */
713static void
714ref_collect (void *cls,
715 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
716 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
717 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
718 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
719{
720 struct RequestHandle *handle = cls;
721 json_t *attr_obj;
722 char *id_str;
723 char *id_attest_str;
724
725 if (NULL == reference)
726 {
727 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
728 return;
729 }
730
731 if ((NULL == reference->name) || (NULL == reference->reference_value))
732 {
733 return;
734 }
735
736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference: %s\n",
737 reference->name);
738 attr_obj = json_object ();
739 json_object_set_new (attr_obj, "name", json_string (reference->name));
740 json_object_set_new (attr_obj, "ref_value", json_string (
741 reference->reference_value));
742 id_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id,
743 sizeof(uint64_t));
744 id_attest_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id_attest,
745 sizeof(uint64_t));
746 json_object_set_new (attr_obj, "id", json_string (id_str));
747 json_object_set_new (attr_obj, "ref_id", json_string (id_attest_str));
748 json_array_append (handle->resp_object, attr_obj);
749 json_decref (attr_obj);
750}
751
752/**
753 * Lists references for identity request
754 *
755 * @param con_handle the connection handle
756 * @param url the url
757 * @param cls the RequestHandle
758 */
759static void
760list_reference_cont (struct GNUNET_REST_RequestHandle *con_handle,
761 const char *url,
762 void *cls)
763{
764 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
765 struct RequestHandle *handle = cls;
766 struct EgoEntry *ego_entry;
767 char *identity;
768
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
770 "Getting references for %s.\n",
771 handle->url);
772 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
773 "reference/") + 1 >= strlen (
774 handle->url))
775 {
776 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
777 GNUNET_SCHEDULER_add_now (&do_error, handle);
778 return;
779 }
780 identity = handle->url + strlen (
781 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
782 + 1;
783 for (ego_entry = handle->ego_head; NULL != ego_entry;
784 ego_entry = ego_entry->next)
785 if (0 == strcmp (identity, ego_entry->identifier))
786 break;
787 handle->resp_object = json_array ();
788
789 if (NULL == ego_entry)
790 {
791 // Done
792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
793 GNUNET_SCHEDULER_add_now (&return_response, handle);
794 return;
795 }
796 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
797 handle->idp = GNUNET_RECLAIM_connect (cfg);
798 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
799 priv_key,
800 &collect_error_cb,
801 handle,
802 &ref_collect,
803 handle,
804 &collect_finished_cb,
805 handle);
806}
807
808/**
809 * Collect all attestations for an ego
810 *
811 */
812static void
813attest_collect (void *cls,
814 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
815 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
816 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
817 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
818{
819 struct RequestHandle *handle = cls;
820 json_t *attr_obj;
821 const char *type;
822 char *tmp_value;
823 char *id_str;
824
825
826 if (NULL != reference)
827 {
828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
829 "Attestation Collection with Reference\n");
830 return;
831 }
832 if (NULL == attest)
833 {
834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
835 "Attestation Collection with empty Attestation\n");
836 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
837 return;
838 }
839
840 if ((NULL == attest->name) || (NULL == attest->data))
841 {
842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
843 "Attestation Collection with empty Name/Value\n");
844 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
845 return;
846 }
847
848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation: %s\n",
849 attest->name);
850
851 tmp_value = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
852 attest->data,
853 attest->data_size);
854 attr_obj = json_object ();
855 json_object_set_new (attr_obj, "value", json_string (tmp_value));
856 json_object_set_new (attr_obj, "name", json_string (attest->name));
857 type = GNUNET_RECLAIM_ATTESTATION_number_to_typename (attest->type);
858 json_object_set_new (attr_obj, "type", json_string (type));
859 id_str = GNUNET_STRINGS_data_to_string_alloc (&attest->id, sizeof(uint64_t));
860 json_object_set_new (attr_obj, "id", json_string (id_str));
861 json_array_append (handle->resp_object, attr_obj);
862 json_decref (attr_obj);
863 GNUNET_free (tmp_value);
864 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
865}
866
867
868/**
869 * Lists attestation for identity request
870 *
871 * @param con_handle the connection handle
872 * @param url the url
873 * @param cls the RequestHandle
874 */
875static void
876list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
877 const char *url,
878 void *cls)
879{
880 struct RequestHandle *handle = cls;
881 /* Check for substring "reference" */
882 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
883 handle->url))
884 {
885 if ( strncmp ("reference/", (handle->url + strlen (
886 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
887 + 1), strlen (
888 "reference/")) == 0)
889 {
890 list_reference_cont (con_handle,url,cls);
891 return;
892 }
893 }
894 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
895 struct EgoEntry *ego_entry;
896 char *identity;
897
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
899 "Getting attestations for %s.\n",
900 handle->url);
901 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
902 handle->url))
903 {
904 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
905 GNUNET_SCHEDULER_add_now (&do_error, handle);
906 return;
907 }
908 identity = handle->url + strlen (
909 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
910
911 for (ego_entry = handle->ego_head; NULL != ego_entry;
912 ego_entry = ego_entry->next)
913 if (0 == strcmp (identity, ego_entry->identifier))
914 break;
915 handle->resp_object = json_array ();
916
917
918 if (NULL == ego_entry)
919 {
920 // Done
921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
922 GNUNET_SCHEDULER_add_now (&return_response, handle);
923 return;
924 }
925 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
926 handle->idp = GNUNET_RECLAIM_connect (cfg);
927 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
928 priv_key,
929 &collect_error_cb,
930 handle,
931 &attest_collect,
932 handle,
933 &collect_finished_cb,
934 handle);
935}
936
937/**
938 * Deletes reference from an identity
939 *
940 * @param con_handle the connection handle
941 * @param url the url
942 * @param cls the RequestHandle
943 */
944static void
945delete_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
946 const char *url,
947 void *cls)
948{
949 struct RequestHandle *handle = cls;
950 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
951 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
952 struct EgoEntry *ego_entry;
953 char *identity;
954 char *identity_id_str;
955 char *id;
956 char term_data[handle->rest_handle->data_size + 1];
957 json_t *data_json;
958 json_error_t err;
959
960 struct GNUNET_JSON_Specification attrspec[] =
961 { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attr),
962 GNUNET_JSON_spec_end () };
963 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
964 "Deleting attestation reference.\n");
965 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
966 "reference/") + 1 >= strlen (
967 handle->url))
968 {
969 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
970 GNUNET_SCHEDULER_add_now (&do_error, handle);
971 return;
972 }
973 identity_id_str = strdup (handle->url + strlen (
974 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
975 + strlen ("reference/")
976 + 1);
977 identity = strtok (identity_id_str, "/");
978 id = strtok (NULL, "/");
979
980 if ((NULL == identity) || (NULL == id))
981 {
982 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
983 GNUNET_SCHEDULER_add_now (&do_error, handle);
984 return;
985 }
986 for (ego_entry = handle->ego_head; NULL != ego_entry;
987 ego_entry = ego_entry->next)
988 if (0 == strcmp (identity, ego_entry->identifier))
989 break;
990 handle->resp_object = json_array ();
991 if (NULL == ego_entry)
992 {
993 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
994 GNUNET_SCHEDULER_add_now (&return_response, handle);
995 return;
996 }
997 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
998 if (0 >= handle->rest_handle->data_size)
999 {
1000 GNUNET_SCHEDULER_add_now (&do_error, handle);
1001 return;
1002 }
1003
1004 term_data[handle->rest_handle->data_size] = '\0';
1005 GNUNET_memcpy (term_data,
1006 handle->rest_handle->data,
1007 handle->rest_handle->data_size);
1008 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
1009 GNUNET_assert (GNUNET_OK ==
1010 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
1011 json_decref (data_json);
1012 if (NULL == attr)
1013 {
1014 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1015 "Unable to parse attestation reference from %s\n",
1016 term_data);
1017 GNUNET_SCHEDULER_add_now (&do_error, handle);
1018 return;
1019 }
1020 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr->id, sizeof(uint64_t));
1021
1022 handle->idp = GNUNET_RECLAIM_connect (cfg);
1023 handle->idp_op = GNUNET_RECLAIM_attestation_reference_delete (handle->idp,
1024 priv_key,
1025 attr,
1026 &
1027 delete_finished_cb,
1028 handle);
1029 GNUNET_JSON_parse_free (attrspec);
1030}
1031
1032
1033/**
1034 * Deletes attestation from an identity
1035 *
1036 * @param con_handle the connection handle
1037 * @param url the url
1038 * @param cls the RequestHandle
1039 */
1040static void
1041delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
1042 const char *url,
1043 void *cls)
1044{
1045 struct RequestHandle *handle = cls;
1046 /* Check for substring "reference" */
1047 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
1048 handle->url))
1049 {
1050 if ( strncmp ("reference", (handle->url + strlen (
1051 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
1052 + 1), strlen (
1053 "reference")) == 0)
1054 {
1055 delete_attestation_ref_cont (con_handle,url,cls);
1056 return;
1057 }
1058 }
1059 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1060 struct GNUNET_RECLAIM_ATTESTATION_Claim attr;
1061 struct EgoEntry *ego_entry;
1062 char *identity_id_str;
1063 char *identity;
1064 char *id;
1065
1066 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attestation.\n");
1067 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
1068 handle->url))
1069 {
1070 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
1071 GNUNET_SCHEDULER_add_now (&do_error, handle);
1072 return;
1073 }
1074 identity_id_str =
1075 strdup (handle->url + strlen (
1076 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1);
1077 identity = strtok (identity_id_str, "/");
1078 id = strtok (NULL, "/");
1079 if ((NULL == identity) || (NULL == id))
1080 {
1081 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
1082 GNUNET_free (identity_id_str);
1083 GNUNET_SCHEDULER_add_now (&do_error, handle);
1084 return;
1085 }
1086
1087 for (ego_entry = handle->ego_head; NULL != ego_entry;
1088 ego_entry = ego_entry->next)
1089 if (0 == strcmp (identity, ego_entry->identifier))
1090 break;
1091 handle->resp_object = json_array ();
1092 if (NULL == ego_entry)
1093 {
1094 // Done
1095 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
1096 GNUNET_free (identity_id_str);
1097 GNUNET_SCHEDULER_add_now (&return_response, handle);
1098 return;
1099 }
1100 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1101 handle->idp = GNUNET_RECLAIM_connect (cfg);
1102 memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim));
1103 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
1104 attr.name = "";
1105 handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp,
1106 priv_key,
1107 &attr,
1108 &delete_finished_cb,
1109 handle);
1110 GNUNET_free (identity_id_str);
1111}
1112
437/** 1113/**
438 * List tickets for identity request 1114 * List tickets for identity request
439 * 1115 *
@@ -568,6 +1244,72 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
568 GNUNET_JSON_parse_free (attrspec); 1244 GNUNET_JSON_parse_free (attrspec);
569} 1245}
570 1246
1247/**
1248 * Parse a JWT and return the respective claim value as Attribute
1249 *
1250 * @param attest the jwt attestation
1251 * @param claim the name of the claim in the JWT
1252 *
1253 * @return a GNUNET_RECLAIM_ATTRIBUTE_Claim, containing the new value
1254 */
1255struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
1256parse_jwt (const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1257 const char *claim)
1258{
1259 char *jwt_string;
1260 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
1261 char delim[] = ".";
1262 const char *type_str = NULL;
1263 const char *val_str = NULL;
1264 char *data;
1265 size_t data_size;
1266 uint32_t type;
1267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
1268 char *decoded_jwt;
1269 json_t *json_val;
1270 json_error_t *json_err = NULL;
1271
1272 jwt_string = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
1273 attest->data,
1274 attest->data_size);
1275 char *jwt_body = strtok (jwt_string, delim);
1276 jwt_body = strtok (NULL, delim);
1277 GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
1278 (void **) &decoded_jwt);
1279 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
1280 const char *key;
1281 json_t *value;
1282 json_object_foreach (json_val, key, value) {
1283 if (0 == strcasecmp (key,claim))
1284 {
1285 val_str = json_dumps (value, JSON_ENCODE_ANY);
1286 }
1287 }
1288 type_str = "String";
1289 type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
1290 if (GNUNET_SYSERR ==(GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,val_str,
1291 (void **) &data,
1292 &data_size)))
1293 {
1294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1295 "Attribute value from JWT Parser invalid!\n");
1296 GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
1297 "Error: Referenced Claim Name not Found",
1298 (void **) &data,
1299 &data_size);
1300 attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
1301 attr->id = attest->id;
1302 attr->flag = 1;
1303 }
1304 else
1305 {
1306 attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
1307 attr->id = attest->id;
1308 attr->flag = 1;
1309 }
1310 return attr;
1311}
1312
571 1313
572/** 1314/**
573 * Collect all attributes for an ego 1315 * Collect all attributes for an ego
@@ -576,40 +1318,93 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
576static void 1318static void
577attr_collect (void *cls, 1319attr_collect (void *cls,
578 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 1320 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
579 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 1321 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1322 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1323 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
580{ 1324{
581 struct RequestHandle *handle = cls; 1325 struct RequestHandle *handle = cls;
582 json_t *attr_obj; 1326 json_t *attr_obj;
583 const char *type; 1327 const char *type;
584 char *tmp_value;
585 char *id_str; 1328 char *id_str;
586 1329
587 if ((NULL == attr->name) || (NULL == attr->data)) 1330 if ((NULL == attr) && (NULL == reference))
588 { 1331 {
1332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1333 "Attribute Collection with empty Attribute/Reference\n");
589 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1334 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
590 return; 1335 return;
591 } 1336 }
592 1337
593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name); 1338 if (NULL == attr)
594 1339 {
595 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
596 attr->data,
597 attr->data_size);
598 1340
599 attr_obj = json_object (); 1341 if ((NULL == reference->name) || (NULL == reference->reference_value))
600 json_object_set_new (attr_obj, "value", json_string (tmp_value)); 1342 {
601 json_object_set_new (attr_obj, "name", json_string (attr->name)); 1343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
602 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type); 1344 "Attribute Collection with empty Reference Name/Value\n");
603 json_object_set_new (attr_obj, "type", json_string (type)); 1345 return;
604 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t)); 1346 }
605 json_object_set_new (attr_obj, "id", json_string (id_str)); 1347 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr2;
606 json_array_append (handle->resp_object, attr_obj); 1348 attr2 = parse_jwt (attest, reference->reference_value);
607 json_decref (attr_obj); 1349 if (NULL == attr2)
608 GNUNET_free (tmp_value); 1350 {
609 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1351 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1352 "Attribute Collection with unparsed Attestation\n");
1353 return;
1354 }
1355 attr2->name = reference->name;
1356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference as attribute: %s\n",
1357 reference->name);
1358 char *tmp_value;
1359 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr2->type,
1360 attr2->data,
1361 attr2->data_size);
1362 attr_obj = json_object ();
1363
1364 json_object_set_new (attr_obj, "value", json_string (tmp_value));
1365 json_object_set_new (attr_obj, "name", json_string (attr2->name));
1366 json_object_set_new (attr_obj, "flag", json_string ("1"));
1367 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr2->type);
1368 json_object_set_new (attr_obj, "type", json_string (type));
1369 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr2->id, sizeof(uint64_t));
1370 json_object_set_new (attr_obj, "id", json_string (id_str));
1371 json_array_append (handle->resp_object, attr_obj);
1372 json_decref (attr_obj);
1373 GNUNET_free (tmp_value);
1374 }
1375 else
1376 {
1377 if ((NULL == attr->name) || (NULL == attr->data))
1378 {
1379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1380 "Attribute Collection with empty Attribute Name/Value\n");
1381 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1382 return;
1383 }
1384 char *tmp_value;
1385 char *flag_str;
1386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
1387
1388 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
1389 attr->data,
1390 attr->data_size);
1391
1392 attr_obj = json_object ();
1393 json_object_set_new (attr_obj, "value", json_string (tmp_value));
1394 json_object_set_new (attr_obj, "name", json_string (attr->name));
1395 GNUNET_asprintf (&flag_str,"%d",attr->flag);
1396 json_object_set_new (attr_obj, "flag", json_string (flag_str));
1397 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
1398 json_object_set_new (attr_obj, "type", json_string (type));
1399 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
1400 json_object_set_new (attr_obj, "id", json_string (id_str));
1401 json_array_append (handle->resp_object, attr_obj);
1402 json_decref (attr_obj);
1403 GNUNET_free (tmp_value);
1404 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1405 }
610} 1406}
611 1407
612
613/** 1408/**
614 * List attributes for identity request 1409 * List attributes for identity request
615 * 1410 *
@@ -665,23 +1460,6 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
665} 1460}
666 1461
667 1462
668static void
669delete_finished_cb (void *cls, int32_t success, const char *emsg)
670{
671 struct RequestHandle *handle = cls;
672 struct MHD_Response *resp;
673
674 resp = GNUNET_REST_create_response (emsg);
675 if (GNUNET_OK != success)
676 {
677 GNUNET_SCHEDULER_add_now (&do_error, handle);
678 return;
679 }
680 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
681 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
682}
683
684
685/** 1463/**
686 * List attributes for identity request 1464 * List attributes for identity request
687 * 1465 *
@@ -825,7 +1603,9 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
825static void 1603static void
826consume_cont (void *cls, 1604consume_cont (void *cls,
827 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 1605 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
828 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 1606 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1607 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1608 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
829{ 1609{
830 struct RequestHandle *handle = cls; 1610 struct RequestHandle *handle = cls;
831 char *val_str; 1611 char *val_str;
@@ -969,6 +1749,15 @@ init_cont (struct RequestHandle *handle)
969 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, 1749 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
970 &delete_attribute_cont }, 1750 &delete_attribute_cont },
971 { MHD_HTTP_METHOD_GET, 1751 { MHD_HTTP_METHOD_GET,
1752 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
1753 &list_attestation_cont },
1754 { MHD_HTTP_METHOD_POST,
1755 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
1756 &add_attestation_cont },
1757 { MHD_HTTP_METHOD_DELETE,
1758 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
1759 &delete_attestation_cont },
1760 { MHD_HTTP_METHOD_GET,
972 GNUNET_REST_API_NS_IDENTITY_TICKETS, 1761 GNUNET_REST_API_NS_IDENTITY_TICKETS,
973 &list_tickets_cont }, 1762 &list_tickets_cont },
974 { MHD_HTTP_METHOD_POST, 1763 { MHD_HTTP_METHOD_POST,
diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h
index 8e731812e..ff953a096 100644
--- a/src/reclaim/reclaim.h
+++ b/src/reclaim/reclaim.h
@@ -153,6 +153,45 @@ struct AttributeResultMessage
153 */ 153 */
154}; 154};
155 155
156/**
157 * Reference plus Attestation is returned from the idp.
158 */
159struct ReferenceResultMessage
160{
161 /**
162 * Message header
163 */
164 struct GNUNET_MessageHeader header;
165
166 /**
167 * Unique identifier for this request (for key collisions).
168 */
169 uint32_t id GNUNET_PACKED;
170
171 /**
172 * Length of serialized attestation data
173 */
174 uint16_t attest_len GNUNET_PACKED;
175
176 /**
177 * Length of serialized reference data
178 */
179 uint16_t ref_len GNUNET_PACKED;
180
181 /**
182 * always zero (for alignment)
183 */
184 uint16_t reserved GNUNET_PACKED;
185
186 /**
187 * The public key of the identity.
188 */
189 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
190
191 /* followed by:
192 * serialized reference data + attestation data
193 */
194};
156 195
157/** 196/**
158 * Start a attribute iteration for the given identity 197 * Start a attribute iteration for the given identity
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
index 7d4d7588a..847abb58a 100644
--- a/src/reclaim/reclaim_api.c
+++ b/src/reclaim/reclaim_api.c
@@ -486,7 +486,7 @@ handle_consume_ticket_result (void *cls,
486 uint32_t r_id = ntohl (msg->id); 486 uint32_t r_id = ntohl (msg->id);
487 487
488 attrs_len = ntohs (msg->attrs_len); 488 attrs_len = ntohs (msg->attrs_len);
489 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n"); 489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
490 490
491 491
492 for (op = h->op_head; NULL != op; op = op->next) 492 for (op = h->op_head; NULL != op; op = op->next)
@@ -498,22 +498,36 @@ handle_consume_ticket_result (void *cls,
498 { 498 {
499 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; 499 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
500 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; 500 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
501 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
501 attrs = 502 attrs =
502 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &msg[1], attrs_len); 503 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &msg[1], attrs_len);
503 if (NULL != op->ar_cb) 504 if (NULL != op->ar_cb)
504 { 505 {
505 if (NULL == attrs) 506 if (NULL == attrs)
506 { 507 {
507 op->ar_cb (op->cls, &msg->identity, NULL); 508 op->ar_cb (op->cls, &msg->identity, NULL, NULL, NULL);
508 } 509 }
509 else 510 else
510 { 511 {
511 for (le = attrs->list_head; NULL != le; le = le->next) 512 for (le = attrs->list_head; NULL != le; le = le->next)
512 op->ar_cb (op->cls, &msg->identity, le->claim); 513 {
514 if (le->reference != NULL && le->attest == NULL)
515 {
516 for (le2 = attrs->list_head; NULL != le2; le2 = le2->next)
517 {
518 if (le2->attest != NULL && le2->attest->id == le->reference->id_attest)
519 {
520 op->ar_cb (op->cls, &msg->identity, le->claim, le2->attest, le->reference);
521 break;
522 }
523
524 }
525 }
526 }
513 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs); 527 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
514 attrs = NULL; 528 attrs = NULL;
515 } 529 }
516 op->ar_cb (op->cls, NULL, NULL); 530 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
517 } 531 }
518 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); 532 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
519 free_op (op); 533 free_op (op);
@@ -597,7 +611,7 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
597 if (NULL != op) 611 if (NULL != op)
598 { 612 {
599 if (NULL != op->ar_cb) 613 if (NULL != op->ar_cb)
600 op->ar_cb (op->cls, NULL, NULL); 614 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
601 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); 615 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
602 free_op (op); 616 free_op (op);
603 } 617 }
@@ -610,12 +624,111 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
610 if (NULL != it) 624 if (NULL != it)
611 { 625 {
612 if (NULL != it->proc) 626 if (NULL != it->proc)
613 it->proc (it->proc_cls, &msg->identity, attr); 627 it->proc (it->proc_cls, &msg->identity, attr, NULL, NULL);
628 }
629 else if (NULL != op)
630 {
631 if (NULL != op->ar_cb)
632 op->ar_cb (op->cls, &msg->identity, attr, NULL, NULL);
633 }
634 GNUNET_free (attr);
635 return;
636 }
637 GNUNET_assert (0);
638}
639
640/**
641 * Handle an incoming message of type
642 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
643 *
644 * @param cls
645 * @param msg the message we received
646 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
647 */
648static int
649check_attestation_result (void *cls, const struct AttributeResultMessage *msg)
650{
651 size_t msg_len;
652 size_t attr_len;
653
654 msg_len = ntohs (msg->header.size);
655 attr_len = ntohs (msg->attr_len);
656 if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
657 {
658 GNUNET_break (0);
659 return GNUNET_SYSERR;
660 }
661 return GNUNET_OK;
662}
663
664
665/**
666 * Handle an incoming message of type
667 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
668 *
669 * @param cls
670 * @param msg the message we received
671 */
672static void
673handle_attestation_result (void *cls, const struct AttributeResultMessage *msg)
674{
675 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
676 struct GNUNET_RECLAIM_Handle *h = cls;
677 struct GNUNET_RECLAIM_AttributeIterator *it;
678 struct GNUNET_RECLAIM_Operation *op;
679 size_t attr_len;
680 uint32_t r_id = ntohl (msg->id);
681
682 attr_len = ntohs (msg->attr_len);
683 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attestation result.\n");
684
685
686 for (it = h->it_head; NULL != it; it = it->next)
687 if (it->r_id == r_id)
688 break;
689 for (op = h->op_head; NULL != op; op = op->next)
690 if (op->r_id == r_id)
691 break;
692 if ((NULL == it) && (NULL == op))
693 return;
694
695 if ((0 ==
696 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
697 {
698 if ((NULL == it) && (NULL == op))
699 {
700 GNUNET_break (0);
701 force_reconnect (h);
702 return;
703 }
704 if (NULL != it)
705 {
706 if (NULL != it->finish_cb)
707 it->finish_cb (it->finish_cb_cls);
708 free_it (it);
709 }
710 if (NULL != op)
711 {
712 if (NULL != op->ar_cb)
713 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
714 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
715 free_op (op);
716 }
717 return;
718 }
719
720 {
721 struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
722 attr = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1], attr_len);
723 if (NULL != it)
724 {
725 if (NULL != it->proc)
726 it->proc (it->proc_cls, &msg->identity, NULL, attr, NULL);
614 } 727 }
615 else if (NULL != op) 728 else if (NULL != op)
616 { 729 {
617 if (NULL != op->ar_cb) 730 if (NULL != op->ar_cb)
618 op->ar_cb (op->cls, &msg->identity, attr); 731 op->ar_cb (op->cls, &msg->identity, NULL, attr, NULL);
619 } 732 }
620 GNUNET_free (attr); 733 GNUNET_free (attr);
621 return; 734 return;
@@ -623,6 +736,110 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
623 GNUNET_assert (0); 736 GNUNET_assert (0);
624} 737}
625 738
739/**
740 * Handle an incoming message of type
741 * #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
742 *
743 * @param cls
744 * @param msg the message we received
745 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
746 */
747static int
748check_reference_result (void *cls, const struct ReferenceResultMessage *msg)
749{
750 size_t msg_len;
751 size_t attr_len;
752 size_t ref_len;
753
754 msg_len = ntohs (msg->header.size);
755 attr_len = ntohs (msg->attest_len);
756 ref_len = ntohs (msg->ref_len);
757 if (msg_len != sizeof(struct ReferenceResultMessage) + attr_len + ref_len)
758 {
759 GNUNET_break (0);
760 return GNUNET_SYSERR;
761 }
762 return GNUNET_OK;
763}
764
765/**
766* Handle an incoming message of type
767* #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
768*
769* @param cls
770* @param msg the message we received
771*/
772static void
773handle_reference_result (void *cls, const struct ReferenceResultMessage *msg)
774{
775 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
776 struct GNUNET_RECLAIM_Handle *h = cls;
777 struct GNUNET_RECLAIM_AttributeIterator *it;
778 struct GNUNET_RECLAIM_Operation *op;
779 size_t attest_len;
780 size_t ref_len;
781 uint32_t r_id = ntohl (msg->id);
782 attest_len = ntohs (msg->attest_len);
783 ref_len = ntohs (msg->ref_len);
784 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing reference result.\n");
785 for (it = h->it_head; NULL != it; it = it->next)
786 if (it->r_id == r_id)
787 break;
788 for (op = h->op_head; NULL != op; op = op->next)
789 if (op->r_id == r_id)
790 break;
791 if ((NULL == it) && (NULL == op))
792 return;
793
794 if ((0 ==
795 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
796 {
797 if ((NULL == it) && (NULL == op))
798 {
799 GNUNET_break (0);
800 force_reconnect (h);
801 return;
802 }
803 if (NULL != it)
804 {
805 if (NULL != it->finish_cb)
806 it->finish_cb (it->finish_cb_cls);
807 free_it (it);
808 }
809 if (NULL != op)
810 {
811 if (NULL != op->ar_cb)
812 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
813 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
814 free_op (op);
815 }
816 return;
817 }
818
819 {
820 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
821 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
822 attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1],
823 attest_len);
824 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &msg[1]
825 + attest_len,
826 ref_len);
827 if (NULL != it)
828 {
829 if (NULL != it->proc)
830 it->proc (it->proc_cls, &msg->identity, NULL, attest, ref);
831 }
832 else if (NULL != op)
833 {
834 if (NULL != op->ar_cb)
835 op->ar_cb (op->cls, &msg->identity, NULL, attest, ref);
836 }
837 GNUNET_free (ref);
838 GNUNET_free (attest);
839 return;
840 }
841 GNUNET_assert (0);
842}
626 843
627/** 844/**
628 * Handle an incoming message of type 845 * Handle an incoming message of type
@@ -742,6 +959,14 @@ reconnect (struct GNUNET_RECLAIM_Handle *h)
742 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT, 959 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
743 struct AttributeResultMessage, 960 struct AttributeResultMessage,
744 h), 961 h),
962 GNUNET_MQ_hd_var_size (attestation_result,
963 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT,
964 struct AttributeResultMessage,
965 h),
966 GNUNET_MQ_hd_var_size (reference_result,
967 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT,
968 struct ReferenceResultMessage,
969 h),
745 GNUNET_MQ_hd_fixed_size (ticket_result, 970 GNUNET_MQ_hd_fixed_size (ticket_result,
746 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT, 971 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
747 struct TicketResultMessage, 972 struct TicketResultMessage,
@@ -925,6 +1150,185 @@ GNUNET_RECLAIM_attribute_delete (
925 return op; 1150 return op;
926} 1151}
927 1152
1153/**
1154 * Store an attestation. If the attestation is already present,
1155 * it is replaced with the new attestation.
1156 *
1157 * @param h handle to the re:claimID service
1158 * @param pkey private key of the identity
1159 * @param attr the attestation value
1160 * @param exp_interval the relative expiration interval for the attestation
1161 * @param cont continuation to call when done
1162 * @param cont_cls closure for @a cont
1163 * @return handle to abort the request
1164 */
1165struct GNUNET_RECLAIM_Operation *
1166GNUNET_RECLAIM_attestation_store (
1167 struct GNUNET_RECLAIM_Handle *h,
1168 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1169 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
1170 const struct GNUNET_TIME_Relative *exp_interval,
1171 GNUNET_RECLAIM_ContinuationWithStatus cont,
1172 void *cont_cls)
1173{
1174 struct GNUNET_RECLAIM_Operation *op;
1175 struct AttributeStoreMessage *sam;
1176 size_t attr_len;
1177
1178 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1179 op->h = h;
1180 op->as_cb = cont;
1181 op->cls = cont_cls;
1182 op->r_id = h->r_id_gen++;
1183 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1184 attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attr);
1185 op->env = GNUNET_MQ_msg_extra (sam,
1186 attr_len,
1187 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE);
1188 sam->identity = *pkey;
1189 sam->id = htonl (op->r_id);
1190 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1191
1192 GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &sam[1]);
1193
1194 sam->attr_len = htons (attr_len);
1195 if (NULL != h->mq)
1196 GNUNET_MQ_send_copy (h->mq, op->env);
1197 return op;
1198}
1199
1200/**
1201 * Delete an attestation. Tickets used to share this attestation are updated
1202 * accordingly.
1203 *
1204 * @param h handle to the re:claimID service
1205 * @param pkey Private key of the identity to add an attribute to
1206 * @param attr The attestation
1207 * @param cont Continuation to call when done
1208 * @param cont_cls Closure for @a cont
1209 * @return handle Used to to abort the request
1210 */
1211struct GNUNET_RECLAIM_Operation *
1212GNUNET_RECLAIM_attestation_delete (
1213 struct GNUNET_RECLAIM_Handle *h,
1214 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1215 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
1216 GNUNET_RECLAIM_ContinuationWithStatus cont,
1217 void *cont_cls)
1218{
1219 struct GNUNET_RECLAIM_Operation *op;
1220 struct AttributeDeleteMessage *dam;
1221 size_t attr_len;
1222
1223 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1224 op->h = h;
1225 op->as_cb = cont;
1226 op->cls = cont_cls;
1227 op->r_id = h->r_id_gen++;
1228 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1229 attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attr);
1230 op->env = GNUNET_MQ_msg_extra (dam,
1231 attr_len,
1232 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE);
1233 dam->identity = *pkey;
1234 dam->id = htonl (op->r_id);
1235 GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &dam[1]);
1236
1237 dam->attr_len = htons (attr_len);
1238 if (NULL != h->mq)
1239 GNUNET_MQ_send_copy (h->mq, op->env);
1240 return op;
1241}
1242
1243/**
1244 * Store an attestation reference. If the reference is already present,
1245 * it is replaced with the new reference.
1246 *
1247 * @param h handle to the re:claimID service
1248 * @param pkey private key of the identity
1249 * @param attr the reference value
1250 * @param exp_interval the relative expiration interval for the reference
1251 * @param cont continuation to call when done
1252 * @param cont_cls closure for @a cont
1253 * @return handle to abort the request
1254 */
1255struct GNUNET_RECLAIM_Operation *
1256GNUNET_RECLAIM_attestation_reference_store (
1257 struct GNUNET_RECLAIM_Handle *h,
1258 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1259 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
1260 const struct GNUNET_TIME_Relative *exp_interval,
1261 GNUNET_RECLAIM_ContinuationWithStatus cont,
1262 void *cont_cls)
1263{
1264 struct GNUNET_RECLAIM_Operation *op;
1265 struct AttributeStoreMessage *sam;
1266 size_t attr_len;
1267 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1268 op->h = h;
1269 op->as_cb = cont;
1270 op->cls = cont_cls;
1271 op->r_id = h->r_id_gen++;
1272 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1273 attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
1274 op->env = GNUNET_MQ_msg_extra (sam,
1275 attr_len,
1276 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE);
1277 sam->identity = *pkey;
1278 sam->id = htonl (op->r_id);
1279 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1280
1281 GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &sam[1]);
1282
1283 sam->attr_len = htons (attr_len);
1284 if (NULL != h->mq)
1285 GNUNET_MQ_send_copy (h->mq, op->env);
1286 return op;
1287}
1288
1289/**
1290 * Delete an attestation reference. Tickets used to share this reference are updated
1291 * accordingly.
1292 *
1293 * @param h handle to the re:claimID service
1294 * @param pkey Private key of the identity to delete the reference from
1295 * @param attr The reference
1296 * @param cont Continuation to call when done
1297 * @param cont_cls Closure for @a cont
1298 * @return handle Used to to abort the request
1299 */
1300struct GNUNET_RECLAIM_Operation *
1301GNUNET_RECLAIM_attestation_reference_delete (
1302 struct GNUNET_RECLAIM_Handle *h,
1303 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1304 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
1305 GNUNET_RECLAIM_ContinuationWithStatus cont,
1306 void *cont_cls)
1307{
1308
1309 struct GNUNET_RECLAIM_Operation *op;
1310 struct AttributeDeleteMessage *dam;
1311 size_t attr_len;
1312
1313 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1314 op->h = h;
1315 op->as_cb = cont;
1316 op->cls = cont_cls;
1317 op->r_id = h->r_id_gen++;
1318 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1319 attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
1320 op->env = GNUNET_MQ_msg_extra (dam,
1321 attr_len,
1322 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE);
1323 dam->identity = *pkey;
1324 dam->id = htonl (op->r_id);
1325 GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &dam[1]);
1326
1327 dam->attr_len = htons (attr_len);
1328 if (NULL != h->mq)
1329 GNUNET_MQ_send_copy (h->mq, op->env);
1330 return op;
1331}
928 1332
929/** 1333/**
930 * List all attributes for a local identity. 1334 * List all attributes for a local identity.
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index c37a34ab7..077c0409a 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -1527,15 +1527,15 @@ test_transport_api_slow_ats_peer2.conf \
1527 tcp_server_mst_legacy.c \ 1527 tcp_server_mst_legacy.c \
1528 tcp_server_legacy.c \ 1528 tcp_server_legacy.c \
1529 tcp_service_legacy.c \ 1529 tcp_service_legacy.c \
1530test_communicator_basic_unix_peer1.conf \ 1530test_communicator_unix_basic_peer1.conf \
1531test_communicator_basic_unix_peer2.conf \ 1531test_communicator_unix_basic_peer2.conf \
1532test_communicator_basic_tcp_peer1.conf \ 1532test_communicator_tcp_basic_peer1.conf \
1533test_communicator_basic_tcp_peer2.conf \ 1533test_communicator_tcp_basic_peer2.conf \
1534test_communicator_basic_udp_peer1.conf \ 1534test_communicator_udp_basic_peer1.conf \
1535test_communicator_basic_udp_peer2.conf \ 1535test_communicator_udp_basic_peer2.conf \
1536test_communicator_rekey_tcp_peer1.conf \ 1536test_communicator_tcp_rekey_peer1.conf \
1537test_communicator_rekey_tcp_peer2.conf \ 1537test_communicator_tcp_rekey_peer2.conf \
1538test_communicator_rekey_udp_peer1.conf \ 1538test_communicator_udp_rekey_peer1.conf \
1539test_communicator_rekey_udp_peer2.conf \ 1539test_communicator_udp_rekey_peer2.conf \
1540test_communicator_backchannel_udp_peer1.conf \ 1540test_communicator_udp_backchannel_peer1.conf \
1541test_communicator_backchannel_udp_peer2.conf 1541test_communicator_udp_backchannel_peer2.conf
diff --git a/src/transport/test_communicator_unix_peer1.conf b/src/transport/test_communicator_unix_basic_peer1.conf
index d50588007..d50588007 100644
--- a/src/transport/test_communicator_unix_peer1.conf
+++ b/src/transport/test_communicator_unix_basic_peer1.conf
diff --git a/src/util/.gitignore b/src/util/.gitignore
index 01ebcc834..84c13708e 100644
--- a/src/util/.gitignore
+++ b/src/util/.gitignore
@@ -1,6 +1,7 @@
1test_common_logging_dummy 1test_common_logging_dummy
2gnunet-config 2gnunet-config
3gnunet-config-diff 3gnunet-config-diff
4gnunet-crypto-tvg
4gnunet-ecc 5gnunet-ecc
5gnunet-qr 6gnunet-qr
6gnunet-resolver 7gnunet-resolver
@@ -30,6 +31,7 @@ test_container_multihashmap32
30test_container_multipeermap 31test_container_multipeermap
31test_crypto_crc 32test_crypto_crc
32test_crypto_ecc_dlog 33test_crypto_ecc_dlog
34test_crypto_ecdh_ecdsa
33test_crypto_ecdh_eddsa 35test_crypto_ecdh_eddsa
34test_crypto_ecdhe 36test_crypto_ecdhe
35test_crypto_ecdsa 37test_crypto_ecdsa
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 0f6251f96..fc8f424dc 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -39,6 +39,7 @@ libgnunetutil_la_SOURCES = \
39 bandwidth.c \ 39 bandwidth.c \
40 $(BENCHMARK) \ 40 $(BENCHMARK) \
41 bio.c \ 41 bio.c \
42 buffer.c \
42 client.c \ 43 client.c \
43 common_allocation.c \ 44 common_allocation.c \
44 common_endian.c \ 45 common_endian.c \
@@ -138,41 +139,11 @@ libgnunetutil_la_LDFLAGS = \
138 $(GN_LIB_LDFLAGS) \ 139 $(GN_LIB_LDFLAGS) \
139 -version-info 13:2:0 140 -version-info 13:2:0
140 141
141libgnunetutil_taler_wallet_la_SOURCES = \
142 common_allocation.c \
143 common_endian.c \
144 common_logging.c \
145 container_heap.c \
146 container_multihashmap.c \
147 container_multihashmap32.c \
148 crypto_symmetric.c \
149 crypto_crc.c \
150 crypto_ecc.c \
151 crypto_hash.c \
152 crypto_hkdf.c \
153 crypto_kdf.c \
154 crypto_mpi.c \
155 crypto_random.c \
156 crypto_rsa.c \
157 strings.c \
158 time.c
159
160libgnunetutil_taler_wallet_la_LIBADD = \
161 $(LIBGCRYPT_LIBS) \
162 -lunistring
163
164libgnunetutil_taler_wallet_la_LDFLAGS = \
165 $(GN_LIB_LDFLAGS) \
166 -version-info 0:0:0
167
168if HAVE_TESTING 142if HAVE_TESTING
169 GNUNET_ECC = gnunet-ecc 143 GNUNET_ECC = gnunet-ecc
170 GNUNET_SCRYPT = gnunet-scrypt 144 GNUNET_SCRYPT = gnunet-scrypt
171endif 145endif
172 146
173if TALER_ONLY
174lib_LTLIBRARIES = libgnunetutil_taler_wallet.la
175else
176lib_LTLIBRARIES = libgnunetutil.la 147lib_LTLIBRARIES = libgnunetutil.la
177 148
178libexec_PROGRAMS = \ 149libexec_PROGRAMS = \
@@ -182,6 +153,7 @@ libexec_PROGRAMS = \
182bin_PROGRAMS = \ 153bin_PROGRAMS = \
183 gnunet-resolver \ 154 gnunet-resolver \
184 gnunet-config \ 155 gnunet-config \
156 gnunet-crypto-tvg \
185 $(GNUNET_ECC) \ 157 $(GNUNET_ECC) \
186 $(GNUNET_SCRYPT) \ 158 $(GNUNET_SCRYPT) \
187 gnunet-uri 159 gnunet-uri
@@ -199,8 +171,6 @@ AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PAT
199TESTS = $(check_PROGRAMS) 171TESTS = $(check_PROGRAMS)
200endif 172endif
201 173
202endif
203
204gnunet_timeout_SOURCES = \ 174gnunet_timeout_SOURCES = \
205 gnunet-timeout.c 175 gnunet-timeout.c
206 176
@@ -220,6 +190,11 @@ gnunet_resolver_LDADD = \
220 libgnunetutil.la \ 190 libgnunetutil.la \
221 $(GN_LIBINTL) 191 $(GN_LIBINTL)
222 192
193gnunet_crypto_tvg_SOURCES = \
194 gnunet-crypto-tvg.c
195gnunet_crypto_tvg_LDADD = \
196 libgnunetutil.la \
197 $(GN_LIBINTL) -lgcrypt
223 198
224gnunet_ecc_SOURCES = \ 199gnunet_ecc_SOURCES = \
225 gnunet-ecc.c 200 gnunet-ecc.c
@@ -298,6 +273,7 @@ check_PROGRAMS = \
298 test_crypto_eddsa \ 273 test_crypto_eddsa \
299 test_crypto_ecdhe \ 274 test_crypto_ecdhe \
300 test_crypto_ecdh_eddsa \ 275 test_crypto_ecdh_eddsa \
276 test_crypto_ecdh_ecdsa \
301 test_crypto_ecc_dlog \ 277 test_crypto_ecc_dlog \
302 test_crypto_hash \ 278 test_crypto_hash \
303 test_crypto_hash_context \ 279 test_crypto_hash_context \
@@ -476,6 +452,13 @@ test_crypto_ecdh_eddsa_LDADD = \
476 libgnunetutil.la \ 452 libgnunetutil.la \
477 $(LIBGCRYPT_LIBS) 453 $(LIBGCRYPT_LIBS)
478 454
455test_crypto_ecdh_ecdsa_SOURCES = \
456 test_crypto_ecdh_ecdsa.c
457test_crypto_ecdh_ecdsa_LDADD = \
458 libgnunetutil.la \
459 $(LIBGCRYPT_LIBS)
460
461
479test_crypto_hash_SOURCES = \ 462test_crypto_hash_SOURCES = \
480 test_crypto_hash.c 463 test_crypto_hash.c
481test_crypto_hash_LDADD = \ 464test_crypto_hash_LDADD = \
diff --git a/src/util/buffer.c b/src/util/buffer.c
new file mode 100644
index 000000000..d89565d68
--- /dev/null
+++ b/src/util/buffer.c
@@ -0,0 +1,226 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2020 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify it under the
6 terms of the GNU Affero General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
12
13 You should have received a copy of the GNU Affero General Public License along with
14 GNUnet; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15*/
16/**
17 * @file buffer.c
18 * @brief Common buffer management functions.
19 * @author Florian Dold
20 */
21#include "platform.h"
22#include "gnunet_util_lib.h"
23#include "gnunet_buffer_lib.h"
24
25/**
26 * Initialize a buffer with the given capacity.
27 *
28 * When a buffer is allocated with this function, a warning is logged
29 * when the buffer exceeds the initial capacity.
30 *
31 * @param buf the buffer to initialize
32 * @param capacity the capacity (in bytes) to allocate for @a buf
33 */
34void
35GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity)
36{
37 /* Buffer should be zero-initialized */
38 GNUNET_assert (0 == buf->mem);
39 GNUNET_assert (0 == buf->capacity);
40 GNUNET_assert (0 == buf->position);
41 buf->mem = GNUNET_malloc (capacity);
42 buf->capacity = capacity;
43 buf->warn_grow = GNUNET_YES;
44}
45
46
47/**
48 * Make sure that at least @a n bytes remaining in the buffer.
49 *
50 * @param buf buffer to potentially grow
51 * @param n number of bytes that should be available to write
52 */
53void
54GNUNET_buffer_ensure_remaining (struct GNUNET_Buffer *buf, size_t n)
55{
56 size_t new_capacity = buf->position + n;
57
58 if (new_capacity <= buf->capacity)
59 return;
60 /* warn if calculation of expected size was wrong */
61 GNUNET_break (GNUNET_YES != buf->warn_grow);
62 if (new_capacity < buf->capacity * 2)
63 new_capacity = buf->capacity * 2;
64 buf->capacity = new_capacity;
65 if (NULL != buf->mem)
66 buf->mem = GNUNET_realloc (buf->mem, new_capacity);
67 else
68 buf->mem = GNUNET_malloc (new_capacity);
69}
70
71
72/**
73 * Write bytes to the buffer.
74 *
75 * Grows the buffer if necessary.
76 *
77 * @param buf buffer to write to
78 * @param data data to read from
79 * @param len number of bytes to copy from @a data to @a buf
80 *
81 */
82void
83GNUNET_buffer_write (struct GNUNET_Buffer *buf, const char *data, size_t len)
84{
85 GNUNET_buffer_ensure_remaining (buf, len);
86 memcpy (buf->mem + buf->position, data, len);
87 buf->position += len;
88}
89
90
91/**
92 * Write a 0-terminated string to a buffer, excluding the 0-terminator.
93 *
94 * @param buf the buffer to write to
95 * @param str the string to write to @a buf
96 */
97void
98GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str)
99{
100 size_t len = strlen (str);
101
102 GNUNET_buffer_write (buf, str, len);
103}
104
105
106/**
107 * Clear the buffer and return the string it contained.
108 * The caller is responsible to eventually #GNUNET_free
109 * the returned string.
110 *
111 * The returned string is always 0-terminated.
112 *
113 * @param buf the buffer to reap the string from
114 * @returns the buffer contained in the string
115 */
116char *
117GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf)
118{
119 char *res;
120
121 /* ensure 0-termination */
122 if ( (0 == buf->position) || ('\0' != buf->mem[buf->position - 1]))
123 {
124 GNUNET_buffer_ensure_remaining (buf, 1);
125 buf->mem[buf->position++] = '\0';
126 }
127 res = buf->mem;
128 *buf = (struct GNUNET_Buffer) { 0 };
129 return res;
130}
131
132
133/**
134 * Free the backing memory of the given buffer.
135 * Does not free the memory of the buffer control structure,
136 * which is typically stack-allocated.
137 */
138void
139GNUNET_buffer_clear (struct GNUNET_Buffer *buf)
140{
141 GNUNET_free_non_null (buf->mem);
142 *buf = (struct GNUNET_Buffer) { 0 };
143}
144
145
146/**
147 * Write a path component to a buffer, ensuring that
148 * there is exactly one slash between the previous contents
149 * of the buffer and the new string.
150 *
151 * @param buf buffer to write to
152 * @param str string containing the new path component
153 */
154void
155GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str)
156{
157 size_t len = strlen (str);
158
159 while ( (0 != len) && ('/' == str[0]) )
160 {
161 str++;
162 len--;
163 }
164 if ( (0 == buf->position) || ('/' != buf->mem[buf->position - 1]) )
165 {
166 GNUNET_buffer_ensure_remaining (buf, 1);
167 buf->mem[buf->position++] = '/';
168 }
169 GNUNET_buffer_write (buf, str, len);
170}
171
172
173/**
174 * Write a 0-terminated formatted string to a buffer, excluding the
175 * 0-terminator.
176 *
177 * Grows the buffer if necessary.
178 *
179 * @param buf the buffer to write to
180 * @param fmt format string
181 * @param ... format arguments
182 */
183void
184GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...)
185{
186 va_list args;
187
188 va_start (args, fmt);
189 GNUNET_buffer_write_vfstr (buf, fmt, args);
190 va_end (args);
191}
192
193
194/**
195 * Write a 0-terminated formatted string to a buffer, excluding the
196 * 0-terminator.
197 *
198 * Grows the buffer if necessary.
199 *
200 * @param buf the buffer to write to
201 * @param fmt format string
202 * @param args format argument list
203 */
204void
205GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf,
206 const char *fmt,
207 va_list args)
208{
209 int res;
210 va_list args2;
211
212 va_copy (args2, args);
213 res = vsnprintf (NULL, 0, fmt, args2);
214 va_end (args2);
215
216 GNUNET_assert (res >= 0);
217 GNUNET_buffer_ensure_remaining (buf, res + 1);
218
219 va_copy (args2, args);
220 res = vsnprintf (buf->mem + buf->position, res + 1, fmt, args2);
221 va_end (args2);
222
223 GNUNET_assert (res >= 0);
224 buf->position += res;
225 GNUNET_assert (buf->position <= buf->capacity);
226}
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 430f75e70..27ac88a05 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -294,7 +294,6 @@ resize_logdefs ()
294} 294}
295 295
296 296
297#if ! TALER_WALLET_ONLY
298/** 297/**
299 * Rotate logs, deleting the oldest log. 298 * Rotate logs, deleting the oldest log.
300 * 299 *
@@ -403,9 +402,6 @@ setup_log_file (const struct tm *tm)
403} 402}
404 403
405 404
406#endif
407
408
409/** 405/**
410 * Utility function - adds a parsed definition to logdefs array. 406 * Utility function - adds a parsed definition to logdefs array.
411 * 407 *
@@ -731,7 +727,7 @@ GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
731 log_file_name = GNUNET_STRINGS_filename_expand (logfile); 727 log_file_name = GNUNET_STRINGS_filename_expand (logfile);
732 if (NULL == log_file_name) 728 if (NULL == log_file_name)
733 return GNUNET_SYSERR; 729 return GNUNET_SYSERR;
734#if TALER_WALLET_ONLY || defined(GNUNET_CULL_LOGGING) 730#if defined(GNUNET_CULL_LOGGING)
735 /* log file option not allowed for wallet logic */ 731 /* log file option not allowed for wallet logic */
736 GNUNET_assert (NULL == logfile); 732 GNUNET_assert (NULL == logfile);
737 return GNUNET_OK; 733 return GNUNET_OK;
@@ -1023,7 +1019,7 @@ mylog (enum GNUNET_ErrorType kind,
1023 } 1019 }
1024 1020
1025 vsnprintf (buf, size, message, va); 1021 vsnprintf (buf, size, message, va);
1026#if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY) 1022#if ! defined(GNUNET_CULL_LOGGING)
1027 if (NULL != tmptr) 1023 if (NULL != tmptr)
1028 (void) setup_log_file (tmptr); 1024 (void) setup_log_file (tmptr);
1029#endif 1025#endif
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index bd7c425d4..237062eb7 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -173,22 +173,8 @@ GNUNET_CRYPTO_ecdsa_key_get_public (
173 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, 173 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
174 struct GNUNET_CRYPTO_EcdsaPublicKey *pub) 174 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
175{ 175{
176 gcry_sexp_t sexp;
177 gcry_ctx_t ctx;
178 gcry_mpi_t q;
179
180 BENCHMARK_START (ecdsa_key_get_public); 176 BENCHMARK_START (ecdsa_key_get_public);
181 177 GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (pub->q_y, priv->d);
182 sexp = decode_private_ecdsa_key (priv);
183 GNUNET_assert (NULL != sexp);
184 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
185 gcry_sexp_release (sexp);
186 q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
187 GNUNET_assert (NULL != q);
188 GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof(pub->q_y), q);
189 gcry_mpi_release (q);
190 gcry_ctx_release (ctx);
191
192 BENCHMARK_END (ecdsa_key_get_public); 178 BENCHMARK_END (ecdsa_key_get_public);
193} 179}
194 180
@@ -1041,45 +1027,6 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (
1041 1027
1042 1028
1043/** 1029/**
1044 * Take point from ECDH and convert it to key material.
1045 *
1046 * @param result point from ECDH
1047 * @param ctx ECC context
1048 * @param key_material[out] set to derived key material
1049 * @return #GNUNET_OK on success
1050 */
1051static int
1052point_to_hash (gcry_mpi_point_t result,
1053 gcry_ctx_t ctx,
1054 struct GNUNET_HashCode *key_material)
1055{
1056 gcry_mpi_t result_x;
1057 unsigned char xbuf[256 / 8];
1058 size_t rsize;
1059
1060 /* finally, convert point to string for hashing */
1061 result_x = gcry_mpi_new (256);
1062 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1063 {
1064 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1065 return GNUNET_SYSERR;
1066 }
1067
1068 rsize = sizeof(xbuf);
1069 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1070 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1071 as that does not include the sign bit; x should be a 255-bit
1072 value, so with the sign it should fit snugly into the 256-bit
1073 xbuf */
1074 GNUNET_assert (
1075 0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1076 GNUNET_CRYPTO_hash (xbuf, rsize, key_material);
1077 gcry_mpi_release (result_x);
1078 return GNUNET_OK;
1079}
1080
1081
1082/**
1083 * @ingroup crypto 1030 * @ingroup crypto
1084 * Derive key material from a ECDH public key and a private EdDSA key. 1031 * Derive key material from a ECDH public key and a private EdDSA key.
1085 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa. 1032 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa.
@@ -1125,41 +1072,18 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1125 const struct GNUNET_CRYPTO_EcdhePublicKey *pub, 1072 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1126 struct GNUNET_HashCode *key_material) 1073 struct GNUNET_HashCode *key_material)
1127{ 1074{
1128 gcry_mpi_point_t result; 1075 uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
1129 gcry_mpi_point_t q; 1076 uint8_t d_rev[GNUNET_TWEETNACL_SCALARMULT_BYTES];
1130 gcry_mpi_t d;
1131 gcry_ctx_t ctx;
1132 gcry_sexp_t pub_sexpr;
1133 int ret;
1134 1077
1135 BENCHMARK_START (ecdsa_ecdh); 1078 BENCHMARK_START (ecdsa_ecdh);
1136 1079 for (size_t i = 0; i < 32; i++)
1137 /* first, extract the q = dP value from the public key */ 1080 d_rev[i] = priv->d[31 - i];
1138 if (0 != gcry_sexp_build (&pub_sexpr, 1081 GNUNET_TWEETNACL_scalarmult_curve25519 (p, d_rev, pub->q_y);
1139 NULL, 1082 GNUNET_CRYPTO_hash (p,
1140 "(public-key(ecc(curve " CURVE ")(q %b)))", 1083 GNUNET_TWEETNACL_SCALARMULT_BYTES,
1141 (int) sizeof(pub->q_y), 1084 key_material);
1142 pub->q_y))
1143 return GNUNET_SYSERR;
1144 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1145 gcry_sexp_release (pub_sexpr);
1146 q = gcry_mpi_ec_get_point ("q", ctx, 0);
1147
1148 /* second, extract the d value from our private key */
1149 GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
1150
1151 /* then call the 'multiply' function, to compute the product */
1152 result = gcry_mpi_point_new (0);
1153 gcry_mpi_ec_mul (result, d, q, ctx);
1154 gcry_mpi_point_release (q);
1155 gcry_mpi_release (d);
1156
1157 /* finally, convert point to string for hashing */
1158 ret = point_to_hash (result, ctx, key_material);
1159 gcry_mpi_point_release (result);
1160 gcry_ctx_release (ctx);
1161 BENCHMARK_END (ecdsa_ecdh); 1085 BENCHMARK_END (ecdsa_ecdh);
1162 return ret; 1086 return GNUNET_OK;
1163} 1087}
1164 1088
1165 1089
@@ -1191,7 +1115,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1191/** 1115/**
1192 * @ingroup crypto 1116 * @ingroup crypto
1193 * Derive key material from a ECDSA public key and a private ECDH key. 1117 * Derive key material from a ECDSA public key and a private ECDH key.
1194 * Dual to #GNUNET_CRRYPTO_eddsa_ecdh. 1118 * Dual to #GNUNET_CRYPTO_ecdsa_ecdh.
1195 * 1119 *
1196 * @param priv private key to use for the ECDH (y) 1120 * @param priv private key to use for the ECDH (y)
1197 * @param pub public key from ECDSA to use for the ECDH (X=h(x)G) 1121 * @param pub public key from ECDSA to use for the ECDH (X=h(x)G)
@@ -1203,10 +1127,13 @@ GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1203 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, 1127 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1204 struct GNUNET_HashCode *key_material) 1128 struct GNUNET_HashCode *key_material)
1205{ 1129{
1206 return GNUNET_CRYPTO_ecdh_eddsa (priv, 1130 uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
1207 (const struct GNUNET_CRYPTO_EddsaPublicKey *) 1131 uint8_t curve25510_pk[GNUNET_TWEETNACL_SIGN_PUBLICBYTES];
1208 pub, 1132
1209 key_material); 1133 GNUNET_TWEETNACL_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y);
1134 GNUNET_TWEETNACL_scalarmult_curve25519 (p, priv->d, curve25510_pk);
1135 GNUNET_CRYPTO_hash (p, GNUNET_TWEETNACL_SCALARMULT_BYTES, key_material);
1136 return GNUNET_OK;
1210} 1137}
1211 1138
1212 1139
diff --git a/src/util/gnunet-crypto-tvg.c b/src/util/gnunet-crypto-tvg.c
new file mode 100644
index 000000000..7d151c10b
--- /dev/null
+++ b/src/util/gnunet-crypto-tvg.c
@@ -0,0 +1,278 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file util/gnunet-crypto-tgv.c
23 * @brief Generate test vectors for cryptographic operations.
24 * @author Florian Dold
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h"
29#include "gnunet_testing_lib.h"
30#include <gcrypt.h>
31
32GNUNET_NETWORK_STRUCT_BEGIN
33
34/**
35 * Sample signature struct.
36 *
37 * Purpose is #GNUNET_SIGNATURE_PURPOSE_TEST
38 */
39struct TestSignatureDataPS
40{
41 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
42 uint32_t testval;
43};
44
45GNUNET_NETWORK_STRUCT_END
46
47
48/**
49 * Print data base32-crockford with a preceding label.
50 *
51 * @param label label to print
52 * @param data data to print
53 * @param size size of data
54 */
55static void
56display_data (char *label, void *data, size_t size)
57{
58 char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size);
59 printf ("%s %s\n", label, enc);
60 GNUNET_free (enc);
61}
62
63
64/**
65 * Main function that will be run.
66 *
67 * @param cls closure
68 * @param args remaining command-line arguments
69 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
70 * @param cfg configuration
71 */
72static void
73run (void *cls,
74 char *const *args,
75 const char *cfgfile,
76 const struct GNUNET_CONFIGURATION_Handle *cfg)
77{
78 {
79 struct GNUNET_HashCode hc;
80 char *str = "Hello, GNUnet";
81
82 GNUNET_CRYPTO_hash (str, strlen (str), &hc);
83
84 printf ("hash code:\n");
85 display_data (" input", str, strlen (str));
86 display_data (" output", &hc, sizeof (struct GNUNET_HashCode));
87 }
88 {
89 struct GNUNET_CRYPTO_EcdhePrivateKey *priv1;
90 struct GNUNET_CRYPTO_EcdhePublicKey pub1;
91 struct GNUNET_CRYPTO_EcdhePrivateKey *priv2;
92 struct GNUNET_HashCode skm;
93 priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
94 priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
95 GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
96 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &skm));
97
98 printf ("ecdhe key:\n");
99 display_data (" priv1", priv1, sizeof (struct
100 GNUNET_CRYPTO_EcdhePrivateKey));
101 display_data (" pub1", &pub1, sizeof (struct
102 GNUNET_CRYPTO_EcdhePublicKey));
103 display_data (" priv2", priv2, sizeof (struct
104 GNUNET_CRYPTO_EcdhePrivateKey));
105 display_data (" skm", &skm, sizeof (struct GNUNET_HashCode));
106 GNUNET_free (priv1);
107 GNUNET_free (priv2);
108 }
109
110 {
111 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
112 struct GNUNET_CRYPTO_EddsaPublicKey pub;
113 priv = GNUNET_CRYPTO_eddsa_key_create ();
114 GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
115
116 printf ("eddsa key:\n");
117 display_data (" priv", priv, sizeof (struct
118 GNUNET_CRYPTO_EddsaPrivateKey));
119 display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
120 GNUNET_free (priv);
121 }
122 {
123 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
124 struct GNUNET_CRYPTO_EddsaPublicKey pub;
125 struct GNUNET_CRYPTO_EddsaSignature sig;
126 struct TestSignatureDataPS data = { 0 };
127 priv = GNUNET_CRYPTO_eddsa_key_create ();
128 GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
129 data.purpose.size = htonl (sizeof (struct TestSignatureDataPS));
130 data.purpose.size = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
131 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (priv, &data.purpose,
132 &sig));
133 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_verify (0,
134 &data.purpose,
135 &sig,
136 &pub));
137
138 printf ("eddsa sig:\n");
139 display_data (" priv", priv, sizeof (struct
140 GNUNET_CRYPTO_EddsaPrivateKey));
141 display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
142 display_data (" data", &data, sizeof (struct TestSignatureDataPS));
143 display_data (" sig", &sig, sizeof (struct GNUNET_CRYPTO_EddsaSignature));
144 GNUNET_free (priv);
145 }
146
147 {
148 size_t out_len = 64;
149 char out[out_len];
150 char *ikm = "I'm the secret input key material";
151 char *salt = "I'm very salty";
152 char *ctx = "I'm a context chunk, also known as 'info' in the RFC";
153
154 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_kdf (&out,
155 out_len,
156 salt,
157 strlen (salt),
158 ikm,
159 strlen (ikm),
160 ctx,
161 strlen (ctx),
162 NULL));
163
164 printf ("kdf:\n");
165 display_data (" salt", salt, strlen (salt));
166 display_data (" ikm", ikm, strlen (ikm));
167 display_data (" ctx", ctx, strlen (ctx));
168 printf (" out_len %u\n", (unsigned int) out_len);
169 display_data (" out", out, out_len);
170 }
171 {
172 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdhe;
173 struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe;
174 struct GNUNET_CRYPTO_EddsaPrivateKey *priv_eddsa;
175 struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa;
176 struct GNUNET_HashCode key_material;
177 priv_ecdhe = GNUNET_CRYPTO_ecdhe_key_create ();
178 GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdhe, &pub_ecdhe);
179 priv_eddsa = GNUNET_CRYPTO_eddsa_key_create ();
180 GNUNET_CRYPTO_eddsa_key_get_public (priv_eddsa, &pub_eddsa);
181 GNUNET_CRYPTO_ecdh_eddsa (priv_ecdhe, &pub_eddsa, &key_material);
182
183 printf ("eddsa_ecdh:\n");
184 display_data (" priv_ecdhe", priv_ecdhe, sizeof (struct
185 GNUNET_CRYPTO_EcdhePrivateKey));
186 display_data (" pub_ecdhe", &pub_ecdhe, sizeof (struct
187 GNUNET_CRYPTO_EcdhePublicKey));
188 display_data (" priv_eddsa", priv_eddsa, sizeof (struct
189 GNUNET_CRYPTO_EddsaPrivateKey));
190 display_data (" pub_eddsa", &pub_eddsa, sizeof (struct
191 GNUNET_CRYPTO_EddsaPublicKey));
192 display_data (" key_material", &key_material, sizeof (struct
193 GNUNET_HashCode));
194 }
195
196 {
197 struct GNUNET_CRYPTO_RsaPrivateKey *skey;
198 struct GNUNET_CRYPTO_RsaPublicKey *pkey;
199 struct GNUNET_HashCode message_hash;
200 struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
201 struct GNUNET_CRYPTO_RsaSignature *blinded_sig;
202 struct GNUNET_CRYPTO_RsaSignature *sig;
203 char *blinded_data;
204 size_t blinded_len;
205 char *public_enc_data;
206 size_t public_enc_len;
207 char *blinded_sig_enc_data;
208 size_t blinded_sig_enc_length;
209 char *sig_enc_data;
210 size_t sig_enc_length;
211 skey = GNUNET_CRYPTO_rsa_private_key_create (2048);
212 pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey);
213 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &message_hash,
214 sizeof (struct GNUNET_HashCode));
215 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &bks, sizeof (struct
216 GNUNET_CRYPTO_RsaBlindingKeySecret));
217 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_blind (&message_hash, &bks,
218 pkey, &blinded_data,
219 &blinded_len));
220 blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data,
221 blinded_len);
222 sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey);
223 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig,
224 pkey));
225 public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey,
226 &public_enc_data);
227 blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig,
228 &
229 blinded_sig_enc_data);
230 sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data);
231 printf ("blind signing:\n");
232 display_data (" message_hash", &message_hash, sizeof (struct
233 GNUNET_HashCode));
234 display_data (" rsa_public_key", public_enc_data, public_enc_len);
235 display_data (" blinding_key_secret", &bks, sizeof (struct
236 GNUNET_CRYPTO_RsaBlindingKeySecret));
237 display_data (" blinded_message", blinded_data, blinded_len);
238 display_data (" blinded_sig", blinded_sig_enc_data,
239 blinded_sig_enc_length);
240 display_data (" sig", sig_enc_data, sig_enc_length);
241 GNUNET_CRYPTO_rsa_private_key_free (skey);
242 GNUNET_CRYPTO_rsa_public_key_free (pkey);
243 GNUNET_CRYPTO_rsa_signature_free (sig);
244 GNUNET_CRYPTO_rsa_signature_free (blinded_sig);
245 }
246}
247
248
249/**
250 * The main function of the test vector generation tool.
251 *
252 * @param argc number of arguments from the command line
253 * @param argv command line arguments
254 * @return 0 ok, 1 on error
255 */
256int
257main (int argc,
258 char *const *argv)
259{
260 const struct GNUNET_GETOPT_CommandLineOption options[] = {
261 GNUNET_GETOPT_OPTION_END
262 };
263
264 GNUNET_assert (GNUNET_OK ==
265 GNUNET_log_setup ("gnunet-crypto-tvg",
266 "INFO",
267 NULL));
268 if (GNUNET_OK !=
269 GNUNET_PROGRAM_run (argc, argv,
270 "gnunet-crypto-tvg",
271 "Generate test vectors for cryptographic operations",
272 options,
273 &run, NULL))
274 return 1;
275 return 0;
276}
277
278/* end of gnunet-crypto-tvg.c */
diff --git a/src/util/test_crypto_ecdh_ecdsa.c b/src/util/test_crypto_ecdh_ecdsa.c
new file mode 100644
index 000000000..8a581ef73
--- /dev/null
+++ b/src/util/test_crypto_ecdh_ecdsa.c
@@ -0,0 +1,97 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2002-2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19
20 */
21/**
22 * @file util/test_crypto_ecdh_ecdsa.c
23 * @brief testcase for ECC DH key exchange with ECDSA private keys.
24 * @author Christian Grothoff
25 * @author Bart Polot
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include <gcrypt.h>
30
31
32static int
33test_ecdh ()
34{
35 struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_dsa;
36 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh;
37 struct GNUNET_CRYPTO_EcdsaPublicKey id1;
38 struct GNUNET_CRYPTO_EcdhePublicKey id2;
39 struct GNUNET_HashCode dh[2];
40
41 /* Generate keys */
42 priv_dsa = GNUNET_CRYPTO_ecdsa_key_create ();
43 GNUNET_CRYPTO_ecdsa_key_get_public (priv_dsa,
44 &id1);
45 for (unsigned int j = 0; j < 4; j++)
46 {
47 fprintf (stderr, ",");
48 priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create ();
49 /* Extract public keys */
50 GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh,
51 &id2);
52 /* Do ECDH */
53 GNUNET_assert (GNUNET_OK ==
54 GNUNET_CRYPTO_ecdsa_ecdh (priv_dsa,
55 &id2,
56 &dh[0]));
57 GNUNET_assert (GNUNET_OK ==
58 GNUNET_CRYPTO_ecdh_ecdsa (priv_ecdh,
59 &id1,
60 &dh[1]));
61 /* Check that both DH results are equal. */
62 GNUNET_assert (0 == memcmp (&dh[0],
63 &dh[1],
64 sizeof(struct GNUNET_HashCode)));
65 GNUNET_free (priv_ecdh);
66 }
67 GNUNET_free (priv_dsa);
68 return 0;
69}
70
71
72int
73main (int argc, char *argv[])
74{
75 if (! gcry_check_version ("1.6.0"))
76 {
77 fprintf (stderr,
78 _ (
79 "libgcrypt has not the expected version (version %s is required).\n"),
80 "1.6.0");
81 return 0;
82 }
83 if (getenv ("GNUNET_GCRYPT_DEBUG"))
84 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
85 GNUNET_log_setup ("test-crypto-ecdh-ecdsa", "WARNING", NULL);
86 for (unsigned int i = 0; i < 4; i++)
87 {
88 fprintf (stderr,
89 ".");
90 if (0 != test_ecdh ())
91 return 1;
92 }
93 return 0;
94}
95
96
97/* end of test_crypto_ecdh_ecdsa.c */
diff --git a/src/util/tweetnacl-gnunet.c b/src/util/tweetnacl-gnunet.c
index 1c27730a4..f01667adb 100644
--- a/src/util/tweetnacl-gnunet.c
+++ b/src/util/tweetnacl-gnunet.c
@@ -424,8 +424,24 @@ GNUNET_TWEETNACL_sign_pk_from_seed (u8 *pk, const u8 *seed)
424 d[31] &= 127; 424 d[31] &= 127;
425 d[31] |= 64; 425 d[31] |= 64;
426 426
427 scalarbase (p,d); 427 scalarbase (p, d);
428 pack (pk,p); 428 pack (pk, p);
429}
430
431void
432GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (u8 *pk, const u8 *s)
433{
434 u8 d[64];
435 gf p[4];
436
437 // Treat s as little endian.
438 for (u32 i = 0; i < 32; i++)
439 d[i] = s[31 - i];
440
441 // For GNUnet, we don't normalize d
442
443 scalarbase (p, d);
444 pack (pk, p);
429} 445}
430 446
431void 447void
diff --git a/src/util/tweetnacl-gnunet.h b/src/util/tweetnacl-gnunet.h
index 239166ffc..d052d8824 100644
--- a/src/util/tweetnacl-gnunet.h
+++ b/src/util/tweetnacl-gnunet.h
@@ -47,4 +47,8 @@ GNUNET_TWEETNACL_sign_detached (uint8_t *sig,
47 const uint8_t *m, 47 const uint8_t *m,
48 uint64_t n, 48 uint64_t n,
49 const uint8_t *sk); 49 const uint8_t *sk);
50
51void
52GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (uint8_t *pk, const uint8_t *s);
53
50#endif 54#endif
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index 50c990b3a..62bc45e41 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -2940,7 +2940,8 @@ run (void *cls,
2940 struct in6_addr v6; 2940 struct in6_addr v6;
2941 char *binary; 2941 char *binary;
2942 2942
2943 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); 2943 cfg = cfg_;
2944 binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-vpn");
2944 2945
2945 if (GNUNET_YES != 2946 if (GNUNET_YES !=
2946 GNUNET_OS_check_helper_binary ( 2947 GNUNET_OS_check_helper_binary (
@@ -2949,8 +2950,8 @@ run (void *cls,
2949 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) // ipv4 only please! 2950 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) // ipv4 only please!
2950 { 2951 {
2951 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2952 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2952 "`%s' is not SUID, refusing to run.\n", 2953 "`%s' is not SUID or the path is invalid, refusing to run.\n",
2953 "gnunet-helper-vpn"); 2954 binary);
2954 GNUNET_free (binary); 2955 GNUNET_free (binary);
2955 global_ret = 1; 2956 global_ret = 1;
2956 /* we won't "really" exit here, as the 'service' is still running; 2957 /* we won't "really" exit here, as the 'service' is still running;
@@ -2958,8 +2959,6 @@ run (void *cls,
2958 anything either */ 2959 anything either */
2959 return; 2960 return;
2960 } 2961 }
2961 GNUNET_free (binary);
2962 cfg = cfg_;
2963 stats = GNUNET_STATISTICS_create ("vpn", cfg); 2962 stats = GNUNET_STATISTICS_create ("vpn", cfg);
2964 if (GNUNET_OK != 2963 if (GNUNET_OK !=
2965 GNUNET_CONFIGURATION_get_value_number (cfg, 2964 GNUNET_CONFIGURATION_get_value_number (cfg,
@@ -2989,6 +2988,7 @@ run (void *cls,
2989 GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname)) 2988 GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
2990 { 2989 {
2991 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME"); 2990 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
2991 GNUNET_free (binary);
2992 GNUNET_SCHEDULER_shutdown (); 2992 GNUNET_SCHEDULER_shutdown ();
2993 return; 2993 return;
2994 } 2994 }
@@ -3006,6 +3006,7 @@ run (void *cls,
3006 "VPN", 3006 "VPN",
3007 "IPV6ADDR", 3007 "IPV6ADDR",
3008 _ ("Must specify valid IPv6 address")); 3008 _ ("Must specify valid IPv6 address"));
3009 GNUNET_free (binary);
3009 GNUNET_SCHEDULER_shutdown (); 3010 GNUNET_SCHEDULER_shutdown ();
3010 GNUNET_free_non_null (ipv6addr); 3011 GNUNET_free_non_null (ipv6addr);
3011 return; 3012 return;
@@ -3033,6 +3034,7 @@ run (void *cls,
3033 "VPN", 3034 "VPN",
3034 "IPV4MASK", 3035 "IPV4MASK",
3035 _ ("Must specify valid IPv6 mask")); 3036 _ ("Must specify valid IPv6 mask"));
3037 GNUNET_free (binary);
3036 GNUNET_SCHEDULER_shutdown (); 3038 GNUNET_SCHEDULER_shutdown ();
3037 return; 3039 return;
3038 } 3040 }
@@ -3058,6 +3060,7 @@ run (void *cls,
3058 "VPN", 3060 "VPN",
3059 "IPV4ADDR", 3061 "IPV4ADDR",
3060 _ ("Must specify valid IPv4 address")); 3062 _ ("Must specify valid IPv4 address"));
3063 GNUNET_free (binary);
3061 GNUNET_SCHEDULER_shutdown (); 3064 GNUNET_SCHEDULER_shutdown ();
3062 GNUNET_free_non_null (ipv4addr); 3065 GNUNET_free_non_null (ipv4addr);
3063 return; 3066 return;
@@ -3074,6 +3077,7 @@ run (void *cls,
3074 "VPN", 3077 "VPN",
3075 "IPV4MASK", 3078 "IPV4MASK",
3076 _ ("Must specify valid IPv4 mask")); 3079 _ ("Must specify valid IPv4 mask"));
3080 GNUNET_free (binary);
3077 GNUNET_SCHEDULER_shutdown (); 3081 GNUNET_SCHEDULER_shutdown ();
3078 GNUNET_free_non_null (ipv4mask); 3082 GNUNET_free_non_null (ipv4mask);
3079 return; 3083 return;
@@ -3093,11 +3097,12 @@ run (void *cls,
3093 cadet_handle = GNUNET_CADET_connect (cfg_); 3097 cadet_handle = GNUNET_CADET_connect (cfg_);
3094 // FIXME never opens ports??? 3098 // FIXME never opens ports???
3095 helper_handle = GNUNET_HELPER_start (GNUNET_NO, 3099 helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3096 "gnunet-helper-vpn", 3100 binary,
3097 vpn_argv, 3101 vpn_argv,
3098 &message_token, 3102 &message_token,
3099 NULL, 3103 NULL,
3100 NULL); 3104 NULL);
3105 GNUNET_free (binary);
3101 GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); 3106 GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL);
3102} 3107}
3103 3108