aboutsummaryrefslogtreecommitdiff
path: root/src/plugin/reclaim/pabc_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugin/reclaim/pabc_helper.c')
-rw-r--r--src/plugin/reclaim/pabc_helper.c374
1 files changed, 374 insertions, 0 deletions
diff --git a/src/plugin/reclaim/pabc_helper.c b/src/plugin/reclaim/pabc_helper.c
new file mode 100644
index 000000000..d7688e9e1
--- /dev/null
+++ b/src/plugin/reclaim/pabc_helper.c
@@ -0,0 +1,374 @@
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 "platform.h"
8#include "pabc_helper.h"
9#include <pwd.h>
10#include <stdlib.h>
11#include <unistd.h>
12
13static char pabc_dir[PATH_MAX + 1];
14
15static const char *
16get_homedir ()
17{
18 const char *homedir;
19 if ((homedir = getenv ("HOME")) == NULL)
20 {
21 homedir = getpwuid (getuid ())->pw_dir;
22 }
23 return homedir;
24}
25
26
27static enum GNUNET_GenericReturnValue
28write_file (char const *const filename, const char *buffer)
29{
30 struct GNUNET_DISK_FileHandle *fh;
31 fh = GNUNET_DISK_file_open (filename,
32 GNUNET_DISK_OPEN_WRITE
33 | GNUNET_DISK_OPEN_TRUNCATE
34 | GNUNET_DISK_OPEN_CREATE,
35 GNUNET_DISK_PERM_USER_WRITE
36 | GNUNET_DISK_PERM_USER_READ);
37 if (fh == NULL)
38 return GNUNET_SYSERR;
39 if (GNUNET_SYSERR == GNUNET_DISK_file_write (fh,
40 buffer, strlen (buffer) + 1))
41 goto fail;
42 GNUNET_DISK_file_close (fh);
43 return GNUNET_OK;
44
45fail:
46 GNUNET_DISK_file_close (fh);
47 return GNUNET_SYSERR;
48}
49
50
51static enum GNUNET_GenericReturnValue
52init_pabc_dir ()
53{
54 size_t filename_size = strlen (get_homedir ()) + 1 + strlen (".local") + 1
55 + strlen ("pabc-reclaim") + 1;
56 snprintf (pabc_dir, filename_size, "%s/%s/%s",
57 get_homedir (), ".local", "pabc-reclaim");
58 return GNUNET_DISK_directory_create (pabc_dir);
59}
60
61
62static const char *
63get_pabcdir ()
64{
65 init_pabc_dir ();
66 return pabc_dir;
67}
68
69
70enum GNUNET_GenericReturnValue
71read_file (char const *const filename, char **buffer)
72{
73 struct GNUNET_DISK_FileHandle *fh;
74 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
75 return GNUNET_SYSERR;
76
77 fh = GNUNET_DISK_file_open (filename,
78 GNUNET_DISK_OPEN_READ,
79 GNUNET_DISK_PERM_USER_READ);
80 if (fh == NULL)
81 return GNUNET_SYSERR;
82 long lSize = GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_END);
83 if (lSize < 0)
84 goto fail;
85 GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET);
86 *buffer = calloc ((size_t) lSize + 1, sizeof(char));
87 if (*buffer == NULL)
88 goto fail;
89
90 // copy the file into the buffer:
91 size_t r = GNUNET_DISK_file_read (fh, *buffer, (size_t) lSize);
92 if (r != (size_t) lSize)
93 goto fail;
94
95 GNUNET_DISK_file_close (fh);
96 return GNUNET_OK;
97
98fail:
99 GNUNET_DISK_file_close (fh);
100 GNUNET_free (*buffer);
101 return GNUNET_SYSERR;
102}
103
104
105struct pabc_public_parameters *
106PABC_read_issuer_ppfile (const char *f, struct pabc_context *const ctx)
107{
108 if (NULL == ctx)
109 {
110 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No global context provided\n");
111 return NULL;
112 }
113 struct pabc_public_parameters *pp;
114 char *buffer;
115 int r;
116 r = read_file (f, &buffer);
117 if (GNUNET_OK != r)
118 {
119 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading file\n");
120 return NULL;
121 }
122 if (PABC_OK != pabc_decode_and_new_public_parameters (ctx, &pp, buffer))
123 {
124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
125 "Failed to decode public parameters\n");
126 PABC_FREE_NULL (buffer);
127 return NULL;
128 }
129 PABC_FREE_NULL (buffer);
130 return pp;
131}
132
133
134enum GNUNET_GenericReturnValue
135PABC_load_public_parameters (struct pabc_context *const ctx,
136 char const *const pp_name,
137 struct pabc_public_parameters **pp)
138{
139 char fname[PATH_MAX];
140 char *pp_filename;
141 const char *pdir = get_pabcdir ();
142
143 if (ctx == NULL)
144 return GNUNET_SYSERR;
145 if (pp_name == NULL)
146 return GNUNET_SYSERR;
147
148 GNUNET_STRINGS_urlencode (strlen (pp_name),
149 pp_name,
150 &pp_filename);
151 if (GNUNET_YES != GNUNET_DISK_directory_test (pdir, GNUNET_YES))
152 {
153 GNUNET_free (pp_filename);
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading %s\n", pdir);
155 return GNUNET_SYSERR;
156 }
157 snprintf (fname, PATH_MAX, "%s/%s%s", pdir, pp_filename, PABC_PP_EXT);
158 if (GNUNET_YES != GNUNET_DISK_file_test (fname))
159 {
160 GNUNET_free (pp_filename);
161 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error testing %s\n", fname);
162 return GNUNET_SYSERR;
163 }
164 *pp = PABC_read_issuer_ppfile (fname, ctx);
165 if (*pp)
166 return GNUNET_OK;
167 else
168 return GNUNET_SYSERR;
169}
170
171
172enum GNUNET_GenericReturnValue
173PABC_write_public_parameters (char const *const pp_name,
174 struct pabc_public_parameters *const pp)
175{
176 char *json;
177 char *filename;
178 char *pp_filename;
179 enum pabc_status status;
180 struct pabc_context *ctx = NULL;
181
182 GNUNET_STRINGS_urlencode (strlen (pp_name),
183 pp_name,
184 &pp_filename);
185 PABC_ASSERT (pabc_new_ctx (&ctx));
186 // store in json file
187 status = pabc_encode_public_parameters (ctx, pp, &json);
188 if (status != PABC_OK)
189 {
190 GNUNET_free (pp_filename);
191 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
192 "Failed to encode public parameters.\n");
193 pabc_free_ctx (&ctx);
194 return GNUNET_SYSERR;
195 }
196
197 size_t filename_size =
198 strlen (get_pabcdir ()) + 1 + strlen (pp_filename) + strlen (PABC_PP_EXT)
199 + 1;
200 filename = GNUNET_malloc (filename_size);
201 if (! filename)
202 {
203 GNUNET_free (pp_filename);
204 PABC_FREE_NULL (json);
205 pabc_free_ctx (&ctx);
206 return GNUNET_SYSERR;
207 }
208 snprintf (filename, filename_size, "%s/%s%s", get_pabcdir (), pp_filename,
209 PABC_PP_EXT);
210
211 GNUNET_free (pp_filename);
212 if (GNUNET_OK != write_file (filename, json))
213 {
214 PABC_FREE_NULL (filename);
215 PABC_FREE_NULL (json);
216 pabc_free_ctx (&ctx);
217 return GNUNET_SYSERR;
218 }
219 PABC_FREE_NULL (filename);
220 PABC_FREE_NULL (json);
221 pabc_free_ctx (&ctx);
222 return GNUNET_OK;
223}
224
225
226enum GNUNET_GenericReturnValue
227PABC_write_usr_ctx (char const *const usr_name,
228 char const *const pp_name,
229 struct pabc_context const *const ctx,
230 struct pabc_public_parameters const *const pp,
231 struct pabc_user_context *const usr_ctx)
232{
233
234 char *pp_filename;
235 char *json = NULL;
236 enum pabc_status status;
237 char *fname = NULL;
238
239 if (NULL == usr_name)
240 {
241 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
242 return GNUNET_SYSERR;
243 }
244 if (NULL == pp_name)
245 {
246 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
247 return GNUNET_SYSERR;
248 }
249 if (NULL == ctx)
250 {
251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
252 return GNUNET_SYSERR;
253 }
254 if (NULL == pp)
255 {
256 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
257 return GNUNET_SYSERR;
258 }
259 if (NULL == usr_ctx)
260 {
261 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
262 return GNUNET_SYSERR;
263 }
264
265 GNUNET_STRINGS_urlencode (strlen (pp_name),
266 pp_name,
267 &pp_filename);
268 status = pabc_encode_user_ctx (ctx, pp, usr_ctx, &json);
269 if (PABC_OK != status)
270 {
271 GNUNET_free (pp_filename);
272 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
273 return status;
274 }
275
276 size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
277 + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
278 fname = GNUNET_malloc (fname_size);
279
280 snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
281 pp_filename,
282 PABC_USR_EXT);
283
284 GNUNET_free (pp_filename);
285 if (GNUNET_OK == write_file (fname, json))
286 {
287 GNUNET_free (fname);
288 GNUNET_free (json);
289 return GNUNET_OK;
290 }
291 else
292 {
293 GNUNET_free (fname);
294 GNUNET_free (json);
295 return GNUNET_SYSERR;
296 }
297}
298
299
300enum GNUNET_GenericReturnValue
301PABC_read_usr_ctx (char const *const usr_name,
302 char const *const pp_name,
303 struct pabc_context const *const ctx,
304 struct pabc_public_parameters const *const pp,
305 struct pabc_user_context **usr_ctx)
306{
307 char *json = NULL;
308 char *pp_filename;
309 enum pabc_status status;
310
311 char *fname = NULL;
312
313 if (NULL == usr_name)
314 {
315 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
316 return GNUNET_SYSERR;
317 }
318 if (NULL == pp_name)
319 {
320 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
321 return GNUNET_SYSERR;
322 }
323 if (NULL == ctx)
324 {
325 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
326 return GNUNET_SYSERR;
327 }
328 if (NULL == pp)
329 {
330 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
331 return GNUNET_SYSERR;
332 }
333 if (NULL == usr_ctx)
334 {
335 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
336 return GNUNET_SYSERR;
337 }
338 GNUNET_STRINGS_urlencode (strlen (pp_name),
339 pp_name,
340 &pp_filename);
341
342 size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
343 + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
344 fname = GNUNET_malloc (fname_size);
345 snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
346 pp_filename,
347 PABC_USR_EXT);
348 GNUNET_free (pp_filename);
349 if (GNUNET_OK != read_file (fname, &json))
350 {
351 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
352 "Failed to read `%s'\n", fname);
353 PABC_FREE_NULL (fname);
354 return GNUNET_SYSERR;
355 }
356 GNUNET_free (fname);
357
358 status = pabc_new_user_context (ctx, pp, usr_ctx);
359 if (PABC_OK != status)
360 {
361 GNUNET_free (json);
362 return GNUNET_SYSERR;
363 }
364 status = pabc_decode_user_ctx (ctx, pp, *usr_ctx, json);
365 GNUNET_free (json);
366 if (PABC_OK != status)
367 {
368 pabc_free_user_context (ctx, pp, usr_ctx);
369 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
370 return GNUNET_SYSERR;
371 }
372
373 return GNUNET_OK;
374}