GNUnet  0.20.0
plugin_reclaim_credential_pabc.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2013, 2014, 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 
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_reclaim_plugin.h"
31 #include <inttypes.h>
32 #include <jansson.h>
33 #include <pabc/pabc.h>
34 #include "pabc_helper.h"
35 
45 static char *
47  uint32_t type,
48  const void *data,
49  size_t data_size)
50 {
51  switch (type)
52  {
54  return GNUNET_strndup (data, data_size);
55 
56  default:
57  return NULL;
58  }
59 }
60 
61 
73 static int
75  uint32_t type,
76  const char *s,
77  void **data,
78  size_t *data_size)
79 {
80  if (NULL == s)
81  return GNUNET_SYSERR;
82  switch (type)
83  {
85  *data = GNUNET_strdup (s);
86  *data_size = strlen (s) + 1;
87  return GNUNET_OK;
88 
89  default:
90  return GNUNET_SYSERR;
91  }
92 }
93 
94 
99 static struct
100 {
101  const char *name;
102  uint32_t number;
104  { NULL, UINT32_MAX } };
105 
113 static uint32_t
114 pabc_typename_to_number (void *cls, const char *pabc_typename)
115 {
116  unsigned int i;
117 
118  i = 0;
119  while ((NULL != pabc_cred_name_map[i].name) &&
120  (0 != strcasecmp (pabc_typename, pabc_cred_name_map[i].name)))
121  i++;
122  return pabc_cred_name_map[i].number;
123 }
124 
125 
133 static const char *
134 pabc_number_to_typename (void *cls, uint32_t type)
135 {
136  unsigned int i;
137 
138  i = 0;
139  while ((NULL != pabc_cred_name_map[i].name) && (type !=
141  number))
142  i++;
143  return pabc_cred_name_map[i].name;
144 }
145 
146 
147 static void
148 inspect_attrs (char const *const key,
149  char const *const value,
150  void *ctx)
151 {
152  struct GNUNET_RECLAIM_AttributeList *attrs = ctx;
153 
154  if (NULL == value)
155  return;
157  "Found attribute in PABC credential: `%s': `%s'\n",
158  key, value);
159  if (0 == strcmp (key, "expiration"))
160  return;
161  if (0 == strcmp (key, "issuer"))
162  return;
163  if (0 == strcmp (key, "subject"))
164  return;
166  key,
167  NULL,
169  value,
170  strlen (value));
171 }
172 
173 
183  const char *data,
184  size_t data_size)
185 {
186  struct GNUNET_RECLAIM_AttributeList *attrs;
187 
189  "Collecting PABC attributes...\n");
190  attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
191  GNUNET_assert (PABC_OK ==
192  pabc_cred_inspect_credential (data,
193  &inspect_attrs, attrs));
194  return attrs;
195 }
196 
197 
207  const struct GNUNET_RECLAIM_Credential *cred)
208 {
210  return NULL;
211  return pabc_parse_attributes (cls, cred->data, cred->data_size);
212 }
213 
214 
224  const struct GNUNET_RECLAIM_Presentation *cred)
225 {
227  return NULL;
228  return pabc_parse_attributes (cls, cred->data, cred->data_size);
229 }
230 
231 
239 char*
240 pabc_get_issuer (void *cls,
241  const char *data,
242  size_t data_size)
243 {
244  char *res;
245  if (PABC_OK != pabc_cred_get_attr_by_name_from_cred (data,
246  "issuer",
247  &res))
248  return NULL;
249  return res;
250 }
251 
252 
260 char *
261 pabc_get_issuer_c (void *cls,
262  const struct GNUNET_RECLAIM_Credential *cred)
263 {
265  return NULL;
266  return pabc_get_issuer (cls, cred->data, cred->data_size);
267 }
268 
269 
277 char *
278 pabc_get_issuer_p (void *cls,
279  const struct GNUNET_RECLAIM_Presentation *cred)
280 {
282  return NULL;
283  return pabc_get_issuer (cls, cred->data, cred->data_size);
284 }
285 
286 
295 pabc_get_expiration (void *cls,
296  const char *data,
297  size_t data_size,
298  struct GNUNET_TIME_Absolute *exp)
299 {
300  char *exp_str;
301  uint64_t exp_i;
302 
303  if (PABC_OK != pabc_cred_get_attr_by_name_from_cred (data,
304  "expiration",
305  &exp_str))
306  return GNUNET_SYSERR;
307 
308  if (1 != sscanf (exp_str, "%llu", &exp_i))
309  {
311  "Invalid expiration `%s'\n", exp_str);
312  GNUNET_free (exp_str);
313  return GNUNET_SYSERR;
314  }
316  "Converted expiration string `%s' to %llu",
317  exp_str, exp_i);
318 
319  GNUNET_free (exp_str);
320  exp->abs_value_us = exp_i * 1000 * 1000;
321  return GNUNET_OK;
322 }
323 
324 
333 pabc_get_expiration_c (void *cls,
334  const struct GNUNET_RECLAIM_Credential *cred,
335  struct GNUNET_TIME_Absolute *exp)
336 {
338  return GNUNET_NO;
339  return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
340 }
341 
342 
351 pabc_get_expiration_p (void *cls,
352  const struct GNUNET_RECLAIM_Presentation *cred,
353  struct GNUNET_TIME_Absolute *exp)
354 {
356  return GNUNET_NO;
357  return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
358 }
359 
360 
361 int
364  const struct GNUNET_RECLAIM_AttributeList *attrs,
365  struct GNUNET_RECLAIM_Presentation **presentation)
366 {
367  struct pabc_context *ctx = NULL;
368  struct pabc_user_context *usr_ctx = NULL;
369  struct pabc_public_parameters *pp = NULL;
370  struct pabc_credential *cred = NULL;
371  struct pabc_blinded_proof *proof = NULL;
373  char *issuer;
374  char *subject;
375  enum pabc_status status;
376 
378  return GNUNET_NO;
379 
380 
381  PABC_ASSERT (pabc_new_ctx (&ctx));
382  issuer = pabc_get_issuer_c (cls, credential);
383  if (NULL == issuer)
384  {
386  "No issuer found in credential\n");
387  pabc_free_ctx (&ctx);
388  return GNUNET_SYSERR;
389  }
391  "Got issuer for credential: %s\n", issuer);
392  status = PABC_load_public_parameters (ctx, issuer, &pp);
393  if (status != PABC_OK)
394  {
396  "Failed to read public parameters.\n");
397  pabc_free_ctx (&ctx);
398  GNUNET_free (issuer);
399  return GNUNET_SYSERR;
400  }
401  if (PABC_OK != pabc_cred_get_attr_by_name_from_cred (credential->data,
402  "subject",
403  &subject))
404  {
406  "Failed to get subject.\n");
407  pabc_free_ctx (&ctx);
408  GNUNET_free (issuer);
409  return GNUNET_SYSERR;
410  }
411  status = PABC_read_usr_ctx (subject, issuer, ctx, pp, &usr_ctx);
412  GNUNET_free (issuer);
414  if (PABC_OK != status)
415  {
417  "Failed to read user context.\n");
418  pabc_free_public_parameters (ctx, &pp);
419  return GNUNET_SYSERR;
420  }
421 
422  status = pabc_new_credential (ctx, pp, &cred);
423  if (status != PABC_OK)
424  {
426  "Failed to allocate credential.\n");
427  pabc_free_user_context (ctx, pp, &usr_ctx);
428  pabc_free_public_parameters (ctx, &pp);
429  return GNUNET_SYSERR;
430  }
431 
432  status = pabc_decode_credential (ctx, pp, cred, credential->data);
433  if (status != PABC_OK)
434  {
436  "Failed to decode credential.\n");
437  pabc_free_credential (ctx, pp, &cred);
438  pabc_free_user_context (ctx, pp, &usr_ctx);
439  pabc_free_public_parameters (ctx, &pp);
440  return GNUNET_SYSERR;
441  }
442 
443  status = pabc_new_proof (ctx, pp, &proof);
444  if (status != PABC_OK)
445  {
447  "Failed to allocate proof.\n");
448  pabc_free_credential (ctx, pp, &cred);
449  pabc_free_user_context (ctx, pp, &usr_ctx);
450  pabc_free_public_parameters (ctx, &pp);
451  return GNUNET_SYSERR;
452  }
453 
454  // now we can parse the attributes to disclose and configure the proof
455  for (ale = attrs->list_head; NULL != ale; ale = ale->next)
456  {
457  status = pabc_set_disclosure_by_attribute_name (ctx, pp, proof,
458  ale->attribute->name,
459  PABC_DISCLOSED, cred);
460  if (status != PABC_OK)
461  {
463  "Failed to configure proof.\n");
464  pabc_free_credential (ctx, pp, &cred);
465  pabc_free_user_context (ctx, pp, &usr_ctx);
466  pabc_free_public_parameters (ctx, &pp);
467  return GNUNET_SYSERR;
468  }
469  }
470 
471  // and finally -> sign the proof
472  status = pabc_gen_proof (ctx, usr_ctx, pp, proof, cred);
473  if (status != PABC_OK)
474  {
476  "Failed to sign proof.\n");
477  pabc_free_proof (ctx, pp, &proof);
478  pabc_free_credential (ctx, pp, &cred);
479  pabc_free_user_context (ctx, pp, &usr_ctx);
480  pabc_free_public_parameters (ctx, &pp);
481  return GNUNET_SYSERR;
482  }
483  // print the result
484  char *json = NULL;
485  char *ppid = NULL;
486  char *userid = NULL;
487  GNUNET_assert (PABC_OK == pabc_cred_get_userid_from_cred (credential->data,
488  &userid));
489  GNUNET_assert (PABC_OK == pabc_cred_get_ppid_from_cred (credential->data,
490  &ppid));
491  pabc_cred_encode_proof (ctx, pp, proof, userid, ppid, &json);
492  GNUNET_free (ppid);
493  GNUNET_free (userid);
494  if (PABC_OK != status)
495  {
497  "Failed to serialize proof.\n");
498  pabc_free_proof (ctx, pp, &proof);
499  pabc_free_credential (ctx, pp, &cred);
500  pabc_free_user_context (ctx, pp, &usr_ctx);
501  pabc_free_public_parameters (ctx, &pp);
502  return GNUNET_SYSERR;
503  }
504  char *json_enc;
506  strlen (json) + 1,
507  &json_enc);
509  "Presentation: %s\n", json_enc);
510  // clean up
511  *presentation = GNUNET_RECLAIM_presentation_new (
513  json_enc,
514  strlen (json_enc) + 1);
515  GNUNET_free (json_enc);
516  PABC_FREE_NULL (json);
517  pabc_free_proof (ctx, pp, &proof);
518  pabc_free_credential (ctx, pp, &cred);
519  pabc_free_user_context (ctx, pp, &usr_ctx);
520  pabc_free_public_parameters (ctx, &pp);
521  return GNUNET_OK;
522 }
523 
524 
531 void *
533 {
535 
552  return api;
553 }
554 
555 
562 void *
564 {
566 
567  GNUNET_free (api);
568  return NULL;
569 }
570 
571 
572 /* end of plugin_reclaim_credential_type_pabc.c */
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static char * subject
Subject pubkey string.
Definition: gnunet-abd.c:86
static int res
struct GNUNET_HashCode key
The key used in the DHT.
uint32_t data
The data value.
uint16_t status
See PRISM_STATUS_*-constants.
static char * value
Value of the record to add/remove.
static struct GNUNET_RECLAIM_Identifier credential
Credential ID.
static uint64_t proof
Definition: gnunet-scrypt.c:49
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Plugin API for reclaim attribute types.
#define GNUNET_log(kind,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_RECLAIM_attribute_list_add(struct GNUNET_RECLAIM_AttributeList *attrs, const char *attr_name, const struct GNUNET_RECLAIM_Identifier *credential, uint32_t type, const void *data, size_t data_size)
Add a new attribute to a claim list.
struct GNUNET_RECLAIM_Presentation * GNUNET_RECLAIM_presentation_new(uint32_t type, const void *data, size_t data_size)
@ GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC
libpabc credential
@ GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING
String attribute.
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1607
enum GNUNET_GenericReturnValue PABC_load_public_parameters(struct pabc_context *const ctx, char const *const pp_name, struct pabc_public_parameters **pp)
Definition: pabc_helper.c:135
enum GNUNET_GenericReturnValue PABC_read_usr_ctx(char const *const usr_name, char const *const pp_name, struct pabc_context const *const ctx, struct pabc_public_parameters const *const pp, struct pabc_user_context **usr_ctx)
Definition: pabc_helper.c:295
enum GNUNET_GenericReturnValue pabc_get_expiration_p(void *cls, const struct GNUNET_RECLAIM_Presentation *cred, struct GNUNET_TIME_Absolute *exp)
Parse a pabc and return the expiration.
char * pabc_get_issuer_c(void *cls, const struct GNUNET_RECLAIM_Credential *cred)
Parse a pabc and return the issuer.
enum GNUNET_GenericReturnValue pabc_get_expiration_c(void *cls, const struct GNUNET_RECLAIM_Credential *cred, struct GNUNET_TIME_Absolute *exp)
Parse a pabc and return the expiration.
char * pabc_get_issuer(void *cls, const char *data, size_t data_size)
Parse a pabc and return the issuer.
struct GNUNET_RECLAIM_AttributeList * pabc_parse_attributes(void *cls, const char *data, size_t data_size)
Parse a pabc and return the respective claim value as Attribute.
static uint32_t pabc_typename_to_number(void *cls, const char *pabc_typename)
Convert a type name to the corresponding number.
static void inspect_attrs(char const *const key, char const *const value, void *ctx)
const char * name
int pabc_create_presentation(void *cls, const struct GNUNET_RECLAIM_Credential *credential, const struct GNUNET_RECLAIM_AttributeList *attrs, struct GNUNET_RECLAIM_Presentation **presentation)
static struct @57 pabc_cred_name_map[]
Mapping of credential type numbers to human-readable credential type names.
void * libgnunet_plugin_reclaim_credential_pabc_init(void *cls)
Entry point for the plugin.
struct GNUNET_RECLAIM_AttributeList * pabc_parse_attributes_c(void *cls, const struct GNUNET_RECLAIM_Credential *cred)
Parse a pabc and return the respective claim value as Attribute.
void * libgnunet_plugin_reclaim_credential_pabc_done(void *cls)
Exit point from the plugin.
struct GNUNET_RECLAIM_AttributeList * pabc_parse_attributes_p(void *cls, const struct GNUNET_RECLAIM_Presentation *cred)
Parse a pabc and return the respective claim value as Attribute.
static const char * pabc_number_to_typename(void *cls, uint32_t type)
Convert a type number (i.e.
static int pabc_string_to_value(void *cls, uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of a 'value' of an credential to the binary representation.
char * pabc_get_issuer_p(void *cls, const struct GNUNET_RECLAIM_Presentation *cred)
Parse a pabc and return the issuer.
static char * pabc_value_to_string(void *cls, uint32_t type, const void *data, size_t data_size)
Convert the 'value' of an credential to a string.
enum GNUNET_GenericReturnValue pabc_get_expiration(void *cls, const char *data, size_t data_size, struct GNUNET_TIME_Absolute *exp)
Parse a pabc and return the expiration.
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
struct GNUNET_RECLAIM_AttributeListEntry * next
DLL.
A list of GNUNET_RECLAIM_Attribute structures.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
const char * name
The name of the attribute.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
GNUNET_RECLAIM_CredentialValueToStringFunction value_to_string
Conversion to string.
GNUNET_RECLAIM_CredentialTypenameToNumberFunction typename_to_number
Typename to number.
GNUNET_RECLAIM_PresentationGetIssuerFunction get_issuer_p
Attesation issuer.
GNUNET_RECLAIM_CredentialNumberToTypenameFunction number_to_typename
Number to typename.
GNUNET_RECLAIM_CredentialGetIssuerFunction get_issuer
Attesation issuer.
GNUNET_RECLAIM_PresentationGetExpirationFunction get_expiration_p
Expiration.
GNUNET_RECLAIM_PresentationValueToStringFunction value_to_string_p
Conversion to string.
GNUNET_RECLAIM_CredentialStringToValueFunction string_to_value
Conversion to binary.
GNUNET_RECLAIM_CredentialGetExpirationFunction get_expiration
Expiration.
void * cls
Closure for all of the callbacks.
GNUNET_RECLAIM_CredentialGetAttributesFunction get_attributes
Attesation attributes.
GNUNET_RECLAIM_PresentationStringToValueFunction string_to_value_p
Conversion to binary.
GNUNET_RECLAIM_PresentationTypenameToNumberFunction typename_to_number_p
Typename to number.
GNUNET_RECLAIM_PresentationNumberToTypenameFunction number_to_typename_p
Number to typename.
GNUNET_RECLAIM_CredentialToPresentation create_presentation
Get presentation.
GNUNET_RECLAIM_PresentationGetAttributesFunction get_attributes_p
Attesation attributes.
uint32_t type
Type/Format of Claim.
const void * data
Binary value stored as credential value.
size_t data_size
Number of bytes in data.
A credential presentation.
const void * data
Binary value stored as presentation value.
uint32_t type
Type/Format of Claim.
size_t data_size
Number of bytes in data.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model