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 
48 
53 
58 
63 
67  void *proc_cls;
68 
73 
77  uint32_t r_id;
78 };
79 
80 
89 
94 
99 
104 
109 
113  struct GNUNET_TIME_Relative reconnect_backoff;
114 
118  uint32_t r_id_gen;
119 };
120 
121 
127 static void
129 
130 
136 static void
137 reconnect_task(void *cls)
138 {
139  struct GNUNET_CREDENTIAL_Handle *handle = cls;
140 
141  handle->reconnect_task = NULL;
142  reconnect(handle);
143 }
144 
145 
151 static void
153 {
154  GNUNET_MQ_destroy(handle->mq);
155  handle->mq = NULL;
156  handle->reconnect_backoff
158  handle->reconnect_task
161  handle);
162 }
163 
164 
173 static void
175  enum GNUNET_MQ_Error error)
176 {
177  struct GNUNET_CREDENTIAL_Handle *handle = cls;
178 
179  force_reconnect(handle);
180 }
181 
188 static int
189 check_result(void *cls,
190  const struct DelegationChainResultMessage *vr_msg)
191 {
192  //TODO
193  return GNUNET_OK;
194 }
195 
196 
203 static void
204 handle_result(void *cls,
205  const struct DelegationChainResultMessage *vr_msg)
206 {
207  struct GNUNET_CREDENTIAL_Handle *handle = cls;
208  uint32_t r_id = ntohl(vr_msg->id);
209  struct GNUNET_CREDENTIAL_Request *vr;
210  size_t mlen = ntohs(vr_msg->header.size) - sizeof(*vr_msg);
211  uint32_t d_count = ntohl(vr_msg->d_count);
212  uint32_t c_count = ntohl(vr_msg->c_count);
213  struct GNUNET_CREDENTIAL_Delegation d_chain[d_count];
214  struct GNUNET_CREDENTIAL_Credential creds[c_count];
216  void *proc_cls;
217 
219  "Received verify reply from CREDENTIAL service\n");
220  for (vr = handle->request_head; NULL != vr; vr = vr->next)
221  if (vr->r_id == r_id)
222  break;
223  if (NULL == vr)
224  return;
225  proc = vr->verify_proc;
226  proc_cls = vr->proc_cls;
228  handle->request_tail,
229  vr);
230  GNUNET_MQ_discard(vr->env);
231  GNUNET_free(vr);
234  (const char*)&vr_msg[1],
235  d_count,
236  d_chain,
237  c_count,
238  creds));
239  if (GNUNET_NO == ntohl(vr_msg->cred_found))
240  {
241  proc(proc_cls,
242  0,
243  NULL,
244  0,
245  NULL); // TODO
246  }
247  else
248  {
249  proc(proc_cls,
250  d_count,
251  d_chain,
252  c_count,
253  creds);
254  }
255 }
256 
257 
263 static void
265 {
266  struct GNUNET_MQ_MessageHandler handlers[] = {
270  handle),
274  handle),
276  };
277  struct GNUNET_CREDENTIAL_Request *vr;
278 
279  GNUNET_assert(NULL == handle->mq);
281  "Trying to connect to CREDENTIAL\n");
282  handle->mq = GNUNET_CLIENT_connect(handle->cfg,
283  "credential",
284  handlers,
286  handle);
287  if (NULL == handle->mq)
288  return;
289  for (vr = handle->request_head; NULL != vr; vr = vr->next)
290  GNUNET_MQ_send_copy(handle->mq,
291  vr->env);
292 }
293 
294 
303 {
305 
306  handle = GNUNET_new(struct GNUNET_CREDENTIAL_Handle);
307  handle->cfg = cfg;
308  reconnect(handle);
309  if (NULL == handle->mq)
310  {
311  GNUNET_free(handle);
312  return NULL;
313  }
314  return handle;
315 }
316 
317 
323 void
325 {
326  if (NULL != handle->mq)
327  {
328  GNUNET_MQ_destroy(handle->mq);
329  handle->mq = NULL;
330  }
331  if (NULL != handle->reconnect_task)
332  {
334  handle->reconnect_task = NULL;
335  }
336  GNUNET_assert(NULL == handle->request_head);
337  GNUNET_free(handle);
338 }
339 
340 
346 void
348 {
350 
352  handle->request_tail,
353  lr);
354  GNUNET_MQ_discard(lr->env);
355  GNUNET_free(lr);
356 }
357 
358 
375  const char *issuer_attribute,
378  void *proc_cls)
379 {
380  /* IPC to shorten credential names, return shorten_handle */
381  struct CollectMessage *c_msg;
382  struct GNUNET_CREDENTIAL_Request *vr;
383  size_t nlen;
384 
385  if (NULL == issuer_attribute)
386  {
387  GNUNET_break(0);
388  return NULL;
389  }
390 
391  //DEBUG LOG
393  "Trying to collect `%s' in CREDENTIAL\n",
394  issuer_attribute);
395  nlen = strlen(issuer_attribute) + 1;
396  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(*vr))
397  {
398  GNUNET_break(0);
399  return NULL;
400  }
403  vr->verify_proc = proc;
404  vr->proc_cls = proc_cls;
405  vr->r_id = handle->r_id_gen++;
406  vr->env = GNUNET_MQ_msg_extra(c_msg,
407  nlen,
409  c_msg->id = htonl(vr->r_id);
410  c_msg->subject_key = *subject_key;
411  c_msg->issuer_key = *issuer_key;
412  c_msg->issuer_attribute_len = htons(strlen(issuer_attribute));
413  GNUNET_memcpy(&c_msg[1],
414  issuer_attribute,
415  strlen(issuer_attribute));
417  handle->request_tail,
418  vr);
419  if (NULL != handle->mq)
420  GNUNET_MQ_send_copy(handle->mq,
421  vr->env);
422  return vr;
423 }
445  const char *issuer_attribute,
447  uint32_t credential_count,
448  const struct GNUNET_CREDENTIAL_Credential *credentials,
450  void *proc_cls)
451 {
452  /* IPC to shorten credential names, return shorten_handle */
453  struct VerifyMessage *v_msg;
454  struct GNUNET_CREDENTIAL_Request *vr;
455  size_t nlen;
456  size_t clen;
457 
458  if (NULL == issuer_attribute || NULL == credentials)
459  {
460  GNUNET_break(0);
461  return NULL;
462  }
463 
464  clen = GNUNET_CREDENTIAL_credentials_get_size(credential_count,
465  credentials);
466 
467  //DEBUG LOG
469  "Trying to verify `%s' in CREDENTIAL\n",
470  issuer_attribute);
471  nlen = strlen(issuer_attribute) + 1 + clen;
472  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(*vr))
473  {
474  GNUNET_break(0);
475  return NULL;
476  }
479  vr->verify_proc = proc;
480  vr->proc_cls = proc_cls;
481  vr->r_id = handle->r_id_gen++;
482  vr->env = GNUNET_MQ_msg_extra(v_msg,
483  nlen,
485  v_msg->id = htonl(vr->r_id);
486  v_msg->subject_key = *subject_key;
487  v_msg->c_count = htonl(credential_count);
488  v_msg->issuer_key = *issuer_key;
489  v_msg->issuer_attribute_len = htons(strlen(issuer_attribute));
490  GNUNET_memcpy(&v_msg[1],
491  issuer_attribute,
492  strlen(issuer_attribute));
494  credentials,
495  clen,
496  ((char*)&v_msg[1])
497  + strlen(issuer_attribute) + 1);
499  handle->request_tail,
500  vr);
501  if (NULL != handle->mq)
502  GNUNET_MQ_send_copy(handle->mq,
503  vr->env);
504  return vr;
505 }
506 
507 /* 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:68
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:115
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:900
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: credential.h:92
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:97
struct GNUNET_CREDENTIAL_Request * next
DLL.
Message from CREDENTIAL service to client: new results.
Definition: credential.h:106
#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:110
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: credential.h:49
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:77
#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:1237
#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:319
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:59
#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:44
Handle to a message queue.
Definition: mq.c:84
uint32_t c_count
Number of credentials.
Definition: credential.h:87
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:83
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:430
Entry in list of pending tasks.
Definition: scheduler.c:131
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:54
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:821
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:82
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:125
uint32_t c_count
The number of credentials in the response.
Definition: credential.h:130
#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:956