aboutsummaryrefslogtreecommitdiff
path: root/src/abd
diff options
context:
space:
mode:
authorAndreas Ebner <a.e.bner@web.de>2019-10-07 11:48:07 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-10-07 12:18:42 +0200
commit1d468ecabd6c2ee5c0eae672292efa0f51bc9e48 (patch)
tree6b527980752f9603945e070c8187bfbb06232b6f /src/abd
parent5cc45c7ee6a3ac522e5a1f58010d4efdf4fd102f (diff)
downloadgnunet-1d468ecabd6c2ee5c0eae672292efa0f51bc9e48.tar.gz
gnunet-1d468ecabd6c2ee5c0eae672292efa0f51bc9e48.zip
Renamed credential service to abd, replaced all related functions, parameters, etc
Diffstat (limited to 'src/abd')
-rw-r--r--src/abd/Makefile.am111
-rw-r--r--src/abd/abd.conf.in5
-rw-r--r--src/abd/abd.h290
-rw-r--r--src/abd/abd_api.c556
-rw-r--r--src/abd/abd_serialization.c508
-rw-r--r--src/abd/abd_serialization.h165
-rw-r--r--src/abd/delegate_misc.c274
-rw-r--r--src/abd/delegate_misc.h36
-rw-r--r--src/abd/gnunet-abd.c1070
-rw-r--r--src/abd/gnunet-service-abd.c1751
-rw-r--r--src/abd/plugin_gnsrecord_abd.c349
-rw-r--r--src/abd/plugin_rest_credential.c1174
-rwxr-xr-xsrc/abd/test_abd_bi_and.sh98
-rwxr-xr-xsrc/abd/test_abd_bi_and2.sh94
-rwxr-xr-xsrc/abd/test_abd_bi_and3.sh96
-rwxr-xr-xsrc/abd/test_abd_bi_and4.sh83
-rwxr-xr-xsrc/abd/test_abd_bi_bw.sh87
-rwxr-xr-xsrc/abd/test_abd_bi_bw_link.sh92
-rwxr-xr-xsrc/abd/test_abd_bi_bw_link2.sh93
-rwxr-xr-xsrc/abd/test_abd_bi_fw.sh92
-rw-r--r--src/abd/test_abd_defaults.conf24
-rwxr-xr-xsrc/abd/test_abd_issue.sh46
-rw-r--r--src/abd/test_abd_lookup.conf28
-rwxr-xr-xsrc/abd/test_abd_own.sh140
-rwxr-xr-xsrc/abd/test_abd_verify.sh87
-rwxr-xr-xsrc/abd/test_abd_verify_and.sh86
-rwxr-xr-xsrc/abd/test_abd_verify_simple.sh56
-rwxr-xr-xsrc/abd/test_credential_collect.sh47
-rwxr-xr-xsrc/abd/test_credential_collect_rest.sh91
-rwxr-xr-xsrc/abd/test_credential_issue_rest.sh53
-rwxr-xr-xsrc/abd/test_credential_verify_rest.sh88
31 files changed, 7770 insertions, 0 deletions
diff --git a/src/abd/Makefile.am b/src/abd/Makefile.am
new file mode 100644
index 000000000..321fb0350
--- /dev/null
+++ b/src/abd/Makefile.am
@@ -0,0 +1,111 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4EXTRA_DIST = \
5 test_abd_defaults.conf \
6 test_abd_lookup.conf
7
8
9if USE_COVERAGE
10 AM_CFLAGS = --coverage -O0
11endif
12
13pkgcfgdir = $(pkgdatadir)/config.d/
14
15libexecdir= $(pkglibdir)/libexec/
16
17plugindir = $(libdir)/gnunet
18
19pkgcfg_DATA = \
20 abd.conf
21
22
23# /usr/lib - compiles a layer which can be used to be communicagte with the service
24lib_LTLIBRARIES = \
25 libgnunetabd.la
26
27# /usr/lib/gnunet/libexec - Business logic . Separate process
28libexec_PROGRAMS = \
29 gnunet-service-abd
30
31bin_PROGRAMS = \
32 gnunet-abd
33
34plugin_LTLIBRARIES = \
35 libgnunet_plugin_gnsrecord_abd.la
36
37
38gnunet_abd_SOURCES = \
39 gnunet-abd.c
40gnunet_abd_LDADD = \
41 libgnunetabd.la \
42 $(top_builddir)/src/util/libgnunetutil.la \
43 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
44 $(top_builddir)/src/identity/libgnunetidentity.la \
45 $(top_builddir)/src/namestore/libgnunetnamestore.la \
46 $(GN_LIBINTL)
47
48
49libgnunet_plugin_gnsrecord_abd_la_SOURCES = \
50 plugin_gnsrecord_abd.c
51libgnunet_plugin_gnsrecord_abd_la_LIBADD = \
52 libgnunetabd.la \
53 $(top_builddir)/src/util/libgnunetutil.la \
54 $(LTLIBINTL)
55libgnunet_plugin_gnsrecord_abd_la_LDFLAGS = \
56 $(GN_PLUGIN_LDFLAGS)
57
58
59
60gnunet_service_abd_SOURCES = \
61 gnunet-service-abd.c
62gnunet_service_abd_LDADD = \
63 libgnunetabd.la \
64 $(top_builddir)/src/util/libgnunetutil.la \
65 $(top_builddir)/src/gns/libgnunetgns.la \
66 $(top_builddir)/src/namestore/libgnunetnamestore.la \
67 $(top_builddir)/src/statistics/libgnunetstatistics.la \
68 $(GN_LIBINTL)
69
70
71libgnunetabd_la_SOURCES = \
72 abd_api.c abd.h\
73 abd_serialization.c \
74 abd_serialization.h \
75 delegate_misc.c \
76 delegate_misc.h
77libgnunetabd_la_LIBADD = \
78 $(top_builddir)/src/util/libgnunetutil.la $(XLIB)
79libgnunetabd_la_LDFLAGS = \
80 $(GN_LIB_LDFLAGS)
81
82
83
84check_SCRIPTS = \
85 test_abd_issue.sh \
86 test_abd_verify_simple.sh \
87 test_abd_verify.sh \
88 test_abd_verify_and.sh
89
90if ENABLE_TEST_RUN
91if HAVE_SQLITE
92 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
93 TESTS = $(check_SCRIPTS)
94endif
95endif
96
97#libgnunet_plugin_rest_abd_la_SOURCES = \
98# plugin_rest_abd.c
99#libgnunet_plugin_rest_abd_la_LIBADD = \
100# $(top_builddir)/src/abd/libgnunetabd.la \
101# $(top_builddir)/src/rest/libgnunetrest.la \
102# $(top_builddir)/src/identity/libgnunetidentity.la \
103# $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
104# $(LTLIBINTL) -ljansson -lmicrohttpd
105#libgnunet_plugin_rest_abd_la_LDFLAGS = \
106# $(GN_PLUGIN_LDFLAGS)
107
108
109
110
111
diff --git a/src/abd/abd.conf.in b/src/abd/abd.conf.in
new file mode 100644
index 000000000..7baf95fc8
--- /dev/null
+++ b/src/abd/abd.conf.in
@@ -0,0 +1,5 @@
1[abd]
2BINARY = gnunet-service-abd
3UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-abd.sock
4RUN_PER_USER = YES
5OPTIONS = -L DEBUG
diff --git a/src/abd/abd.h b/src/abd/abd.h
new file mode 100644
index 000000000..854814832
--- /dev/null
+++ b/src/abd/abd.h
@@ -0,0 +1,290 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2012-2013 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 * @file abd/abd.h
22 * @brief IPC messages between ABD API and ABD service
23 * @author Martin Schanzenbach
24 */
25#ifndef ABD_H
26#define ABD_H
27
28#include "gnunet_abd_service.h"
29
30GNUNET_NETWORK_STRUCT_BEGIN
31
32/**
33 * Message from client to Credential service to collect credentials.
34 */
35struct CollectMessage
36{
37 /**
38 * Header of type #GNUNET_MESSAGE_TYPE_ABD_VERIFY
39 */
40 struct GNUNET_MessageHeader header;
41
42 /**
43 * Subject public key
44 */
45 struct GNUNET_CRYPTO_EcdsaPrivateKey subject_key;
46
47 /**
48 * Trust anchor
49 */
50 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
51
52 /**
53 * Length of the issuer attribute
54 */
55 uint16_t issuer_attribute_len;
56
57 /**
58 * Direction of the resolution algo
59 */
60 uint16_t resolution_algo;
61
62 /**
63 * Unique identifier for this request (for key collisions).
64 */
65 uint32_t id GNUNET_PACKED;
66
67 /* Followed by the zero-terminated attribute */
68};
69
70
71/**
72 * Message from client to Credential service to verify attributes.
73 */
74struct VerifyMessage
75{
76 /**
77 * Header of type #GNUNET_MESSAGE_TYPE_ABD_VERIFY
78 */
79 struct GNUNET_MessageHeader header;
80
81 /**
82 * Subject public key
83 */
84 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
85
86 /**
87 * Trust anchor
88 */
89 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
90
91 /**
92 * Number of delegates
93 */
94 uint32_t d_count;
95
96 /**
97 * Length of the issuer attribute
98 */
99 uint16_t issuer_attribute_len;
100
101 /**
102 * Direction of the resolution algo
103 */
104 uint16_t resolution_algo;
105
106 /**
107 * Unique identifier for this request (for key collisions).
108 */
109 uint32_t id GNUNET_PACKED;
110
111 /* Followed by the zero-terminated attribute and credentials to look up */
112};
113
114
115/**
116 * Message from ABD service to client: new results.
117 */
118struct DelegationChainResultMessage
119{
120 /**
121 * Header of type #GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT
122 */
123 struct GNUNET_MessageHeader header;
124
125 /**
126 * Unique identifier for this request (for key collisions).
127 */
128 uint32_t id GNUNET_PACKED;
129
130 /**
131 * Indicates if credential has been found at all
132 */
133 uint32_t del_found GNUNET_PACKED;
134
135 /**
136 * The number of delegations in the response
137 */
138 uint32_t d_count GNUNET_PACKED;
139
140 /**
141 * The number of credentials in the response
142 */
143 uint32_t c_count GNUNET_PACKED;
144
145 /* followed by ad_count GNUNET_ABD_RecordData structs*/
146};
147
148/**
149 * Message from ABD service to client: new results.
150 */
151struct DelegationChainIntermediateMessage
152{
153 /**
154 * Header of type #GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT
155 */
156 struct GNUNET_MessageHeader header;
157
158 /**
159 * Unique identifier for this request (for key collisions).
160 */
161 uint32_t id GNUNET_PACKED;
162
163 uint16_t is_bw GNUNET_PACKED;
164
165 uint32_t size GNUNET_PACKED;
166};
167
168struct DelegationRecordData
169{
170 /**
171 * Subject key
172 */
173 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
174
175 /**
176 * Subject attributes
177 */
178 uint32_t subject_attribute_len GNUNET_PACKED;
179};
180
181
182struct ChainEntry
183{
184 /**
185 * Issuer key
186 */
187 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
188
189 /**
190 * Subject key
191 */
192 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
193
194 /**
195 * Issuer attributes
196 */
197 uint32_t issuer_attribute_len GNUNET_PACKED;
198
199 /**
200 * Subject attributes
201 */
202 uint32_t subject_attribute_len GNUNET_PACKED;
203};
204
205
206struct CredentialEntry
207{
208
209 /**
210 * The signature for this credential by the issuer
211 */
212 struct GNUNET_CRYPTO_EcdsaSignature signature;
213
214 /**
215 * Signature meta
216 */
217 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
218
219 /**
220 * Public key of the issuer
221 */
222 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
223
224 /**
225 * Public key of the subject this credential was issued to
226 */
227 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
228
229 /**
230 * Expiration time of this credential
231 */
232 uint64_t expiration GNUNET_PACKED;
233
234 /**
235 * Issuer attribute length
236 */
237 uint32_t issuer_attribute_len;
238
239 /**
240 * Followed by the attribute string
241 */
242};
243
244struct DelegateEntry
245{
246
247 /**
248 * The signature for this credential by the issuer
249 */
250 struct GNUNET_CRYPTO_EcdsaSignature signature;
251
252 /**
253 * Signature meta
254 */
255 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
256
257 /**
258 * Public key of the issuer
259 */
260 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
261
262 /**
263 * Public key of the subject this credential was issued to
264 */
265 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
266
267 /**
268 * Expiration time of this credential
269 */
270 uint64_t expiration GNUNET_PACKED;
271
272 /**
273 * Issuer subject attribute length
274 */
275 uint32_t issuer_attribute_len;
276
277 /**
278 * Issuer attribute length
279 */
280 uint32_t subject_attribute_len;
281
282 /**
283 * Followed by the subject attribute string
284 */
285};
286
287
288GNUNET_NETWORK_STRUCT_END
289
290#endif
diff --git a/src/abd/abd_api.c b/src/abd/abd_api.c
new file mode 100644
index 000000000..cdc52df91
--- /dev/null
+++ b/src/abd/abd_api.c
@@ -0,0 +1,556 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 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 * @file abd/abd_api.c
22 * @brief library to access the ABD service
23 * @author Martin Schanzenbach
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_constants.h"
28#include "gnunet_arm_service.h"
29#include "gnunet_hello_lib.h"
30#include "gnunet_protocols.h"
31#include "gnunet_signatures.h"
32#include "abd.h"
33#include "abd_serialization.h"
34#include "gnunet_abd_service.h"
35#include "gnunet_identity_service.h"
36
37
38#define LOG(kind, ...) GNUNET_log_from (kind, "abd-api", __VA_ARGS__)
39
40/**
41 * Handle to a verify request
42 */
43struct GNUNET_ABD_Request
44{
45
46 /**
47 * DLL
48 */
49 struct GNUNET_ABD_Request *next;
50
51 /**
52 * DLL
53 */
54 struct GNUNET_ABD_Request *prev;
55
56 /**
57 * handle to abd service
58 */
59 struct GNUNET_ABD_Handle *abd_handle;
60
61 /**
62 * processor to call on verify result
63 */
64 GNUNET_ABD_CredentialResultProcessor verify_proc;
65
66 /**
67 * @e verify_proc closure
68 */
69 void *proc_cls;
70
71 /**
72 * processor to call on intermediate result
73 */
74 GNUNET_ABD_IntermediateResultProcessor int_proc;
75
76 /**
77 * @e verify_proc2 closure
78 */
79 void *proc2_cls;
80
81 /**
82 * Envelope with the message for this queue entry.
83 */
84 struct GNUNET_MQ_Envelope *env;
85
86 /**
87 * request id
88 */
89 uint32_t r_id;
90};
91
92
93/**
94 * Connection to the ABD service.
95 */
96struct GNUNET_ABD_Handle
97{
98
99 /**
100 * Configuration to use.
101 */
102 const struct GNUNET_CONFIGURATION_Handle *cfg;
103
104 /**
105 * Connection to service (if available).
106 */
107 struct GNUNET_MQ_Handle *mq;
108
109 /**
110 * Head of linked list of active verify requests.
111 */
112 struct GNUNET_ABD_Request *request_head;
113
114 /**
115 * Tail of linked list of active verify requests.
116 */
117 struct GNUNET_ABD_Request *request_tail;
118
119 /**
120 * Reconnect task
121 */
122 struct GNUNET_SCHEDULER_Task *reconnect_task;
123
124 /**
125 * How long do we wait until we try to reconnect?
126 */
127 struct GNUNET_TIME_Relative reconnect_backoff;
128
129 /**
130 * Request Id generator. Incremented by one for each request.
131 */
132 uint32_t r_id_gen;
133};
134
135
136/**
137 * Reconnect to ABD service.
138 *
139 * @param handle the handle to the ABD service
140 */
141static void
142reconnect (struct GNUNET_ABD_Handle *handle);
143
144
145/**
146 * Reconnect to ABD
147 *
148 * @param cls the handle
149 */
150static void
151reconnect_task (void *cls)
152{
153 struct GNUNET_ABD_Handle *handle = cls;
154
155 handle->reconnect_task = NULL;
156 reconnect (handle);
157}
158
159
160/**
161 * Disconnect from service and then reconnect.
162 *
163 * @param handle our handle
164 */
165static void
166force_reconnect (struct GNUNET_ABD_Handle *handle)
167{
168 GNUNET_MQ_destroy (handle->mq);
169 handle->mq = NULL;
170 handle->reconnect_backoff =
171 GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
172 handle->reconnect_task =
173 GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
174 &reconnect_task,
175 handle);
176}
177
178
179/**
180 * Generic error handler, called with the appropriate error code and
181 * the same closure specified at the creation of the message queue.
182 * Not every message queue implementation supports an error handler.
183 *
184 * @param cls closure with the `struct GNUNET_ABD_Handle *`
185 * @param error error code
186 */
187static void
188mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
189{
190 struct GNUNET_ABD_Handle *handle = cls;
191
192 force_reconnect (handle);
193}
194
195/**
196 * Check validity of message received from the ABD service
197 *
198 * @param cls the `struct GNUNET_ABD_Handle *`
199 * @param vr_msg the incoming message
200 */
201static int
202check_result (void *cls, const struct DelegationChainResultMessage *vr_msg)
203{
204 //TODO
205 return GNUNET_OK;
206}
207
208
209/**
210 * Handler for messages received from the ABD service
211 *
212 * @param cls the `struct GNUNET_ABD_Handle *`
213 * @param vr_msg the incoming message
214 */
215static void
216handle_result (void *cls, const struct DelegationChainResultMessage *vr_msg)
217{
218 struct GNUNET_ABD_Handle *handle = cls;
219 uint32_t r_id = ntohl (vr_msg->id);
220 struct GNUNET_ABD_Request *vr;
221 size_t mlen = ntohs (vr_msg->header.size) - sizeof (*vr_msg);
222 uint32_t d_count = ntohl (vr_msg->d_count);
223 uint32_t c_count = ntohl (vr_msg->c_count);
224 struct GNUNET_ABD_Delegation d_chain[d_count];
225 struct GNUNET_ABD_Delegate dels[c_count];
226 GNUNET_ABD_CredentialResultProcessor proc;
227 void *proc_cls;
228
229 LOG (GNUNET_ERROR_TYPE_DEBUG,
230 "Received verify reply from ABD service\n");
231 for (vr = handle->request_head; NULL != vr; vr = vr->next)
232 if (vr->r_id == r_id)
233 break;
234 if (NULL == vr)
235 return;
236 proc = vr->verify_proc;
237 proc_cls = vr->proc_cls;
238 GNUNET_CONTAINER_DLL_remove (handle->request_head, handle->request_tail, vr);
239 GNUNET_MQ_discard (vr->env);
240 GNUNET_free (vr);
241 GNUNET_assert (
242 GNUNET_OK ==
243 GNUNET_ABD_delegation_chain_deserialize (mlen,
244 (const char *) &vr_msg[1],
245 d_count,
246 d_chain,
247 c_count,
248 dels));
249 if (GNUNET_NO == ntohl (vr_msg->del_found))
250 {
251 proc (proc_cls, 0, NULL, 0,
252 NULL);
253 }
254 else
255 {
256 proc (proc_cls, d_count, d_chain, c_count, dels);
257 }
258}
259
260static int
261check_intermediate (void *cls, const struct DelegationChainIntermediateMessage *vr_msg)
262{
263 //TODO
264 return GNUNET_OK;
265}
266
267static void
268handle_intermediate (void *cls, const struct DelegationChainIntermediateMessage *vr_msg)
269{
270 struct GNUNET_ABD_Handle *handle = cls;
271 uint32_t r_id = ntohl (vr_msg->id);
272 uint32_t size = ntohl (vr_msg->size);
273 bool is_bw = ntohs(vr_msg->is_bw);
274 struct GNUNET_ABD_Request *vr;
275 GNUNET_ABD_IntermediateResultProcessor proc;
276 void *proc_cls;
277 struct GNUNET_ABD_Delegation *dd;
278
279
280 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received intermediate reply from ABD service\n");
281
282 for (vr = handle->request_head; NULL != vr; vr = vr->next)
283 if (vr->r_id == r_id)
284 break;
285 if (NULL == vr)
286 return;
287
288 proc = vr->int_proc;
289 proc_cls = vr->proc2_cls;
290
291 dd = GNUNET_new (struct GNUNET_ABD_Delegation);
292 GNUNET_assert (
293 GNUNET_OK ==
294 GNUNET_ABD_delegation_chain_deserialize (size,
295 (const char *) &vr_msg[1],
296 1,
297 dd,
298 0,
299 NULL));
300 proc (proc_cls, dd, is_bw);
301}
302
303
304
305/**
306 * Reconnect to ABD service.
307 *
308 * @param handle the handle to the ABD service
309 */
310static void
311reconnect (struct GNUNET_ABD_Handle *handle)
312{
313 struct GNUNET_MQ_MessageHandler handlers[] =
314 {GNUNET_MQ_hd_var_size (result,
315 GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT,
316 struct DelegationChainResultMessage,
317 handle),
318 GNUNET_MQ_hd_var_size (result,
319 GNUNET_MESSAGE_TYPE_ABD_COLLECT_RESULT,
320 struct DelegationChainResultMessage,
321 handle),
322 GNUNET_MQ_hd_var_size (intermediate,
323 GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT,
324 struct DelegationChainIntermediateMessage,
325 handle),
326 GNUNET_MQ_handler_end ()};
327 struct GNUNET_ABD_Request *vr;
328
329 GNUNET_assert (NULL == handle->mq);
330 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to ABD\n");
331 handle->mq = GNUNET_CLIENT_connect (handle->cfg,
332 "abd",
333 handlers,
334 &mq_error_handler,
335 handle);
336 if (NULL == handle->mq)
337 return;
338 for (vr = handle->request_head; NULL != vr; vr = vr->next)
339 GNUNET_MQ_send_copy (handle->mq, vr->env);
340}
341
342
343/**
344 * Initialize the connection with the ABD service.
345 *
346 * @param cfg configuration to use
347 * @return handle to the ABD service, or NULL on error
348 */
349struct GNUNET_ABD_Handle *
350GNUNET_ABD_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
351{
352 struct GNUNET_ABD_Handle *handle;
353
354 handle = GNUNET_new (struct GNUNET_ABD_Handle);
355 handle->cfg = cfg;
356 reconnect (handle);
357 if (NULL == handle->mq)
358 {
359 GNUNET_free (handle);
360 return NULL;
361 }
362 return handle;
363}
364
365
366/**
367 * Shutdown connection with the ABD service.
368 *
369 * @param handle handle of the ABD connection to stop
370 */
371void
372GNUNET_ABD_disconnect (struct GNUNET_ABD_Handle *handle)
373{
374 if (NULL != handle->mq)
375 {
376 GNUNET_MQ_destroy (handle->mq);
377 handle->mq = NULL;
378 }
379 if (NULL != handle->reconnect_task)
380 {
381 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
382 handle->reconnect_task = NULL;
383 }
384 GNUNET_assert (NULL == handle->request_head);
385 GNUNET_free (handle);
386}
387
388
389/**
390 * Cancel pending verify request
391 *
392 * @param lr the verify request to cancel
393 */
394void
395GNUNET_ABD_request_cancel (struct GNUNET_ABD_Request *lr)
396{
397 struct GNUNET_ABD_Handle *handle = lr->abd_handle;
398
399 GNUNET_CONTAINER_DLL_remove (handle->request_head, handle->request_tail, lr);
400 GNUNET_MQ_discard (lr->env);
401 GNUNET_free (lr);
402}
403
404
405/**
406 * Performs attribute collection.
407 * Collects all abds of subject to fulfill the
408 * attribute, if possible
409 *
410 * @param handle handle to the Credential service
411 * @param issuer_key the issuer public key
412 * @param issuer_attribute the issuer attribute
413 * @param subject_key the subject public key
414 * @param proc function to call on result
415 * @param proc_cls closure for processor
416 * @return handle to the queued request
417 */
418struct GNUNET_ABD_Request *
419GNUNET_ABD_collect (
420 struct GNUNET_ABD_Handle *handle,
421 const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
422 const char *issuer_attribute,
423 const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key,
424 enum GNUNET_ABD_AlgoDirectionFlags direction,
425 GNUNET_ABD_CredentialResultProcessor proc,
426 void *proc_cls,
427 GNUNET_ABD_IntermediateResultProcessor proc2,
428 void *proc2_cls)
429{
430 /* IPC to shorten abd names, return shorten_handle */
431 struct CollectMessage *c_msg;
432 struct GNUNET_ABD_Request *vr;
433 size_t nlen;
434
435 if (NULL == issuer_attribute)
436 {
437 GNUNET_break (0);
438 return NULL;
439 }
440
441 //DEBUG LOG
442 LOG (GNUNET_ERROR_TYPE_DEBUG,
443 "Trying to collect `%s' in ABD\n",
444 issuer_attribute);
445 nlen = strlen (issuer_attribute) + 1;
446 if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
447 {
448 GNUNET_break (0);
449 return NULL;
450 }
451 vr = GNUNET_new (struct GNUNET_ABD_Request);
452 vr->abd_handle = handle;
453 vr->verify_proc = proc;
454 vr->proc_cls = proc_cls;
455 vr->int_proc = proc2;
456 vr->proc2_cls = proc2_cls;
457 vr->r_id = handle->r_id_gen++;
458 vr->env =
459 GNUNET_MQ_msg_extra (c_msg, nlen, GNUNET_MESSAGE_TYPE_ABD_COLLECT);
460 c_msg->id = htonl (vr->r_id);
461 c_msg->subject_key = *subject_key;
462 c_msg->issuer_key = *issuer_key;
463 c_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
464 c_msg->resolution_algo = htons (direction);
465
466 GNUNET_memcpy (&c_msg[1], issuer_attribute, strlen (issuer_attribute));
467 GNUNET_CONTAINER_DLL_insert (handle->request_head, handle->request_tail, vr);
468 if (NULL != handle->mq)
469 GNUNET_MQ_send_copy (handle->mq, vr->env);
470 return vr;
471}
472/**
473 * Performs attribute verification.
474 * Checks if there is a delegation chain from
475 * attribute ``issuer_attribute'' issued by the issuer
476 * with public key ``issuer_key'' maps to the attribute
477 * ``subject_attribute'' claimed by the subject with key
478 * ``subject_key''
479 *
480 * @param handle handle to the Credential service
481 * @param issuer_key the issuer public key
482 * @param issuer_attribute the issuer attribute
483 * @param subject_key the subject public key
484 * @param delegate_count number of delegates provided
485 * @param delegates subject delegates
486 * @param proc function to call on result
487 * @param proc_cls closure for processor
488 * @return handle to the queued request
489 */
490struct GNUNET_ABD_Request *
491GNUNET_ABD_verify (
492 struct GNUNET_ABD_Handle *handle,
493 const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
494 const char *issuer_attribute,
495 const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key,
496 uint32_t delegate_count,
497 const struct GNUNET_ABD_Delegate *delegates,
498 enum GNUNET_ABD_AlgoDirectionFlags direction,
499 GNUNET_ABD_CredentialResultProcessor proc,
500 void *proc_cls,
501 GNUNET_ABD_IntermediateResultProcessor proc2,
502 void *proc2_cls)
503{
504 /* IPC to shorten abd names, return shorten_handle */
505 struct VerifyMessage *v_msg;
506 struct GNUNET_ABD_Request *vr;
507 size_t nlen;
508 size_t clen;
509
510 if (NULL == issuer_attribute || NULL == delegates)
511 {
512 GNUNET_break (0);
513 return NULL;
514 }
515
516 clen = GNUNET_ABD_delegates_get_size (delegate_count, delegates);
517
518 //DEBUG LOG
519 LOG (GNUNET_ERROR_TYPE_DEBUG,
520 "Trying to verify `%s' in ABD\n",
521 issuer_attribute);
522 nlen = strlen (issuer_attribute) + 1 + clen;
523 if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
524 {
525 GNUNET_break (0);
526 return NULL;
527 }
528 vr = GNUNET_new (struct GNUNET_ABD_Request);
529 vr->abd_handle = handle;
530 vr->verify_proc = proc;
531 vr->proc_cls = proc_cls;
532 vr->int_proc = proc2;
533 vr->proc2_cls = proc2_cls;
534 vr->r_id = handle->r_id_gen++;
535 vr->env =
536 GNUNET_MQ_msg_extra (v_msg, nlen, GNUNET_MESSAGE_TYPE_ABD_VERIFY);
537 v_msg->id = htonl (vr->r_id);
538 v_msg->subject_key = *subject_key;
539 v_msg->d_count = htonl (delegate_count);
540 v_msg->issuer_key = *issuer_key;
541 v_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
542 v_msg->resolution_algo = htons (direction);
543
544 GNUNET_memcpy (&v_msg[1], issuer_attribute, strlen (issuer_attribute));
545 GNUNET_ABD_delegates_serialize (delegate_count,
546 delegates,
547 clen,
548 ((char *) &v_msg[1]) +
549 strlen (issuer_attribute) + 1);
550 GNUNET_CONTAINER_DLL_insert (handle->request_head, handle->request_tail, vr);
551 if (NULL != handle->mq)
552 GNUNET_MQ_send_copy (handle->mq, vr->env);
553 return vr;
554}
555
556/* end of abd_api.c */
diff --git a/src/abd/abd_serialization.c b/src/abd/abd_serialization.c
new file mode 100644
index 000000000..d2bc15166
--- /dev/null
+++ b/src/abd/abd_serialization.c
@@ -0,0 +1,508 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 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/**
23 * @file abd/abd_serialization.c
24 * @brief API to serialize and deserialize delegation chains
25 * and abds
26 * @author Martin Schanzenbach
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_abd_service.h"
32#include "gnunet_signatures.h"
33#include "abd.h"
34
35/**
36 * Calculate how many bytes we will need to serialize
37 * the given delegation chain
38 *
39 * @param ds_count number of delegation chain entries
40 * @param dsr array of #GNUNET_ABD_DelegationSet
41 * @return the required size to serialize
42 */
43size_t
44GNUNET_ABD_delegation_set_get_size (
45 unsigned int ds_count,
46 const struct GNUNET_ABD_DelegationSet *dsr)
47{
48 unsigned int i;
49 size_t ret;
50
51 ret = sizeof (struct DelegationRecordData) * (ds_count);
52
53 for (i = 0; i < ds_count; i++)
54 {
55 GNUNET_assert ((ret + dsr[i].subject_attribute_len) >= ret);
56 ret += dsr[i].subject_attribute_len;
57 }
58 return ret;
59}
60
61/**
62 * Serizalize the given delegation chain entries and abd
63 *
64 * @param d_count number of delegation chain entries
65 * @param dsr array of #GNUNET_ABD_DelegationSet
66 * @param dest_size size of the destination
67 * @param dest where to store the result
68 * @return the size of the data, -1 on failure
69 */
70ssize_t
71GNUNET_ABD_delegation_set_serialize (
72 unsigned int d_count,
73 const struct GNUNET_ABD_DelegationSet *dsr,
74 size_t dest_size,
75 char *dest)
76{
77 struct DelegationRecordData rec;
78 unsigned int i;
79 size_t off;
80
81 off = 0;
82 for (i = 0; i < d_count; i++)
83 {
84 rec.subject_attribute_len = htonl ((uint32_t) dsr[i].subject_attribute_len);
85 rec.subject_key = dsr[i].subject_key;
86 if (off + sizeof (rec) > dest_size)
87 return -1;
88 GNUNET_memcpy (&dest[off], &rec, sizeof (rec));
89 off += sizeof (rec);
90 if (0 == dsr[i].subject_attribute_len)
91 continue;
92 if (off + dsr[i].subject_attribute_len > dest_size)
93 return -1;
94 GNUNET_memcpy (&dest[off],
95 dsr[i].subject_attribute,
96 dsr[i].subject_attribute_len);
97 off += dsr[i].subject_attribute_len;
98 }
99 return off;
100}
101
102
103/**
104 * Deserialize the given destination
105 *
106 * @param len size of the serialized delegation chain and cred
107 * @param src the serialized data
108 * @param d_count the number of delegation chain entries
109 * @param dsr where to put the delegation chain entries
110 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
111 */
112int
113GNUNET_ABD_delegation_set_deserialize (
114 size_t len,
115 const char *src,
116 unsigned int d_count,
117 struct GNUNET_ABD_DelegationSet *dsr)
118{
119 struct DelegationRecordData rec;
120 unsigned int i;
121 size_t off;
122
123 off = 0;
124 for (i = 0; i < d_count; i++)
125 {
126 if (off + sizeof (rec) > len)
127 return GNUNET_SYSERR;
128 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
129 dsr[i].subject_key = rec.subject_key;
130 off += sizeof (rec);
131 dsr[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
132 if (off + dsr[i].subject_attribute_len > len)
133 return GNUNET_SYSERR;
134 dsr[i].subject_attribute = (char *) &src[off];
135 off += dsr[i].subject_attribute_len;
136 }
137 return GNUNET_OK;
138}
139
140
141/**
142 * Calculate how many bytes we will need to serialize
143 * the abds
144 *
145 * @param c_count number of abd entries
146 * @param cd a #GNUNET_ABD_Credential
147 * @return the required size to serialize
148 */
149size_t
150GNUNET_ABD_delegates_get_size (
151 unsigned int c_count,
152 const struct GNUNET_ABD_Delegate *cd)
153{
154 unsigned int i;
155 size_t ret;
156
157 ret = sizeof (struct DelegateEntry) * (c_count);
158
159 for (i = 0; i < c_count; i++)
160 {
161 GNUNET_assert ((ret + cd[i].issuer_attribute_len + cd[i].subject_attribute_len) >= ret);
162 // subject_attribute_len should be 0
163 ret += cd[i].issuer_attribute_len + cd[i].subject_attribute_len;
164 }
165 return ret;
166}
167/**
168 * Serizalize the given abds
169 *
170 * @param c_count number of abd entries
171 * @param cd a #GNUNET_ABD_Credential
172 * @param dest_size size of the destination
173 * @param dest where to store the result
174 * @return the size of the data, -1 on failure
175 */
176ssize_t
177GNUNET_ABD_delegates_serialize (
178 unsigned int c_count,
179 const struct GNUNET_ABD_Delegate *cd,
180 size_t dest_size,
181 char *dest)
182{
183 struct DelegateEntry c_rec;
184 unsigned int i;
185 size_t off;
186
187 off = 0;
188 for (i = 0; i < c_count; i++)
189 {
190 //c_rec.subject_attribute_len = htonl ((uint32_t) cd[i].subject_attribute_len);
191 c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
192 c_rec.issuer_key = cd[i].issuer_key;
193 c_rec.subject_key = cd[i].subject_key;
194 c_rec.signature = cd[i].signature;
195 c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
196 c_rec.purpose.size =
197 htonl ((sizeof (struct DelegateEntry) + cd[i].issuer_attribute_len) -
198 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
199 c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us);
200 if (off + sizeof (c_rec) > dest_size)
201 return -1;
202 GNUNET_memcpy (&dest[off], &c_rec, sizeof (c_rec));
203 off += sizeof (c_rec);
204 if (off + cd[i].issuer_attribute_len > dest_size)
205 return -1;
206 GNUNET_memcpy (&dest[off],
207 cd[i].issuer_attribute,
208 cd[i].issuer_attribute_len);
209 off += cd[i].issuer_attribute_len;
210 }
211
212 return off;
213}
214
215
216/**
217 * Deserialize the given destination
218 *
219 * @param len size of the serialized creds
220 * @param src the serialized data
221 * @param c_count the number of abd entries
222 * @param cd where to put the abd data
223 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
224 */
225int
226GNUNET_ABD_delegates_deserialize (size_t len,
227 const char *src,
228 unsigned int c_count,
229 struct GNUNET_ABD_Delegate *cd)
230{
231 struct DelegateEntry c_rec;
232 unsigned int i;
233 size_t off;
234
235 off = 0;
236 for (i = 0; i < c_count; i++)
237 {
238 if (off + sizeof (c_rec) > len)
239 return GNUNET_SYSERR;
240 GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
241 cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
242 cd[i].issuer_key = c_rec.issuer_key;
243 cd[i].subject_key = c_rec.subject_key;
244 cd[i].signature = c_rec.signature;
245 cd[i].expiration.abs_value_us = GNUNET_ntohll (c_rec.expiration);
246 off += sizeof (c_rec);
247 if (off + cd[i].issuer_attribute_len > len)
248 return GNUNET_SYSERR;
249 cd[i].issuer_attribute = &src[off];
250 off += cd[i].issuer_attribute_len;
251 cd[i].subject_attribute_len = 0;
252 }
253 return GNUNET_OK;
254}
255
256
257/**
258 * Calculate how many bytes we will need to serialize
259 * the given delegation chain and abd
260 *
261 * @param d_count number of delegation chain entries
262 * @param dd array of #GNUNET_ABD_Delegation
263 * @param c_count number of abd entries
264 * @param cd a #GNUNET_ABD_Credential
265 * @return the required size to serialize
266 */
267size_t
268GNUNET_ABD_delegation_chain_get_size (
269 unsigned int d_count,
270 const struct GNUNET_ABD_Delegation *dd,
271 unsigned int c_count,
272 const struct GNUNET_ABD_Delegate *cd)
273{
274 unsigned int i;
275 size_t ret;
276
277 ret = sizeof (struct ChainEntry) * (d_count);
278
279 for (i = 0; i < d_count; i++)
280 {
281 GNUNET_assert (
282 (ret + dd[i].issuer_attribute_len + dd[i].subject_attribute_len) >= ret);
283 ret += dd[i].issuer_attribute_len + dd[i].subject_attribute_len;
284 }
285 return ret + GNUNET_ABD_delegates_get_size (c_count, cd);
286}
287
288/**
289 * Serizalize the given delegation chain entries and abd
290 *
291 * @param d_count number of delegation chain entries
292 * @param dd array of #GNUNET_ABD_Delegation
293 * @param c_count number of abd entries
294 * @param cd a #GNUNET_ABD_Credential
295 * @param dest_size size of the destination
296 * @param dest where to store the result
297 * @return the size of the data, -1 on failure
298 */
299ssize_t
300GNUNET_ABD_delegation_chain_serialize (
301 unsigned int d_count,
302 const struct GNUNET_ABD_Delegation *dd,
303 unsigned int c_count,
304 const struct GNUNET_ABD_Delegate *cd,
305 size_t dest_size,
306 char *dest)
307{
308 struct ChainEntry rec;
309 unsigned int i;
310 size_t off;
311
312 off = 0;
313 for (i = 0; i < d_count; i++)
314 {
315 rec.issuer_attribute_len = htonl ((uint32_t) dd[i].issuer_attribute_len);
316 rec.subject_attribute_len = htonl ((uint32_t) dd[i].subject_attribute_len);
317 rec.issuer_key = dd[i].issuer_key;
318 rec.subject_key = dd[i].subject_key;
319 if (off + sizeof (rec) > dest_size)
320 return -1;
321 GNUNET_memcpy (&dest[off], &rec, sizeof (rec));
322 off += sizeof (rec);
323 if (off + dd[i].issuer_attribute_len > dest_size)
324 return -1;
325 GNUNET_memcpy (&dest[off],
326 dd[i].issuer_attribute,
327 dd[i].issuer_attribute_len);
328 off += dd[i].issuer_attribute_len;
329 if (0 == dd[i].subject_attribute_len)
330 continue;
331 if (off + dd[i].subject_attribute_len > dest_size)
332 return -1;
333 GNUNET_memcpy (&dest[off],
334 dd[i].subject_attribute,
335 dd[i].subject_attribute_len);
336 off += dd[i].subject_attribute_len;
337 }
338 return off + GNUNET_ABD_delegates_serialize (c_count,
339 cd,
340 dest_size - off,
341 &dest[off]);
342}
343
344
345/**
346 * Deserialize the given destination
347 *
348 * @param len size of the serialized delegation chain and cred
349 * @param src the serialized data
350 * @param d_count the number of delegation chain entries
351 * @param dd where to put the delegation chain entries
352 * @param c_count the number of abd entries
353 * @param cd where to put the abd data
354 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
355 */
356int
357GNUNET_ABD_delegation_chain_deserialize (
358 size_t len,
359 const char *src,
360 unsigned int d_count,
361 struct GNUNET_ABD_Delegation *dd,
362 unsigned int c_count,
363 struct GNUNET_ABD_Delegate *cd)
364{
365 struct ChainEntry rec;
366 unsigned int i;
367 size_t off;
368
369 off = 0;
370 for (i = 0; i < d_count; i++)
371 {
372 if (off + sizeof (rec) > len)
373 return GNUNET_SYSERR;
374 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
375 dd[i].issuer_attribute_len = ntohl ((uint32_t) rec.issuer_attribute_len);
376 dd[i].issuer_key = rec.issuer_key;
377 dd[i].subject_key = rec.subject_key;
378 off += sizeof (rec);
379 if (off + dd[i].issuer_attribute_len > len)
380 return GNUNET_SYSERR;
381 dd[i].issuer_attribute = &src[off];
382 off += dd[i].issuer_attribute_len;
383 dd[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
384 if (off + dd[i].subject_attribute_len > len)
385 return GNUNET_SYSERR;
386 dd[i].subject_attribute = &src[off];
387 off += dd[i].subject_attribute_len;
388 }
389 return GNUNET_ABD_delegates_deserialize (len - off,
390 &src[off],
391 c_count,
392 cd);
393}
394
395int
396GNUNET_ABD_delegate_serialize (struct GNUNET_ABD_Delegate *dele,
397 char **data)
398{
399 size_t size;
400 struct DelegateEntry *cdata;
401 int attr_len;
402
403 // +1 for \0
404 if (0 == dele->subject_attribute_len)
405 {
406 attr_len = dele->issuer_attribute_len + 1;
407 }
408 else
409 {
410 attr_len = dele->issuer_attribute_len + dele->subject_attribute_len + 2;
411 }
412 size = sizeof (struct DelegateEntry) + attr_len;
413
414 char tmp_str[attr_len];
415 GNUNET_memcpy (tmp_str, dele->issuer_attribute, dele->issuer_attribute_len);
416 if (0 != dele->subject_attribute_len)
417 {
418 tmp_str[dele->issuer_attribute_len] = '\0';
419 GNUNET_memcpy (tmp_str + dele->issuer_attribute_len + 1,
420 dele->subject_attribute,
421 dele->subject_attribute_len);
422 }
423 tmp_str[attr_len - 1] = '\0';
424
425 *data = GNUNET_malloc (size);
426 cdata = (struct DelegateEntry *) *data;
427 cdata->subject_key = dele->subject_key;
428 cdata->issuer_key = dele->issuer_key;
429 cdata->expiration = GNUNET_htonll (dele->expiration.abs_value_us);
430 cdata->signature = dele->signature;
431 cdata->issuer_attribute_len = htonl (dele->issuer_attribute_len + 1);
432 if (0 == dele->subject_attribute_len)
433 {
434 cdata->subject_attribute_len = htonl (0);
435 }
436 else
437 {
438 cdata->subject_attribute_len = htonl (dele->subject_attribute_len + 1);
439 }
440 cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
441 cdata->purpose.size =
442 htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
443
444 GNUNET_memcpy (&cdata[1], tmp_str, attr_len);
445
446 if (GNUNET_OK !=
447 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_DELEGATE,
448 &cdata->purpose,
449 &cdata->signature,
450 &cdata->issuer_key))
451 {
452 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n");
453 return 0;
454 }
455 return size;
456}
457
458struct GNUNET_ABD_Delegate *
459GNUNET_ABD_delegate_deserialize (const char *data, size_t data_size)
460{
461 struct GNUNET_ABD_Delegate *dele;
462 struct DelegateEntry *cdata;
463 char *attr_combo_str;
464
465 if (data_size < sizeof (struct DelegateEntry))
466 return NULL;
467 cdata = (struct DelegateEntry *) data;
468 if (GNUNET_OK !=
469 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_DELEGATE,
470 &cdata->purpose,
471 &cdata->signature,
472 &cdata->issuer_key))
473 {
474 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n");
475 return NULL;
476 }
477 attr_combo_str = (char *) &cdata[1];
478 int iss_len = ntohl (cdata->issuer_attribute_len);
479 int sub_len = ntohl (cdata->subject_attribute_len);
480 int attr_combo_len = iss_len + sub_len;
481
482 dele =
483 GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate) + attr_combo_len);
484
485 dele->issuer_key = cdata->issuer_key;
486 dele->subject_key = cdata->subject_key;
487 GNUNET_memcpy (&dele[1], attr_combo_str, attr_combo_len);
488 dele->signature = cdata->signature;
489
490 // Set the pointers for the attributes
491 dele->issuer_attribute = (char *) &dele[1];
492 dele->issuer_attribute_len = iss_len;
493 dele->subject_attribute_len = sub_len;
494 if (0 == sub_len)
495 {
496 dele->subject_attribute = NULL;
497 }
498 else
499 {
500 dele->subject_attribute = (char *) &dele[1] + iss_len;
501 }
502
503 dele->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
504
505 return dele;
506}
507
508/* end of abd_serialization.c */
diff --git a/src/abd/abd_serialization.h b/src/abd/abd_serialization.h
new file mode 100644
index 000000000..cef9f42ef
--- /dev/null
+++ b/src/abd/abd_serialization.h
@@ -0,0 +1,165 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 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/**
23 * @file abd/abd_serialization.h
24 * @brief API to serialize and deserialize delegation chains
25 * and abds
26 * @author Martin Schanzenbach
27 */
28#ifndef ABD_SERIALIZATION_H
29#define ABD_SERIALIZATION_H
30
31#include "platform.h"
32#include "gnunet_util_lib.h"
33#include "gnunet_constants.h"
34#include "gnunet_abd_service.h"
35
36/**
37 * Calculate how many bytes we will need to serialize
38 * the given delegation record
39 *
40 * @param ds_count number of delegation chain entries
41 * @param dsr array of #GNUNET_ABD_Delegation
42 * @return the required size to serialize
43 */
44size_t
45GNUNET_ABD_delegation_set_get_size (
46 unsigned int ds_count,
47 const struct GNUNET_ABD_DelegationSet *dsr);
48
49/**
50 * Serizalize the given delegation record entries
51 *
52 * @param d_count number of delegation chain entries
53 * @param dsr array of #GNUNET_ABD_Delegation
54 * @param dest_size size of the destination
55 * @param dest where to store the result
56 * @return the size of the data, -1 on failure
57 */
58ssize_t
59GNUNET_ABD_delegation_set_serialize (
60 unsigned int d_count,
61 const struct GNUNET_ABD_DelegationSet *dsr,
62 size_t dest_size,
63 char *dest);
64
65
66/**
67 * Deserialize the given destination
68 *
69 * @param len size of the serialized delegation recird
70 * @param src the serialized data
71 * @param d_count the number of delegation chain entries
72 * @param dsr where to put the delegation chain entries
73 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
74 */
75int
76GNUNET_ABD_delegation_set_deserialize (
77 size_t len,
78 const char *src,
79 unsigned int d_count,
80 struct GNUNET_ABD_DelegationSet *dsr);
81
82/**
83 * Calculate how many bytes we will need to serialize
84 * the given delegation chain and abd
85 *
86 * @param d_count number of delegation chain entries
87 * @param dd array of #GNUNET_ABD_Delegation
88 * @param c_count number of abd entries
89 * @param cd a #GNUNET_ABD_Delegate
90 * @return the required size to serialize
91 */
92size_t
93GNUNET_ABD_delegation_chain_get_size (
94 unsigned int d_count,
95 const struct GNUNET_ABD_Delegation *dd,
96 unsigned int c_count,
97 const struct GNUNET_ABD_Delegate *cd);
98
99/**
100 * Serizalize the given delegation chain entries and abd
101 *
102 * @param d_count number of delegation chain entries
103 * @param dd array of #GNUNET_ABD_Delegation
104 * @param c_count number of abd entries
105 * @param cd a #GNUNET_ABD_Delegate
106 * @param dest_size size of the destination
107 * @param dest where to store the result
108 * @return the size of the data, -1 on failure
109 */
110ssize_t
111GNUNET_ABD_delegation_chain_serialize (
112 unsigned int d_count,
113 const struct GNUNET_ABD_Delegation *dd,
114 unsigned int c_count,
115 const struct GNUNET_ABD_Delegate *cd,
116 size_t dest_size,
117 char *dest);
118
119
120/**
121 * Deserialize the given destination
122 *
123 * @param len size of the serialized delegation chain and cred
124 * @param src the serialized data
125 * @param d_count the number of delegation chain entries
126 * @param dd where to put the delegation chain entries
127 * @param c_count number of abd entries
128 * @param cd where to put the abd data
129 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
130 */
131int
132GNUNET_ABD_delegation_chain_deserialize (
133 size_t len,
134 const char *src,
135 unsigned int d_count,
136 struct GNUNET_ABD_Delegation *dd,
137 unsigned int c_count,
138 struct GNUNET_ABD_Delegate *cd);
139size_t
140GNUNET_ABD_delegates_get_size (
141 unsigned int c_count,
142 const struct GNUNET_ABD_Delegate *cd);
143
144ssize_t
145GNUNET_ABD_delegates_serialize (
146 unsigned int c_count,
147 const struct GNUNET_ABD_Delegate *cd,
148 size_t dest_size,
149 char *dest);
150
151
152int
153GNUNET_ABD_delegates_deserialize (size_t len,
154 const char *src,
155 unsigned int c_count,
156 struct GNUNET_ABD_Delegate *cd);
157
158int
159GNUNET_ABD_delegate_serialize (struct GNUNET_ABD_Delegate *cred,
160 char **data);
161
162struct GNUNET_ABD_Delegate *
163GNUNET_ABD_delegate_deserialize (const char *data, size_t data_size);
164#endif
165/* end of abd_serialization.h */
diff --git a/src/abd/delegate_misc.c b/src/abd/delegate_misc.c
new file mode 100644
index 000000000..ecc7f7669
--- /dev/null
+++ b/src/abd/delegate_misc.c
@@ -0,0 +1,274 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 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/**
23 * @file abd/delegate_misc.c
24 * @brief Misc API for delegate
25 *
26 * @author Martin Schanzenbach
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_abd_service.h"
32#include "gnunet_signatures.h"
33#include "abd.h"
34#include <inttypes.h>
35
36char *
37GNUNET_ABD_delegate_to_string (
38 const struct GNUNET_ABD_Delegate *cred)
39{
40 char *cred_str;
41 char *subject_pkey;
42 char *issuer_pkey;
43 char *signature;
44
45 subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
46 issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
47 GNUNET_STRINGS_base64_encode ((char *) &cred->signature,
48 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
49 &signature);
50 if (0 == cred->subject_attribute_len)
51 {
52 GNUNET_asprintf (&cred_str,
53 "%s.%s -> %s | %s | %" SCNu64,
54 issuer_pkey,
55 cred->issuer_attribute,
56 subject_pkey,
57 signature,
58 cred->expiration.abs_value_us);
59 }
60 else
61 {
62 GNUNET_asprintf (&cred_str,
63 "%s.%s -> %s.%s | %s | %" SCNu64,
64 issuer_pkey,
65 cred->issuer_attribute,
66 subject_pkey,
67 cred->subject_attribute,
68 signature,
69 cred->expiration.abs_value_us);
70 }
71 GNUNET_free (subject_pkey);
72 GNUNET_free (issuer_pkey);
73 GNUNET_free (signature);
74
75 return cred_str;
76}
77
78struct GNUNET_ABD_Delegate *
79GNUNET_ABD_delegate_from_string (const char *s)
80{
81 struct GNUNET_ABD_Delegate *dele;
82 size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
83 if (enclen % 5 > 0)
84 enclen += 5 - enclen % 5;
85 enclen /= 5; /* 260/5 = 52 */
86 char subject_pkey[enclen + 1];
87 char issuer_pkey[enclen + 1];
88 char iss_attr[253 + 1];
89 // Needs to be initialized, in case of Type 1 credential (A.a <- B)
90 char sub_attr[253 + 1] = "";
91 char signature[256]; //TODO max payload size
92
93 struct GNUNET_CRYPTO_EcdsaSignature *sig;
94 struct GNUNET_TIME_Absolute etime_abs;
95
96 // If it's A.a <- B.b...
97 if (6 != SSCANF (s,
98 "%52s.%253s -> %52s.%253s | %s | %" SCNu64,
99 issuer_pkey,
100 iss_attr,
101 subject_pkey,
102 sub_attr,
103 signature,
104 &etime_abs.abs_value_us))
105 {
106 // Try if it's A.a <- B
107 if (5 != SSCANF (s,
108 "%52s.%253s -> %52s | %s | %" SCNu64,
109 issuer_pkey,
110 iss_attr,
111 subject_pkey,
112 signature,
113 &etime_abs.abs_value_us))
114 {
115 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
116 "Unable to parse DEL record string `%s'\n",
117 s);
118 return NULL;
119 }
120 }
121
122 // +1 for \0
123 int attr_len;
124 if (strcmp (sub_attr, "") == 0)
125 {
126 attr_len = strlen (iss_attr) + 1;
127 }
128 else
129 {
130 attr_len = strlen (iss_attr) + strlen (sub_attr) + 2;
131 }
132 dele = GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate) + attr_len);
133
134 char tmp_str[attr_len];
135 GNUNET_memcpy (tmp_str, iss_attr, strlen (iss_attr));
136 if (strcmp (sub_attr, "") != 0)
137 {
138 tmp_str[strlen (iss_attr)] = '\0';
139 GNUNET_memcpy (tmp_str + strlen (iss_attr) + 1,
140 sub_attr,
141 strlen (sub_attr));
142 }
143 tmp_str[attr_len - 1] = '\0';
144
145 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
146 strlen (subject_pkey),
147 &dele->subject_key);
148 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
149 strlen (issuer_pkey),
150 &dele->issuer_key);
151 GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) ==
152 GNUNET_STRINGS_base64_decode (signature,
153 strlen (signature),
154 (void **) &sig));
155 dele->signature = *sig;
156 dele->expiration = etime_abs;
157 GNUNET_free (sig);
158
159 GNUNET_memcpy (&dele[1], tmp_str, attr_len);
160
161 dele->issuer_attribute = (char *) &dele[1];
162 dele->issuer_attribute_len = strlen (iss_attr);
163 if (strcmp (sub_attr, "") == 0)
164 {
165 dele->subject_attribute = NULL;
166 dele->subject_attribute_len = 0;
167 }
168 else
169 {
170 dele->subject_attribute = (char *) &dele[1] + strlen (iss_attr) + 1;
171 dele->subject_attribute_len = strlen (sub_attr);
172 }
173
174 return dele;
175}
176
177/**
178 * Issue an attribute to a subject
179 *
180 * @param issuer the ego that should be used to issue the attribute
181 * @param subject the subject of the attribute
182 * @param iss_attr the name of the attribute
183 * @return handle to the queued request
184 */
185
186struct GNUNET_ABD_Delegate *
187GNUNET_ABD_delegate_issue (
188 const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
189 struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
190 const char *iss_attr,
191 const char *sub_attr,
192 struct GNUNET_TIME_Absolute *expiration)
193{
194 struct DelegateEntry *del;
195 struct GNUNET_ABD_Delegate *dele;
196 size_t size;
197 int attr_len;
198
199 if (NULL == sub_attr)
200 {
201 // +1 for \0
202 attr_len = strlen (iss_attr) + 1;
203 }
204 else
205 {
206 // +2 for both strings need to be terminated with \0
207 attr_len = strlen (iss_attr) + strlen (sub_attr) + 2;
208 }
209 size = sizeof (struct DelegateEntry) + attr_len;
210
211 char tmp_str[attr_len];
212 GNUNET_memcpy (tmp_str, iss_attr, strlen (iss_attr));
213 if (NULL != sub_attr)
214 {
215 tmp_str[strlen (iss_attr)] = '\0';
216 GNUNET_memcpy (tmp_str + strlen (iss_attr) + 1,
217 sub_attr,
218 strlen (sub_attr));
219 }
220 tmp_str[attr_len - 1] = '\0';
221
222 del = GNUNET_malloc (size);
223 del->purpose.size =
224 htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
225 del->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
226 GNUNET_CRYPTO_ecdsa_key_get_public (issuer, &del->issuer_key);
227 del->subject_key = *subject;
228 del->expiration = GNUNET_htonll (expiration->abs_value_us);
229 del->issuer_attribute_len = htonl (strlen (iss_attr) + 1);
230 if (NULL == sub_attr)
231 {
232 del->subject_attribute_len = htonl (0);
233 }
234 else
235 {
236 del->subject_attribute_len = htonl (strlen (sub_attr) + 1);
237 }
238
239 GNUNET_memcpy (&del[1], tmp_str, attr_len);
240
241 if (GNUNET_OK !=
242 GNUNET_CRYPTO_ecdsa_sign (issuer, &del->purpose, &del->signature))
243 {
244 GNUNET_break (0);
245 GNUNET_free (del);
246 return NULL;
247 }
248
249 dele = GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate) + attr_len);
250 dele->signature = del->signature;
251 dele->expiration = *expiration;
252 GNUNET_CRYPTO_ecdsa_key_get_public (issuer, &dele->issuer_key);
253
254 dele->subject_key = *subject;
255
256 // Copy the combined string at the part in the memory where the struct ends
257 GNUNET_memcpy (&dele[1], tmp_str, attr_len);
258
259 dele->issuer_attribute = (char *) &dele[1];
260 dele->issuer_attribute_len = strlen (iss_attr);
261 if (NULL == sub_attr)
262 {
263 dele->subject_attribute = NULL;
264 dele->subject_attribute_len = 0;
265 }
266 else
267 {
268 dele->subject_attribute = (char *) &dele[1] + strlen (iss_attr) + 1;
269 dele->subject_attribute_len = strlen (sub_attr);
270 }
271
272 GNUNET_free (del);
273 return dele;
274}
diff --git a/src/abd/delegate_misc.h b/src/abd/delegate_misc.h
new file mode 100644
index 000000000..42a95ce99
--- /dev/null
+++ b/src/abd/delegate_misc.h
@@ -0,0 +1,36 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2012-2013 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 * @file abd/delegate_misc.h
22 * @brief Delegate helper functions
23 */
24#ifndef DELEGATE_MISC_H
25#define DELEGATE_MISC_H
26
27#include "gnunet_abd_service.h"
28
29char *
30GNUNET_ABD_delegate_to_string (
31 const struct GNUNET_ABD_Delegate *cred);
32
33struct GNUNET_ABD_Delegate *
34GNUNET_ABD_delegate_from_string (const char *str);
35
36#endif
diff --git a/src/abd/gnunet-abd.c b/src/abd/gnunet-abd.c
new file mode 100644
index 000000000..23083ec68
--- /dev/null
+++ b/src/abd/gnunet-abd.c
@@ -0,0 +1,1070 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2013 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 * @file gnunet-abd.c
22 * @brief command line tool to access command line Credential service
23 * @author Martin Schanzenbach
24 */
25#include "platform.h"
26#include <gnunet_util_lib.h>
27#include <gnunet_abd_service.h>
28#include <gnunet_gnsrecord_lib.h>
29#include <gnunet_namestore_service.h>
30#include "delegate_misc.h"
31#include "abd_serialization.h"
32
33/**
34 * Configuration we are using.
35 */
36static const struct GNUNET_CONFIGURATION_Handle *cfg;
37
38/**
39 * Handle to the namestore.
40 */
41static struct GNUNET_NAMESTORE_Handle *ns;
42
43/**
44 * Private key for the our zone.
45 */
46static struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey;
47
48/**
49 * EgoLookup
50 */
51static struct GNUNET_IDENTITY_EgoLookup *el;
52
53/**
54 * Handle to Credential service.
55 */
56static struct GNUNET_ABD_Handle *abd;
57
58/**
59 * Desired timeout for the lookup (default is no timeout).
60 */
61static struct GNUNET_TIME_Relative timeout;
62
63/**
64 * Handle to verify request
65 */
66static struct GNUNET_ABD_Request *verify_request;
67
68/**
69 * Handle to collect request
70 */
71static struct GNUNET_ABD_Request *collect_request;
72
73/**
74 * Task scheduled to handle timeout.
75 */
76static struct GNUNET_SCHEDULER_Task *tt;
77
78/**
79 * Return value of the commandline.
80 */
81static int ret = 0;
82
83/**
84 * Subject pubkey string
85 */
86static char *subject;
87
88/**
89 * Subject delegate string
90 */
91static char *subject_delegate;
92
93/**
94 * Credential TTL
95 */
96static char *expiration;
97
98/**
99 * Subject key
100 */
101struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey;
102
103/**
104 * Issuer key
105 */
106struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey;
107
108
109/**
110 * Issuer pubkey string
111 */
112static char *issuer_key;
113
114/**
115 * ego
116 */
117static char *ego_name;
118
119/**
120 * Issuer attribute
121 */
122static char *issuer_attr;
123
124/**
125 * Verify mode
126 */
127static int verify;
128
129/**
130 * Collect mode
131 */
132static int collect;
133
134/**
135 * Create mode
136 */
137static int create_is;
138
139/**
140 * Create mode
141 */
142static int create_ss;
143
144/**
145 * Create mode
146 */
147static int sign_ss;
148
149/**
150 * Signed issue credentials
151 */
152static char *import;
153
154/**
155 * Is record private
156 */
157static int is_private;
158
159/**
160 * Search direction: forward
161 */
162static int forward;
163
164/**
165 * Search direction: backward
166 */
167static int backward;
168
169/**
170 * API enum, filled and passed for collect/verify
171 */
172enum GNUNET_ABD_AlgoDirectionFlags direction = 0;
173
174/**
175 * Queue entry for the 'add' operation.
176 */
177static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
178
179/**
180 * Value in binary format.
181 */
182static void *data;
183
184/**
185 * Number of bytes in #data.
186 */
187static size_t data_size;
188
189/**
190 * Type string converted to DNS type value.
191 */
192static uint32_t type;
193
194/**
195 * Type of the record to add/remove, NULL to remove all.
196 */
197static char *typestring;
198/**
199 * Expiration string converted to numeric value.
200 */
201static uint64_t etime;
202
203/**
204 * Is expiration time relative or absolute time?
205 */
206static int etime_is_rel = GNUNET_SYSERR;
207
208/**
209 * Fixed size of the public/private keys
210 */
211static const int key_length = 52;
212
213/**
214 * Record label for storing delegations
215 */
216static char *record_label;
217
218/**
219 * Task run on shutdown. Cleans up everything.
220 *
221 * @param cls unused
222 */
223static void
224do_shutdown (void *cls)
225{
226 if (NULL != verify_request)
227 {
228 GNUNET_ABD_request_cancel (verify_request);
229 verify_request = NULL;
230 }
231 if (NULL != abd)
232 {
233 GNUNET_ABD_disconnect (abd);
234 abd = NULL;
235 }
236 if (NULL != tt)
237 {
238 GNUNET_SCHEDULER_cancel (tt);
239 tt = NULL;
240 }
241 if (NULL != el)
242 {
243 GNUNET_IDENTITY_ego_lookup_cancel (el);
244 el = NULL;
245 }
246 if (NULL != add_qe)
247 {
248 GNUNET_NAMESTORE_cancel (add_qe);
249 add_qe = NULL;
250 }
251 if (NULL != ns)
252 {
253 GNUNET_NAMESTORE_disconnect (ns);
254 ns = NULL;
255 }
256}
257
258
259/**
260 * Task run on timeout. Triggers shutdown.
261 *
262 * @param cls unused
263 */
264static void
265do_timeout (void *cls)
266{
267 tt = NULL;
268 GNUNET_SCHEDULER_shutdown ();
269}
270
271static void
272handle_intermediate_result(void *cls,
273 struct GNUNET_ABD_Delegation *dd,
274 bool is_bw)
275{
276 char *prefix = "";
277 if(is_bw)
278 prefix = "Backward -";
279 else
280 prefix = "Forward -";
281
282 printf ("%s Intermediate result: %s.%s <- %s.%s\n",
283 prefix,
284 GNUNET_CRYPTO_ecdsa_public_key_to_string (&dd->issuer_key),
285 dd->issuer_attribute,
286 GNUNET_CRYPTO_ecdsa_public_key_to_string (&dd->subject_key),
287 dd->subject_attribute);
288}
289
290static void
291handle_collect_result (void *cls,
292 unsigned int d_count,
293 struct GNUNET_ABD_Delegation *dc,
294 unsigned int c_count,
295 struct GNUNET_ABD_Delegate *dele)
296{
297 int i;
298 char *line;
299
300 verify_request = NULL;
301 if (NULL != dele)
302 {
303 for (i = 0; i < c_count; i++)
304 {
305 line = GNUNET_ABD_delegate_to_string (&dele[i]);
306 printf ("%s\n", line);
307 GNUNET_free (line);
308 }
309 }
310 else
311 {
312 printf ("Received NULL\n");
313 }
314
315 GNUNET_SCHEDULER_shutdown ();
316}
317
318
319static void
320handle_verify_result (void *cls,
321 unsigned int d_count,
322 struct GNUNET_ABD_Delegation *dc,
323 unsigned int c_count,
324 struct GNUNET_ABD_Delegate *dele)
325{
326 int i;
327 char *iss_key;
328 char *sub_key;
329
330 verify_request = NULL;
331 if (NULL == dele)
332 ret = 1;
333 else
334 {
335 printf ("Delegation Chain:\n");
336 for (i = 0; i < d_count; i++)
337 {
338 iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].issuer_key);
339 sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].subject_key);
340
341 if (0 != dc[i].subject_attribute_len)
342 {
343 printf ("(%d) %s.%s <- %s.%s\n",
344 i,
345 iss_key,
346 dc[i].issuer_attribute,
347 sub_key,
348 dc[i].subject_attribute);
349 }
350 else
351 {
352 printf ("(%d) %s.%s <- %s\n",
353 i,
354 iss_key,
355 dc[i].issuer_attribute,
356 sub_key);
357 }
358 GNUNET_free (iss_key);
359 GNUNET_free (sub_key);
360 }
361 printf ("\nDelegate(s):\n");
362 for (i = 0; i < c_count; i++)
363 {
364 iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dele[i].issuer_key);
365 sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dele[i].subject_key);
366 printf ("%s.%s <- %s\n", iss_key, dele[i].issuer_attribute, sub_key);
367 GNUNET_free (iss_key);
368 GNUNET_free (sub_key);
369 }
370 printf ("Successful.\n");
371 }
372
373 GNUNET_SCHEDULER_shutdown ();
374}
375
376/**
377 * Callback invoked from identity service with ego information.
378 * An @a ego of NULL means the ego was not found.
379 *
380 * @param cls closure with the configuration
381 * @param ego an ego known to identity service, or NULL
382 */
383static void
384identity_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
385{
386 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
387
388 el = NULL;
389 if (NULL == ego)
390 {
391 if (NULL != ego_name)
392 {
393 fprintf (stderr,
394 _ ("Ego `%s' not known to identity service\n"),
395 ego_name);
396 }
397 GNUNET_SCHEDULER_shutdown ();
398 return;
399 }
400
401 if (GNUNET_YES == collect)
402 {
403
404 if (GNUNET_OK !=
405 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
406 strlen (issuer_key),
407 &issuer_pkey))
408 {
409 fprintf (stderr,
410 _ ("Issuer public key `%s' is not well-formed\n"),
411 issuer_key);
412 GNUNET_SCHEDULER_shutdown ();
413 }
414 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
415
416 collect_request = GNUNET_ABD_collect (abd,
417 &issuer_pkey,
418 issuer_attr,
419 privkey,
420 direction,
421 &handle_collect_result,
422 NULL,
423 &handle_intermediate_result,
424 NULL);
425 return;
426 }
427 GNUNET_SCHEDULER_shutdown ();
428}
429
430/**
431 * Parse expiration time.
432 *
433 * @param expirationstring text to parse
434 * @param etime_is_rel[out] set to #GNUNET_YES if time is relative
435 * @param etime[out] set to expiration time (abs or rel)
436 * @return #GNUNET_OK on success
437 */
438static int
439parse_expiration (const char *expirationstring,
440 int *etime_is_rel,
441 uint64_t *etime)
442{
443 // copied from namestore/gnunet-namestore.c
444 struct GNUNET_TIME_Relative etime_rel;
445 struct GNUNET_TIME_Absolute etime_abs;
446
447 if (0 == strcmp (expirationstring, "never"))
448 {
449 *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
450 *etime_is_rel = GNUNET_NO;
451 return GNUNET_OK;
452 }
453 if (GNUNET_OK ==
454 GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel))
455 {
456 *etime_is_rel = GNUNET_YES;
457 *etime = etime_rel.rel_value_us;
458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
459 "Storing record with relative expiration time of %s\n",
460 GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO));
461 return GNUNET_OK;
462 }
463 if (GNUNET_OK ==
464 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs))
465 {
466 *etime_is_rel = GNUNET_NO;
467 *etime = etime_abs.abs_value_us;
468 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
469 "Storing record with absolute expiration time of %s\n",
470 GNUNET_STRINGS_absolute_time_to_string (etime_abs));
471 return GNUNET_OK;
472 }
473 return GNUNET_SYSERR;
474}
475
476/**
477 * Function called if lookup fails.
478 */
479static void
480error_cb (void *cls)
481{
482 fprintf (stderr, "Error occured during lookup, shutting down.\n");
483 GNUNET_SCHEDULER_shutdown ();
484 return;
485}
486static void
487add_continuation (void *cls, int32_t success, const char *emsg)
488{
489 struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
490 *qe = NULL;
491
492 if(GNUNET_OK == success)
493 printf ("Adding successful.\n");
494 else
495 fprintf (stderr, "Error occured during adding, shutting down.\n");
496
497 GNUNET_SCHEDULER_shutdown ();
498}
499
500static void
501get_existing_record (void *cls,
502 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
503 const char *rec_name,
504 unsigned int rd_count,
505 const struct GNUNET_GNSRECORD_Data *rd)
506{
507 struct GNUNET_GNSRECORD_Data rdn[rd_count + 1];
508 struct GNUNET_GNSRECORD_Data *rde;
509
510 memset (rdn, 0, sizeof (struct GNUNET_GNSRECORD_Data));
511 GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
512 rde = &rdn[0];
513 rde->data = data;
514 rde->data_size = data_size;
515 rde->record_type = type;
516
517 // Set flags
518 if (GNUNET_YES == is_private)
519 rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
520 rde->expiration_time = etime;
521 if (GNUNET_YES == etime_is_rel)
522 rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
523 else if (GNUNET_NO != etime_is_rel)
524 rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
525
526 GNUNET_assert (NULL != rec_name);
527 add_qe = GNUNET_NAMESTORE_records_store (ns,
528 &zone_pkey,
529 rec_name,
530 rd_count + 1,
531 rde,
532 &add_continuation,
533 &add_qe);
534
535 return;
536}
537
538static void
539store_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
540{
541 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
542
543 el = NULL;
544
545 ns = GNUNET_NAMESTORE_connect (cfg);
546 if (NULL == ns)
547 {
548 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
549 _ ("Failed to connect to namestore\n"));
550 GNUNET_SCHEDULER_shutdown ();
551 return;
552 }
553
554 // Key handling
555 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
556
557 if (GNUNET_GNSRECORD_TYPE_DELEGATE == type)
558 {
559 // Parse import
560 struct GNUNET_ABD_Delegate *cred;
561 cred = GNUNET_ABD_delegate_from_string (import);
562
563 // Get import subject public key string
564 char *subject_pubkey_str =
565 GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
566
567 // Get zone public key string
568 struct GNUNET_CRYPTO_EcdsaPublicKey zone_pubkey;
569 GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey);
570 char *zone_pubkey_str =
571 GNUNET_CRYPTO_ecdsa_public_key_to_string (&zone_pubkey);
572
573 // Check if the subject key in the signed import matches the zone's key it is issued to
574 if (strcmp (zone_pubkey_str, subject_pubkey_str) != 0)
575 {
576 fprintf (stderr,
577 "Import signed delegate does not match this ego's public key.\n");
578 GNUNET_SCHEDULER_shutdown ();
579 return;
580 }
581
582 // Expiration
583 etime = cred->expiration.abs_value_us;
584 etime_is_rel = GNUNET_NO;
585
586 // Prepare the data to be store in the record
587 data_size = GNUNET_ABD_delegate_serialize (cred, (char **) &data);
588 GNUNET_free (cred);
589 }
590 else
591 {
592 // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE
593 if (GNUNET_OK !=
594 GNUNET_GNSRECORD_string_to_value (type, subject, &data, &data_size))
595 {
596 fprintf (stderr,
597 "Value `%s' invalid for record type `%s'\n",
598 subject,
599 typestring);
600 GNUNET_SCHEDULER_shutdown ();
601 return;
602 }
603
604 // Take care of expiration
605 if (NULL == expiration)
606 {
607 fprintf (stderr, "Missing option -e for operation 'create'\n");
608 GNUNET_SCHEDULER_shutdown ();
609 return;
610 }
611 if (GNUNET_OK != parse_expiration (expiration, &etime_is_rel, &etime))
612 {
613 fprintf (stderr, "Invalid time format `%s'\n", expiration);
614 GNUNET_SCHEDULER_shutdown ();
615 return;
616 }
617 }
618
619 // Start lookup
620 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
621 &zone_pkey,
622 record_label,
623 &error_cb,
624 NULL,
625 &get_existing_record,
626 NULL);
627 return;
628}
629
630static void
631sign_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
632{
633 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
634 struct GNUNET_ABD_Delegate *dele;
635 struct GNUNET_TIME_Absolute etime_abs;
636 char *res;
637
638 el = NULL;
639
640 // work on expiration time
641 if (NULL == expiration)
642 {
643 fprintf (stderr, "Please specify a TTL\n");
644 GNUNET_SCHEDULER_shutdown ();
645 return;
646 }
647 else if (GNUNET_OK !=
648 GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs))
649 {
650 fprintf (stderr,
651 "%s is not a valid ttl! Only absolute times are accepted!\n",
652 expiration);
653 GNUNET_SCHEDULER_shutdown ();
654 return;
655 }
656
657 // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
658 char *subject_pubkey_str;
659 char *subject_attr = NULL;
660 char *token;
661
662 // Subject Public Key
663 token = strtok (subject, " ");
664 if (key_length == strlen (token))
665 {
666 subject_pubkey_str = token;
667 }
668 else
669 {
670 fprintf (stderr, "Key error, wrong length: %ld!\n", strlen (token));
671 GNUNET_SCHEDULER_shutdown ();
672 return;
673 }
674 // Subject Attribute(s)
675 token = strtok (NULL, " ");
676 if (NULL != token)
677 {
678 subject_attr = token;
679 }
680
681 // work on keys
682 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
683
684 if (GNUNET_OK !=
685 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pubkey_str,
686 strlen (subject_pubkey_str),
687 &subject_pkey))
688 {
689 fprintf (stderr,
690 "Subject public key `%s' is not well-formed\n",
691 subject_pubkey_str);
692 GNUNET_SCHEDULER_shutdown ();
693 return;
694 }
695
696 // Sign delegate
697 dele = GNUNET_ABD_delegate_issue (privkey,
698 &subject_pkey,
699 issuer_attr,
700 subject_attr,
701 &etime_abs);
702 res = GNUNET_ABD_delegate_to_string (dele);
703 GNUNET_free (dele);
704 printf ("%s\n", res);
705
706 GNUNET_free_non_null (ego_name);
707 ego_name = NULL;
708
709 GNUNET_SCHEDULER_shutdown ();
710}
711
712/**
713 * Main function that will be run.
714 *
715 * @param cls closure
716 * @param args remaining command-line arguments
717 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
718 * @param c configuration
719 */
720static void
721run (void *cls,
722 char *const *args,
723 const char *cfgfile,
724 const struct GNUNET_CONFIGURATION_Handle *c)
725{
726 cfg = c;
727
728 tt = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL);
729 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
730
731 // Check relevant cmdline parameters
732 if (GNUNET_YES == create_is)
733 {
734 if (NULL == ego_name)
735 {
736 fprintf (stderr, "Missing option '-ego'\n");
737 GNUNET_SCHEDULER_shutdown ();
738 return;
739 }
740 if (NULL == issuer_attr)
741 {
742 fprintf (stderr, "Missing option '-attribute' for issuer attribute\n");
743 GNUNET_SCHEDULER_shutdown ();
744 return;
745 }
746 if (NULL == subject)
747 {
748 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
749 GNUNET_SCHEDULER_shutdown ();
750 return;
751 }
752
753 // Lookup ego, on success call store_cb and store as ATTRIBUTE type
754 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE;
755 record_label = issuer_attr;
756 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
757 return;
758 }
759
760 if (GNUNET_YES == create_ss)
761 {
762
763 // check if signed parameter has been passed in cmd line call
764 if (NULL == import)
765 {
766 fprintf (stderr, "'import' required\n");
767 GNUNET_SCHEDULER_shutdown ();
768 return;
769 }
770
771 type = GNUNET_GNSRECORD_TYPE_DELEGATE;
772 record_label = GNUNET_GNS_EMPTY_LABEL_AT;
773 // Store subject side
774 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
775
776 return;
777 }
778
779 if (GNUNET_YES == sign_ss)
780 {
781 if (NULL == ego_name)
782 {
783 fprintf (stderr, "ego required\n");
784 GNUNET_SCHEDULER_shutdown ();
785 return;
786 }
787 if (NULL == subject)
788 {
789 fprintf (stderr, "Subject public key needed\n");
790 GNUNET_SCHEDULER_shutdown ();
791 return;
792 }
793
794 // lookup ego and call function sign_cb on success
795 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &sign_cb, (void *) cfg);
796 return;
797 }
798
799 if (GNUNET_NO == forward && GNUNET_NO == backward)
800 {
801 // set default: bidirectional
802 forward = GNUNET_YES;
803 backward = GNUNET_YES;
804 }
805 if (GNUNET_YES == forward)
806 direction |= GNUNET_ABD_FLAG_FORWARD;
807 if (GNUNET_YES == backward)
808 direction |= GNUNET_ABD_FLAG_BACKWARD;
809
810 if (GNUNET_YES == collect)
811 {
812 if (NULL == issuer_key)
813 {
814 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
815 GNUNET_SCHEDULER_shutdown ();
816 return;
817 }
818
819 abd = GNUNET_ABD_connect (cfg);
820
821 if (NULL == abd)
822 {
823 fprintf (stderr, _ ("Failed to connect to ABD\n"));
824 GNUNET_SCHEDULER_shutdown ();
825 return;
826 }
827 if (NULL == issuer_attr)
828 {
829 fprintf (stderr, _ ("You must provide issuer the attribute\n"));
830 GNUNET_SCHEDULER_shutdown ();
831 return;
832 }
833
834 if (NULL == ego_name)
835 {
836 fprintf (stderr, _ ("ego required\n"));
837 GNUNET_SCHEDULER_shutdown ();
838 return;
839 }
840 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) cfg);
841 return;
842 }
843
844 if (NULL == subject)
845 {
846 fprintf (stderr, _ ("Subject public key needed\n"));
847 GNUNET_SCHEDULER_shutdown ();
848 return;
849 }
850 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (subject,
851 strlen (subject),
852 &subject_pkey))
853 {
854 fprintf (stderr,
855 _ ("Subject public key `%s' is not well-formed\n"),
856 subject);
857 GNUNET_SCHEDULER_shutdown ();
858 return;
859 }
860
861 if (GNUNET_YES == verify)
862 {
863 if (NULL == issuer_key)
864 {
865 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
866 GNUNET_SCHEDULER_shutdown ();
867 return;
868 }
869 if (GNUNET_OK !=
870 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
871 strlen (issuer_key),
872 &issuer_pkey))
873 {
874 fprintf (stderr,
875 _ ("Issuer public key `%s' is not well-formed\n"),
876 issuer_key);
877 GNUNET_SCHEDULER_shutdown ();
878 return;
879 }
880 abd = GNUNET_ABD_connect (cfg);
881
882 if (NULL == abd)
883 {
884 fprintf (stderr, _ ("Failed to connect to ABD\n"));
885 GNUNET_SCHEDULER_shutdown ();
886 return;
887 }
888 if (NULL == issuer_attr || NULL == subject_delegate)
889 {
890 fprintf (stderr, _ ("You must provide issuer and subject attributes\n"));
891 GNUNET_SCHEDULER_shutdown ();
892 return;
893 }
894
895 //Subject credentials are comma separated
896 char *tmp = GNUNET_strdup (subject_delegate);
897 char *tok = strtok (tmp, ",");
898 if (NULL == tok)
899 {
900 fprintf (stderr, "Invalid subject credentials\n");
901 GNUNET_free (tmp);
902 GNUNET_SCHEDULER_shutdown ();
903 return;
904 }
905 int count = 1;
906 int i;
907 while (NULL != (tok = strtok (NULL, ",")))
908 count++;
909 struct GNUNET_ABD_Delegate delegates[count];
910 struct GNUNET_ABD_Delegate *dele;
911 GNUNET_free (tmp);
912 tmp = GNUNET_strdup (subject_delegate);
913 tok = strtok (tmp, ",");
914 for (i = 0; i < count; i++)
915 {
916 dele = GNUNET_ABD_delegate_from_string (tok);
917 GNUNET_memcpy (&delegates[i],
918 dele,
919 sizeof (struct GNUNET_ABD_Delegate));
920 delegates[i].issuer_attribute = GNUNET_strdup (dele->issuer_attribute);
921 tok = strtok (NULL, ",");
922 GNUNET_free (dele);
923 }
924
925 verify_request = GNUNET_ABD_verify (abd,
926 &issuer_pkey,
927 issuer_attr,
928 &subject_pkey,
929 count,
930 delegates,
931 direction,
932 &handle_verify_result,
933 NULL,
934 &handle_intermediate_result,
935 NULL);
936 for (i = 0; i < count; i++)
937 {
938 GNUNET_free ((char *) delegates[i].issuer_attribute);
939 }
940 GNUNET_free (tmp);
941 }
942 else
943 {
944 fprintf (stderr,
945 _ (
946 "Please specify name to lookup, subject key and issuer key!\n"));
947 GNUNET_SCHEDULER_shutdown ();
948 }
949 return;
950}
951
952
953/**
954 * The main function for gnunet-gns.
955 *
956 * @param argc number of arguments from the command line
957 * @param argv command line arguments
958 * @return 0 ok, 1 on error
959 */
960int
961main (int argc, char *const *argv)
962{
963 struct GNUNET_GETOPT_CommandLineOption options[] =
964 {GNUNET_GETOPT_option_flag ('V',
965 "verify",
966 gettext_noop (
967 "verify credential against attribute"),
968 &verify),
969 GNUNET_GETOPT_option_string (
970 's',
971 "subject",
972 "PKEY",
973 gettext_noop (
974 "The public key of the subject to lookup the"
975 "credential for, or for issuer side storage: subject and its attributes"),
976 &subject),
977 GNUNET_GETOPT_option_string (
978 'd',
979 "delegate",
980 "DELE",
981 gettext_noop ("The private, signed delegate presented by the subject"),
982 &subject_delegate),
983 GNUNET_GETOPT_option_string (
984 'i',
985 "issuer",
986 "PKEY",
987 gettext_noop (
988 "The public key of the authority to verify the credential against"),
989 &issuer_key),
990 GNUNET_GETOPT_option_string ('e',
991 "ego",
992 "EGO",
993 gettext_noop ("The ego/zone name to use"),
994 &ego_name),
995 GNUNET_GETOPT_option_string (
996 'a',
997 "attribute",
998 "ATTR",
999 gettext_noop ("The issuer attribute to verify against or to issue"),
1000 &issuer_attr),
1001 GNUNET_GETOPT_option_string ('T',
1002 "ttl",
1003 "EXP",
1004 gettext_noop (
1005 "The time to live for the credential."
1006 "e.g. 5m, 6h, \"1990-12-30 12:00:00\""),
1007 &expiration),
1008 GNUNET_GETOPT_option_flag ('g',
1009 "collect",
1010 gettext_noop ("collect credentials"),
1011 &collect),
1012 GNUNET_GETOPT_option_flag ('U',
1013 "createIssuerSide",
1014 gettext_noop (
1015 "Create and issue a credential issuer side."),
1016 &create_is),
1017 GNUNET_GETOPT_option_flag ('C',
1018 "createSubjectSide",
1019 gettext_noop (
1020 "Issue a credential subject side."),
1021 &create_ss),
1022 GNUNET_GETOPT_option_flag (
1023 'S',
1024 "signSubjectSide",
1025 gettext_noop ("Create, sign and return a credential subject side."),
1026 &sign_ss),
1027 GNUNET_GETOPT_option_string (
1028 'x',
1029 "import",
1030 "IMP",
1031 gettext_noop (
1032 "Import signed credentials that should be issued to a zone/ego"),
1033 &import),
1034 GNUNET_GETOPT_option_flag ('P',
1035 "private",
1036 gettext_noop ("Create private record entry."),
1037 &is_private),
1038 GNUNET_GETOPT_option_flag (
1039 'F',
1040 "forward",
1041 gettext_noop (
1042 "Indicates that the collect/verify process is done via forward search."),
1043 &forward),
1044 GNUNET_GETOPT_option_flag (
1045 'B',
1046 "backward",
1047 gettext_noop (
1048 "Indicates that the collect/verify process is done via forward search."),
1049 &backward),
1050 GNUNET_GETOPT_OPTION_END};
1051
1052
1053 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1054 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1055 return 2;
1056
1057 GNUNET_log_setup ("gnunet-abd", "WARNING", NULL);
1058 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
1059 argv,
1060 "gnunet-abd",
1061 _ ("GNUnet abd resolver tool"),
1062 options,
1063 &run,
1064 NULL))
1065 ret = 1;
1066 GNUNET_free ((void *) argv);
1067 return ret;
1068}
1069
1070/* end of gnunet-abd.c */
diff --git a/src/abd/gnunet-service-abd.c b/src/abd/gnunet-service-abd.c
new file mode 100644
index 000000000..84222b290
--- /dev/null
+++ b/src/abd/gnunet-service-abd.c
@@ -0,0 +1,1751 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011-2013 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 * @file abd/gnunet-service-abd.c
22 * @brief GNUnet Credential Service (main service)
23 * @author Martin Schanzenbach
24 */
25#include "platform.h"
26
27#include "gnunet_util_lib.h"
28
29#include "abd.h"
30#include "abd_serialization.h"
31#include "gnunet_abd_service.h"
32#include "gnunet_protocols.h"
33#include "gnunet_signatures.h"
34#include "gnunet_statistics_service.h"
35#include <gnunet_dnsparser_lib.h>
36#include <gnunet_gns_service.h>
37#include <gnunet_gnsrecord_lib.h>
38#include <gnunet_identity_service.h>
39#include <gnunet_namestore_service.h>
40
41
42#define GNUNET_ABD_MAX_LENGTH 255
43
44struct VerifyRequestHandle;
45
46struct DelegationSetQueueEntry;
47
48
49struct DelegationChainEntry
50{
51 /**
52 * DLL
53 */
54 struct DelegationChainEntry *next;
55
56 /**
57 * DLL
58 */
59 struct DelegationChainEntry *prev;
60
61 /**
62 * The issuer
63 */
64 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
65
66 /**
67 * The subject
68 */
69 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
70
71 /**
72 * The issued attribute
73 */
74 char *issuer_attribute;
75
76 /**
77 * The delegated attribute
78 */
79 char *subject_attribute;
80};
81
82/**
83 * DLL for record
84 */
85struct DelegateRecordEntry
86{
87 /**
88 * DLL
89 */
90 struct DelegateRecordEntry *next;
91
92 /**
93 * DLL
94 */
95 struct DelegateRecordEntry *prev;
96
97 /**
98 * Number of references in delegation chains
99 */
100 uint32_t refcount;
101
102 /**
103 * Payload
104 */
105 struct GNUNET_ABD_Delegate *delegate;
106};
107
108/**
109 * DLL used for delegations
110 * Used for OR delegations
111 */
112struct DelegationQueueEntry
113{
114 /**
115 * DLL
116 */
117 struct DelegationQueueEntry *next;
118
119 /**
120 * DLL
121 */
122 struct DelegationQueueEntry *prev;
123
124 /**
125 * Parent set
126 */
127 struct DelegationSetQueueEntry *parent_set;
128
129 /**
130 * Required solutions
131 */
132 uint32_t required_solutions;
133};
134
135/**
136 * DLL for delegation sets
137 * Used for AND delegation set
138 */
139struct DelegationSetQueueEntry
140{
141 /**
142 * DLL
143 */
144 struct DelegationSetQueueEntry *next;
145
146 /**
147 * DLL
148 */
149 struct DelegationSetQueueEntry *prev;
150
151 /**
152 * GNS handle
153 */
154 struct GNUNET_GNS_LookupRequest *lookup_request;
155
156 /**
157 * Verify handle
158 */
159 struct VerifyRequestHandle *handle;
160
161 /**
162 * Parent attribute delegation
163 */
164 struct DelegationQueueEntry *parent;
165
166 /**
167 * Issuer key
168 */
169 struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key;
170
171 /**
172 * Queue entries of this set
173 */
174 struct DelegationQueueEntry *queue_entries_head;
175
176 /**
177 * Queue entries of this set
178 */
179 struct DelegationQueueEntry *queue_entries_tail;
180
181 /**
182 * Parent QueueEntry
183 */
184 struct DelegationQueueEntry *parent_queue_entry;
185
186 /**
187 * Issuer attribute delegated to
188 */
189 char *issuer_attribute;
190
191 /**
192 * The current attribute to look up
193 */
194 char *lookup_attribute;
195
196 /**
197 * Trailing attribute context
198 */
199 char *attr_trailer;
200
201 /**
202 * Still to resolve delegation as string
203 */
204 char *unresolved_attribute_delegation;
205
206 /**
207 * The delegation chain entry
208 */
209 struct DelegationChainEntry *delegation_chain_entry;
210
211 /**
212 * True if added by backward resolution
213 */
214 bool from_bw;
215};
216
217
218/**
219 * Handle to a lookup operation from api
220 */
221struct VerifyRequestHandle
222{
223 /**
224 * True if created by a collect request.
225 */
226 bool is_collect;
227 /**
228 * We keep these in a DLL.
229 */
230 struct VerifyRequestHandle *next;
231
232 /**
233 * We keep these in a DLL.
234 */
235 struct VerifyRequestHandle *prev;
236
237 /**
238 * Handle to the requesting client
239 */
240 struct GNUNET_SERVICE_Client *client;
241
242 /**
243 * Size of delegation tree
244 */
245 uint32_t delegation_chain_size;
246
247 /**
248 * Children of this attribute
249 */
250 struct DelegationChainEntry *delegation_chain_head;
251
252 /**
253 * Children of this attribute
254 */
255 struct DelegationChainEntry *delegation_chain_tail;
256
257 /**
258 * List for bidirectional matching
259 */
260 struct DelegationSetQueueEntry *dsq_head;
261
262 /**
263 * List for bidirectional matching
264 */
265 struct DelegationSetQueueEntry *dsq_tail;
266
267 /**
268 * Issuer public key
269 */
270 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
271
272 /**
273 * Issuer attribute
274 */
275 char *issuer_attribute;
276
277 /**
278 * Subject public key
279 */
280 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
281
282 /**
283 * Delegate DLL
284 */
285 struct DelegateRecordEntry *del_chain_head;
286
287 /**
288 * Delegate DLL
289 */
290 struct DelegateRecordEntry *del_chain_tail;
291
292 /**
293 * Delegate DLL size
294 */
295 uint32_t del_chain_size;
296
297 /**
298 * Current Delegation Pointer
299 */
300 struct DelegationQueueEntry *current_delegation;
301
302 /**
303 * request id
304 */
305 uint32_t request_id;
306
307 /**
308 * Pending lookups
309 */
310 uint64_t pending_lookups;
311
312 /**
313 * Direction of the resolution algo
314 */
315 enum GNUNET_ABD_AlgoDirectionFlags resolution_algo;
316
317 /**
318 * Delegate iterator for lookup
319 */
320 struct GNUNET_NAMESTORE_QueueEntry *dele_qe;
321};
322
323
324/**
325 * Head of the DLL.
326 */
327static struct VerifyRequestHandle *vrh_head = NULL;
328
329/**
330 * Tail of the DLL.
331 */
332static struct VerifyRequestHandle *vrh_tail = NULL;
333
334/**
335 * Handle to the statistics service
336 */
337static struct GNUNET_STATISTICS_Handle *statistics;
338
339/**
340 * Handle to GNS service.
341 */
342static struct GNUNET_GNS_Handle *gns;
343
344/**
345 * Handle to namestore service
346 */
347static struct GNUNET_NAMESTORE_Handle *namestore;
348
349static void
350print_deleset (struct DelegationSetQueueEntry *dsentry, char *text)
351{
352 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
353 "%s %s.%s <- %s.%s\n",
354 text,
355 GNUNET_CRYPTO_ecdsa_public_key_to_string (
356 &dsentry->delegation_chain_entry->issuer_key),
357 dsentry->delegation_chain_entry->issuer_attribute,
358 GNUNET_CRYPTO_ecdsa_public_key_to_string (
359 &dsentry->delegation_chain_entry->subject_key),
360 dsentry->delegation_chain_entry->subject_attribute);
361}
362
363static void
364cleanup_dsq_entry (struct DelegationSetQueueEntry *ds_entry)
365{
366 GNUNET_free_non_null (ds_entry->issuer_key);
367 GNUNET_free_non_null (ds_entry->issuer_attribute);
368 GNUNET_free_non_null (ds_entry->attr_trailer);
369 // those fields are only set/used in bw search
370 if (ds_entry->from_bw)
371 {
372 GNUNET_free_non_null (ds_entry->lookup_attribute);
373 GNUNET_free_non_null (ds_entry->unresolved_attribute_delegation);
374 }
375 if (NULL != ds_entry->lookup_request)
376 {
377 GNUNET_GNS_lookup_cancel (ds_entry->lookup_request);
378 ds_entry->lookup_request = NULL;
379 }
380 if (NULL != ds_entry->delegation_chain_entry)
381 {
382 GNUNET_free_non_null (
383 ds_entry->delegation_chain_entry->subject_attribute);
384 GNUNET_free_non_null (ds_entry->delegation_chain_entry->issuer_attribute);
385 GNUNET_free (ds_entry->delegation_chain_entry);
386 }
387 // Free DQ entries
388 for(struct DelegationQueueEntry *dq_entry = ds_entry->queue_entries_head;
389 NULL != ds_entry->queue_entries_head;
390 dq_entry = ds_entry->queue_entries_head)
391 {
392 GNUNET_CONTAINER_DLL_remove (ds_entry->queue_entries_head,
393 ds_entry->queue_entries_tail,
394 dq_entry);
395 GNUNET_free (dq_entry);
396 }
397 GNUNET_free (ds_entry);
398}
399
400static void
401cleanup_handle (struct VerifyRequestHandle *vrh)
402{
403 struct DelegateRecordEntry *del_entry;
404 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n");
405
406 if (NULL != vrh->dsq_head)
407 {
408 for (struct DelegationSetQueueEntry *ds_entry = vrh->dsq_head; NULL != vrh->dsq_head;
409 ds_entry = vrh->dsq_head)
410 {
411 GNUNET_CONTAINER_DLL_remove (vrh->dsq_head, vrh->dsq_tail, ds_entry);
412 cleanup_dsq_entry(ds_entry);
413 }
414 }
415 if (NULL != vrh->del_chain_head)
416 {
417 for (del_entry = vrh->del_chain_head; NULL != vrh->del_chain_head;
418 del_entry = vrh->del_chain_head)
419 {
420 GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head,
421 vrh->del_chain_tail,
422 del_entry);
423 GNUNET_free_non_null (del_entry->delegate);
424 GNUNET_free (del_entry);
425 }
426 }
427 GNUNET_free_non_null (vrh->issuer_attribute);
428 GNUNET_free (vrh);
429}
430
431static void
432shutdown_task (void *cls)
433{
434 struct VerifyRequestHandle *vrh;
435
436 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n");
437
438 while (NULL != (vrh = vrh_head))
439 {
440 // ABD_resolver_lookup_cancel (clh->lookup);
441 GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
442 cleanup_handle (vrh);
443 }
444
445 if (NULL != gns)
446 {
447 GNUNET_GNS_disconnect (gns);
448 gns = NULL;
449 }
450 if (NULL != namestore)
451 {
452 GNUNET_NAMESTORE_disconnect (namestore);
453 namestore = NULL;
454 }
455 if (NULL != statistics)
456 {
457 GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
458 statistics = NULL;
459 }
460}
461
462static void
463send_intermediate_response(struct VerifyRequestHandle *vrh, struct DelegationChainEntry *ch_entry, bool is_bw){
464 struct DelegationChainIntermediateMessage *rmsg;
465 struct GNUNET_MQ_Envelope *env;
466 struct GNUNET_ABD_Delegation *dd;
467 size_t size;
468
469 // Don't report immediate results during collect
470 if(vrh->is_collect)
471 return;
472
473 dd = GNUNET_new (struct GNUNET_ABD_Delegation);
474 dd->issuer_key = ch_entry->issuer_key;
475 dd->subject_key = ch_entry->subject_key;
476 dd->issuer_attribute = ch_entry->issuer_attribute;
477 dd->issuer_attribute_len = strlen (ch_entry->issuer_attribute) + 1;
478 dd->subject_attribute_len = 0;
479 dd->subject_attribute = NULL;
480 if (NULL != ch_entry->subject_attribute)
481 {
482 dd->subject_attribute = ch_entry->subject_attribute;
483 dd->subject_attribute_len = strlen (ch_entry->subject_attribute) + 1;
484 }
485
486
487 size = GNUNET_ABD_delegation_chain_get_size (1,
488 dd,
489 0,
490 NULL);
491
492 env = GNUNET_MQ_msg_extra (rmsg,
493 size,
494 GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT);
495 // Assign id so that client can find associated request
496 rmsg->id = vrh->request_id;
497 rmsg->is_bw = htons(is_bw);
498 rmsg->size = htonl(size);
499
500 GNUNET_assert (
501 -1 != GNUNET_ABD_delegation_chain_serialize (1,
502 dd,
503 0,
504 NULL,
505 size,
506 (char *) &rmsg[1]));
507 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env);
508}
509
510static void
511send_lookup_response (struct VerifyRequestHandle *vrh)
512{
513 struct GNUNET_MQ_Envelope *env;
514 struct DelegationChainResultMessage *rmsg;
515 struct DelegationChainEntry *dce;
516 struct GNUNET_ABD_Delegation dd[vrh->delegation_chain_size];
517 struct GNUNET_ABD_Delegate dele[vrh->del_chain_size];
518 struct DelegateRecordEntry *del;
519 struct DelegateRecordEntry *tmp;
520 size_t size;
521
522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
523 dce = vrh->delegation_chain_head;
524 for (uint32_t i = 0; i < vrh->delegation_chain_size; i++)
525 {
526 dd[i].issuer_key = dce->issuer_key;
527 dd[i].subject_key = dce->subject_key;
528 dd[i].issuer_attribute = dce->issuer_attribute;
529 dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1;
530 dd[i].subject_attribute_len = 0;
531 dd[i].subject_attribute = NULL;
532 if (NULL != dce->subject_attribute)
533 {
534 dd[i].subject_attribute = dce->subject_attribute;
535 dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1;
536 }
537 dce = dce->next;
538 }
539
540 // Remove all not needed credentials
541 for (del = vrh->del_chain_head; NULL != del;)
542 {
543 if (del->refcount > 0)
544 {
545 del = del->next;
546 continue;
547 }
548 tmp = del;
549 del = del->next;
550 GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head, vrh->del_chain_tail, tmp);
551 GNUNET_free (tmp->delegate);
552 GNUNET_free (tmp);
553 vrh->del_chain_size--;
554 }
555
556 // Get serialized record data
557 // Append at the end of rmsg
558 del = vrh->del_chain_head;
559 for (uint32_t i = 0; i < vrh->del_chain_size; i++)
560 {
561 dele[i].issuer_key = del->delegate->issuer_key;
562 dele[i].subject_key = del->delegate->subject_key;
563 dele[i].issuer_attribute_len = strlen (del->delegate->issuer_attribute) + 1;
564 dele[i].issuer_attribute = del->delegate->issuer_attribute;
565 dele[i].subject_attribute_len = del->delegate->subject_attribute_len;
566 dele[i].subject_attribute = del->delegate->subject_attribute;
567 dele[i].expiration = del->delegate->expiration;
568 dele[i].signature = del->delegate->signature;
569 del = del->next;
570 }
571 size =
572 GNUNET_ABD_delegation_chain_get_size (vrh->delegation_chain_size,
573 dd,
574 vrh->del_chain_size,
575 dele);
576 env = GNUNET_MQ_msg_extra (rmsg,
577 size,
578 GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT);
579 // Assign id so that client can find associated request
580 rmsg->id = vrh->request_id;
581 rmsg->d_count = htonl (vrh->delegation_chain_size);
582 rmsg->c_count = htonl (vrh->del_chain_size);
583
584 if (0 < vrh->del_chain_size)
585 rmsg->del_found = htonl (GNUNET_YES);
586 else
587 rmsg->del_found = htonl (GNUNET_NO);
588
589 GNUNET_assert (
590 -1 !=
591 GNUNET_ABD_delegation_chain_serialize (vrh->delegation_chain_size,
592 dd,
593 vrh->del_chain_size,
594 dele,
595 size,
596 (char *) &rmsg[1]));
597
598 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env);
599 GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
600 cleanup_handle (vrh);
601 GNUNET_STATISTICS_update (statistics,
602 "Completed verifications",
603 1,
604 GNUNET_NO);
605}
606
607static char *
608partial_match (char *tmp_trail,
609 char *tmp_subattr,
610 char *parent_trail,
611 char *issuer_attribute)
612{
613 char *saveptr1, *saveptr2;
614 char *trail_token;
615 char *sub_token;
616 char *attr_trailer;
617
618 // tok both, parent->attr_trailer and del->sub_attr to see how far they match,
619 // take rest of parent trailer (only when del->sub_attr token is null), and
620 // create new/actual trailer with del->iss_attr
621 trail_token = strtok_r (tmp_trail, ".", &saveptr1);
622 sub_token = strtok_r (tmp_subattr, ".", &saveptr2);
623 while (NULL != trail_token && NULL != sub_token)
624 {
625 if (0 == strcmp (trail_token, sub_token))
626 {
627 // good, matches, remove
628 }
629 else
630 {
631 // not relevant for solving the chain, end for iteration here
632 return NULL;
633 }
634
635 trail_token = strtok_r (NULL, ".", &saveptr1);
636 sub_token = strtok_r (NULL, ".", &saveptr2);
637 }
638 // skip this entry and go to next for if:
639 // 1. at some point the attr of the trailer and the subject dont match
640 // 2. the trailer is NULL, but the subject has more attributes
641 // Reason: This will lead to "startzone.attribute" but we're looking for a solution
642 // for "<- startzone"
643 if (NULL == trail_token)
644 {
645 return NULL;
646 }
647
648 // do not have to check sub_token == NULL, if both would be NULL
649 // at the same time, the complete match part above should have triggered already
650
651 // otherwise, above while only ends when sub_token == NULL
652 GNUNET_asprintf (&attr_trailer, "%s", trail_token);
653 trail_token = strtok_r (NULL, ".", &saveptr1);
654 while (NULL != trail_token)
655 {
656 GNUNET_asprintf (&attr_trailer, "%s.%s", parent_trail, trail_token);
657 trail_token = strtok_r (NULL, ".", &saveptr1);
658 }
659 GNUNET_asprintf (&attr_trailer, "%s.%s", issuer_attribute, attr_trailer);
660 return attr_trailer;
661}
662
663static int
664handle_bidirectional_match (struct DelegationSetQueueEntry *actual_entry,
665 struct DelegationSetQueueEntry *match_entry,
666 struct VerifyRequestHandle *vrh)
667{
668 struct DelegationSetQueueEntry *old_fw_parent;
669 struct DelegationSetQueueEntry *fw_entry = actual_entry;
670 struct DelegationSetQueueEntry *last_entry = match_entry;
671 // parent fixing, combine backward and forward chain parts
672 while (NULL != fw_entry->parent_queue_entry)
673 {
674 old_fw_parent = fw_entry->parent_queue_entry->parent_set;
675 // set parent
676 fw_entry->parent_queue_entry->parent_set = last_entry;
677
678 last_entry = fw_entry;
679 fw_entry = old_fw_parent;
680 }
681 // set last entry of chain as actual_entry
682 //actual_entry = last_entry;
683 // set refcount, loop all delegations
684 for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
685 del_entry != NULL;
686 del_entry = del_entry->next)
687 {
688 if (0 != memcmp (&last_entry->delegation_chain_entry->subject_key,
689 &del_entry->delegate->issuer_key,
690 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
691 continue;
692 if (0 != strcmp (last_entry->delegation_chain_entry->subject_attribute,
693 del_entry->delegate->issuer_attribute))
694 continue;
695
696 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found delegate.\n");
697 // increase refcount of the start delegation
698 del_entry->refcount++;
699 }
700 // backtrack
701 for (struct DelegationSetQueueEntry *tmp_set = last_entry;
702 NULL != tmp_set->parent_queue_entry;
703 tmp_set = tmp_set->parent_queue_entry->parent_set)
704 {
705 tmp_set->parent_queue_entry->required_solutions--;
706
707 // add new found entry to vrh
708 vrh->delegation_chain_size++;
709 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head,
710 vrh->delegation_chain_tail,
711 tmp_set->delegation_chain_entry);
712
713 // if one node on the path still needs solutions, this current
714 // patch cannot fullfil the conditions and therefore stops here
715 // however, it is in the vrh and can be used by the other paths
716 // related to this path/collection/verification
717 if (0 < tmp_set->parent_queue_entry->required_solutions)
718 {
719 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
720 "Chain requires more solutions, waiting...\n");
721 return GNUNET_NO;
722 }
723 }
724 return GNUNET_YES;
725}
726
727static void
728forward_resolution (void *cls,
729 uint32_t rd_count,
730 const struct GNUNET_GNSRECORD_Data *rd)
731{
732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count);
733
734 struct VerifyRequestHandle *vrh;
735 struct DelegationSetQueueEntry *current_set;
736 struct DelegationSetQueueEntry *ds_entry;
737 struct DelegationQueueEntry *dq_entry;
738
739 current_set = cls;
740 // set handle to NULL (as el = NULL)
741 current_set->lookup_request = NULL;
742 vrh = current_set->handle;
743 vrh->pending_lookups--;
744
745 // Loop record entries
746 for (uint32_t i = 0; i < rd_count; i++)
747 {
748 if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
749 continue;
750
751 // Start deserialize into Delegate
752 struct GNUNET_ABD_Delegate *del;
753 del = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size);
754
755 // Start: Create DQ Entry
756 dq_entry = GNUNET_new (struct DelegationQueueEntry);
757 // AND delegations are not possible, only 1 solution
758 dq_entry->required_solutions = 1;
759 dq_entry->parent_set = current_set;
760
761 // Insert it into the current set
762 GNUNET_CONTAINER_DLL_insert (current_set->queue_entries_head,
763 current_set->queue_entries_tail,
764 dq_entry);
765
766 // Start: Create DS Entry
767 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
768 GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
769 ds_entry->from_bw = false;
770
771 // (1) A.a <- A.b.c
772 // (2) A.b <- D.d
773 // (3) D.d <- E
774 // (4) E.c <- F.c
775 // (5) F.c <- G
776 // Possibilities:
777 // 1. complete match: trailer = 0, validate
778 // 2. partial match: replace
779 // 3. new solution: replace, add trailer
780
781 // At resolution chain start trailer of parent is NULL
782 if (NULL == current_set->attr_trailer)
783 {
784 // for (5) F.c <- G, remember .c when going upwards
785 ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
786 }
787 else
788 {
789 if (0 == del->subject_attribute_len)
790 {
791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: New solution\n");
792 // new solution
793 // create new trailer del->issuer_attribute, ds_entry->attr_trailer
794 GNUNET_asprintf (&ds_entry->attr_trailer,
795 "%s.%s",
796 del->issuer_attribute,
797 current_set->attr_trailer);
798 }
799 else if (0 == strcmp (del->subject_attribute, current_set->attr_trailer))
800 {
801 // complete match
802 // new trailer == issuer attribute (e.g. (5) to (4))
803 ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
804 }
805 else
806 {
807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Partial match\n");
808 // partial match
809
810 char *trail = partial_match (GNUNET_strdup (current_set->attr_trailer),
811 GNUNET_strdup (del->subject_attribute),
812 current_set->attr_trailer,
813 GNUNET_strdup (del->issuer_attribute));
814
815 // if null: skip this record entry (reasons: mismatch or overmatch, both not relevant)
816 if (NULL == trail)
817 {
818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
819 "Entry not relevant, discarding: %s.%s <- %s.%s\n",
820 GNUNET_CRYPTO_ecdsa_public_key_to_string (
821 &del->issuer_key),
822 del->issuer_attribute,
823 GNUNET_CRYPTO_ecdsa_public_key_to_string (
824 &del->subject_key),
825 del->subject_attribute);
826 continue;
827 }
828 else
829 ds_entry->attr_trailer = trail;
830 }
831 }
832
833
834 // Start: Credential Chain Entry
835 // issuer key is subject key, who needs to be contacted to resolve this (forward, therefore subject)
836 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
837 GNUNET_memcpy (ds_entry->issuer_key,
838 &del->subject_key,
839 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
840
841 ds_entry->delegation_chain_entry = GNUNET_new (struct DelegationChainEntry);
842 ds_entry->delegation_chain_entry->subject_key = del->subject_key;
843 if (0 < del->subject_attribute_len)
844 ds_entry->delegation_chain_entry->subject_attribute =
845 GNUNET_strdup (del->subject_attribute);
846 ds_entry->delegation_chain_entry->issuer_key = del->issuer_key;
847 ds_entry->delegation_chain_entry->issuer_attribute =
848 GNUNET_strdup (del->issuer_attribute);
849
850 // Found new entry, repoting intermediate result
851 send_intermediate_response(vrh, ds_entry->delegation_chain_entry, false);
852
853 // current delegation as parent
854 ds_entry->parent_queue_entry = dq_entry;
855
856 // Check for solution
857 // if: issuer key we looking for
858 if (0 == memcmp (&del->issuer_key,
859 &vrh->issuer_key,
860 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
861 {
862 // if: issuer attr we looking for
863 if (0 == strcmp (del->issuer_attribute, vrh->issuer_attribute))
864 {
865 // if: complete match, meaning new trailer == issuer attr
866 if (0 == strcmp (vrh->issuer_attribute, ds_entry->attr_trailer))
867 {
868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Solution\n");
869
870 // Add found solution into delegation_chain
871 struct DelegationSetQueueEntry *tmp_set;
872 for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
873 tmp_set = tmp_set->parent_queue_entry->parent_set)
874 {
875 if (NULL != tmp_set->delegation_chain_entry)
876 {
877 vrh->delegation_chain_size++;
878 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head,
879 vrh->delegation_chain_tail,
880 tmp_set->delegation_chain_entry);
881 }
882 }
883
884 // Increase refcount for this delegate
885 for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
886 del_entry != NULL;
887 del_entry = del_entry->next)
888 {
889 if (0 == memcmp (&del_entry->delegate->issuer_key,
890 &vrh->delegation_chain_head->subject_key,
891 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
892 {
893 if (0 == strcmp (del_entry->delegate->issuer_attribute,
894 vrh->delegation_chain_head->subject_attribute))
895 {
896 del_entry->refcount++;
897 }
898 }
899 }
900
901 send_lookup_response (vrh);
902 return;
903 }
904 }
905 }
906
907 // Check for bidirectional crossmatch
908 for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
909 del_entry != NULL;
910 del_entry = del_entry->next)
911 {
912 // only check entries not by backward algorithm
913 if (del_entry->from_bw)
914 {
915 // key of list entry matches actual key
916 if (0 == memcmp (&del_entry->delegation_chain_entry->subject_key,
917 &ds_entry->delegation_chain_entry->issuer_key,
918 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
919 {
920 // compare entry subject attributes to this trailer (iss attr + old trailer)
921 if (0 == strcmp (del_entry->unresolved_attribute_delegation,
922 ds_entry->attr_trailer))
923 {
924 print_deleset (del_entry, "Forward:");
925 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
926 "Forward: Found match with above!\n");
927
928 // one node on the path still needs solutions: return
929 if (GNUNET_NO ==
930 handle_bidirectional_match (ds_entry, del_entry, vrh))
931 return;
932
933 send_lookup_response (vrh);
934 return;
935 }
936 }
937 }
938 }
939
940 // Starting a new GNS lookup
941 vrh->pending_lookups++;
942 ds_entry->handle = vrh;
943
944 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
945 "Starting to look up trailer %s in zone %s\n",
946 ds_entry->attr_trailer,
947 GNUNET_CRYPTO_ecdsa_public_key_to_string (&del->issuer_key));
948
949 ds_entry->lookup_request =
950 GNUNET_GNS_lookup (gns,
951 GNUNET_GNS_EMPTY_LABEL_AT,
952 &del->issuer_key,
953 GNUNET_GNSRECORD_TYPE_DELEGATE,
954 GNUNET_GNS_LO_DEFAULT,
955 &forward_resolution,
956 ds_entry);
957 }
958
959 if (0 == vrh->pending_lookups)
960 {
961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
962 send_lookup_response (vrh);
963 return;
964 }
965}
966
967static void
968backward_resolution (void *cls,
969 uint32_t rd_count,
970 const struct GNUNET_GNSRECORD_Data *rd)
971{
972 struct VerifyRequestHandle *vrh;
973 const struct GNUNET_ABD_DelegationRecord *sets;
974 struct DelegateRecordEntry *del_pointer;
975 struct DelegationSetQueueEntry *current_set;
976 struct DelegationSetQueueEntry *ds_entry;
977 struct DelegationSetQueueEntry *tmp_set;
978 struct DelegationQueueEntry *dq_entry;
979 char *expanded_attr;
980 char *lookup_attribute;
981
982 current_set = cls;
983 current_set->lookup_request = NULL;
984 vrh = current_set->handle;
985 vrh->pending_lookups--;
986
987 // Each OR
988 for (uint32_t i = 0; i < rd_count; i++)
989 {
990 if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
991 continue;
992
993 sets = rd[i].data;
994 struct GNUNET_ABD_DelegationSet set[ntohl (sets->set_count)];
995 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
996 "Found new attribute delegation with %d sets. Creating new Job...\n",
997 ntohl (sets->set_count));
998
999 if (GNUNET_OK !=
1000 GNUNET_ABD_delegation_set_deserialize (GNUNET_ntohll (
1001 sets->data_size),
1002 (const char *) &sets[1],
1003 ntohl (sets->set_count),
1004 set))
1005 {
1006 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
1007 continue;
1008 }
1009 dq_entry = GNUNET_new (struct DelegationQueueEntry);
1010 dq_entry->required_solutions = ntohl (sets->set_count);
1011 dq_entry->parent_set = current_set;
1012
1013 GNUNET_CONTAINER_DLL_insert (current_set->queue_entries_head,
1014 current_set->queue_entries_tail,
1015 dq_entry);
1016 // Each AND
1017 for (uint32_t j = 0; j < ntohl (sets->set_count); j++)
1018 {
1019 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1020 GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1021 ds_entry->from_bw = true;
1022
1023 if (NULL != current_set->attr_trailer)
1024 {
1025 if (0 == set[j].subject_attribute_len)
1026 {
1027 GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer);
1028 }
1029 else
1030 {
1031 GNUNET_asprintf (&expanded_attr,
1032 "%s.%s",
1033 set[j].subject_attribute,
1034 current_set->attr_trailer);
1035 }
1036 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
1037 ds_entry->unresolved_attribute_delegation = expanded_attr;
1038 }
1039 else
1040 {
1041 if (0 != set[j].subject_attribute_len)
1042 {
1043 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1044 "Not Expanding %s\n",
1045 set[j].subject_attribute);
1046 ds_entry->unresolved_attribute_delegation =
1047 GNUNET_strdup (set[j].subject_attribute);
1048 }
1049 }
1050
1051 // Add a credential chain entry
1052 ds_entry->delegation_chain_entry =
1053 GNUNET_new (struct DelegationChainEntry);
1054 ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
1055 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
1056 GNUNET_memcpy (ds_entry->issuer_key,
1057 &set[j].subject_key,
1058 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1059 if (0 < set[j].subject_attribute_len)
1060 ds_entry->delegation_chain_entry->subject_attribute =
1061 GNUNET_strdup (set[j].subject_attribute);
1062 ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
1063 ds_entry->delegation_chain_entry->issuer_attribute =
1064 GNUNET_strdup (current_set->lookup_attribute);
1065
1066 // Found new entry, repoting intermediate result
1067 send_intermediate_response(vrh, ds_entry->delegation_chain_entry, true);
1068
1069 ds_entry->parent_queue_entry = dq_entry; // current_delegation;
1070
1071 /**
1072 * Check if this delegation already matches one of our credentials
1073 */
1074 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking for cred match\n");
1075
1076 for (del_pointer = vrh->del_chain_head; del_pointer != NULL;
1077 del_pointer = del_pointer->next)
1078 {
1079 // If key and attribute match credential: continue and backtrack
1080 if (0 != memcmp (&set[j].subject_key,
1081 &del_pointer->delegate->issuer_key,
1082 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1083 continue;
1084 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1085 "Checking if %s matches %s\n",
1086 ds_entry->unresolved_attribute_delegation,
1087 del_pointer->delegate->issuer_attribute);
1088
1089 if (0 != strcmp (ds_entry->unresolved_attribute_delegation,
1090 del_pointer->delegate->issuer_attribute))
1091 continue;
1092
1093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
1094 // increase refcount of the start delegation
1095 del_pointer->refcount++;
1096
1097 // Backtrack
1098 for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
1099 tmp_set = tmp_set->parent_queue_entry->parent_set)
1100 {
1101 tmp_set->parent_queue_entry->required_solutions--;
1102 if (NULL != tmp_set->delegation_chain_entry)
1103 {
1104 vrh->delegation_chain_size++;
1105 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head,
1106 vrh->delegation_chain_tail,
1107 tmp_set->delegation_chain_entry);
1108 }
1109 if (0 < tmp_set->parent_queue_entry->required_solutions)
1110 break;
1111 }
1112
1113 // if the break above is not called the condition of the for is met
1114 if (NULL == tmp_set->parent_queue_entry)
1115 {
1116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All solutions found\n");
1117 // Found match
1118 send_lookup_response (vrh);
1119 return;
1120 }
1121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not all solutions found yet.\n");
1122 continue;
1123 }
1124
1125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1126 "Building new lookup request from %s\n",
1127 ds_entry->unresolved_attribute_delegation);
1128 // Continue with next/new backward resolution
1129 char issuer_attribute_name[strlen (
1130 ds_entry->unresolved_attribute_delegation) +
1131 1];
1132 strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
1133 char *next_attr = strtok (issuer_attribute_name, ".");
1134 if (NULL == next_attr)
1135 {
1136 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1137 "Failed to parse next attribute\n");
1138 continue;
1139 }
1140 GNUNET_asprintf (&lookup_attribute, "%s", next_attr);
1141 GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr);
1142 if (strlen (next_attr) ==
1143 strlen (ds_entry->unresolved_attribute_delegation))
1144 {
1145 ds_entry->attr_trailer = NULL;
1146 }
1147 else
1148 {
1149 next_attr += strlen (next_attr) + 1;
1150 ds_entry->attr_trailer = GNUNET_strdup (next_attr);
1151 }
1152
1153 // Check for bidirectional crossmatch
1154 for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
1155 del_entry != NULL;
1156 del_entry = del_entry->next)
1157 {
1158 // only check entries added by forward algorithm
1159 if (!del_entry->from_bw)
1160 {
1161 // key of list entry matches actual key
1162 if (0 == memcmp (&del_entry->delegation_chain_entry->issuer_key,
1163 &ds_entry->delegation_chain_entry->subject_key,
1164 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1165 {
1166 // compare entry subject attributes to this trailer (iss attr + old trailer)
1167 if (0 == strcmp (del_entry->attr_trailer,
1168 ds_entry->unresolved_attribute_delegation))
1169 {
1170 print_deleset (del_entry, "Backward:");
1171 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1172 "Backward: Found match with above!\n");
1173
1174 // if one node on the path still needs solutions: return
1175 if (GNUNET_NO ==
1176 handle_bidirectional_match (del_entry, ds_entry, vrh))
1177 break;
1178
1179 // Send lookup response
1180 send_lookup_response (vrh);
1181 return;
1182 }
1183 }
1184 }
1185 }
1186
1187 // Starting a new GNS lookup
1188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1189 "Looking up %s\n",
1190 ds_entry->lookup_attribute);
1191 if (NULL != ds_entry->attr_trailer)
1192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1193 "%s still to go...\n",
1194 ds_entry->attr_trailer);
1195
1196 vrh->pending_lookups++;
1197 ds_entry->handle = vrh;
1198 ds_entry->lookup_request =
1199 GNUNET_GNS_lookup (gns,
1200 lookup_attribute,
1201 ds_entry->issuer_key, // issuer_key,
1202 GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
1203 GNUNET_GNS_LO_DEFAULT,
1204 &backward_resolution,
1205 ds_entry);
1206
1207 GNUNET_free (lookup_attribute);
1208 }
1209 }
1210
1211 if (0 == vrh->pending_lookups)
1212 {
1213 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
1214 send_lookup_response (vrh);
1215 return;
1216 }
1217}
1218
1219
1220/**
1221 * Result from GNS lookup.
1222 *
1223 * @param cls the closure (our client lookup handle)
1224 */
1225static int
1226delegation_chain_bw_resolution_start (void *cls)
1227{
1228 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Backward Resolution...\n");
1229
1230 struct VerifyRequestHandle *vrh = cls;
1231 struct DelegationSetQueueEntry *ds_entry;
1232 struct DelegateRecordEntry *del_entry;
1233
1234 if (0 == vrh->del_chain_size)
1235 {
1236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegates found\n");
1237 send_lookup_response (vrh);
1238 return 1;
1239 }
1240
1241 // Pre-check with vrh->dele_chain_.. if match issuer_key
1242 // Backward: check every cred entry if match issuer key
1243 // otherwise: start at issuer and go down till match
1244 // A.a <- ...
1245 // X.x <- C
1246 // Y.y <- C
1247 // if not X.x or Y.y == A.a start at A
1248 for (del_entry = vrh->del_chain_head; del_entry != NULL;
1249 del_entry = del_entry->next)
1250 {
1251 if (0 != memcmp (&del_entry->delegate->issuer_key,
1252 &vrh->issuer_key,
1253 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1254 continue;
1255 if (0 !=
1256 strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1257 continue;
1258 del_entry->refcount++;
1259 // Found match prematurely
1260 send_lookup_response (vrh);
1261 return 1;
1262 }
1263
1264
1265 //Check for attributes from the issuer and follow the chain
1266 //till you get the required subject's attributes
1267 char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1];
1268 strcpy (issuer_attribute_name, vrh->issuer_attribute);
1269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1270 "Looking up %s\n",
1271 issuer_attribute_name);
1272 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1273 GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1274 ds_entry->from_bw = true;
1275 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
1276 GNUNET_memcpy (ds_entry->issuer_key,
1277 &vrh->issuer_key,
1278 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1279 ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute);
1280
1281 ds_entry->delegation_chain_entry = GNUNET_new (struct DelegationChainEntry);
1282 ds_entry->delegation_chain_entry->issuer_key = vrh->issuer_key;
1283 ds_entry->delegation_chain_entry->issuer_attribute =
1284 GNUNET_strdup (vrh->issuer_attribute);
1285
1286 ds_entry->handle = vrh;
1287 ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute);
1288 ds_entry->unresolved_attribute_delegation = NULL;
1289 vrh->pending_lookups = 1;
1290
1291 // Start with backward resolution
1292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Backward Resolution\n");
1293
1294 ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
1295 issuer_attribute_name,
1296 &vrh->issuer_key, // issuer_key,
1297 GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
1298 GNUNET_GNS_LO_DEFAULT,
1299 &backward_resolution,
1300 ds_entry);
1301 return 0;
1302}
1303
1304static int
1305delegation_chain_fw_resolution_start (void *cls)
1306{
1307 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Forward Resolution...\n");
1308
1309 struct VerifyRequestHandle *vrh = cls;
1310 struct DelegationSetQueueEntry *ds_entry;
1311 struct DelegateRecordEntry *del_entry;
1312
1313 // set to 0 and increase on each lookup: for fw multiple lookups (may be) started
1314 vrh->pending_lookups = 0;
1315
1316 if (0 == vrh->del_chain_size)
1317 {
1318 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegations found\n");
1319 send_lookup_response (vrh);
1320 return 1;
1321 }
1322
1323 // Pre-check with vrh->dele_chain_.. if match issuer_key
1324 // otherwise FW: start mutliple lookups for each vrh->dele_chain
1325 // A.a <- ...
1326 // X.x <- C
1327 // Y.y <- C
1328 // if not X.x or Y.y == A.a start at X and at Y
1329 for (del_entry = vrh->del_chain_head; del_entry != NULL;
1330 del_entry = del_entry->next)
1331 {
1332 if (0 != memcmp (&del_entry->delegate->issuer_key,
1333 &vrh->issuer_key,
1334 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1335 continue;
1336 if (0 !=
1337 strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1338 continue;
1339 del_entry->refcount++;
1340 // Found match prematurely
1341 send_lookup_response (vrh);
1342 return 1;
1343 }
1344
1345 // None match, therefore start for every delegation found a lookup chain
1346 // Return and end collect process on first chain iss <-> sub found
1347
1348 // ds_entry created belongs to the first lookup, vrh still has the
1349 // issuer+attr we look for
1350 for (del_entry = vrh->del_chain_head; del_entry != NULL;
1351 del_entry = del_entry->next)
1352 {
1353
1354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1355 "Looking for %s.%s\n",
1356 GNUNET_CRYPTO_ecdsa_public_key_to_string (
1357 &del_entry->delegate->issuer_key),
1358 del_entry->delegate->issuer_attribute);
1359
1360 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1361 GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1362 ds_entry->from_bw = false;
1363 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
1364 GNUNET_memcpy (ds_entry->issuer_key,
1365 &del_entry->delegate->subject_key,
1366 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1367
1368 ds_entry->delegation_chain_entry = GNUNET_new (struct DelegationChainEntry);
1369 ds_entry->delegation_chain_entry->subject_key = del_entry->delegate->subject_key;
1370 ds_entry->delegation_chain_entry->subject_attribute = NULL;
1371 ds_entry->delegation_chain_entry->issuer_key = del_entry->delegate->issuer_key;
1372 ds_entry->delegation_chain_entry->issuer_attribute =
1373 GNUNET_strdup (del_entry->delegate->issuer_attribute);
1374
1375 ds_entry->attr_trailer =
1376 GNUNET_strdup (del_entry->delegate->issuer_attribute);
1377 ds_entry->handle = vrh;
1378
1379 vrh->pending_lookups++;
1380 // Start with forward resolution
1381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Forward Resolution\n");
1382
1383 ds_entry->lookup_request =
1384 GNUNET_GNS_lookup (gns,
1385 GNUNET_GNS_EMPTY_LABEL_AT,
1386 &del_entry->delegate->issuer_key, // issuer_key,
1387 GNUNET_GNSRECORD_TYPE_DELEGATE,
1388 GNUNET_GNS_LO_DEFAULT,
1389 &forward_resolution,
1390 ds_entry);
1391 }
1392 return 0;
1393}
1394
1395static int
1396check_verify (void *cls, const struct VerifyMessage *v_msg)
1397{
1398 size_t msg_size;
1399 const char *attr;
1400
1401 msg_size = ntohs (v_msg->header.size);
1402 if (msg_size < sizeof (struct VerifyMessage))
1403 {
1404 GNUNET_break (0);
1405 return GNUNET_SYSERR;
1406 }
1407 if (ntohs (v_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1408 {
1409 GNUNET_break (0);
1410 return GNUNET_SYSERR;
1411 }
1412 attr = (const char *) &v_msg[1];
1413
1414 if (strlen (attr) > GNUNET_ABD_MAX_LENGTH)
1415 {
1416 GNUNET_break (0);
1417 return GNUNET_SYSERR;
1418 }
1419 return GNUNET_OK;
1420}
1421
1422static void
1423handle_verify (void *cls, const struct VerifyMessage *v_msg)
1424{
1425 struct VerifyRequestHandle *vrh;
1426 struct GNUNET_SERVICE_Client *client = cls;
1427 struct DelegateRecordEntry *del_entry;
1428 uint32_t delegate_count;
1429 uint32_t delegate_data_size;
1430 char attr[GNUNET_ABD_MAX_LENGTH + 1];
1431 char issuer_attribute[GNUNET_ABD_MAX_LENGTH + 1];
1432 char *attrptr = attr;
1433 char *delegate_data;
1434 const char *utf_in;
1435
1436 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
1437 utf_in = (const char *) &v_msg[1];
1438 GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1439 GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
1440 issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
1441 vrh = GNUNET_new (struct VerifyRequestHandle);
1442 vrh->is_collect = false;
1443 GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
1444 vrh->client = client;
1445 vrh->request_id = v_msg->id;
1446 vrh->issuer_key = v_msg->issuer_key;
1447 vrh->subject_key = v_msg->subject_key;
1448 vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1449 vrh->resolution_algo = ntohs (v_msg->resolution_algo);
1450
1451 vrh->del_chain_head = NULL;
1452 vrh->del_chain_tail = NULL;
1453 vrh->dsq_head = NULL;
1454 vrh->dsq_tail = NULL;
1455 vrh->del_chain_head = NULL;
1456 vrh->del_chain_tail = NULL;
1457
1458 GNUNET_SERVICE_client_continue (vrh->client);
1459 if (0 == strlen (issuer_attribute))
1460 {
1461 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1462 send_lookup_response (vrh);
1463 return;
1464 }
1465
1466 // Parse delegates from verifaction message
1467 delegate_count = ntohl (v_msg->d_count);
1468 delegate_data_size = ntohs (v_msg->header.size) -
1469 sizeof (struct VerifyMessage) -
1470 ntohs (v_msg->issuer_attribute_len) - 1;
1471 struct GNUNET_ABD_Delegate delegates[delegate_count];
1472 memset (delegates,
1473 0,
1474 sizeof (struct GNUNET_ABD_Delegate) * delegate_count);
1475 delegate_data = (char *) &v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
1476 if (GNUNET_OK != GNUNET_ABD_delegates_deserialize (delegate_data_size,
1477 delegate_data,
1478 delegate_count,
1479 delegates))
1480 {
1481 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize delegates!\n");
1482 send_lookup_response (vrh);
1483 return;
1484 }
1485
1486 // Prepare vrh delegation chain for later validation
1487 for (uint32_t i = 0; i < delegate_count; i++)
1488 {
1489 del_entry = GNUNET_new (struct DelegateRecordEntry);
1490 del_entry->delegate =
1491 GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate) +
1492 delegates[i].issuer_attribute_len + 1);
1493 GNUNET_memcpy (del_entry->delegate,
1494 &delegates[i],
1495 sizeof (struct GNUNET_ABD_Delegate));
1496 GNUNET_memcpy (&del_entry->delegate[1],
1497 delegates[i].issuer_attribute,
1498 delegates[i].issuer_attribute_len);
1499 del_entry->delegate->issuer_attribute_len =
1500 delegates[i].issuer_attribute_len;
1501 del_entry->delegate->issuer_attribute = (char *) &del_entry->delegate[1];
1502 GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head,
1503 vrh->del_chain_tail,
1504 del_entry);
1505 vrh->del_chain_size++;
1506 }
1507
1508 // Switch resolution algo
1509 if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo &&
1510 GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1511 {
1512 if(1 == delegation_chain_fw_resolution_start (vrh))
1513 return;
1514 delegation_chain_bw_resolution_start (vrh);
1515 }
1516 else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1517 {
1518 delegation_chain_bw_resolution_start (vrh);
1519 }
1520 else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1521 {
1522 delegation_chain_fw_resolution_start (vrh);
1523 }
1524}
1525
1526static void
1527handle_delegate_collection_error_cb (void *cls)
1528{
1529 struct VerifyRequestHandle *vrh = cls;
1530 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1531 "Got disconnected from namestore database.\n");
1532 vrh->dele_qe = NULL;
1533 send_lookup_response (vrh);
1534}
1535
1536static void
1537delegate_collection_finished (void *cls)
1538{
1539 struct VerifyRequestHandle *vrh = cls;
1540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting delegates.\n");
1541
1542 // if both are set: bidirectional search, meaning start both chain resolutions
1543 if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo &&
1544 GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1545 {
1546 // if premature match found don't start bw resultion
1547 if(1 == delegation_chain_fw_resolution_start (vrh))
1548 return;
1549 delegation_chain_bw_resolution_start (vrh);
1550 }
1551 else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1552 {
1553 delegation_chain_bw_resolution_start (vrh);
1554 }
1555 else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1556 {
1557 delegation_chain_fw_resolution_start (vrh);
1558 }
1559}
1560
1561static void
1562handle_delegate_collection_cb (void *cls,
1563 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
1564 const char *label,
1565 unsigned int rd_count,
1566 const struct GNUNET_GNSRECORD_Data *rd)
1567{
1568 struct VerifyRequestHandle *vrh = cls;
1569 struct GNUNET_ABD_Delegate *del;
1570 struct DelegateRecordEntry *del_entry;
1571 int cred_record_count;
1572 cred_record_count = 0;
1573 vrh->dele_qe = NULL;
1574
1575 for (uint32_t i = 0; i < rd_count; i++)
1576 {
1577 if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
1578 continue;
1579 cred_record_count++;
1580 del = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size);
1581 if (NULL == del)
1582 {
1583 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid delegate found\n");
1584 continue;
1585 }
1586 // only add the entries that are explicity marked as private
1587 // and therefor symbolize the end of a chain
1588 if (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)
1589 {
1590 del_entry = GNUNET_new (struct DelegateRecordEntry);
1591 del_entry->delegate = del;
1592 GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head,
1593 vrh->del_chain_tail,
1594 del_entry);
1595 vrh->del_chain_size++;
1596 }
1597 }
1598
1599 delegate_collection_finished (vrh);
1600}
1601
1602static void
1603handle_collect (void *cls, const struct CollectMessage *c_msg)
1604{
1605 char attr[GNUNET_ABD_MAX_LENGTH + 1];
1606 char issuer_attribute[GNUNET_ABD_MAX_LENGTH + 1];
1607 struct VerifyRequestHandle *vrh;
1608 struct GNUNET_SERVICE_Client *client = cls;
1609 char *attrptr = attr;
1610 const char *utf_in;
1611
1612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
1613
1614 utf_in = (const char *) &c_msg[1];
1615 GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1616
1617 GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
1618 issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0';
1619 vrh = GNUNET_new (struct VerifyRequestHandle);
1620 vrh->is_collect = true;
1621 GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
1622 vrh->client = client;
1623 vrh->request_id = c_msg->id;
1624 vrh->issuer_key = c_msg->issuer_key;
1625 GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key, &vrh->subject_key);
1626 vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1627 vrh->resolution_algo = ntohs (c_msg->resolution_algo);
1628
1629 vrh->del_chain_head = NULL;
1630 vrh->del_chain_tail = NULL;
1631 vrh->dsq_head = NULL;
1632 vrh->dsq_tail = NULL;
1633 vrh->del_chain_head = NULL;
1634 vrh->del_chain_tail = NULL;
1635
1636 if (0 == strlen (issuer_attribute))
1637 {
1638 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1639 send_lookup_response (vrh);
1640 return;
1641 }
1642 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting delegates for subject\n");
1643
1644 // Get all delegates from subject
1645 vrh->dele_qe =
1646 GNUNET_NAMESTORE_records_lookup (namestore,
1647 &c_msg->subject_key,
1648 GNUNET_GNS_EMPTY_LABEL_AT,
1649 &handle_delegate_collection_error_cb,
1650 vrh,
1651 &handle_delegate_collection_cb,
1652 vrh);
1653 GNUNET_SERVICE_client_continue (vrh->client);
1654}
1655
1656
1657static int
1658check_collect (void *cls, const struct CollectMessage *c_msg)
1659{
1660 size_t msg_size;
1661 const char *attr;
1662
1663 msg_size = ntohs (c_msg->header.size);
1664 if (msg_size < sizeof (struct CollectMessage))
1665 {
1666 GNUNET_break (0);
1667 return GNUNET_SYSERR;
1668 }
1669 if (ntohs (c_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1670 {
1671 GNUNET_break (0);
1672 return GNUNET_SYSERR;
1673 }
1674 attr = (const char *) &c_msg[1];
1675
1676 if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) ||
1677 (strlen (attr) > GNUNET_ABD_MAX_LENGTH))
1678 {
1679 GNUNET_break (0);
1680 return GNUNET_SYSERR;
1681 }
1682 return GNUNET_OK;
1683}
1684
1685static void
1686client_disconnect_cb (void *cls,
1687 struct GNUNET_SERVICE_Client *client,
1688 void *app_ctx)
1689{
1690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1691}
1692
1693static void *
1694client_connect_cb (void *cls,
1695 struct GNUNET_SERVICE_Client *client,
1696 struct GNUNET_MQ_Handle *mq)
1697{
1698 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1699 return client;
1700}
1701
1702/**
1703 * Process Credential requests.
1704 *
1705 * @param cls closure
1706 * @param c configuration to use
1707 * @param handle service handle
1708 */
1709static void
1710run (void *cls,
1711 const struct GNUNET_CONFIGURATION_Handle *c,
1712 struct GNUNET_SERVICE_Handle *handle)
1713{
1714
1715 gns = GNUNET_GNS_connect (c);
1716 if (NULL == gns)
1717 {
1718 fprintf (stderr, _ ("Failed to connect to GNS\n"));
1719 }
1720 namestore = GNUNET_NAMESTORE_connect (c);
1721 if (NULL == namestore)
1722 {
1723 fprintf (stderr, _ ("Failed to connect to namestore\n"));
1724 }
1725
1726 statistics = GNUNET_STATISTICS_create ("abd", c);
1727 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
1728}
1729
1730
1731/**
1732 * Define "main" method using service macro
1733 */
1734GNUNET_SERVICE_MAIN (
1735 "abd",
1736 GNUNET_SERVICE_OPTION_NONE,
1737 &run,
1738 &client_connect_cb,
1739 &client_disconnect_cb,
1740 NULL,
1741 GNUNET_MQ_hd_var_size (verify,
1742 GNUNET_MESSAGE_TYPE_ABD_VERIFY,
1743 struct VerifyMessage,
1744 NULL),
1745 GNUNET_MQ_hd_var_size (collect,
1746 GNUNET_MESSAGE_TYPE_ABD_COLLECT,
1747 struct CollectMessage,
1748 NULL),
1749 GNUNET_MQ_handler_end ());
1750
1751/* end of gnunet-service-abd.c */
diff --git a/src/abd/plugin_gnsrecord_abd.c b/src/abd/plugin_gnsrecord_abd.c
new file mode 100644
index 000000000..811878627
--- /dev/null
+++ b/src/abd/plugin_gnsrecord_abd.c
@@ -0,0 +1,349 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013 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 abd/plugin_gnsrecord_abd.c
23 * @brief gnsrecord plugin to provide the API for ABD records
24 * @author Martin Schanzenbach
25 */
26#include "platform.h"
27
28#include "gnunet_util_lib.h"
29
30#include "delegate_misc.h"
31#include "abd_serialization.h"
32#include "gnunet_abd_service.h"
33#include "gnunet_gnsrecord_lib.h"
34#include "gnunet_gnsrecord_plugin.h"
35#include "gnunet_signatures.h"
36/**
37 * Convert the 'value' of a record to a string.
38 *
39 * @param cls closure, unused
40 * @param type type of the record
41 * @param data value in binary encoding
42 * @param data_size number of bytes in @a data
43 * @return NULL on error, otherwise human-readable representation of the value
44 */
45static char *
46abd_value_to_string (void *cls,
47 uint32_t type,
48 const void *data,
49 size_t data_size)
50{
51 const char *cdata;
52
53 switch (type)
54 {
55 case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
56 {
57 struct GNUNET_ABD_DelegationRecord sets;
58 char *attr_str;
59 char *subject_pkey;
60 char *tmp_str;
61 int i;
62 if (data_size < sizeof (struct GNUNET_ABD_DelegationRecord))
63 return NULL; /* malformed */
64
65 GNUNET_memcpy (&sets, data, sizeof (sets));
66 cdata = data;
67
68 struct GNUNET_ABD_DelegationSet set[ntohl (sets.set_count)];
69 if (GNUNET_OK !=
70 GNUNET_ABD_delegation_set_deserialize (GNUNET_ntohll (
71 sets.data_size),
72 &cdata[sizeof (sets)],
73 ntohl (sets.set_count),
74 set))
75 return NULL;
76
77 for (i = 0; i < ntohl (sets.set_count); i++)
78 {
79 subject_pkey =
80 GNUNET_CRYPTO_ecdsa_public_key_to_string (&set[i].subject_key);
81
82 if (0 == set[i].subject_attribute_len)
83 {
84 if (0 == i)
85 {
86 GNUNET_asprintf (&attr_str, "%s", subject_pkey);
87 }
88 else
89 {
90 GNUNET_asprintf (&tmp_str, "%s,%s", attr_str, subject_pkey);
91 GNUNET_free (attr_str);
92 attr_str = tmp_str;
93 }
94 }
95 else
96 {
97 if (0 == i)
98 {
99 GNUNET_asprintf (&attr_str,
100 "%s %s",
101 subject_pkey,
102 set[i].subject_attribute);
103 }
104 else
105 {
106 GNUNET_asprintf (&tmp_str,
107 "%s,%s %s",
108 attr_str,
109 subject_pkey,
110 set[i].subject_attribute);
111 GNUNET_free (attr_str);
112 attr_str = tmp_str;
113 }
114 }
115 GNUNET_free (subject_pkey);
116 }
117 return attr_str;
118 }
119 case GNUNET_GNSRECORD_TYPE_DELEGATE:
120 {
121 struct GNUNET_ABD_Delegate *cred;
122 char *cred_str;
123
124 cred = GNUNET_ABD_delegate_deserialize (data, data_size);
125 cred_str = GNUNET_ABD_delegate_to_string (cred);
126 GNUNET_free (cred);
127 return cred_str;
128 }
129 default:
130 return NULL;
131 }
132}
133
134
135/**
136 * Convert human-readable version of a 'value' of a record to the binary
137 * representation.
138 *
139 * @param cls closure, unused
140 * @param type type of the record
141 * @param s human-readable string
142 * @param data set to value in binary encoding (will be allocated)
143 * @param data_size set to number of bytes in @a data
144 * @return #GNUNET_OK on success
145 */
146static int
147abd_string_to_value (void *cls,
148 uint32_t type,
149 const char *s,
150 void **data,
151 size_t *data_size)
152{
153 if (NULL == s)
154 return GNUNET_SYSERR;
155 switch (type)
156 {
157 case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
158 {
159 struct GNUNET_ABD_DelegationRecord *sets;
160 char attr_str[253 + 1];
161 char subject_pkey[52 + 1];
162 char *token;
163 char *tmp_str;
164 int matches = 0;
165 int entries;
166 size_t tmp_data_size;
167 int i;
168
169 tmp_str = GNUNET_strdup (s);
170 token = strtok (tmp_str, ",");
171 entries = 0;
172 tmp_data_size = 0;
173 *data_size = sizeof (struct GNUNET_ABD_DelegationRecord);
174 while (NULL != token)
175 {
176 // also fills the variables subject_pley and attr_str if "regex"-like match
177 matches = SSCANF (token, "%s %s", subject_pkey, attr_str);
178
179 if (0 == matches)
180 {
181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
182 _ ("Unable to parse ATTR record string `%s'\n"),
183 s);
184 GNUNET_free (tmp_str);
185 return GNUNET_SYSERR;
186 }
187
188 entries++;
189 token = strtok (NULL, ",");
190 }
191 GNUNET_free (tmp_str);
192
193 tmp_str = GNUNET_strdup (s);
194 token = strtok (tmp_str, ",");
195 if (NULL == token)
196 {
197 GNUNET_free (tmp_str);
198 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed string %s\n", s);
199 return GNUNET_SYSERR;
200 }
201
202 struct GNUNET_ABD_DelegationSet set[entries];
203 // sets memory to be 0, starting at *set for the size of struct * entries
204 memset (set, 0, sizeof (struct GNUNET_ABD_DelegationSet) * entries);
205 for (i = 0; i < entries; i++)
206 {
207 matches = SSCANF (token, "%s %s", subject_pkey, attr_str);
208
209 // sets the public key for the set entry
210 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
211 strlen (subject_pkey),
212 &set[i].subject_key);
213
214 // If not just key, also set subject attribute (Not A.a <- B but A.a <- B.b)
215 if (2 == matches)
216 {
217 set[i].subject_attribute_len = strlen (attr_str) + 1;
218 set[i].subject_attribute = GNUNET_strdup (attr_str);
219 }
220 // If more entries, then token string can take the next entry (separated by ',') by calling strtok again
221 token = strtok (NULL, ",");
222 }
223 tmp_data_size = GNUNET_ABD_delegation_set_get_size (entries, set);
224
225 if (-1 == tmp_data_size)
226 {
227 GNUNET_free (tmp_str);
228 return GNUNET_SYSERR;
229 }
230 *data_size += tmp_data_size;
231 *data = sets = GNUNET_malloc (*data_size);
232 GNUNET_ABD_delegation_set_serialize (entries,
233 set,
234 tmp_data_size,
235 (char *) &sets[1]);
236 for (i = 0; i < entries; i++)
237 {
238 if (0 != set[i].subject_attribute_len)
239 GNUNET_free ((char *) set[i].subject_attribute);
240 }
241 sets->set_count = htonl (entries);
242 sets->data_size = GNUNET_htonll (tmp_data_size);
243
244 GNUNET_free (tmp_str);
245 return GNUNET_OK;
246 }
247 case GNUNET_GNSRECORD_TYPE_DELEGATE:
248 {
249 struct GNUNET_ABD_Delegate *cred;
250 cred = GNUNET_ABD_delegate_from_string (s);
251
252 *data_size = GNUNET_ABD_delegate_serialize (cred, (char **) data);
253
254 return GNUNET_OK;
255 }
256 default:
257 return GNUNET_SYSERR;
258 }
259}
260
261
262/**
263 * Mapping of record type numbers to human-readable
264 * record type names.
265 */
266static struct
267{
268 const char *name;
269 uint32_t number;
270} name_map[] = {{"ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE},
271 {"DEL", GNUNET_GNSRECORD_TYPE_DELEGATE},
272 {NULL, UINT32_MAX}};
273
274
275/**
276 * Convert a type name (i.e. "AAAA") to the corresponding number.
277 *
278 * @param cls closure, unused
279 * @param gns_typename name to convert
280 * @return corresponding number, UINT32_MAX on error
281 */
282static uint32_t
283abd_typename_to_number (void *cls, const char *gns_typename)
284{
285 unsigned int i;
286
287 i = 0;
288 while ((name_map[i].name != NULL) &&
289 (0 != strcasecmp (gns_typename, name_map[i].name)))
290 i++;
291 return name_map[i].number;
292}
293
294
295/**
296 * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
297 *
298 * @param cls closure, unused
299 * @param type number of a type to convert
300 * @return corresponding typestring, NULL on error
301 */
302static const char *
303abd_number_to_typename (void *cls, uint32_t type)
304{
305 unsigned int i;
306
307 i = 0;
308 while ((name_map[i].name != NULL) && (type != name_map[i].number))
309 i++;
310 return name_map[i].name;
311}
312
313
314/**
315 * Entry point for the plugin.
316 *
317 * @param cls NULL
318 * @return the exported block API
319 */
320void *
321libgnunet_plugin_gnsrecord_abd_init (void *cls)
322{
323 struct GNUNET_GNSRECORD_PluginFunctions *api;
324
325 api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
326 api->value_to_string = &abd_value_to_string;
327 api->string_to_value = &abd_string_to_value;
328 api->typename_to_number = &abd_typename_to_number;
329 api->number_to_typename = &abd_number_to_typename;
330 return api;
331}
332
333
334/**
335 * Exit point from the plugin.
336 *
337 * @param cls the return value from #libgnunet_plugin_block_test_init
338 * @return NULL
339 */
340void *
341libgnunet_plugin_gnsrecord_abd_done (void *cls)
342{
343 struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
344
345 GNUNET_free (api);
346 return NULL;
347}
348
349/* end of plugin_gnsrecord_abd.c */
diff --git a/src/abd/plugin_rest_credential.c b/src/abd/plugin_rest_credential.c
new file mode 100644
index 000000000..513ddfff9
--- /dev/null
+++ b/src/abd/plugin_rest_credential.c
@@ -0,0 +1,1174 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2016 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 * @author Martin Schanzenbach
22 * @file credential/plugin_rest_credential.c
23 * @brief GNUnet CREDENTIAL REST plugin
24 *
25 */
26
27#include "platform.h"
28#include "gnunet_rest_plugin.h"
29#include <gnunet_identity_service.h>
30#include <gnunet_gnsrecord_lib.h>
31#include <gnunet_namestore_service.h>
32#include <gnunet_credential_service.h>
33#include <gnunet_rest_lib.h>
34#include <gnunet_jsonapi_lib.h>
35#include <gnunet_jsonapi_util.h>
36#include <jansson.h>
37
38#define GNUNET_REST_API_NS_CREDENTIAL "/credential"
39
40#define GNUNET_REST_API_NS_CREDENTIAL_ISSUE "/credential/issue"
41
42#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify"
43
44#define GNUNET_REST_API_NS_CREDENTIAL_COLLECT "/credential/collect"
45
46#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration"
47
48#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key"
49
50#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO "subject"
51
52#define GNUNET_REST_JSONAPI_CREDENTIAL "credential"
53
54#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential"
55
56#define GNUNET_REST_JSONAPI_DELEGATIONS "delegations"
57
58#define GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR "attribute"
59
60#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_ATTR "credential"
61
62/**
63 * @brief struct returned by the initialization function of the plugin
64 */
65struct Plugin
66{
67 const struct GNUNET_CONFIGURATION_Handle *cfg;
68};
69
70const struct GNUNET_CONFIGURATION_Handle *cfg;
71
72struct RequestHandle
73{
74 /**
75 * Handle to Credential service.
76 */
77 struct GNUNET_CREDENTIAL_Handle *credential;
78
79 /**
80 * Handle to lookup request
81 */
82 struct GNUNET_CREDENTIAL_Request *verify_request;
83
84 /**
85 * Handle to issue request
86 */
87 struct GNUNET_CREDENTIAL_Request *issue_request;
88
89 /**
90 * Handle to identity
91 */
92 struct GNUNET_IDENTITY_Handle *identity;
93
94 /**
95 * Handle to identity operation
96 */
97 struct GNUNET_IDENTITY_Operation *id_op;
98
99 /**
100 * Handle to ego lookup
101 */
102 struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
103
104 /**
105 * Handle to rest request
106 */
107 struct GNUNET_REST_RequestHandle *rest_handle;
108
109 /**
110 * ID of a task associated with the resolution process.
111 */
112 struct GNUNET_SCHEDULER_Task *timeout_task;
113
114 /**
115 * The root of the received JSON or NULL
116 */
117 json_t *json_root;
118
119 /**
120 * The plugin result processor
121 */
122 GNUNET_REST_ResultProcessor proc;
123
124 /**
125 * The closure of the result processor
126 */
127 void *proc_cls;
128
129 /**
130 * The issuer attribute to verify
131 */
132 char *issuer_attr;
133
134 /**
135 * The subject attribute
136 */
137 char *subject_attr;
138
139 /**
140 * The public key of the issuer
141 */
142 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
143
144 /**
145 * The public key of the subject
146 */
147 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
148
149 /**
150 * HTTP response code
151 */
152 int response_code;
153
154 /**
155 * Timeout
156 */
157 struct GNUNET_TIME_Relative timeout;
158};
159
160
161/**
162 * Cleanup lookup handle.
163 *
164 * @param handle Handle to clean up
165 */
166static void
167cleanup_handle (struct RequestHandle *handle)
168{
169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
170 "Cleaning up\n");
171 if (NULL != handle->json_root)
172 json_decref (handle->json_root);
173
174 if (NULL != handle->issuer_attr)
175 GNUNET_free (handle->issuer_attr);
176 if (NULL != handle->subject_attr)
177 GNUNET_free (handle->subject_attr);
178 if (NULL != handle->verify_request)
179 GNUNET_CREDENTIAL_request_cancel (handle->verify_request);
180 if (NULL != handle->credential)
181 GNUNET_CREDENTIAL_disconnect (handle->credential);
182 if (NULL != handle->id_op)
183 GNUNET_IDENTITY_cancel (handle->id_op);
184 if (NULL != handle->ego_lookup)
185 GNUNET_IDENTITY_ego_lookup_cancel (handle->ego_lookup);
186 if (NULL != handle->identity)
187 GNUNET_IDENTITY_disconnect (handle->identity);
188 if (NULL != handle->timeout_task)
189 {
190 GNUNET_SCHEDULER_cancel (handle->timeout_task);
191 }
192 GNUNET_free (handle);
193}
194
195
196static void
197do_error (void *cls)
198{
199 struct RequestHandle *handle = cls;
200 struct MHD_Response *resp;
201
202 resp = GNUNET_REST_create_response (NULL);
203 handle->proc (handle->proc_cls, resp, handle->response_code);
204 cleanup_handle (handle);
205}
206
207/**
208 * Attribute delegation to JSON
209 *
210 * @param delegation_chain_entry the DSE
211 * @return JSON, NULL if failed
212 */
213static json_t*
214attribute_delegation_to_json (struct
215 GNUNET_CREDENTIAL_Delegation *
216 delegation_chain_entry)
217{
218 char *subject;
219 char *issuer;
220 json_t *attr_obj;
221
222 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (
223 &delegation_chain_entry->issuer_key);
224 if (NULL == issuer)
225 {
226 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
227 "Issuer in delegation malformed\n");
228 return NULL;
229 }
230 subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (
231 &delegation_chain_entry->subject_key);
232 if (NULL == subject)
233 {
234 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
235 "Subject in credential malformed\n");
236 GNUNET_free (issuer);
237 return NULL;
238 }
239 attr_obj = json_object ();
240
241 json_object_set_new (attr_obj, "issuer", json_string (issuer));
242 json_object_set_new (attr_obj, "issuer_attribute",
243 json_string (delegation_chain_entry->issuer_attribute));
244
245 json_object_set_new (attr_obj, "subject", json_string (subject));
246 if (0 < delegation_chain_entry->subject_attribute_len)
247 {
248 json_object_set_new (attr_obj, "subject_attribute",
249 json_string (
250 delegation_chain_entry->subject_attribute));
251 }
252 GNUNET_free (issuer);
253 GNUNET_free (subject);
254 return attr_obj;
255}
256
257/**
258 * JSONAPI resource to Credential
259 *
260 * @param res the JSONAPI resource
261 * @return the resulting credential, NULL if failed
262 */
263static struct GNUNET_CREDENTIAL_Credential*
264json_to_credential (json_t *res)
265{
266 struct GNUNET_CREDENTIAL_Credential *cred;
267 json_t *tmp;
268 const char *attribute;
269 const char *signature;
270 char *sig;
271
272 tmp = json_object_get (res, "attribute");
273 if (0 == json_is_string (tmp))
274 {
275 return NULL;
276 }
277 attribute = json_string_value (tmp);
278 cred = GNUNET_malloc (sizeof(struct GNUNET_CREDENTIAL_Credential)
279 + strlen (attribute));
280 cred->issuer_attribute = attribute;
281 cred->issuer_attribute_len = strlen (attribute);
282 tmp = json_object_get (res, "issuer");
283 if (0 == json_is_string (tmp))
284 {
285 GNUNET_free (cred);
286 return NULL;
287 }
288
289 GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value (tmp),
290 strlen (json_string_value (tmp)),
291 &cred->issuer_key);
292 tmp = json_object_get (res, "subject");
293 if (0 == json_is_string (tmp))
294 {
295 GNUNET_free (cred);
296 return NULL;
297 }
298 GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value (tmp),
299 strlen (json_string_value (tmp)),
300 &cred->subject_key);
301
302 tmp = json_object_get (res, "signature");
303 if (0 == json_is_string (tmp))
304 {
305 GNUNET_free (cred);
306 return NULL;
307 }
308 signature = json_string_value (tmp);
309 GNUNET_STRINGS_base64_decode (signature,
310 strlen (signature),
311 (char**) &sig);
312 GNUNET_memcpy (&cred->signature,
313 sig,
314 sizeof(struct GNUNET_CRYPTO_EcdsaSignature));
315 GNUNET_free (sig);
316
317 tmp = json_object_get (res, "expiration");
318 if (0 == json_is_integer (tmp))
319 {
320 GNUNET_free (cred);
321 return NULL;
322 }
323 cred->expiration.abs_value_us = json_integer_value (tmp);
324 return cred;
325}
326
327
328/**
329 * Credential to JSON
330 *
331 * @param cred the credential
332 * @return the resulting json, NULL if failed
333 */
334static json_t*
335credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred)
336{
337 char *issuer;
338 char *subject;
339 char *signature;
340 char attribute[cred->issuer_attribute_len + 1];
341 json_t *cred_obj;
342
343 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
344 if (NULL == issuer)
345 {
346 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
347 "Issuer in credential malformed\n");
348 return NULL;
349 }
350 subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
351 if (NULL == subject)
352 {
353 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
354 "Subject in credential malformed\n");
355 GNUNET_free (issuer);
356 return NULL;
357 }
358 GNUNET_STRINGS_base64_encode ((char*) &cred->signature,
359 sizeof(struct GNUNET_CRYPTO_EcdsaSignature),
360 &signature);
361 GNUNET_memcpy (attribute,
362 cred->issuer_attribute,
363 cred->issuer_attribute_len);
364 attribute[cred->issuer_attribute_len] = '\0';
365 cred_obj = json_object ();
366 json_object_set_new (cred_obj, "issuer", json_string (issuer));
367 json_object_set_new (cred_obj, "subject", json_string (subject));
368 json_object_set_new (cred_obj, "attribute", json_string (attribute));
369 json_object_set_new (cred_obj, "signature", json_string (signature));
370 json_object_set_new (cred_obj, "expiration", json_integer (
371 cred->expiration.abs_value_us));
372 GNUNET_free (issuer);
373 GNUNET_free (subject);
374 GNUNET_free (signature);
375 return cred_obj;
376}
377
378static void
379handle_collect_response (void *cls,
380 unsigned int d_count,
381 struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
382 unsigned int c_count,
383 struct GNUNET_CREDENTIAL_Credential *cred)
384{
385 struct RequestHandle *handle = cls;
386 struct MHD_Response *resp;
387 struct GNUNET_JSONAPI_Document *json_document;
388 struct GNUNET_JSONAPI_Resource *json_resource;
389 json_t *cred_obj;
390 json_t *cred_array;
391 char *result;
392 char *issuer;
393 char *id;
394 uint32_t i;
395
396 handle->verify_request = NULL;
397 if (NULL == cred)
398 {
399 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
400 "Verify failed.\n");
401 handle->response_code = MHD_HTTP_NOT_FOUND;
402 GNUNET_SCHEDULER_add_now (&do_error, handle);
403 return;
404 }
405 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key);
406 if (NULL == issuer)
407 {
408 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
409 "Issuer in delegation malformed\n");
410 return;
411 }
412 GNUNET_asprintf (&id,
413 "%s.%s",
414 issuer,
415 handle->issuer_attr);
416 GNUNET_free (issuer);
417 json_document = GNUNET_JSONAPI_document_new ();
418 json_resource = GNUNET_JSONAPI_resource_new (
419 GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
420 id);
421 GNUNET_free (id);
422 cred_array = json_array ();
423 for (i = 0; i < c_count; i++)
424 {
425 cred_obj = credential_to_json (&cred[i]);
426 json_array_append_new (cred_array, cred_obj);
427 }
428 GNUNET_JSONAPI_resource_add_attr (json_resource,
429 GNUNET_REST_JSONAPI_CREDENTIAL,
430 cred_array);
431 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
432 GNUNET_JSONAPI_document_serialize (json_document, &result);
433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
434 "Result %s\n",
435 result);
436 json_decref (cred_array);
437 GNUNET_JSONAPI_document_delete (json_document);
438 resp = GNUNET_REST_create_response (result);
439 GNUNET_free (result);
440 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
441 cleanup_handle (handle);
442}
443
444static void
445subject_ego_lookup (void *cls,
446 const struct GNUNET_IDENTITY_Ego *ego)
447{
448 struct RequestHandle *handle = cls;
449 const struct GNUNET_CRYPTO_EcdsaPrivateKey *sub_key;
450
451 handle->ego_lookup = NULL;
452
453 if (NULL == ego)
454 {
455 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
456 "Subject not found\n");
457 GNUNET_SCHEDULER_add_now (&do_error, handle);
458 return;
459 }
460 sub_key = GNUNET_IDENTITY_ego_get_private_key (ego);
461 handle->verify_request = GNUNET_CREDENTIAL_collect (handle->credential,
462 &handle->issuer_key,
463 handle->issuer_attr,
464 sub_key,
465 &handle_collect_response,
466 handle);
467}
468
469
470
471static void
472handle_verify_response (void *cls,
473 unsigned int d_count,
474 struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
475 unsigned int c_count,
476 struct GNUNET_CREDENTIAL_Credential *cred)
477{
478 struct RequestHandle *handle = cls;
479 struct MHD_Response *resp;
480 struct GNUNET_JSONAPI_Document *json_document;
481 struct GNUNET_JSONAPI_Resource *json_resource;
482 json_t *cred_obj;
483 json_t *attr_obj;
484 json_t *cred_array;
485 json_t *attr_array;
486 char *result;
487 char *issuer;
488 char *id;
489 uint32_t i;
490
491 handle->verify_request = NULL;
492 if (NULL == cred)
493 {
494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
495 "Verify failed.\n");
496 handle->response_code = MHD_HTTP_NOT_FOUND;
497 GNUNET_SCHEDULER_add_now (&do_error, handle);
498 return;
499 }
500 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key);
501 if (NULL == issuer)
502 {
503 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
504 "Issuer in delegation malformed\n");
505 return;
506 }
507 GNUNET_asprintf (&id,
508 "%s.%s",
509 issuer,
510 handle->issuer_attr);
511 GNUNET_free (issuer);
512 json_document = GNUNET_JSONAPI_document_new ();
513 json_resource = GNUNET_JSONAPI_resource_new (
514 GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
515 id);
516 GNUNET_free (id);
517 attr_array = json_array ();
518 for (i = 0; i < d_count; i++)
519 {
520 attr_obj = attribute_delegation_to_json (&delegation_chain[i]);
521 json_array_append_new (attr_array, attr_obj);
522 }
523 cred_array = json_array ();
524 for (i = 0; i < c_count; i++)
525 {
526 cred_obj = credential_to_json (&cred[i]);
527 json_array_append_new (cred_array, cred_obj);
528 }
529 GNUNET_JSONAPI_resource_add_attr (json_resource,
530 GNUNET_REST_JSONAPI_CREDENTIAL,
531 cred_array);
532 GNUNET_JSONAPI_resource_add_attr (json_resource,
533 GNUNET_REST_JSONAPI_DELEGATIONS,
534 attr_array);
535 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
536 GNUNET_JSONAPI_document_serialize (json_document, &result);
537 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
538 "Result %s\n",
539 result);
540 json_decref (attr_array);
541 json_decref (cred_array);
542 GNUNET_JSONAPI_document_delete (json_document);
543 resp = GNUNET_REST_create_response (result);
544 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
545 GNUNET_free (result);
546 cleanup_handle (handle);
547}
548
549static void
550collect_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
551 const char*url,
552 void *cls)
553{
554 struct RequestHandle *handle = cls;
555 struct GNUNET_HashCode key;
556 char *tmp;
557 char *entity_attr;
558
559 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
560 "Connecting...\n");
561 handle->credential = GNUNET_CREDENTIAL_connect (cfg);
562 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
563 &do_error, handle);
564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
565 "Connected\n");
566 if (NULL == handle->credential)
567 {
568 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
569 "Connecting to CREDENTIAL failed\n");
570 GNUNET_SCHEDULER_add_now (&do_error, handle);
571 return;
572 }
573 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR,
574 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR),
575 &key);
576 if (GNUNET_NO ==
577 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
578 &key))
579 {
580 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
581 "Missing issuer attribute\n");
582 GNUNET_SCHEDULER_add_now (&do_error, handle);
583 return;
584 }
585 tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
586 &key);
587 entity_attr = GNUNET_strdup (tmp);
588 tmp = strtok (entity_attr, ".");
589 if (NULL == tmp)
590 {
591 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
592 "Malformed issuer or attribute\n");
593 GNUNET_free (entity_attr);
594 GNUNET_SCHEDULER_add_now (&do_error, handle);
595 return;
596 }
597 if (GNUNET_OK !=
598 GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp,
599 strlen (tmp),
600 &handle->issuer_key))
601 {
602 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
603 "Malformed issuer key\n");
604 GNUNET_free (entity_attr);
605 GNUNET_SCHEDULER_add_now (&do_error, handle);
606 return;
607 }
608 tmp = strtok (NULL, "."); // Issuer attribute
609 if (NULL == tmp)
610 {
611 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
612 "Malformed attribute\n");
613 GNUNET_free (entity_attr);
614 GNUNET_SCHEDULER_add_now (&do_error, handle);
615 return;
616 }
617 handle->issuer_attr = GNUNET_strdup (tmp);
618 GNUNET_free (entity_attr);
619
620 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO,
621 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO),
622 &key);
623 if (GNUNET_NO ==
624 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
625 &key))
626 {
627 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
628 "Missing subject\n");
629 GNUNET_SCHEDULER_add_now (&do_error, handle);
630 return;
631 }
632 tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
633 &key);
634 if (NULL == tmp)
635 {
636 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
637 "Malformed subject\n");
638 GNUNET_SCHEDULER_add_now (&do_error, handle);
639 return;
640 }
641 handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg,
642 tmp,
643 &subject_ego_lookup,
644 handle);
645}
646
647
648
649static void
650verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
651 const char*url,
652 void *cls)
653{
654 struct RequestHandle *handle = cls;
655 struct GNUNET_HashCode key;
656 struct GNUNET_JSONAPI_Document *json_obj;
657 struct GNUNET_JSONAPI_Resource *res;
658 struct GNUNET_CREDENTIAL_Credential *cred;
659 char *tmp;
660 char *entity_attr;
661 int i;
662 uint32_t credential_count;
663 uint32_t resource_count;
664 json_t *cred_json;
665 json_t *data_js;
666 json_error_t err;
667
668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
669 "Connecting...\n");
670 handle->credential = GNUNET_CREDENTIAL_connect (cfg);
671 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
672 &do_error, handle);
673 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
674 "Connected\n");
675 if (NULL == handle->credential)
676 {
677 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
678 "Connecting to CREDENTIAL failed\n");
679 GNUNET_SCHEDULER_add_now (&do_error, handle);
680 return;
681 }
682 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR,
683 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR),
684 &key);
685 if (GNUNET_NO ==
686 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
687 &key))
688 {
689 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
690 "Missing issuer attribute\n");
691 GNUNET_SCHEDULER_add_now (&do_error, handle);
692 return;
693 }
694 tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
695 &key);
696 entity_attr = GNUNET_strdup (tmp);
697 tmp = strtok (entity_attr, ".");
698 if (NULL == tmp)
699 {
700 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
701 "Malformed issuer or attribute\n");
702 GNUNET_free (entity_attr);
703 GNUNET_SCHEDULER_add_now (&do_error, handle);
704 return;
705 }
706 if (GNUNET_OK !=
707 GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp,
708 strlen (tmp),
709 &handle->issuer_key))
710 {
711 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
712 "Malformed issuer key\n");
713 GNUNET_free (entity_attr);
714 GNUNET_SCHEDULER_add_now (&do_error, handle);
715 return;
716 }
717 tmp = strtok (NULL, "."); // Issuer attribute
718 if (NULL == tmp)
719 {
720 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
721 "Malformed attribute\n");
722 GNUNET_free (entity_attr);
723 GNUNET_SCHEDULER_add_now (&do_error, handle);
724 return;
725 }
726 handle->issuer_attr = GNUNET_strdup (tmp);
727 GNUNET_free (entity_attr);
728
729 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY,
730 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY),
731 &key);
732 if (GNUNET_NO ==
733 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
734 &key))
735 {
736 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
737 "Missing subject key\n");
738 GNUNET_SCHEDULER_add_now (&do_error, handle);
739 return;
740 }
741 tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
742 &key);
743 if (NULL == tmp)
744 {
745 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
746 "Malformed subject\n");
747 GNUNET_SCHEDULER_add_now (&do_error, handle);
748 return;
749 }
750 if (GNUNET_OK !=
751 GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp,
752 strlen (tmp),
753 &handle->subject_key))
754 {
755 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
756 "Malformed subject key\n");
757 GNUNET_SCHEDULER_add_now (&do_error, handle);
758 return;
759 }
760
761 if (0 >= handle->rest_handle->data_size)
762 {
763 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
764 "Missing credentials\n");
765 GNUNET_SCHEDULER_add_now (&do_error, handle);
766 return;
767 }
768
769 struct GNUNET_JSON_Specification docspec[] = {
770 GNUNET_JSON_spec_jsonapi_document (&json_obj),
771 GNUNET_JSON_spec_end ()
772 };
773 char term_data[handle->rest_handle->data_size + 1];
774 term_data[handle->rest_handle->data_size] = '\0';
775 credential_count = 0;
776 GNUNET_memcpy (term_data,
777 handle->rest_handle->data,
778 handle->rest_handle->data_size);
779 data_js = json_loads (term_data,
780 JSON_DECODE_ANY,
781 &err);
782 GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, docspec,
783 NULL, NULL));
784 json_decref (data_js);
785 if (NULL == json_obj)
786 {
787 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
788 "Unable to parse JSONAPI Object from %s\n",
789 term_data);
790 GNUNET_SCHEDULER_add_now (&do_error, handle);
791 return;
792 }
793
794 resource_count = GNUNET_JSONAPI_document_resource_count (json_obj);
795 GNUNET_assert (1 == resource_count);
796 res = (GNUNET_JSONAPI_document_get_resource (json_obj, 0));
797 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (res,
798 GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO))
799 {
800 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
801 "Resource not a credential!\n");
802 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
803 "Unable to parse JSONAPI Object from %s\n",
804 term_data);
805 GNUNET_JSONAPI_document_delete (json_obj);
806 GNUNET_SCHEDULER_add_now (&do_error, handle);
807 return;
808 }
809 cred_json = GNUNET_JSONAPI_resource_read_attr (res,
810 GNUNET_REST_JSONAPI_CREDENTIAL);
811
812 GNUNET_assert (json_is_array (cred_json));
813
814 credential_count = json_array_size (cred_json);
815
816 struct GNUNET_CREDENTIAL_Credential credentials[credential_count];
817 for (i = 0; i < credential_count; i++)
818 {
819 cred = json_to_credential (json_array_get (cred_json, i));
820 if (NULL == cred)
821 {
822 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
823 "Unable to parse credential!\n");
824 continue;
825 }
826 GNUNET_memcpy (&credentials[i],
827 cred,
828 sizeof(struct GNUNET_CREDENTIAL_Credential));
829 credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute);
830 GNUNET_free (cred);
831 }
832 GNUNET_JSONAPI_document_delete (json_obj);
833 handle->verify_request = GNUNET_CREDENTIAL_verify (handle->credential,
834 &handle->issuer_key,
835 handle->issuer_attr,
836 &handle->subject_key,
837 credential_count,
838 credentials,
839 &handle_verify_response,
840 handle);
841 for (i = 0; i < credential_count; i++)
842 GNUNET_free ((char*) credentials[i].issuer_attribute);
843}
844
845void
846send_cred_response (struct RequestHandle *handle,
847 struct GNUNET_CREDENTIAL_Credential *cred)
848{
849 struct MHD_Response *resp;
850 struct GNUNET_JSONAPI_Document *json_document;
851 struct GNUNET_JSONAPI_Resource *json_resource;
852 json_t *cred_obj;
853 char *result;
854 char *issuer;
855 char *subject;
856 char *signature;
857 char *id;
858
859 GNUNET_assert (NULL != cred);
860 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
861 if (NULL == issuer)
862 {
863 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
864 "Subject malformed\n");
865 GNUNET_free (issuer);
866 return;
867 }
868 GNUNET_asprintf (&id,
869 "%s.%s",
870 issuer,
871 (char*) &cred[1]);
872 subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
873 if (NULL == subject)
874 {
875 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
876 "Subject malformed\n");
877 GNUNET_free (id);
878 GNUNET_free (issuer);
879 return;
880 }
881 GNUNET_STRINGS_base64_encode ((char*) &cred->signature,
882 sizeof(struct GNUNET_CRYPTO_EcdsaSignature),
883 &signature);
884 json_document = GNUNET_JSONAPI_document_new ();
885 json_resource = GNUNET_JSONAPI_resource_new (
886 GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
887 id);
888 GNUNET_free (id);
889 cred_obj = json_object ();
890 json_object_set_new (cred_obj, "issuer", json_string (issuer));
891 json_object_set_new (cred_obj, "subject", json_string (subject));
892 json_object_set_new (cred_obj, "expiration", json_integer (
893 cred->expiration.abs_value_us));
894 json_object_set_new (cred_obj, "signature", json_string (signature));
895 GNUNET_JSONAPI_resource_add_attr (json_resource,
896 GNUNET_REST_JSONAPI_CREDENTIAL,
897 cred_obj);
898 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
899 GNUNET_JSONAPI_document_serialize (json_document, &result);
900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
901 "Result %s\n",
902 result);
903 json_decref (cred_obj);
904 GNUNET_JSONAPI_document_delete (json_document);
905 resp = GNUNET_REST_create_response (result);
906 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
907 GNUNET_free (result);
908 GNUNET_free (signature);
909 GNUNET_free (issuer);
910 GNUNET_free (subject);
911 cleanup_handle (handle);
912}
913
914void
915get_cred_issuer_cb (void *cls,
916 struct GNUNET_IDENTITY_Ego *ego,
917 void **ctx,
918 const char *name)
919{
920 struct RequestHandle *handle = cls;
921 struct GNUNET_TIME_Absolute etime_abs;
922 struct GNUNET_TIME_Relative etime_rel;
923 const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer_key;
924 struct GNUNET_HashCode key;
925 struct GNUNET_CREDENTIAL_Credential *cred;
926 char*expiration_str;
927 char*tmp;
928
929 handle->id_op = NULL;
930
931 if (NULL == name)
932 {
933 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
934 "Issuer not configured!\n");
935 GNUNET_SCHEDULER_add_now (&do_error, handle);
936 return;
937 }
938
939 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
940 "Connecting to credential service...\n");
941 handle->credential = GNUNET_CREDENTIAL_connect (cfg);
942 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
943 "Connected\n");
944 if (NULL == handle->credential)
945 {
946 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
947 "Connecting to CREDENTIAL failed\n");
948 GNUNET_SCHEDULER_add_now (&do_error, handle);
949 return;
950 }
951 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION,
952 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION),
953 &key);
954 if (GNUNET_NO ==
955 GNUNET_CONTAINER_multihashmap_contains (
956 handle->rest_handle->url_param_map,
957 &key))
958 {
959 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
960 "Missing expiration\n");
961 GNUNET_SCHEDULER_add_now (&do_error, handle);
962 return;
963 }
964 expiration_str = GNUNET_CONTAINER_multihashmap_get (
965 handle->rest_handle->url_param_map,
966 &key);
967 if (NULL == expiration_str)
968 {
969 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
970 "Expiration malformed\n");
971 GNUNET_SCHEDULER_add_now (&do_error, handle);
972 return;
973 }
974
975 if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str,
976 &etime_rel))
977 {
978 etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
979 }
980 else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration_str,
981 &etime_abs))
982 {
983 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
984 "Malformed expiration: %s\n", expiration_str);
985 GNUNET_SCHEDULER_add_now (&do_error, handle);
986 return;
987 }
988 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR,
989 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR),
990 &key);
991 if (GNUNET_NO ==
992 GNUNET_CONTAINER_multihashmap_contains (
993 handle->rest_handle->url_param_map,
994 &key))
995 {
996 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
997 "Missing issuer attribute\n");
998 GNUNET_SCHEDULER_add_now (&do_error, handle);
999 return;
1000 }
1001 handle->issuer_attr = GNUNET_strdup (GNUNET_CONTAINER_multihashmap_get
1002 (handle->rest_handle->url_param_map,
1003 &key));
1004 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY,
1005 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY),
1006 &key);
1007 if (GNUNET_NO ==
1008 GNUNET_CONTAINER_multihashmap_contains (
1009 handle->rest_handle->url_param_map,
1010 &key))
1011 {
1012 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1013 "Missing subject\n");
1014 GNUNET_SCHEDULER_add_now (&do_error, handle);
1015 return;
1016 }
1017 tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
1018 &key);
1019 if (NULL == tmp)
1020 {
1021 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1022 "Malformed subject\n");
1023 GNUNET_SCHEDULER_add_now (&do_error, handle);
1024 return;
1025 }
1026 if (GNUNET_OK !=
1027 GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp,
1028 strlen (tmp),
1029 &handle->subject_key))
1030 {
1031 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1032 "Malformed subject key\n");
1033 GNUNET_SCHEDULER_add_now (&do_error, handle);
1034 return;
1035 }
1036 issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego);
1037 cred = GNUNET_CREDENTIAL_credential_issue (issuer_key,
1038 &handle->subject_key,
1039 handle->issuer_attr,
1040 &etime_abs);
1041 if (NULL == cred)
1042 {
1043 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1044 "Failed to create credential\n");
1045 GNUNET_SCHEDULER_add_now (&do_error, handle);
1046 return;
1047 }
1048 send_cred_response (handle, cred);
1049}
1050
1051
1052static void
1053issue_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
1054 const char*url,
1055 void *cls)
1056{
1057 struct RequestHandle *handle = cls;
1058
1059 handle->identity = GNUNET_IDENTITY_connect (cfg,
1060 NULL,
1061 NULL);
1062 handle->id_op = GNUNET_IDENTITY_get (handle->identity,
1063 "credential-issuer",
1064 &get_cred_issuer_cb,
1065 handle);
1066 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
1067 &do_error,
1068 handle);
1069}
1070
1071static void
1072options_cont (struct GNUNET_REST_RequestHandle *con_handle,
1073 const char*url,
1074 void *cls)
1075{
1076 struct MHD_Response *resp;
1077 struct RequestHandle *handle = cls;
1078
1079 // For GNS, independent of path return all options
1080 resp = GNUNET_REST_create_response (NULL);
1081 MHD_add_response_header (resp,
1082 "Access-Control-Allow-Methods",
1083 MHD_HTTP_METHOD_GET);
1084 handle->proc (handle->proc_cls,
1085 resp,
1086 MHD_HTTP_OK);
1087 cleanup_handle (handle);
1088}
1089
1090
1091static void
1092rest_credential_process_request (struct
1093 GNUNET_REST_RequestHandle *conndata_handle,
1094 GNUNET_REST_ResultProcessor proc,
1095 void *proc_cls)
1096{
1097 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1098 struct GNUNET_REST_RequestHandlerError err;
1099
1100 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1101 handle->proc_cls = proc_cls;
1102 handle->proc = proc;
1103 handle->rest_handle = conndata_handle;
1104
1105 static const struct GNUNET_REST_RequestHandler handlers[] = {
1106 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CREDENTIAL_VERIFY,
1107 &verify_cred_cont },
1108 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_COLLECT,
1109 &collect_cred_cont },
1110 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE,
1111 &issue_cred_cont },
1112 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont },
1113 GNUNET_REST_HANDLER_END
1114 };
1115
1116 if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle,
1117 handlers,
1118 &err,
1119 handle))
1120 {
1121 handle->response_code = err.error_code;
1122 GNUNET_SCHEDULER_add_now (&do_error, handle);
1123 }
1124}
1125
1126
1127/**
1128 * Entry point for the plugin.
1129 *
1130 * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
1131 * @return NULL on error, otherwise the plugin context
1132 */
1133void *
1134libgnunet_plugin_rest_credential_init (void *cls)
1135{
1136 static struct Plugin plugin;
1137
1138 cfg = cls;
1139 struct GNUNET_REST_Plugin *api;
1140
1141 if (NULL != plugin.cfg)
1142 return NULL; /* can only initialize once! */
1143 memset (&plugin, 0, sizeof(struct Plugin));
1144 plugin.cfg = cfg;
1145 api = GNUNET_new (struct GNUNET_REST_Plugin);
1146 api->cls = &plugin;
1147 api->name = GNUNET_REST_API_NS_CREDENTIAL;
1148 api->process_request = &rest_credential_process_request;
1149 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1150 _ ("GNS REST API initialized\n"));
1151 return api;
1152}
1153
1154
1155/**
1156 * Exit point from the plugin.
1157 *
1158 * @param cls the plugin context (as returned by "init")
1159 * @return always NULL
1160 */
1161void *
1162libgnunet_plugin_rest_credential_done (void *cls)
1163{
1164 struct GNUNET_REST_Plugin *api = cls;
1165 struct Plugin *plugin = api->cls;
1166
1167 plugin->cfg = NULL;
1168 GNUNET_free (api);
1169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1170 "GNS REST plugin is finished\n");
1171 return NULL;
1172}
1173
1174/* end of plugin_rest_gns.c */
diff --git a/src/abd/test_abd_bi_and.sh b/src/abd/test_abd_bi_and.sh
new file mode 100755
index 000000000..b32313636
--- /dev/null
+++ b/src/abd/test_abd_bi_and.sh
@@ -0,0 +1,98 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
22gnunet-arm -s -c test_abd_lookup.conf
23
24gnunet-identity -C a -c test_abd_lookup.conf
25gnunet-identity -C b -c test_abd_lookup.conf
26gnunet-identity -C c -c test_abd_lookup.conf
27gnunet-identity -C d -c test_abd_lookup.conf
28gnunet-identity -C e -c test_abd_lookup.conf
29gnunet-identity -C f -c test_abd_lookup.conf
30gnunet-identity -C g -c test_abd_lookup.conf
31gnunet-identity -C h -c test_abd_lookup.conf
32AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
33BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
34CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
35DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
36EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
37FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
38GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
39HKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep h | awk '{print $3}')
40gnunet-identity -d
41
42# (1) (A.a) <- B.b
43# (2) (B.b) <- C.c AND G.g
44# (3) C.c <- (D.D)
45# (4) D.d <- (E.e)
46# (5) E.e <- (F) priv
47# (6) (G.g) <- H.h
48# (7) H.h <- (F) priv
49
50# BIDIRECTIONAL
51gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
52gnunet-namestore -D -z a
53gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$CKEY c, $GKEY g" --ttl=5m -c test_abd_lookup.conf
54gnunet-namestore -D -z b
55gnunet-abd --createIssuerSide --ego=g --attribute="g" --subject="$HKEY h" --ttl=5m -c test_abd_lookup.conf
56gnunet-namestore -D -z b
57
58SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
59gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
60gnunet-namestore -D -z d
61SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY e" --ttl="2019-12-12 10:00:00"`
62gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
63gnunet-namestore -D -z e
64SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="e" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
65gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
66gnunet-namestore -D -z f
67SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=h --attribute="h" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
68gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
69gnunet-namestore -D -z h
70
71# Starting to resolve
72echo "+++ Starting to Resolve +++"
73
74DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=f --forward --backward -c test_abd_lookup.conf | paste -d, -s - -`
75echo $DELS
76echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate=\'$DELS\' --forward --backward -c test_abd_lookup.conf
77gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate="$DELS" --forward --backward -c test_abd_lookup.conf
78
79RES=$?
80
81# Cleanup properly
82gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
83gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
84gnunet-namestore -z g -d -n "g" -t ATTR -c test_abd_lookup.conf
85gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
86gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
87gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
88
89gnunet-arm -e -c test_abd_lookup.conf
90
91if [ "$RES" == 0 ]
92then
93 exit 0
94else
95 echo "FAIL: Failed to verify credential."
96 exit 1
97fi
98
diff --git a/src/abd/test_abd_bi_and2.sh b/src/abd/test_abd_bi_and2.sh
new file mode 100755
index 000000000..8d1601ef4
--- /dev/null
+++ b/src/abd/test_abd_bi_and2.sh
@@ -0,0 +1,94 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
22gnunet-arm -s -c test_abd_lookup.conf
23
24gnunet-identity -C a -c test_abd_lookup.conf
25gnunet-identity -C b -c test_abd_lookup.conf
26gnunet-identity -C c -c test_abd_lookup.conf
27gnunet-identity -C d -c test_abd_lookup.conf
28gnunet-identity -C e -c test_abd_lookup.conf
29gnunet-identity -C f -c test_abd_lookup.conf
30gnunet-identity -C g -c test_abd_lookup.conf
31gnunet-identity -C h -c test_abd_lookup.conf
32AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
33BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
34CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
35DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
36EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
37FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
38GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
39HKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep h | awk '{print $3}')
40gnunet-identity -d
41
42# (1) (A.a) <- B.b
43# (2) (B.b) <- C.c AND G.g
44# (3) C.c <- (D.D)
45# (4) D.d <- (E.e)
46# (5) E.e <- (F) priv
47# (6) G.g <- (F) priv
48
49# BIDIRECTIONAL
50gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
51gnunet-namestore -D -z a
52gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$CKEY c, $GKEY g" --ttl=5m -c test_abd_lookup.conf
53gnunet-namestore -D -z b
54
55SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
56gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
57gnunet-namestore -D -z d
58SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY e" --ttl="2019-12-12 10:00:00"`
59gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
60gnunet-namestore -D -z e
61SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="e" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
62gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
63gnunet-namestore -D -z f
64SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=g --attribute="g" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
65gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
66gnunet-namestore -D -z h
67
68# Starting to resolve
69echo "+++ Starting to Resolve +++"
70
71DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=f -c test_abd_lookup.conf | paste -d, -s - -`
72echo $DELS
73echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate=\'$DELS\' -c test_abd_lookup.conf
74gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate="$DELS" -c test_abd_lookup.conf
75
76RES=$?
77
78# Cleanup properly
79gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
80gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
81gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
82gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
83gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
84
85gnunet-arm -e -c test_abd_lookup.conf
86
87if [ "$RES" == 0 ]
88then
89 exit 0
90else
91 echo "FAIL: Failed to verify credential."
92 exit 1
93fi
94
diff --git a/src/abd/test_abd_bi_and3.sh b/src/abd/test_abd_bi_and3.sh
new file mode 100755
index 000000000..cde2a020b
--- /dev/null
+++ b/src/abd/test_abd_bi_and3.sh
@@ -0,0 +1,96 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
21gnunet-arm -s -c test_abd_lookup.conf
22
23gnunet-identity -C a -c test_abd_lookup.conf
24gnunet-identity -C b -c test_abd_lookup.conf
25gnunet-identity -C c -c test_abd_lookup.conf
26gnunet-identity -C d -c test_abd_lookup.conf
27gnunet-identity -C e -c test_abd_lookup.conf
28gnunet-identity -C f -c test_abd_lookup.conf
29gnunet-identity -C g -c test_abd_lookup.conf
30gnunet-identity -C h -c test_abd_lookup.conf
31AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
32BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
33CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
34DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
35EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
36FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
37GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
38HKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep h | awk '{print $3}')
39gnunet-identity -d
40
41# (1) (A.a) <- B.b
42# (2) (B.b) <- C.c AND G.g
43# (3) C.c <- (D.d)
44# (4) D.d <- (E.e)
45# (5) E.e <- (F) priv
46# (6) G.g <- (H.h)
47# (7) H.h <- (F) priv
48
49# BIDIRECTIONAL
50gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
51gnunet-namestore -D -z a
52gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$CKEY c, $GKEY g" --ttl=5m -c test_abd_lookup.conf
53gnunet-namestore -D -z b
54
55SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
56gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
57gnunet-namestore -D -z d
58SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY e" --ttl="2019-12-12 10:00:00"`
59gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
60gnunet-namestore -D -z e
61SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=g --attribute="g" --subject="$HKEY h" --ttl="2019-12-12 10:00:00"`
62gnunet-abd --createSubjectSide --ego=h --import="$SIGNED"
63gnunet-namestore -D -z h
64SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="e" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
65gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
66SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=h --attribute="h" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
67gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
68gnunet-namestore -D -z f
69
70# Starting to resolve
71echo "+++ Starting to Resolve +++"
72
73DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=f -c test_abd_lookup.conf | paste -d, -s - -`
74echo $DELS
75echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate=\'$DELS\' -c test_abd_lookup.conf
76gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate="$DELS" -c test_abd_lookup.conf
77
78RES=$?
79
80# Cleanup properly
81gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
82gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
83gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
84gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
85gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
86gnunet-namestore -z h -d -n "@" -t DEL -c test_abd_lookup.conf
87
88gnunet-arm -e -c test_abd_lookup.conf
89
90if [ "$RES" == 0 ]
91then
92 exit 0
93else
94 echo "FAIL: Failed to verify credential."
95 exit 1
96fi
diff --git a/src/abd/test_abd_bi_and4.sh b/src/abd/test_abd_bi_and4.sh
new file mode 100755
index 000000000..e8cd6efd6
--- /dev/null
+++ b/src/abd/test_abd_bi_and4.sh
@@ -0,0 +1,83 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
22gnunet-arm -s -c test_abd_lookup.conf
23
24gnunet-identity -C a -c test_abd_lookup.conf
25gnunet-identity -C b -c test_abd_lookup.conf
26gnunet-identity -C c -c test_abd_lookup.conf
27gnunet-identity -C d -c test_abd_lookup.conf
28gnunet-identity -C e -c test_abd_lookup.conf
29gnunet-identity -C f -c test_abd_lookup.conf
30gnunet-identity -C g -c test_abd_lookup.conf
31gnunet-identity -C h -c test_abd_lookup.conf
32AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
33BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
34CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
35DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
36EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
37FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
38GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
39HKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep h | awk '{print $3}')
40gnunet-identity -d
41
42# (1) (A.a) <- B.b
43# (2) (B.b) <- C.c AND G.g
44# (3) C.c <- (F) priv
45# (4) G.g <- (F) priv
46
47# BIDIRECTIONAL
48gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
49gnunet-namestore -D -z a
50gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$CKEY c, $GKEY g" --ttl=5m -c test_abd_lookup.conf
51gnunet-namestore -D -z b
52
53SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=g --attribute="g" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
54gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
55SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
56gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
57gnunet-namestore -D -z f
58
59# Starting to resolve
60echo "+++ Starting to Resolve +++"
61
62DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=f --backward -c test_abd_lookup.conf | paste -d, -s - -`
63echo $DELS
64echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate=\'$DELS\' --backward -c test_abd_lookup.conf
65gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate="$DELS" --backward -c test_abd_lookup.conf
66
67RES=$?
68
69# Cleanup properly
70gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
71gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
72gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
73
74gnunet-arm -e -c test_abd_lookup.conf
75
76if [ "$RES" == 0 ]
77then
78 exit 0
79else
80 echo "FAIL: Failed to verify credential."
81 exit 1
82fi
83
diff --git a/src/abd/test_abd_bi_bw.sh b/src/abd/test_abd_bi_bw.sh
new file mode 100755
index 000000000..6b0e51722
--- /dev/null
+++ b/src/abd/test_abd_bi_bw.sh
@@ -0,0 +1,87 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
22gnunet-arm -s -c test_abd_lookup.conf
23
24gnunet-identity -C a -c test_abd_lookup.conf
25gnunet-identity -C b -c test_abd_lookup.conf
26gnunet-identity -C c -c test_abd_lookup.conf
27gnunet-identity -C d -c test_abd_lookup.conf
28gnunet-identity -C e -c test_abd_lookup.conf
29gnunet-identity -C f -c test_abd_lookup.conf
30gnunet-identity -C g -c test_abd_lookup.conf
31AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
32BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
33CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
34DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
35EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
36FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
37GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
38gnunet-identity -d
39
40# (1) (A.a) <- B.b
41# (2) (B.b) <- C.c
42# (3) C.c <- (D.D)
43# (4) D.d <- (E.e)
44# (5) E.e <- (F)
45
46# BIDIRECTIONAL
47gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
48gnunet-namestore -D -z a
49gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$CKEY c" --ttl=5m -c test_abd_lookup.conf
50gnunet-namestore -D -z b
51
52SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
53gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
54gnunet-namestore -D -z d
55SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY e" --ttl="2019-12-12 10:00:00"`
56gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
57gnunet-namestore -D -z e
58SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="e" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
59gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
60gnunet-namestore -D -z f
61
62# Starting to resolve
63echo "+++ Starting to Resolve +++"
64
65DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=f --forward --backward -c test_abd_lookup.conf | paste -d, -s - -`
66echo $DELS
67echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate=\'$DELS\' --forward --backward -c test_abd_lookup.conf
68gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate="$DELS" --forward --backward -c test_abd_lookup.conf
69
70RES=$?
71
72# Cleanup properly
73gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
74gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
75gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
76gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
77gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
78
79gnunet-arm -e -c test_abd_lookup.conf
80
81if [ "$RES" == 0 ]
82then
83 exit 0
84else
85 echo "FAIL: Failed to verify credential."
86 exit 1
87fi
diff --git a/src/abd/test_abd_bi_bw_link.sh b/src/abd/test_abd_bi_bw_link.sh
new file mode 100755
index 000000000..f60f78827
--- /dev/null
+++ b/src/abd/test_abd_bi_bw_link.sh
@@ -0,0 +1,92 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
22gnunet-arm -s -c test_abd_lookup.conf
23
24gnunet-identity -C a -c test_abd_lookup.conf
25gnunet-identity -C b -c test_abd_lookup.conf
26gnunet-identity -C c -c test_abd_lookup.conf
27gnunet-identity -C d -c test_abd_lookup.conf
28gnunet-identity -C e -c test_abd_lookup.conf
29gnunet-identity -C f -c test_abd_lookup.conf
30gnunet-identity -C g -c test_abd_lookup.conf
31AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
32BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
33CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
34DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
35EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
36FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
37GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
38gnunet-identity -d
39
40# (1) (A.a) <- B.b
41# (2) (B.b) <- G.g.c
42# (3) (G.g) <- C
43# (3) C.c <- (D.D)
44# (4) D.d <- (E.e)
45# (5) E.e <- (F)
46
47# BIDIRECTIONAL
48gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
49gnunet-namestore -D -z a
50gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$GKEY g.c" --ttl=5m -c test_abd_lookup.conf
51gnunet-namestore -D -z b
52gnunet-abd --createIssuerSide --ego=g --attribute="g" --subject="$CKEY" --ttl=5m -c test_abd_lookup.conf
53gnunet-namestore -D -z b
54
55SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
56gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
57gnunet-namestore -D -z d
58SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY e" --ttl="2019-12-12 10:00:00"`
59gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
60gnunet-namestore -D -z e
61SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="e" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
62gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
63gnunet-namestore -D -z f
64
65# Starting to resolve
66echo "+++ Starting to Resolve +++"
67
68DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=f --forward --backward -c test_abd_lookup.conf | paste -d, -s - -`
69echo $DELS
70echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate=\'$DELS\' --forward --backward -c test_abd_lookup.conf
71gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate="$DELS" --forward --backward -c test_abd_lookup.conf
72
73RES=$?
74
75# Cleanup properly
76gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
77gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
78gnunet-namestore -z g -d -n "g" -t ATTR -c test_abd_lookup.conf
79gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
80gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
81gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
82
83gnunet-arm -e -c test_abd_lookup.conf
84
85if [ "$RES" == 0 ]
86then
87 exit 0
88else
89 echo "FAIL: Failed to verify credential."
90 exit 1
91fi
92
diff --git a/src/abd/test_abd_bi_bw_link2.sh b/src/abd/test_abd_bi_bw_link2.sh
new file mode 100755
index 000000000..b0fb49b8e
--- /dev/null
+++ b/src/abd/test_abd_bi_bw_link2.sh
@@ -0,0 +1,93 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
22gnunet-arm -s -c test_abd_lookup.conf
23
24gnunet-identity -C a -c test_abd_lookup.conf
25gnunet-identity -C b -c test_abd_lookup.conf
26gnunet-identity -C c -c test_abd_lookup.conf
27gnunet-identity -C d -c test_abd_lookup.conf
28gnunet-identity -C e -c test_abd_lookup.conf
29gnunet-identity -C f -c test_abd_lookup.conf
30gnunet-identity -C g -c test_abd_lookup.conf
31AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
32BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
33CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
34DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
35EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
36FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
37GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
38gnunet-identity -d
39
40# (1) (A.a) <- B.b
41# (2) (B.b) <- G.g.c
42# (3) G.g <- (C)
43# (3) C.c <- (D.d)
44# (4) D.d <- (E.e)
45# (5) E.e <- (F)
46
47# BIDIRECTIONAL
48gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
49gnunet-namestore -D -z a
50gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$GKEY g.c" --ttl=5m -c test_abd_lookup.conf
51gnunet-namestore -D -z b
52
53SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=g --attribute="g" --subject="$CKEY" --ttl="2019-12-12 10:00:00"`
54gnunet-abd --createSubjectSide --ego=c --import="$SIGNED"
55gnunet-namestore -D -z c
56SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
57gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
58gnunet-namestore -D -z d
59SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY e" --ttl="2019-12-12 10:00:00"`
60gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
61gnunet-namestore -D -z e
62SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="e" --subject="$FKEY" --ttl="2019-12-12 10:00:00"`
63gnunet-abd --createSubjectSide --ego=f --import="$SIGNED" --private
64gnunet-namestore -D -z f
65
66# Starting to resolve
67echo "+++ Starting to Resolve +++"
68
69DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=f --forward --backward -c test_abd_lookup.conf | paste -d, -s - -`
70echo $DELS
71echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate=\'$DELS\' --forward --backward -c test_abd_lookup.conf
72gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$FKEY --delegate="$DELS" --forward --backward -c test_abd_lookup.conf
73
74RES=$?
75
76# Cleanup properly
77gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
78gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
79gnunet-namestore -z c -d -n "@" -t DEL -c test_abd_lookup.conf
80gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
81gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
82gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
83
84gnunet-arm -e -c test_abd_lookup.conf
85
86if [ "$RES" == 0 ]
87then
88 exit 0
89else
90 echo "FAIL: Failed to verify credential."
91 exit 1
92fi
93
diff --git a/src/abd/test_abd_bi_fw.sh b/src/abd/test_abd_bi_fw.sh
new file mode 100755
index 000000000..75a940fbe
--- /dev/null
+++ b/src/abd/test_abd_bi_fw.sh
@@ -0,0 +1,92 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
22gnunet-arm -s -c test_abd_lookup.conf
23
24gnunet-identity -C a -c test_abd_lookup.conf
25gnunet-identity -C b -c test_abd_lookup.conf
26gnunet-identity -C c -c test_abd_lookup.conf
27gnunet-identity -C d -c test_abd_lookup.conf
28gnunet-identity -C e -c test_abd_lookup.conf
29gnunet-identity -C f -c test_abd_lookup.conf
30gnunet-identity -C g -c test_abd_lookup.conf
31AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
32BKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep b | awk '{print $3}')
33CKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep c | awk '{print $3}')
34DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
35EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
36FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
37GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
38gnunet-identity -d
39
40# (1) (A.a) <- B.b
41# (2) (B.b) <- C.c
42# (3) C.c <- (D.D)
43# (4) D.d <- (E.e)
44# (5) E.e <- (F.f)
45# (6) F.f <- (G)
46
47# BIDIRECTIONAL
48gnunet-abd --createIssuerSide --ego=a --attribute="a" --subject="$BKEY b" --ttl=5m -c test_abd_lookup.conf
49gnunet-namestore -D -z a
50gnunet-abd --createIssuerSide --ego=b --attribute="b" --subject="$CKEY c" --ttl=5m -c test_abd_lookup.conf
51gnunet-namestore -D -z b
52
53SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=c --attribute="c" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
54gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
55gnunet-namestore -D -z d
56SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY e" --ttl="2019-12-12 10:00:00"`
57gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
58gnunet-namestore -D -z e
59SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="e" --subject="$FKEY f" --ttl="2019-12-12 10:00:00"`
60gnunet-abd --createSubjectSide --ego=f --import="$SIGNED"
61gnunet-namestore -D -z f
62SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=f --attribute="f" --subject="$GKEY" --ttl="2019-12-12 10:00:00"`
63gnunet-abd --createSubjectSide --ego=g --import="$SIGNED" --private
64gnunet-namestore -D -z g
65
66# Starting to resolve
67echo "+++ Starting to Resolve +++"
68
69DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=g --forward --backward -c test_abd_lookup.conf | paste -d, -s - -`
70echo $DELS
71echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$GKEY --delegate=\'$DELS\' --forward --backward -c test_abd_lookup.conf
72gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$GKEY --delegate="$DELS" --forward --backward -c test_abd_lookup.conf
73
74RES=$?
75
76# Cleanup properly
77gnunet-namestore -z a -d -n "a" -t ATTR -c test_abd_lookup.conf
78gnunet-namestore -z b -d -n "b" -t ATTR -c test_abd_lookup.conf
79gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
80gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
81gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
82gnunet-namestore -z g -d -n "@" -t DEL -c test_abd_lookup.conf
83
84gnunet-arm -e -c test_abd_lookup.conf
85
86if [ "$RES" == 0 ]
87then
88 exit 0
89else
90 echo "FAIL: Failed to verify credential."
91 exit 1
92fi
diff --git a/src/abd/test_abd_defaults.conf b/src/abd/test_abd_defaults.conf
new file mode 100644
index 000000000..7b4cb576d
--- /dev/null
+++ b/src/abd/test_abd_defaults.conf
@@ -0,0 +1,24 @@
1@INLINE@ ../../contrib/conf/gnunet/no_forcestart.conf
2
3[PATHS]
4GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-abd-testing/
5
6[namestore-sqlite]
7FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db
8
9[namecache-sqlite]
10FILENAME=$GNUNET_TEST_HOME/namecache/namecache.db
11
12[identity]
13# Directory where we store information about our egos
14EGODIR = $GNUNET_TEST_HOME/identity/egos/
15
16[dhtcache]
17DATABASE = heap
18
19[transport]
20PLUGINS = tcp
21
22[transport-tcp]
23BINDTO = 127.0.0.1
24
diff --git a/src/abd/test_abd_issue.sh b/src/abd/test_abd_issue.sh
new file mode 100755
index 000000000..8076aa921
--- /dev/null
+++ b/src/abd/test_abd_issue.sh
@@ -0,0 +1,46 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26gnunet-arm -s -c test_abd_lookup.conf
27gnunet-identity -C testissuer -c test_abd_lookup.conf
28gnunet-identity -C testsubject -c test_abd_lookup.conf
29SUBJECT_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep testsubject | awk '{print $3}')
30ISSUER_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep testissuer | awk '{print $3}')
31
32# Get abd and store it with subject (3)
33SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=testissuer --attribute=$TEST_ATTR --subject=$SUBJECT_KEY --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf`
34
35STATUS=$?
36
37if test $? != 0
38then
39 echo "Error issuing..."
40 exit 1
41fi
42#Try import
43$DO_TIMEOUT gnunet-abd --createSubjectSide --ego=testsubject --import="$SIGNED" --private -c test_abd_lookup.conf
44RES=$?
45gnunet-arm -e -c test_abd_lookup.conf
46exit $RES
diff --git a/src/abd/test_abd_lookup.conf b/src/abd/test_abd_lookup.conf
new file mode 100644
index 000000000..4072ba23b
--- /dev/null
+++ b/src/abd/test_abd_lookup.conf
@@ -0,0 +1,28 @@
1@INLINE@ test_abd_defaults.conf
2
3[PATHS]
4GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-abd-peer-1/
5
6[dht]
7START_ON_DEMAND = YES
8
9[transport]
10PLUGINS =
11
12[abd]
13START_ON_DEMAND = YES
14#PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/credlog
15
16[rest]
17PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=$GNUNET_TMP/restlog
18
19[gns]
20#PREFIX = valgrind --leak-check=full --track-origins=yes
21START_ON_DEMAND = YES
22AUTO_IMPORT_PKEY = YES
23MAX_PARALLEL_BACKGROUND_QUERIES = 10
24DEFAULT_LOOKUP_TIMEOUT = 15 s
25RECORD_PUT_INTERVAL = 1 h
26ZONE_PUBLISH_TIME_WINDOW = 1 h
27DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0
28
diff --git a/src/abd/test_abd_own.sh b/src/abd/test_abd_own.sh
new file mode 100755
index 000000000..f4780ea90
--- /dev/null
+++ b/src/abd/test_abd_own.sh
@@ -0,0 +1,140 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18
19
20which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 10"
21gnunet-arm -s -c test_abd_lookup.conf
22
23gnunet-identity -C a -c test_abd_lookup.conf
24gnunet-identity -C d -c test_abd_lookup.conf
25gnunet-identity -C e -c test_abd_lookup.conf
26gnunet-identity -C f -c test_abd_lookup.conf
27gnunet-identity -C g -c test_abd_lookup.conf
28AKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep a | awk '{print $3}')
29DKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep d | awk '{print $3}')
30EKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep e | awk '{print $3}')
31FKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep f | awk '{print $3}')
32GKEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep g | awk '{print $3}')
33
34############################################################################################
35# (1) EPub.discount <- EOrg.preferred
36# (2) EOrg.preferred <- StateU.student
37# (3) StateU.student <- RegistrarB.student
38# (4) RegistrarB.student <- Alice
39
40gnunet-identity -C epub -c test_abd_lookup.conf
41gnunet-identity -C eorg -c test_abd_lookup.conf
42gnunet-identity -C stateu -c test_abd_lookup.conf
43gnunet-identity -C registrarb -c test_abd_lookup.conf
44gnunet-identity -C alice -c test_abd_lookup.conf
45
46EPUB_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep epub | awk '{print $3}')
47EORG_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep eorg | awk '{print $3}')
48STATEU_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep stateu | awk '{print $3}')
49REGISTRARB_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep registrarb | awk '{print $3}')
50ALICE_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep alice | awk '{print $3}')
51
52
53DISC_ATTR="discount"
54PREF_ATTR="preferred"
55STATE_STUD_ATTR="student"
56REG_STUD_ATTR="student"
57END_ATTR="end"
58
59gnunet-identity -d
60
61# FORWARD, subject side stored (different constallations)
62SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=a --attribute="a" --subject="$AKEY b.c" --ttl="2019-12-12 10:00:00"`
63gnunet-abd --createSubjectSide --ego=a --import="$SIGNED"
64gnunet-namestore -D -z a
65
66SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=a --attribute="b" --subject="$DKEY d" --ttl="2019-12-12 10:00:00"`
67gnunet-abd --createSubjectSide --ego=d --import="$SIGNED"
68gnunet-namestore -D -z d
69
70SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="d" --subject="$EKEY" --ttl="2019-12-12 10:00:00"`
71gnunet-abd --createSubjectSide --ego=e --import="$SIGNED"
72gnunet-namestore -D -z e
73
74SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="c" --subject="$FKEY c" --ttl="2019-12-12 10:00:00"`
75gnunet-abd --createSubjectSide --ego=f --import="$SIGNED"
76SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=e --attribute="k" --subject="$FKEY c.k" --ttl="2019-12-12 10:00:00"`
77gnunet-abd --createSubjectSide --ego=f --import="$SIGNED"
78gnunet-namestore -D -z f
79
80SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=f --attribute="c" --subject="$GKEY" --ttl="2019-12-12 10:00:00"`
81gnunet-abd --createSubjectSide --ego=g --import="$SIGNED" --private
82SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=a --attribute="c" --subject="$GKEY" --ttl="2019-12-12 10:00:00"`
83gnunet-abd --createSubjectSide --ego=g --import="$SIGNED" --private
84SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=d --attribute="h.o" --subject="$GKEY" --ttl="2019-12-12 10:00:00"`
85gnunet-abd --createSubjectSide --ego=g --import="$SIGNED"
86gnunet-namestore -D -z g
87
88
89# BACKWARD, issuer side stored
90# (1) EPub assigns the attribute "discount" to all entities that have been assigned "preferred" by EOrg
91gnunet-abd --createIssuerSide --ego=epub --attribute=$DISC_ATTR --subject="$EORG_KEY $PREF_ATTR" --ttl=5m -c test_abd_lookup.conf
92
93# (2) EOrg assigns the attribute "preferred" to all entities that have been assigned "student" by StateU
94gnunet-abd --createIssuerSide --ego=eorg --attribute=$PREF_ATTR --subject="$STATEU_KEY $STATE_STUD_ATTR" --ttl=5m -c test_abd_lookup.conf
95
96# (3) StateU assigns the attribute "student" to all entities that have been asssigned "student" by RegistrarB
97gnunet-abd --createIssuerSide --ego=stateu --attribute=$STATE_STUD_ATTR --subject="$REGISTRARB_KEY $REG_STUD_ATTR" --ttl=5m -c test_abd_lookup.conf
98
99# (4) RegistrarB issues Alice the credential "student"
100SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=registrarb --attribute="$REG_STUD_ATTR" --subject="$ALICE_KEY" --ttl="2019-12-12 10:00:00"`
101gnunet-abd --createSubjectSide --ego=alice --import="$SIGNED" --private
102
103# Starting to resolve
104echo "+++ Starting to Resolve +++"
105
106# FORWARD
107#DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$AKEY --attribute="a" --ego=g --forward -c test_abd_lookup.conf | paste -d, -s - -`
108#echo $DELS
109#echo gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$GKEY --delegate=\'$DELS\' --forward -c test_abd_lookup.conf
110#RES_DELS=`gnunet-abd --verify --issuer=$AKEY --attribute="a" --subject=$GKEY --delegate="$DELS" --forward -c test_abd_lookup.conf`
111
112# BACKWARD
113DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$EPUB_KEY --attribute=$DISC_ATTR --ego=alice --backward -c test_abd_lookup.conf | paste -d, -s - -`
114echo $DELS
115echo gnunet-abd --verify --issuer=$EPUB_KEY --attribute=$DISC_ATTR --subject=$ALICE_KEY --delegate=\'$DELS\' --backward -c test_abd_lookup.conf
116gnunet-abd --verify --issuer=$EPUB_KEY --attribute=$DISC_ATTR --subject=$ALICE_KEY --delegate="$DELS" --backward -c test_abd_lookup.conf
117
118RES=$?
119
120# Cleanup properly
121gnunet-namestore -z epub -d -n $DISC_ATTR -t ATTR -c test_abd_lookup.conf
122gnunet-namestore -z eorg -d -n $PREF_ATTR -t ATTR -c test_abd_lookup.conf
123gnunet-namestore -z stateu -d -n $STATE_STUD_ATTR -t ATTR -c test_abd_lookup.conf
124#gnunet-namestore -z a -d -n "@" -t DEL -c test_abd_lookup.conf
125#gnunet-namestore -z d -d -n "@" -t DEL -c test_abd_lookup.conf
126#gnunet-namestore -z e -d -n "@" -t DEL -c test_abd_lookup.conf
127#gnunet-namestore -z f -d -n "@" -t DEL -c test_abd_lookup.conf
128#gnunet-namestore -z g -d -n "@" -t DEL -c test_abd_lookup.conf
129
130
131gnunet-arm -e -c test_abd_lookup.conf
132
133if [ "$RES" == 0 ]
134then
135 exit 0
136else
137 echo "FAIL: Failed to verify credential."
138 exit 1
139fi
140
diff --git a/src/abd/test_abd_verify.sh b/src/abd/test_abd_verify.sh
new file mode 100755
index 000000000..9ece91c62
--- /dev/null
+++ b/src/abd/test_abd_verify.sh
@@ -0,0 +1,87 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) Service.user -> GNU.project.member
19# (2) GNU.project -> GNUnet
20# (3) GNUnet.member -> GNUnet.developer
21# (4) GNUnet.member -> GNUnet.user
22# (5) GNUnet.developer -> Alice
23
24
25which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
26gnunet-arm -s -c test_abd_lookup.conf
27gnunet-identity -C service -c test_abd_lookup.conf
28gnunet-identity -C alice -c test_abd_lookup.conf
29gnunet-identity -C gnu -c test_abd_lookup.conf
30gnunet-identity -C gnunet -c test_abd_lookup.conf
31
32GNU_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}')
33ALICE_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep alice | awk '{print $3}')
34GNUNET_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep gnunet | awk '{print $3}')
35SERVICE_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep service | awk '{print $3}')
36
37USER_ATTR="user"
38GNU_PROJECT_ATTR="project"
39MEMBER_ATTR="member"
40DEVELOPER_ATTR="developer"
41DEV_ATTR="developer"
42TEST_CREDENTIAL="mygnunetcreds"
43
44gnunet-identity -d
45
46# (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU
47gnunet-abd --createIssuerSide --ego=service --attribute="$USER_ATTR" --subject="$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf
48gnunet-namestore -D -z service
49
50# (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute
51gnunet-abd --createIssuerSide --ego=gnu --attribute="$GNU_PROJECT_ATTR" --subject="$GNUNET_KEY" --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf
52gnunet-namestore -D -z gnu
53
54# (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user"
55gnunet-abd --createIssuerSide --ego=gnunet --attribute="$MEMBER_ATTR" --subject="$GNUNET_KEY $DEVELOPER_ATTR" --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf
56gnunet-abd --createIssuerSide --ego=gnunet --attribute="$MEMBER_ATTR" --subject="$GNUNET_KEY $USER_ATTR" --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf
57gnunet-namestore -D -z gnunet
58
59# (5) GNUnet signes the delegate and Alice stores it
60SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=gnunet --attribute=$DEV_ATTR --subject=$ALICE_KEY --ttl="2019-12-12 10:00:00"`
61gnunet-abd --createSubjectSide --ego=alice --import="$SIGNED" --private
62gnunet-namestore -D -z alice
63
64# Starting to resolve
65echo "+++ Starting to Resolve +++"
66
67DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$SERVICE_KEY --attribute=$USER_ATTR --ego=alice --backward -c test_abd_lookup.conf | paste -d, -s - -`
68echo $DELS
69echo gnunet-abd --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --delegate=\'$DELS\' --backward -c test_abd_lookup.conf
70gnunet-abd --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --delegate="$DELS" --backward -c test_abd_lookup.conf
71
72RES=$?
73
74# Cleanup properly
75gnunet-namestore -z alice -d -n "@" -t DEL -c test_abd_lookup.conf
76gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_abd_lookup.conf
77gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_abd_lookup.conf
78gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_abd_lookup.conf
79gnunet-arm -e -c test_abd_lookup.conf
80
81if [ "$RES" == 0 ]
82then
83 exit 0
84else
85 echo "FAIL: Failed to verify credential."
86 exit 1
87fi
diff --git a/src/abd/test_abd_verify_and.sh b/src/abd/test_abd_verify_and.sh
new file mode 100755
index 000000000..c6287055e
--- /dev/null
+++ b/src/abd/test_abd_verify_and.sh
@@ -0,0 +1,86 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) Service.user -> GNU.project.member
19# (2) GNU.project -> GNUnet
20# (3) GNUnet.member -> GNUnet.developer AND GNUnet.user
21# (4) GNUnet.developer -> Alice
22
23
24which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
25gnunet-arm -s -c test_abd_lookup.conf
26gnunet-identity -C service -c test_abd_lookup.conf
27gnunet-identity -C alice -c test_abd_lookup.conf
28gnunet-identity -C gnu -c test_abd_lookup.conf
29gnunet-identity -C gnunet -c test_abd_lookup.conf
30
31GNU_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}')
32ALICE_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep alice | awk '{print $3}')
33GNUNET_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep gnunet | awk '{print $3}')
34SERVICE_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep service | awk '{print $3}')
35
36USER_ATTR="user"
37GNU_PROJECT_ATTR="project"
38MEMBER_ATTR="member"
39DEVELOPER_ATTR="developer"
40DEV_ATTR="developer"
41
42gnunet-identity -d
43
44# (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU
45gnunet-abd --createIssuerSide --ego=service --attribute="$USER_ATTR" --subject="$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf
46gnunet-namestore -D -z service
47
48# (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute
49gnunet-abd --createIssuerSide --ego=gnu --attribute="$GNU_PROJECT_ATTR" --subject="$GNUNET_KEY" --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf
50gnunet-namestore -D -z gnu
51
52# (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user"
53gnunet-abd --createIssuerSide --ego=gnunet --attribute="$MEMBER_ATTR" --subject="$GNUNET_KEY $DEVELOPER_ATTR, $GNUNET_KEY $USER_ATTR" --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf
54gnunet-namestore -D -z gnunet
55
56# (5) GNUnet signes the delegates and Alice stores it
57SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=gnunet --attribute=$DEV_ATTR --subject=$ALICE_KEY --ttl="2019-12-12 10:00:00"`
58gnunet-abd --createSubjectSide --ego=alice --import="$SIGNED" --private
59SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=gnunet --attribute=$USER_ATTR --subject=$ALICE_KEY --ttl="2019-12-12 10:00:00"`
60gnunet-abd --createSubjectSide --ego=alice --import="$SIGNED" --private
61gnunet-namestore -D -z alice
62
63# Starting to resolve
64echo "+++ Starting to Resolve +++"
65
66DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$SERVICE_KEY --attribute=$USER_ATTR --ego=alice --backward -c test_abd_lookup.conf | paste -d, -s - -`
67echo $DELS
68echo gnunet-abd --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --delegate=\'$DELS\' --backward -c test_abd_lookup.conf
69gnunet-abd --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --delegate="$DELS" --backward -c test_abd_lookup.conf
70
71RES=$?
72
73# Cleanup properly
74gnunet-namestore -z alice -d -n "@" -t DEL -c test_abd_lookup.conf
75gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_abd_lookup.conf
76gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_abd_lookup.conf
77gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_abd_lookup.conf
78gnunet-arm -e -c test_abd_lookup.conf
79
80if [ "$RES" == 0 ]
81then
82 exit 0
83else
84 echo "FAIL: Failed to verify credentials."
85 exit 1
86fi
diff --git a/src/abd/test_abd_verify_simple.sh b/src/abd/test_abd_verify_simple.sh
new file mode 100755
index 000000000..e917f8793
--- /dev/null
+++ b/src/abd/test_abd_verify_simple.sh
@@ -0,0 +1,56 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_abd_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_abd_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) Issuer.user -> Subject
19
20
21which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
22gnunet-arm -s -c test_abd_lookup.conf
23gnunet-identity -C testissuer -c test_abd_lookup.conf
24gnunet-identity -C testsubject -c test_abd_lookup.conf
25
26TEST_ATTR="user"
27SUBJECT_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep testsubject | awk '{print $3}')
28ISSUER_KEY=$(gnunet-identity -d -c test_abd_lookup.conf | grep testissuer | awk '{print $3}')
29
30gnunet-identity -d
31
32# Create delegate (1)
33SIGNED=`$DO_TIMEOUT gnunet-abd --signSubjectSide --ego=testissuer --attribute=$TEST_ATTR --subject=$SUBJECT_KEY --ttl="2019-12-12 10:00:00" -c test_abd_lookup.conf`
34gnunet-abd --createSubjectSide --ego=testsubject --import="$SIGNED" --private
35gnunet-namestore -D -z testsubject
36
37# Starting to resolve
38echo "+++ Starting to Resolve +++"
39
40DELS=`$DO_TIMEOUT gnunet-abd --collect --issuer=$ISSUER_KEY --attribute=$TEST_ATTR --ego=testsubject -c test_abd_lookup.conf | paste -d, -s - -`
41echo $DELS
42gnunet-abd --verify --issuer=$ISSUER_KEY --attribute=$TEST_ATTR --subject=$SUBJECT_KEY --delegate="$DELS" -c test_abd_lookup.conf
43
44RES=$?
45
46# Cleanup properly
47gnunet-namestore -z testsubject -d -n "@" -t DEL -c test_abd_lookup.conf
48gnunet-arm -e -c test_abd_lookup.conf
49
50if [ "$RES" == 0 ]
51then
52 exit 0
53else
54 echo "FAIL: Failed to verify credential."
55 exit 1
56fi \ No newline at end of file
diff --git a/src/abd/test_credential_collect.sh b/src/abd/test_credential_collect.sh
new file mode 100755
index 000000000..0ae063eda
--- /dev/null
+++ b/src/abd/test_credential_collect.sh
@@ -0,0 +1,47 @@
1#!/bin/sh
2trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26TEST_ATTR2="test2"
27gnunet-arm -s -c test_credential_lookup.conf
28gnunet-identity -C testissuer -c test_credential_lookup.conf
29gnunet-identity -C testsubject -c test_credential_lookup.conf
30SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}')
31ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}')
32#TODO1 Get credential and store it with subject (3)
33CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf`
34$DO_TIMEOUT gnunet-namestore -a -z testsubject -n c1 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
35CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR2 --ttl=5m -c test_credential_lookup.conf`
36$DO_TIMEOUT gnunet-namestore -a -z testsubject -n c2 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
37CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$ISSUER_KEY --attribute=$TEST_ATTR --ego=testsubject -c test_credential_lookup.conf | paste -d, -s`
38echo $CREDS
39RES=$?
40gnunet-arm -e -c test_credential_lookup.conf
41
42if test $? != 0
43then
44 echo "Error collecting..."
45 exit 1
46fi
47
diff --git a/src/abd/test_credential_collect_rest.sh b/src/abd/test_credential_collect_rest.sh
new file mode 100755
index 000000000..fe59d9399
--- /dev/null
+++ b/src/abd/test_credential_collect_rest.sh
@@ -0,0 +1,91 @@
1#!/bin/sh
2trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) Service.user -> GNU.project.member
19# (2) GNU.project -> GNUnet
20# (3) GNUnet.member -> GNUnet.developer
21# (4) GNUnet.member -> GNUnet.user
22# (5) GNUnet.developer -> Alice
23
24
25which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
26gnunet-arm -s -c test_credential_lookup.conf
27gnunet-identity -C service -c test_credential_lookup.conf
28gnunet-identity -C alice -c test_credential_lookup.conf
29gnunet-identity -C gnu -c test_credential_lookup.conf
30gnunet-identity -C gnunet -c test_credential_lookup.conf
31
32GNU_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}')
33ALICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep alice | awk '{print $3}')
34GNUNET_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnunet | awk '{print $3}')
35SERVICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep service | awk '{print $3}')
36
37USER_ATTR="user"
38GNU_PROJECT_ATTR="project"
39MEMBER_ATTR="member"
40DEVELOPER_ATTR="developer"
41DEV_ATTR="developer"
42TEST_CREDENTIAL="mygnunetcreds"
43
44# (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU
45gnunet-namestore -p -z service -a -n $USER_ATTR -t ATTR -V "$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" -e 5m -c test_credential_lookup.conf
46
47# (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute
48gnunet-namestore -p -z gnu -a -n $GNU_PROJECT_ATTR -t ATTR -V "$GNUNET_KEY" -e 5m -c test_credential_lookup.conf
49
50# (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user"
51gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $DEVELOPER_ATTR" -e 5m -c test_credential_lookup.conf
52gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $USER_ATTR" -e 5m -c test_credential_lookup.conf
53
54# (5) GNUnet issues Alice the credential "developer"
55CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$DEV_ATTR --ttl=5m -c test_credential_lookup.conf`
56
57# Alice stores the credential under "mygnunetcreds"
58gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
59
60# (5) GNUnet issues Alice the credential "developer"
61CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$USER_ATTR --ttl=5m -c test_credential_lookup.conf`
62
63# Alice stores the credential under "mygnunetcreds"
64gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
65
66#TODO2 Add -z swich like in gnunet-gns
67#RES_CRED=`gnunet-credential --collect --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY -c test_credential_lookup.conf`
68
69gnunet-arm -i rest -c test_credential_lookup.conf
70
71sleep 5
72
73curl -v "localhost:7776/credential/collect?attribute=$SERVICE_KEY.$USER_ATTR&subject=alice"
74
75#TODO cleanup properly
76gnunet-namestore -z alice -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf
77gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_credential_lookup.conf
78gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_credential_lookup.conf
79gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_credential_lookup.conf
80echo "Stopping arm..."
81gnunet-arm -e -c test_credential_lookup.conf
82echo "Done"
83if [ "$RES_CRED" != "Failed." ]
84then
85 # TODO: replace echo -e bashism.
86 echo -e "${RES_CRED}"
87 exit 0
88else
89 echo "FAIL: Failed to verify credential $RES_CRED."
90 exit 1
91fi
diff --git a/src/abd/test_credential_issue_rest.sh b/src/abd/test_credential_issue_rest.sh
new file mode 100755
index 000000000..c518c08ec
--- /dev/null
+++ b/src/abd/test_credential_issue_rest.sh
@@ -0,0 +1,53 @@
1#!/bin/sh
2trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) PKEY1.user -> PKEY2.resu.user
19# (2) PKEY2.resu -> PKEY3
20# (3) PKEY3.user -> PKEY4
21
22
23which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
24
25TEST_ATTR="test"
26gnunet-arm -s -c test_credential_lookup.conf
27gnunet-arm -i gns
28gnunet-arm -i credential
29gnunet-arm -i identity
30gnunet-arm -i rest -c test_credential_lookup.conf
31
32gnunet-arm -I -c test_credential_lookup.conf
33gnunet-identity -C testissuer -c test_credential_lookup.conf
34gnunet-identity -C testsubject -c test_credential_lookup.conf
35gnunet-identity -s credential-issuer -e testissuer
36SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}')
37ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}')
38#TODO1 Get credential and store it with subject (3)
39sleep 5
40curl "localhost:7776/credential/issue?subject_key=$SUBJECT_KEY&attribute=$TEST_ATTR&expiration=1d"
41#CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf`
42STATUS=$?
43
44if test $? != 0
45then
46 echo "Error issuing..."
47 exit 1
48fi
49#Try import
50#$DO_TIMEOUT gnunet-namestore -a -z testsubject -n c1 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
51RES=$?
52gnunet-arm -e -c test_credential_lookup.conf
53exit $RES
diff --git a/src/abd/test_credential_verify_rest.sh b/src/abd/test_credential_verify_rest.sh
new file mode 100755
index 000000000..99db5da8a
--- /dev/null
+++ b/src/abd/test_credential_verify_rest.sh
@@ -0,0 +1,88 @@
1#!/usr/bin/env bash
2trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f`
17
18# (1) Service.user -> GNU.project.member
19# (2) GNU.project -> GNUnet
20# (3) GNUnet.member -> GNUnet.developer
21# (4) GNUnet.member -> GNUnet.user
22# (5) GNUnet.developer -> Alice
23
24
25which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30"
26gnunet-arm -s -c test_credential_lookup.conf
27gnunet-identity -C service -c test_credential_lookup.conf
28gnunet-identity -C alice -c test_credential_lookup.conf
29gnunet-identity -C gnu -c test_credential_lookup.conf
30gnunet-identity -C gnunet -c test_credential_lookup.conf
31
32GNU_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}')
33ALICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep alice | awk '{print $3}')
34GNUNET_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnunet | awk '{print $3}')
35SERVICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep service | awk '{print $3}')
36
37USER_ATTR="user"
38GNU_PROJECT_ATTR="project"
39MEMBER_ATTR="member"
40DEVELOPER_ATTR="developer"
41DEV_ATTR="developer"
42TEST_CREDENTIAL="mygnunetcreds"
43
44# (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU
45gnunet-namestore -p -z service -a -n $USER_ATTR -t ATTR -V "$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" -e 5m -c test_credential_lookup.conf
46
47# (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute
48gnunet-namestore -p -z gnu -a -n $GNU_PROJECT_ATTR -t ATTR -V "$GNUNET_KEY" -e 5m -c test_credential_lookup.conf
49
50# (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user"
51gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $DEVELOPER_ATTR" -e 5m -c test_credential_lookup.conf
52gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $USER_ATTR" -e 5m -c test_credential_lookup.conf
53
54# (5) GNUnet issues Alice the credential "developer"
55CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$DEV_ATTR --ttl=5m -c test_credential_lookup.conf`
56
57# Alice stores the credential under "mygnunetcreds"
58gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
59
60#TODO2 Add -z swich like in gnunet-gns
61#RES_CRED=`gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf`
62
63gnunet-arm -i rest -c test_credential_lookup.conf
64
65sleep 5
66
67CREDS=`curl "localhost:7776/credential/collect?attribute=$SERVICE_KEY.$USER_ATTR&subject=alice"`
68
69echo $CREDS
70
71curl -v "localhost:7776/credential/verify?attribute=$SERVICE_KEY.$USER_ATTR&subject_key=$ALICE_KEY" --data "$CREDS"
72
73#TODO cleanup properly
74gnunet-namestore -z alice -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf
75gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_credential_lookup.conf
76gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_credential_lookup.conf
77gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_credential_lookup.conf
78gnunet-arm -e -c test_credential_lookup.conf
79
80if [ "$RES_CRED" != "Failed." ]
81then
82 # TODO: replace echo -e bashism
83 echo -e "${RES_CRED}"
84 exit 0
85else
86 echo "FAIL: Failed to verify credential $RES_CRED."
87 exit 1
88fi