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 {
45 
50 
55 
60 
65 
69  void *proc_cls;
70 
75 
79  uint32_t r_id;
80 
81 };
82 
83 
88 {
89 
94 
99 
104 
109 
114 
118  struct GNUNET_TIME_Relative reconnect_backoff;
119 
123  uint32_t r_id_gen;
124 
125 };
126 
127 
133 static void
135 
136 
142 static void
143 reconnect_task (void *cls)
144 {
145  struct GNUNET_CREDENTIAL_Handle *handle = cls;
146 
147  handle->reconnect_task = NULL;
148  reconnect (handle);
149 }
150 
151 
157 static void
159 {
160  GNUNET_MQ_destroy (handle->mq);
161  handle->mq = NULL;
162  handle->reconnect_backoff
164  handle->reconnect_task
167  handle);
168 }
169 
170 
179 static void
180 mq_error_handler (void *cls,
181  enum GNUNET_MQ_Error error)
182 {
183  struct GNUNET_CREDENTIAL_Handle *handle = cls;
184 
185  force_reconnect (handle);
186 }
187 
194 static int
195 check_result (void *cls,
196  const struct DelegationChainResultMessage *vr_msg)
197 {
198  //TODO
199  return GNUNET_OK;
200 }
201 
202 
209 static void
210 handle_result (void *cls,
211  const struct DelegationChainResultMessage *vr_msg)
212 {
213  struct GNUNET_CREDENTIAL_Handle *handle = cls;
214  uint32_t r_id = ntohl (vr_msg->id);
215  struct GNUNET_CREDENTIAL_Request *vr;
216  size_t mlen = ntohs (vr_msg->header.size) - sizeof (*vr_msg);
217  uint32_t d_count = ntohl (vr_msg->d_count);
218  uint32_t c_count = ntohl (vr_msg->c_count);
219  struct GNUNET_CREDENTIAL_Delegation d_chain[d_count];
220  struct GNUNET_CREDENTIAL_Credential creds[c_count];
222  void *proc_cls;
223 
225  "Received verify reply from CREDENTIAL service\n");
226  for (vr = handle->request_head; NULL != vr; vr = vr->next)
227  if (vr->r_id == r_id)
228  break;
229  if (NULL == vr)
230  return;
231  proc = vr->verify_proc;
232  proc_cls = vr->proc_cls;
234  handle->request_tail,
235  vr);
236  GNUNET_MQ_discard (vr->env);
237  GNUNET_free (vr);
240  (const char*) &vr_msg[1],
241  d_count,
242  d_chain,
243  c_count,
244  creds));
245  if (GNUNET_NO == ntohl (vr_msg->cred_found))
246  {
247  proc (proc_cls,
248  0,
249  NULL,
250  0,
251  NULL); // TODO
252  } else {
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 
379  const char *issuer_attribute,
382  void *proc_cls)
383 {
384  /* IPC to shorten credential names, return shorten_handle */
385  struct CollectMessage *c_msg;
386  struct GNUNET_CREDENTIAL_Request *vr;
387  size_t nlen;
388 
389  if (NULL == issuer_attribute)
390  {
391  GNUNET_break (0);
392  return NULL;
393  }
394 
395  //DEBUG LOG
397  "Trying to collect `%s' in CREDENTIAL\n",
398  issuer_attribute);
399  nlen = strlen (issuer_attribute) + 1;
400  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
401  {
402  GNUNET_break (0);
403  return NULL;
404  }
407  vr->verify_proc = proc;
408  vr->proc_cls = proc_cls;
409  vr->r_id = handle->r_id_gen++;
410  vr->env = GNUNET_MQ_msg_extra (c_msg,
411  nlen,
413  c_msg->id = htonl (vr->r_id);
414  c_msg->subject_key = *subject_key;
415  c_msg->issuer_key = *issuer_key;
416  c_msg->issuer_attribute_len = htons(strlen(issuer_attribute));
417  GNUNET_memcpy (&c_msg[1],
418  issuer_attribute,
419  strlen (issuer_attribute));
421  handle->request_tail,
422  vr);
423  if (NULL != handle->mq)
424  GNUNET_MQ_send_copy (handle->mq,
425  vr->env);
426  return vr;
427 }
449  const char *issuer_attribute,
451  uint32_t credential_count,
452  const struct GNUNET_CREDENTIAL_Credential *credentials,
454  void *proc_cls)
455 {
456  /* IPC to shorten credential names, return shorten_handle */
457  struct VerifyMessage *v_msg;
458  struct GNUNET_CREDENTIAL_Request *vr;
459  size_t nlen;
460  size_t clen;
461 
462  if (NULL == issuer_attribute || NULL == credentials)
463  {
464  GNUNET_break (0);
465  return NULL;
466  }
467 
468  clen = GNUNET_CREDENTIAL_credentials_get_size (credential_count,
469  credentials);
470 
471  //DEBUG LOG
473  "Trying to verify `%s' in CREDENTIAL\n",
474  issuer_attribute);
475  nlen = strlen (issuer_attribute) + 1 + clen;
476  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr))
477  {
478  GNUNET_break (0);
479  return NULL;
480  }
483  vr->verify_proc = proc;
484  vr->proc_cls = proc_cls;
485  vr->r_id = handle->r_id_gen++;
486  vr->env = GNUNET_MQ_msg_extra (v_msg,
487  nlen,
489  v_msg->id = htonl (vr->r_id);
490  v_msg->subject_key = *subject_key;
491  v_msg->c_count = htonl(credential_count);
492  v_msg->issuer_key = *issuer_key;
493  v_msg->issuer_attribute_len = htons(strlen(issuer_attribute));
494  GNUNET_memcpy (&v_msg[1],
495  issuer_attribute,
496  strlen (issuer_attribute));
497  GNUNET_CREDENTIAL_credentials_serialize (credential_count,
498  credentials,
499  clen,
500  ((char*)&v_msg[1])
501  + strlen (issuer_attribute) + 1);
503  handle->request_tail,
504  vr);
505  if (NULL != handle->mq)
506  GNUNET_MQ_send_copy (handle->mq,
507  vr->env);
508  return vr;
509 }
510 
511 /* 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:70
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:120
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:901
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: credential.h:95
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:100
struct GNUNET_CREDENTIAL_Request * next
DLL.
Message from CREDENTIAL service to client: new results.
Definition: credential.h:110
#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:115
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_NO
Definition: gnunet_common.h:81
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Subject public key.
Definition: credential.h:80
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:1246
#define GNUNET_memcpy(dst, src, n)
#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:104
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:90
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:85
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:130
uint32_t c_count
The number of credentials in the response.
Definition: credential.h:135
#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:965