GNUnet  0.10.x
credential_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 "credential.h"
36 
37 
38 #define LOG(kind, ...) GNUNET_log_from (kind, "credential-api", __VA_ARGS__)
39 
44 {
49 
54 
59 
64 
68  void *proc_cls;
69 
74 
78  uint32_t r_id;
79 };
80 
81 
86 {
91 
96 
101 
106 
111 
115  struct GNUNET_TIME_Relative reconnect_backoff;
116 
120  uint32_t r_id_gen;
121 };
122 
123 
129 static void
131 
132 
138 static void
139 reconnect_task (void *cls)
140 {
141  struct GNUNET_CREDENTIAL_Handle *handle = cls;
142 
143  handle->reconnect_task = NULL;
144  reconnect (handle);
145 }
146 
147 
153 static void
155 {
156  GNUNET_MQ_destroy (handle->mq);
157  handle->mq = NULL;
158  handle->reconnect_backoff
160  handle->reconnect_task
163  handle);
164 }
165 
166 
175 static void
176 mq_error_handler (void *cls,
177  enum GNUNET_MQ_Error error)
178 {
179  struct GNUNET_CREDENTIAL_Handle *handle = cls;
180 
181  force_reconnect (handle);
182 }
183 
190 static int
191 check_result (void *cls,
192  const struct DelegationChainResultMessage *vr_msg)
193 {
194  // TODO
195  return GNUNET_OK;
196 }
197 
198 
205 static void
206 handle_result (void *cls,
207  const struct DelegationChainResultMessage *vr_msg)
208 {
209  struct GNUNET_CREDENTIAL_Handle *handle = cls;
210  uint32_t r_id = ntohl (vr_msg->id);
211  struct GNUNET_CREDENTIAL_Request *vr;
212  size_t mlen = ntohs (vr_msg->header.size) - sizeof(*vr_msg);
213  uint32_t d_count = ntohl (vr_msg->d_count);
214  uint32_t c_count = ntohl (vr_msg->c_count);
215  struct GNUNET_CREDENTIAL_Delegation d_chain[d_count];
216  struct GNUNET_CREDENTIAL_Credential creds[c_count];
218  void *proc_cls;
219 
221  "Received verify reply from CREDENTIAL service\n");
222  for (vr = handle->request_head; NULL != vr; vr = vr->next)
223  if (vr->r_id == r_id)
224  break;
225  if (NULL == vr)
226  return;
227  proc = vr->verify_proc;
228  proc_cls = vr->proc_cls;
230  handle->request_tail,
231  vr);
232  GNUNET_MQ_discard (vr->env);
233  GNUNET_free (vr);
236  (const
237  char*) &vr_msg
238  [1],
239  d_count,
240  d_chain,
241  c_count,
242  creds));
243  if (GNUNET_NO == ntohl (vr_msg->cred_found))
244  {
245  proc (proc_cls,
246  0,
247  NULL,
248  0,
249  NULL); // TODO
250  }
251  else
252  {
253  proc (proc_cls,
254  d_count,
255  d_chain,
256  c_count,
257  creds);
258  }
259 }
260 
261 
267 static void
269 {
270  struct GNUNET_MQ_MessageHandler handlers[] = {
274  handle),
278  handle),
280  };
281  struct GNUNET_CREDENTIAL_Request *vr;
282 
283  GNUNET_assert (NULL == handle->mq);
285  "Trying to connect to CREDENTIAL\n");
286  handle->mq = GNUNET_CLIENT_connect (handle->cfg,
287  "credential",
288  handlers,
290  handle);
291  if (NULL == handle->mq)
292  return;
293  for (vr = handle->request_head; NULL != vr; vr = vr->next)
294  GNUNET_MQ_send_copy (handle->mq,
295  vr->env);
296 }
297 
298 
307 {
309 
310  handle = GNUNET_new (struct GNUNET_CREDENTIAL_Handle);
311  handle->cfg = cfg;
312  reconnect (handle);
313  if (NULL == handle->mq)
314  {
315  GNUNET_free (handle);
316  return NULL;
317  }
318  return handle;
319 }
320 
321 
327 void
329 {
330  if (NULL != handle->mq)
331  {
332  GNUNET_MQ_destroy (handle->mq);
333  handle->mq = NULL;
334  }
335  if (NULL != handle->reconnect_task)
336  {
338  handle->reconnect_task = NULL;
339  }
340  GNUNET_assert (NULL == handle->request_head);
341  GNUNET_free (handle);
342 }
343 
344 
350 void
352 {
354 
356  handle->request_tail,
357  lr);
358  GNUNET_MQ_discard (lr->env);
359  GNUNET_free (lr);
360 }
361 
362 
378  const struct
380  const char *issuer_attribute,
381  const struct
384  void *proc_cls)
385 {
386  /* IPC to shorten credential names, return shorten_handle */
387  struct CollectMessage *c_msg;
388  struct GNUNET_CREDENTIAL_Request *vr;
389  size_t nlen;
390 
391  if (NULL == issuer_attribute)
392  {
393  GNUNET_break (0);
394  return NULL;
395  }
396 
397  // DEBUG LOG
399  "Trying to collect `%s' in CREDENTIAL\n",
400  issuer_attribute);
401  nlen = strlen (issuer_attribute) + 1;
402  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(*vr))
403  {
404  GNUNET_break (0);
405  return NULL;
406  }
409  vr->verify_proc = proc;
410  vr->proc_cls = proc_cls;
411  vr->r_id = handle->r_id_gen++;
412  vr->env = GNUNET_MQ_msg_extra (c_msg,
413  nlen,
415  c_msg->id = htonl (vr->r_id);
416  c_msg->subject_key = *subject_key;
417  c_msg->issuer_key = *issuer_key;
418  c_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
419  GNUNET_memcpy (&c_msg[1],
420  issuer_attribute,
421  strlen (issuer_attribute));
423  handle->request_tail,
424  vr);
425  if (NULL != handle->mq)
426  GNUNET_MQ_send_copy (handle->mq,
427  vr->env);
428  return vr;
429 }
451  const char *issuer_attribute,
452  const struct
454  uint32_t credential_count,
455  const struct
456  GNUNET_CREDENTIAL_Credential *credentials,
458  void *proc_cls)
459 {
460  /* IPC to shorten credential names, return shorten_handle */
461  struct VerifyMessage *v_msg;
462  struct GNUNET_CREDENTIAL_Request *vr;
463  size_t nlen;
464  size_t clen;
465 
466  if ((NULL == issuer_attribute)||(NULL == credentials))
467  {
468  GNUNET_break (0);
469  return NULL;
470  }
471 
472  clen = GNUNET_CREDENTIAL_credentials_get_size (credential_count,
473  credentials);
474 
475  // DEBUG LOG
477  "Trying to verify `%s' in CREDENTIAL\n",
478  issuer_attribute);
479  nlen = strlen (issuer_attribute) + 1 + clen;
480  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(*vr))
481  {
482  GNUNET_break (0);
483  return NULL;
484  }
487  vr->verify_proc = proc;
488  vr->proc_cls = proc_cls;
489  vr->r_id = handle->r_id_gen++;
490  vr->env = GNUNET_MQ_msg_extra (v_msg,
491  nlen,
493  v_msg->id = htonl (vr->r_id);
494  v_msg->subject_key = *subject_key;
495  v_msg->c_count = htonl (credential_count);
496  v_msg->issuer_key = *issuer_key;
497  v_msg->issuer_attribute_len = htons (strlen (issuer_attribute));
498  GNUNET_memcpy (&v_msg[1],
499  issuer_attribute,
500  strlen (issuer_attribute));
501  GNUNET_CREDENTIAL_credentials_serialize (credential_count,
502  credentials,
503  clen,
504  ((char*) &v_msg[1])
505  + strlen (issuer_attribute) + 1);
507  handle->request_tail,
508  vr);
509  if (NULL != handle->mq)
510  GNUNET_MQ_send_copy (handle->mq,
511  vr->env);
512  return vr;
513 }
514 
515 /* end of credential_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: credential.h:69
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:118
void(* GNUNET_CREDENTIAL_CredentialResultProcessor)(void *cls, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *delegation_chain, unsigned int c_count, struct GNUNET_CREDENTIAL_Credential *credential)
Iterator called on obtained result for an attribute verification.
struct GNUNET_CREDENTIAL_Request * request_head
Head of linked list of active verify requests.
void GNUNET_CREDENTIAL_request_cancel(struct GNUNET_CREDENTIAL_Request *lr)
Cancel pending verify request.
#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:75
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:1058
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: credential.h:94
struct GNUNET_SCHEDULER_Task * reconnect_task
Reconnect task.
GNUNET_MQ_Error
Error codes for the queue.
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:99
struct GNUNET_CREDENTIAL_Request * next
DLL.
Message from CREDENTIAL service to client: new results.
Definition: credential.h:108
#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT
static char * subject_key
Subject pubkey string.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT.
Definition: credential.h:113
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: credential.h:50
API to serialize and deserialize delegation chains and credentials.
IPC messages between CREDENTIAL API and CREDENTIAL service.
#define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT
Message from client to Credential service to collect credentials.
Definition: credential.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: credential.h:79
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint32_t r_id
request id
static void force_reconnect(struct GNUNET_CREDENTIAL_Handle *handle)
Disconnect from service and then reconnect.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT_RESULT
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define LOG(kind,...)
void GNUNET_CREDENTIAL_disconnect(struct GNUNET_CREDENTIAL_Handle *handle)
Shutdown connection with the CREDENTIAL service.
ssize_t GNUNET_CREDENTIAL_credentials_serialize(unsigned int c_count, const struct GNUNET_CREDENTIAL_Credential *cd, size_t dest_size, char *dest)
Serizalize the given credentials.
#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
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static void handle_result(void *cls, const struct DelegationChainResultMessage *vr_msg)
Handler for messages received from the CREDENTIAL service.
struct GNUNET_CREDENTIAL_Handle * GNUNET_CREDENTIAL_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the CREDENTIAL service.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int result
Global testing status.
struct GNUNET_MQ_Handle * mq
Connection to service (if available).
Connection to the CREDENTIAL service.
Message handler for a specific message type.
struct GNUNET_CREDENTIAL_Request * GNUNET_CREDENTIAL_collect(struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls)
Performs attribute collection.
uint32_t r_id_gen
Request Id generator.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
Handle to a verify request.
static void reconnect_task(void *cls)
Reconnect to CREDENTIAL.
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:60
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static char * issuer_key
Issuer pubkey string.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
int GNUNET_CREDENTIAL_delegation_chain_deserialize(size_t len, const char *src, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *dd, unsigned int c_count, struct GNUNET_CREDENTIAL_Credential *cd)
Deserialize the given destination.
struct GNUNET_CRYPTO_EcdsaPrivateKey subject_key
Subject public key.
Definition: credential.h:45
Handle to a message queue.
Definition: mq.c:85
uint32_t c_count
Number of credentials.
Definition: credential.h:89
size_t GNUNET_CREDENTIAL_credentials_get_size(unsigned int c_count, const struct GNUNET_CREDENTIAL_Credential *cd)
Calculate how many bytes we will need to serialize the credentials.
configuration data
Definition: configuration.c:85
static void reconnect(struct GNUNET_CREDENTIAL_Handle *handle)
Reconnect to CREDENTIAL service.
#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY
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
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...
GNUNET_CREDENTIAL_CredentialResultProcessor verify_proc
processor to call on verify result
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: credential.h:55
struct GNUNET_TIME_Relative reconnect_backoff
How long do we wait until we try to reconnect?
void * proc_cls
verify_proc closure
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
struct GNUNET_MQ_Envelope * env
Envelope with the message for this queue entry.
struct GNUNET_CREDENTIAL_Request * request_tail
Tail of linked list of active verify requests.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: credential.h:84
struct GNUNET_CREDENTIAL_Request * GNUNET_CREDENTIAL_verify(struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, uint32_t credential_count, const struct GNUNET_CREDENTIAL_Credential *credentials, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls)
Performs attribute verification.
struct GNUNET_CREDENTIAL_Handle * credential_handle
handle to credential service
struct GNUNET_CREDENTIAL_Request * prev
DLL.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static int check_result(void *cls, const struct DelegationChainResultMessage *vr_msg)
Check validity of message received from the CREDENTIAL service.
uint32_t d_count
The number of delegations in the response.
Definition: credential.h:128
uint32_t c_count
The number of credentials in the response.
Definition: credential.h:133
#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