GNUnet  0.11.x
abd_api.c
Go to the documentation of this file.
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 */
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"
36 
37 
38 #define LOG(kind, ...) GNUNET_log_from (kind, "abd-api", __VA_ARGS__)
39 
44 {
45 
50 
55 
60 
65 
69  void *proc_cls;
70 
75 
79  void *proc2_cls;
80 
85 
89  uint32_t r_id;
90 };
91 
92 
97 {
98 
103 
108 
113 
118 
123 
127  struct GNUNET_TIME_Relative reconnect_backoff;
128 
132  uint32_t r_id_gen;
133 };
134 
135 
141 static void
143 
144 
150 static void
151 reconnect_task (void *cls)
152 {
153  struct GNUNET_ABD_Handle *handle = cls;
154 
155  handle->reconnect_task = NULL;
156  reconnect (handle);
157 }
158 
159 
165 static void
167 {
168  GNUNET_MQ_destroy (handle->mq);
169  handle->mq = NULL;
170  handle->reconnect_backoff =
172  handle->reconnect_task =
175  handle);
176 }
177 
178 
187 static void
188 mq_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 
202 static int
203 check_result (void *cls, const struct DelegationChainResultMessage *vr_msg)
204 {
205  // TODO
206  return GNUNET_OK;
207 }
208 
209 
216 static void
217 handle_result (void *cls, const struct DelegationChainResultMessage *vr_msg)
218 {
219  struct GNUNET_ABD_Handle *handle = cls;
220  uint32_t r_id = ntohl (vr_msg->id);
221  struct GNUNET_ABD_Request *vr;
222  size_t mlen = ntohs (vr_msg->header.size) - sizeof (*vr_msg);
223  uint32_t d_count = ntohl (vr_msg->d_count);
224  uint32_t c_count = ntohl (vr_msg->c_count);
225  struct GNUNET_ABD_Delegation d_chain[d_count];
226  struct GNUNET_ABD_Delegate dels[c_count];
228  void *proc_cls;
229 
231  "Received verify reply from ABD service\n");
232  for (vr = handle->request_head; NULL != vr; vr = vr->next)
233  if (vr->r_id == r_id)
234  break;
235  if (NULL == vr)
236  return;
237  proc = vr->verify_proc;
238  proc_cls = vr->proc_cls;
240  GNUNET_MQ_discard (vr->env);
241  GNUNET_free (vr);
242  GNUNET_assert (
243  GNUNET_OK ==
245  (const char *) &vr_msg[1],
246  d_count,
247  d_chain,
248  c_count,
249  dels));
250  if (GNUNET_NO == ntohl (vr_msg->del_found))
251  {
252  proc (proc_cls, 0, NULL, 0,
253  NULL);
254  }
255  else
256  {
257  proc (proc_cls, d_count, d_chain, c_count, dels);
258  }
259 }
260 
261 
262 static int
263 check_intermediate (void *cls, const struct
265 {
266  // TODO
267  return GNUNET_OK;
268 }
269 
270 
271 static void
272 handle_intermediate (void *cls, const struct
274 {
275  struct GNUNET_ABD_Handle *handle = cls;
276  uint32_t r_id = ntohl (vr_msg->id);
277  uint32_t size = ntohl (vr_msg->size);
278  bool is_bw = ntohs (vr_msg->is_bw);
279  struct GNUNET_ABD_Request *vr;
281  void *proc_cls;
282  struct GNUNET_ABD_Delegation *dd;
283 
284 
286  "Received intermediate reply from ABD service\n");
287 
288  for (vr = handle->request_head; NULL != vr; vr = vr->next)
289  if (vr->r_id == r_id)
290  break;
291  if (NULL == vr)
292  return;
293 
294  proc = vr->int_proc;
295  proc_cls = vr->proc2_cls;
296 
297  dd = GNUNET_new (struct GNUNET_ABD_Delegation);
298  GNUNET_assert (
299  GNUNET_OK ==
301  (const char *) &vr_msg[1],
302  1,
303  dd,
304  0,
305  NULL));
306  proc (proc_cls, dd, is_bw);
307 }
308 
309 
315 static void
317 {
318  struct GNUNET_MQ_MessageHandler handlers[] =
322  handle),
326  handle),
327  GNUNET_MQ_hd_var_size (intermediate,
330  handle),
332  struct GNUNET_ABD_Request *vr;
333 
334  GNUNET_assert (NULL == handle->mq);
335  LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to ABD\n");
336  handle->mq = GNUNET_CLIENT_connect (handle->cfg,
337  "abd",
338  handlers,
340  handle);
341  if (NULL == handle->mq)
342  return;
343  for (vr = handle->request_head; NULL != vr; vr = vr->next)
344  GNUNET_MQ_send_copy (handle->mq, vr->env);
345 }
346 
347 
354 struct GNUNET_ABD_Handle *
356 {
357  struct GNUNET_ABD_Handle *handle;
358 
359  handle = GNUNET_new (struct GNUNET_ABD_Handle);
360  handle->cfg = cfg;
361  reconnect (handle);
362  if (NULL == handle->mq)
363  {
364  GNUNET_free (handle);
365  return NULL;
366  }
367  return handle;
368 }
369 
370 
376 void
378 {
379  if (NULL != handle->mq)
380  {
381  GNUNET_MQ_destroy (handle->mq);
382  handle->mq = NULL;
383  }
384  if (NULL != handle->reconnect_task)
385  {
387  handle->reconnect_task = NULL;
388  }
389  GNUNET_assert (NULL == handle->request_head);
390  GNUNET_free (handle);
391 }
392 
393 
399 void
401 {
402  struct GNUNET_ABD_Handle *handle = lr->abd_handle;
403 
405  GNUNET_MQ_discard (lr->env);
406  GNUNET_free (lr);
407 }
408 
409 
423 struct GNUNET_ABD_Request *
425  struct GNUNET_ABD_Handle *handle,
427  const char *issuer_attribute,
428  const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key,
431  void *proc_cls,
433  void *proc2_cls)
434 {
435  /* IPC to shorten abd names, return shorten_handle */
436  struct CollectMessage *c_msg;
437  struct GNUNET_ABD_Request *vr;
438  size_t nlen;
439 
440  if (NULL == issuer_attribute)
441  {
442  GNUNET_break (0);
443  return NULL;
444  }
445 
446  // DEBUG LOG
448  "Trying to collect `%s' in ABD\n",
449  issuer_attribute);
450  nlen = strlen (issuer_attribute) + 1;
451  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
452  {
453  GNUNET_break (0);
454  return NULL;
455  }
456  vr = GNUNET_new (struct GNUNET_ABD_Request);
457  vr->abd_handle = handle;
458  vr->verify_proc = proc;
459  vr->proc_cls = proc_cls;
460  vr->int_proc = proc2;
461  vr->proc2_cls = proc2_cls;
462  vr->r_id = handle->r_id_gen++;
463  vr->env =
465  c_msg->id = htonl (vr->r_id);
466  c_msg->subject_key = *subject_key;
467  c_msg->issuer_key = *issuer_key;
468  c_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
469  c_msg->resolution_algo = htons (direction);
470 
471  GNUNET_memcpy (&c_msg[1], issuer_attribute, strlen (issuer_attribute));
473  if (NULL != handle->mq)
474  GNUNET_MQ_send_copy (handle->mq, vr->env);
475  return vr;
476 }
477 
478 
497 struct GNUNET_ABD_Request *
499  struct GNUNET_ABD_Handle *handle,
501  const char *issuer_attribute,
502  const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key,
503  uint32_t delegate_count,
504  const struct GNUNET_ABD_Delegate *delegates,
507  void *proc_cls,
509  void *proc2_cls)
510 {
511  /* IPC to shorten abd names, return shorten_handle */
512  struct VerifyMessage *v_msg;
513  struct GNUNET_ABD_Request *vr;
514  size_t nlen;
515  size_t clen;
516 
517  if ((NULL == issuer_attribute) || (NULL == delegates))
518  {
519  GNUNET_break (0);
520  return NULL;
521  }
522 
523  clen = GNUNET_ABD_delegates_get_size (delegate_count, delegates);
524 
525  // DEBUG LOG
527  "Trying to verify `%s' in ABD\n",
528  issuer_attribute);
529  nlen = strlen (issuer_attribute) + 1 + clen;
530  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
531  {
532  GNUNET_break (0);
533  return NULL;
534  }
535  vr = GNUNET_new (struct GNUNET_ABD_Request);
536  vr->abd_handle = handle;
537  vr->verify_proc = proc;
538  vr->proc_cls = proc_cls;
539  vr->int_proc = proc2;
540  vr->proc2_cls = proc2_cls;
541  vr->r_id = handle->r_id_gen++;
542  vr->env =
544  v_msg->id = htonl (vr->r_id);
545  v_msg->subject_key = *subject_key;
546  v_msg->d_count = htonl (delegate_count);
547  v_msg->issuer_key = *issuer_key;
548  v_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
549  v_msg->resolution_algo = htons (direction);
550 
551  GNUNET_memcpy (&v_msg[1], issuer_attribute, strlen (issuer_attribute));
552  GNUNET_ABD_delegates_serialize (delegate_count,
553  delegates,
554  clen,
555  ((char *) &v_msg[1])
556  + strlen (issuer_attribute) + 1);
558  if (NULL != handle->mq)
559  GNUNET_MQ_send_copy (handle->mq, vr->env);
560  return vr;
561 }
562 
563 
564 /* end of abd_api.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Message from client to Credential service to verify attributes.
Definition: abd.h:74
#define GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT
struct GNUNET_ABD_Handle * abd_handle
handle to abd service
Definition: abd_api.c:59
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:128
struct GNUNET_ABD_Handle * GNUNET_ABD_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the ABD service.
Definition: abd_api.c:355
IPC messages between ABD API and ABD service.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static struct GNUNET_GNS_LookupWithTldRequest * lr
Handle to lookup request.
Definition: gnunet-gns.c:99
struct GNUNET_ABD_Request * request_head
Head of linked list of active verify requests.
Definition: abd_api.c:112
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: abd.h:99
uint16_t resolution_algo
Direction of the resolution algo.
Definition: abd.h:104
GNUNET_MQ_Error
Error codes for the queue.
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:109
struct GNUNET_TIME_Relative reconnect_backoff
How long do we wait until we try to reconnect?
Definition: abd_api.c:127
Message from ABD service to client: new results.
Definition: abd.h:118
void(* GNUNET_ABD_IntermediateResultProcessor)(void *cls, struct GNUNET_ABD_Delegation *delegation, bool is_bw)
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:161
#define LOG(kind,...)
Definition: abd_api.c:38
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void * proc2_cls
verify_proc2 closure
Definition: abd_api.c:79
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT.
Definition: abd.h:123
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: abd.h:50
GNUNET_ABD_AlgoDirectionFlags
struct GNUNET_ABD_Request * GNUNET_ABD_collect(struct GNUNET_ABD_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, enum GNUNET_ABD_AlgoDirectionFlags direction, GNUNET_ABD_CredentialResultProcessor proc, void *proc_cls, GNUNET_ABD_IntermediateResultProcessor proc2, void *proc2_cls)
Performs attribute collection.
Definition: abd_api.c:424
Message from client to Credential service to collect credentials.
Definition: abd.h:35
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Subject public key.
Definition: abd.h:84
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: abd_api.c:102
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
GNUNET_ABD_IntermediateResultProcessor int_proc
processor to call on intermediate result
Definition: abd_api.c:74
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Handle to a verify request.
Definition: abd_api.c:43
Message from ABD service to client: new results.
Definition: abd.h:151
static void handle_result(void *cls, const struct DelegationChainResultMessage *vr_msg)
Handler for messages received from the ABD service.
Definition: abd_api.c:217
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void * proc_cls
verify_proc closure
Definition: abd_api.c:69
enum GNUNET_ABD_AlgoDirectionFlags direction
API enum, filled and passed for collect/verify.
Definition: gnunet-abd.c:172
void(* GNUNET_ABD_CredentialResultProcessor)(void *cls, unsigned int d_count, struct GNUNET_ABD_Delegation *delegation_chain, unsigned int c_count, struct GNUNET_ABD_Delegate *delegte)
Iterator called on obtained result for an attribute verification.
static void force_reconnect(struct GNUNET_ABD_Handle *handle)
Disconnect from service and then reconnect.
Definition: abd_api.c:166
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
ssize_t GNUNET_ABD_delegates_serialize(unsigned int c_count, const struct GNUNET_ABD_Delegate *cd, size_t dest_size, char *dest)
Serizalize the given abds.
struct GNUNET_MQ_Handle * mq
Connection to service (if available).
Definition: abd_api.c:107
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
Definition: abd_api.c:188
uint16_t resolution_algo
Direction of the resolution algo.
Definition: abd.h:60
GNUNET_ABD_CredentialResultProcessor verify_proc
processor to call on verify result
Definition: abd_api.c:64
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int result
Global testing status.
struct GNUNET_ABD_Request * next
DLL.
Definition: abd_api.c:49
int GNUNET_ABD_delegation_chain_deserialize(size_t len, const char *src, unsigned int d_count, struct GNUNET_ABD_Delegation *dd, unsigned int c_count, struct GNUNET_ABD_Delegate *cd)
Deserialize the given destination.
static void reconnect_task(void *cls)
Reconnect to ABD.
Definition: abd_api.c:151
Message handler for a specific message type.
static void reconnect(struct GNUNET_ABD_Handle *handle)
Reconnect to ABD service.
Definition: abd_api.c:316
static char * issuer_key
Issuer pubkey string.
Definition: gnunet-abd.c:112
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
static int check_intermediate(void *cls, const struct DelegationChainIntermediateMessage *vr_msg)
Definition: abd_api.c:263
#define GNUNET_MESSAGE_TYPE_ABD_VERIFY
Connection to the ABD service.
Definition: abd_api.c:96
static unsigned int size
Size of the "table".
Definition: peer.c:67
static int check_result(void *cls, const struct DelegationChainResultMessage *vr_msg)
Check validity of message received from the ABD service.
Definition: abd_api.c:203
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:65
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
#define GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
uint32_t d_count
Number of delegates.
Definition: abd.h:94
struct GNUNET_SCHEDULER_Task * reconnect_task
Reconnect task.
Definition: abd_api.c:122
struct GNUNET_CRYPTO_EcdsaPrivateKey subject_key
Subject public key.
Definition: abd.h:45
Handle to a message queue.
Definition: mq.c:85
void GNUNET_ABD_request_cancel(struct GNUNET_ABD_Request *lr)
Cancel pending verify request.
Definition: abd_api.c:400
configuration data
Definition: configuration.c:85
#define GNUNET_MESSAGE_TYPE_ABD_COLLECT
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
void GNUNET_MQ_send_copy(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MQ_Envelope *ev)
Send a copy of a message with the given message queue.
Definition: mq.c:432
Entry in list of pending tasks.
Definition: scheduler.c:134
struct GNUNET_ABD_Request * request_tail
Tail of linked list of active verify requests.
Definition: abd_api.c:117
size_t GNUNET_ABD_delegates_get_size(unsigned int c_count, const struct GNUNET_ABD_Delegate *cd)
Calculate how many bytes we will need to serialize the abds.
uint32_t r_id_gen
Request Id generator.
Definition: abd_api.c:132
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: abd.h:55
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
struct GNUNET_ABD_Request * prev
DLL.
Definition: abd_api.c:54
struct GNUNET_MQ_Envelope * env
Envelope with the message for this queue entry.
Definition: abd_api.c:84
void GNUNET_ABD_disconnect(struct GNUNET_ABD_Handle *handle)
Shutdown connection with the ABD service.
Definition: abd_api.c:377
static void handle_intermediate(void *cls, const struct DelegationChainIntermediateMessage *vr_msg)
Definition: abd_api.c:272
#define GNUNET_MESSAGE_TYPE_ABD_COLLECT_RESULT
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: abd.h:89
struct GNUNET_ABD_Request * GNUNET_ABD_verify(struct GNUNET_ABD_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, uint32_t delegate_count, const struct GNUNET_ABD_Delegate *delegates, enum GNUNET_ABD_AlgoDirectionFlags direction, GNUNET_ABD_CredentialResultProcessor proc, void *proc_cls, GNUNET_ABD_IntermediateResultProcessor proc2, void *proc2_cls)
Performs attribute verification.
Definition: abd_api.c:498
API to serialize and deserialize delegation chains and abds.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
uint32_t d_count
The number of delegations in the response.
Definition: abd.h:138
uint32_t c_count
The number of credentials in the response.
Definition: abd.h:143
uint32_t r_id
request id
Definition: abd_api.c:89
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966