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