GNUnet  0.11.x
pabc_helper.c
Go to the documentation of this file.
1 // maximilian.kaul@aisec.fraunhofer.de
2 
3 // WIP implementation of
4 // https://github.com/ontio/ontology-crypto/wiki/Anonymous-Credential
5 // using the relic library https://github.com/relic-toolkit/relic/
6 
7 #include "pabc_helper.h"
8 #include <pwd.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 
12 static char pabc_dir[PATH_MAX + 1];
13 
14 static const char *
16 {
17  const char *homedir;
18  if ((homedir = getenv ("HOME")) == NULL)
19  {
20  homedir = getpwuid (getuid ())->pw_dir;
21  }
22  return homedir;
23 }
24 
25 
26 static enum GNUNET_GenericReturnValue
27 write_file (char const *const filename, const char *buffer)
28 {
29  struct GNUNET_DISK_FileHandle *fh;
30  fh = GNUNET_DISK_file_open (filename,
36  if (fh == NULL)
37  return GNUNET_SYSERR;
39  buffer, strlen (buffer) + 1))
40  goto fail;
42  return GNUNET_OK;
43 
44 fail:
46  return GNUNET_SYSERR;
47 }
48 
49 
50 static enum GNUNET_GenericReturnValue
52 {
53  size_t filename_size = strlen (get_homedir ()) + 1 + strlen (".local") + 1
54  + strlen ("pabc-reclaim") + 1;
55  snprintf (pabc_dir, filename_size, "%s/%s/%s",
56  get_homedir (), ".local", "pabc-reclaim");
58 }
59 
60 
61 static const char *
63 {
64  init_pabc_dir ();
65  return pabc_dir;
66 }
67 
68 
70 read_file (char const *const filename, char **buffer)
71 {
72  struct GNUNET_DISK_FileHandle *fh;
73  if (GNUNET_YES != GNUNET_DISK_file_test (filename))
74  return GNUNET_SYSERR;
75 
76  fh = GNUNET_DISK_file_open (filename,
79  if (fh == NULL)
80  return GNUNET_SYSERR;
81  long lSize = GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_END);
82  if (lSize < 0)
83  goto fail;
85  *buffer = calloc ((size_t) lSize + 1, sizeof(char));
86  if (*buffer == NULL)
87  goto fail;
88 
89  // copy the file into the buffer:
90  size_t r = GNUNET_DISK_file_read (fh, *buffer, (size_t) lSize);
91  if (r != (size_t) lSize)
92  goto fail;
93 
95  return GNUNET_OK;
96 
97 fail:
99  return GNUNET_SYSERR;
100 }
101 
102 
103 struct pabc_public_parameters *
104 PABC_read_issuer_ppfile (const char *f, struct pabc_context *const ctx)
105 {
106  if (NULL == ctx)
107  {
108  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No global context provided\n");
109  return NULL;
110  }
111  struct pabc_public_parameters *pp;
112  char *buffer;
113  int r;
114  r = read_file (f, &buffer);
115  if (GNUNET_OK != r)
116  {
117  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading file\n");
118  return NULL;
119  }
120  if (PABC_OK != pabc_decode_and_new_public_parameters (ctx, &pp, buffer))
121  {
123  "Failed to decode public parameters\n");
124  PABC_FREE_NULL (buffer);
125  return NULL;
126  }
127  PABC_FREE_NULL (buffer);
128  return pp;
129 }
130 
131 
133 PABC_load_public_parameters (struct pabc_context *const ctx,
134  char const *const pp_name,
135  struct pabc_public_parameters **pp)
136 {
137  char fname[PATH_MAX];
138  char *pp_filename;
139  const char *pdir = get_pabcdir ();
140 
141  if (ctx == NULL)
142  return GNUNET_SYSERR;
143  if (pp_name == NULL)
144  return GNUNET_SYSERR;
145 
146  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
148  {
149  GNUNET_free (pp_filename);
150  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading %s\n", pdir);
151  return GNUNET_SYSERR;
152  }
153  snprintf (fname, PATH_MAX, "%s/%s%s", pdir, pp_filename, PABC_PP_EXT);
154  if (GNUNET_YES != GNUNET_DISK_file_test (fname))
155  {
156  GNUNET_free (pp_filename);
157  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error testing %s\n", fname);
158  return GNUNET_SYSERR;
159  }
160  *pp = PABC_read_issuer_ppfile (fname, ctx);
161  if (*pp)
162  return GNUNET_OK;
163  else
164  return GNUNET_SYSERR;
165 }
166 
167 
169 PABC_write_public_parameters (char const *const pp_name,
170  struct pabc_public_parameters *const pp)
171 {
172  char *json;
173  char *filename;
174  char *pp_filename;
175  enum pabc_status status;
176  struct pabc_context *ctx = NULL;
177 
178  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
179  PABC_ASSERT (pabc_new_ctx (&ctx));
180  // store in json file
181  status = pabc_encode_public_parameters (ctx, pp, &json);
182  if (status != PABC_OK)
183  {
184  GNUNET_free (pp_filename);
186  "Failed to encode public parameters.\n");
187  pabc_free_ctx (&ctx);
188  return GNUNET_SYSERR;
189  }
190 
191  size_t filename_size =
192  strlen (get_pabcdir ()) + 1 + strlen (pp_filename) + strlen (PABC_PP_EXT)
193  + 1;
194  filename = GNUNET_malloc (filename_size);
195  if (! filename)
196  {
197  GNUNET_free (pp_filename);
198  PABC_FREE_NULL (json);
199  pabc_free_ctx (&ctx);
200  return GNUNET_SYSERR;
201  }
202  snprintf (filename, filename_size, "%s/%s%s", get_pabcdir (), pp_filename,
203  PABC_PP_EXT);
204 
205  GNUNET_free (pp_filename);
206  if (GNUNET_OK != write_file (filename, json))
207  {
208  PABC_FREE_NULL (filename);
209  PABC_FREE_NULL (json);
210  pabc_free_ctx (&ctx);
211  return GNUNET_SYSERR;
212  }
213  PABC_FREE_NULL (filename);
214  PABC_FREE_NULL (json);
215  pabc_free_ctx (&ctx);
216  return GNUNET_OK;
217 }
218 
219 
221 PABC_write_usr_ctx (char const *const usr_name,
222  char const *const pp_name,
223  struct pabc_context const *const ctx,
224  struct pabc_public_parameters const *const pp,
225  struct pabc_user_context *const usr_ctx)
226 {
227 
228  char *pp_filename;
229  char *json = NULL;
230  enum pabc_status status;
231  char *fname = NULL;
232 
233  if (NULL == usr_name)
234  {
235  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
236  return GNUNET_SYSERR;
237  }
238  if (NULL == pp_name)
239  {
240  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
241  return GNUNET_SYSERR;
242  }
243  if (NULL == ctx)
244  {
245  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
246  return GNUNET_SYSERR;
247  }
248  if (NULL == pp)
249  {
250  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
251  return GNUNET_SYSERR;
252  }
253  if (NULL == usr_ctx)
254  {
255  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
256  return GNUNET_SYSERR;
257  }
258 
259  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
260  status = pabc_encode_user_ctx (ctx, pp, usr_ctx, &json);
261  if (PABC_OK != status)
262  {
263  GNUNET_free (pp_filename);
264  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
265  return status;
266  }
267 
268  size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
269  + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
270  fname = GNUNET_malloc (fname_size);
271 
272  snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
273  pp_filename,
274  PABC_USR_EXT);
275 
276  GNUNET_free (pp_filename);
277  if (GNUNET_OK == write_file (fname, json))
278  {
279  GNUNET_free (fname);
280  GNUNET_free (json);
281  return GNUNET_OK;
282  }
283  else
284  {
285  GNUNET_free (fname);
286  GNUNET_free (json);
287  return GNUNET_SYSERR;
288  }
289 }
290 
291 
293 PABC_read_usr_ctx (char const *const usr_name,
294  char const *const pp_name,
295  struct pabc_context const *const ctx,
296  struct pabc_public_parameters const *const pp,
297  struct pabc_user_context **usr_ctx)
298 {
299  char *json = NULL;
300  char *pp_filename;
301  enum pabc_status status;
302 
303  char *fname = NULL;
304 
305  if (NULL == usr_name)
306  {
307  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
308  return GNUNET_SYSERR;
309  }
310  if (NULL == pp_name)
311  {
312  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
313  return GNUNET_SYSERR;
314  }
315  if (NULL == ctx)
316  {
317  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
318  return GNUNET_SYSERR;
319  }
320  if (NULL == pp)
321  {
322  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
323  return GNUNET_SYSERR;
324  }
325  if (NULL == usr_ctx)
326  {
327  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
328  return GNUNET_SYSERR;
329  }
330  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
331 
332  size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
333  + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
334  fname = GNUNET_malloc (fname_size);
335  snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
336  pp_filename,
337  PABC_USR_EXT);
338  GNUNET_free (pp_filename);
339  if (GNUNET_OK != read_file (fname, &json))
340  {
342  "Failed to read `%s'\n", fname);
343  PABC_FREE_NULL (fname);
344  return GNUNET_SYSERR;
345  }
346  GNUNET_free (fname);
347 
348  status = pabc_new_user_context (ctx, pp, usr_ctx);
349  if (PABC_OK != status)
350  {
351  GNUNET_free (json);
352  return GNUNET_SYSERR;
353  }
354  status = pabc_decode_user_ctx (ctx, pp, *usr_ctx, json);
355  GNUNET_free (json);
356  if (PABC_OK != status)
357  {
358  pabc_free_user_context (ctx, pp, usr_ctx);
359  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
360  return GNUNET_SYSERR;
361  }
362 
363  return GNUNET_OK;
364 }
Open the file for reading.
static const char * get_pabcdir()
Definition: pabc_helper.c:62
Create file if it doesn&#39;t exist.
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:133
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:602
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1126
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:83
#define PABC_USR_EXT
Definition: pabc_helper.h:13
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:206
static const char * get_homedir()
Definition: pabc_helper.c:15
struct pabc_public_parameters * PABC_read_issuer_ppfile(const char *f, struct pabc_context *const ctx)
Definition: pabc_helper.c:104
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static char pabc_dir[4096+1]
Definition: pabc_helper.c:12
static enum GNUNET_GenericReturnValue init_pabc_dir()
Definition: pabc_helper.c:51
#define PABC_PP_EXT
Definition: pabc_helper.h:11
Truncate file if it exists.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:666
uint16_t status
See PRISM_STATUS_*-constants.
static char * filename
#define PATH_MAX
Assumed maximum path length.
Definition: platform.h:247
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:476
static int fh
Handle to the unique file.
enum GNUNET_GenericReturnValue read_file(char const *const filename, char **buffer)
Definition: pabc_helper.c:70
enum GNUNET_GenericReturnValue PABC_write_public_parameters(char const *const pp_name, struct pabc_public_parameters *const pp)
Definition: pabc_helper.c:169
size_t GNUNET_STRINGS_urlencode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition: strings.c:2147
Seek an absolute position from the end of the file.
Open the file for writing.
char * getenv()
static enum GNUNET_GenericReturnValue write_file(char const *const filename, const char *buffer)
Definition: pabc_helper.c:27
enum GNUNET_GenericReturnValue PABC_write_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 *const usr_ctx)
Definition: pabc_helper.c:221
Seek an absolute position (from the start of the file).
#define GNUNET_log(kind,...)
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:293
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1055
Handle used to access files (and pipes).
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:404
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:437
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.