aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/reclaim/Makefile.am6
-rw-r--r--src/reclaim/pabc_helper.c336
-rw-r--r--src/reclaim/pabc_helper.h41
-rw-r--r--src/reclaim/plugin_reclaim_credential_jwt.c12
-rw-r--r--src/reclaim/plugin_reclaim_credential_pabc.c140
-rw-r--r--src/reclaim/plugin_rest_pabc.c65
6 files changed, 532 insertions, 68 deletions
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 6ad842789..1a0b7fae4 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -94,7 +94,8 @@ libgnunet_plugin_rest_openid_connect_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
94 94
95if HAVE_PABC 95if HAVE_PABC
96libgnunet_plugin_rest_pabc_la_SOURCES = \ 96libgnunet_plugin_rest_pabc_la_SOURCES = \
97 plugin_rest_pabc.c 97 plugin_rest_pabc.c \
98 pabc_helper.c
98libgnunet_plugin_rest_pabc_la_LIBADD = \ 99libgnunet_plugin_rest_pabc_la_LIBADD = \
99 libgnunetreclaim.la \ 100 libgnunetreclaim.la \
100 $(top_builddir)/src/json/libgnunetjson.la \ 101 $(top_builddir)/src/json/libgnunetjson.la \
@@ -160,7 +161,8 @@ libgnunet_plugin_reclaim_attribute_basic_la_LDFLAGS = \
160 161
161if HAVE_PABC 162if HAVE_PABC
162libgnunet_plugin_reclaim_credential_pabc_la_SOURCES = \ 163libgnunet_plugin_reclaim_credential_pabc_la_SOURCES = \
163 plugin_reclaim_credential_pabc.c 164 plugin_reclaim_credential_pabc.c \
165 pabc_helper.c
164libgnunet_plugin_reclaim_credential_pabc_la_LIBADD = \ 166libgnunet_plugin_reclaim_credential_pabc_la_LIBADD = \
165 $(top_builddir)/src/util/libgnunetutil.la \ 167 $(top_builddir)/src/util/libgnunetutil.la \
166 libgnunetreclaim.la \ 168 libgnunetreclaim.la \
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}
diff --git a/src/reclaim/pabc_helper.h b/src/reclaim/pabc_helper.h
new file mode 100644
index 000000000..491672a8b
--- /dev/null
+++ b/src/reclaim/pabc_helper.h
@@ -0,0 +1,41 @@
1#include "platform.h"
2#include "gnunet_util_lib.h"
3#include <libpabc/libpabc.h>
4
5#ifndef PATH_MAX
6#define PATH_MAX 4096
7#endif
8
9#define PABC_ISK_EXT ".isk"
10
11#define PABC_PP_EXT ".pp"
12
13#define PABC_USR_EXT ".usr"
14
15#define PABC_ATTR_DELIM "="
16
17enum GNUNET_GenericReturnValue
18PABC_write_public_parameters (char const *const pp_name,
19 struct pabc_public_parameters *const pp);
20
21
22enum GNUNET_GenericReturnValue
23PABC_load_public_parameters (struct pabc_context *const ctx,
24 char const *const pp_name,
25 struct pabc_public_parameters **pp);
26
27enum GNUNET_GenericReturnValue
28PABC_write_usr_ctx (char const *const user_name,
29 char const *const pp_name,
30 struct pabc_context const *const ctx,
31 struct pabc_public_parameters const *const
32 pp,
33 struct pabc_user_context *const usr_ctx);
34
35enum GNUNET_GenericReturnValue
36PABC_read_usr_ctx (char const *const user_name,
37 char const *const pp_name,
38 struct pabc_context const *const ctx,
39 struct pabc_public_parameters const *const
40 pp,
41 struct pabc_user_context **usr_ctx);
diff --git a/src/reclaim/plugin_reclaim_credential_jwt.c b/src/reclaim/plugin_reclaim_credential_jwt.c
index aac0a6ea5..425ac3450 100644
--- a/src/reclaim/plugin_reclaim_credential_jwt.c
+++ b/src/reclaim/plugin_reclaim_credential_jwt.c
@@ -162,7 +162,7 @@ jwt_parse_attributes (void *cls,
162 char *decoded_jwt; 162 char *decoded_jwt;
163 char *tmp; 163 char *tmp;
164 json_t *json_val; 164 json_t *json_val;
165 json_error_t *json_err = NULL; 165 json_error_t json_err;
166 166
167 attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); 167 attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
168 168
@@ -173,7 +173,7 @@ jwt_parse_attributes (void *cls,
173 (void **) &decoded_jwt); 173 (void **) &decoded_jwt);
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt); 174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt);
175 GNUNET_assert (NULL != decoded_jwt); 175 GNUNET_assert (NULL != decoded_jwt);
176 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); 176 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
177 GNUNET_free (decoded_jwt); 177 GNUNET_free (decoded_jwt);
178 const char *key; 178 const char *key;
179 const char *addr_key; 179 const char *addr_key;
@@ -291,14 +291,14 @@ jwt_get_issuer (void *cls,
291 json_t *issuer_json; 291 json_t *issuer_json;
292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n"); 292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
293 json_t *json_val; 293 json_t *json_val;
294 json_error_t *json_err = NULL; 294 json_error_t json_err;
295 295
296 jwt_string = GNUNET_strndup (data, data_size); 296 jwt_string = GNUNET_strndup (data, data_size);
297 jwt_body = strtok (jwt_string, delim); 297 jwt_body = strtok (jwt_string, delim);
298 jwt_body = strtok (NULL, delim); 298 jwt_body = strtok (NULL, delim);
299 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), 299 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
300 (void **) &decoded_jwt); 300 (void **) &decoded_jwt);
301 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); 301 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
302 GNUNET_free (decoded_jwt); 302 GNUNET_free (decoded_jwt);
303 GNUNET_free (jwt_string); 303 GNUNET_free (jwt_string);
304 if (NULL == json_val) 304 if (NULL == json_val)
@@ -368,14 +368,14 @@ jwt_get_expiration (void *cls,
368 json_t *exp_json; 368 json_t *exp_json;
369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n"); 369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
370 json_t *json_val; 370 json_t *json_val;
371 json_error_t *json_err = NULL; 371 json_error_t json_err;
372 372
373 jwt_string = GNUNET_strndup (data, data_size); 373 jwt_string = GNUNET_strndup (data, data_size);
374 jwt_body = strtok (jwt_string, delim); 374 jwt_body = strtok (jwt_string, delim);
375 jwt_body = strtok (NULL, delim); 375 jwt_body = strtok (NULL, delim);
376 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), 376 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
377 (void **) &decoded_jwt); 377 (void **) &decoded_jwt);
378 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); 378 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
379 GNUNET_free (decoded_jwt); 379 GNUNET_free (decoded_jwt);
380 GNUNET_free (jwt_string); 380 GNUNET_free (jwt_string);
381 if (NULL == json_val) 381 if (NULL == json_val)
diff --git a/src/reclaim/plugin_reclaim_credential_pabc.c b/src/reclaim/plugin_reclaim_credential_pabc.c
index 6bc94b404..dae23ab1a 100644
--- a/src/reclaim/plugin_reclaim_credential_pabc.c
+++ b/src/reclaim/plugin_reclaim_credential_pabc.c
@@ -31,6 +31,7 @@
31#include <inttypes.h> 31#include <inttypes.h>
32#include <jansson.h> 32#include <jansson.h>
33#include <libpabc/libpabc.h> 33#include <libpabc/libpabc.h>
34#include "pabc_helper.h"
34 35
35/** 36/**
36 * Convert the 'value' of an credential to a string. 37 * Convert the 'value' of an credential to a string.
@@ -43,9 +44,9 @@
43 */ 44 */
44static char * 45static char *
45pabc_value_to_string (void *cls, 46pabc_value_to_string (void *cls,
46 uint32_t type, 47 uint32_t type,
47 const void *data, 48 const void *data,
48 size_t data_size) 49 size_t data_size)
49{ 50{
50 switch (type) 51 switch (type)
51 { 52 {
@@ -71,10 +72,10 @@ pabc_value_to_string (void *cls,
71 */ 72 */
72static int 73static int
73pabc_string_to_value (void *cls, 74pabc_string_to_value (void *cls,
74 uint32_t type, 75 uint32_t type,
75 const char *s, 76 const char *s,
76 void **data, 77 void **data,
77 size_t *data_size) 78 size_t *data_size)
78{ 79{
79 if (NULL == s) 80 if (NULL == s)
80 return GNUNET_SYSERR; 81 return GNUNET_SYSERR;
@@ -100,7 +101,7 @@ static struct
100 const char *name; 101 const char *name;
101 uint32_t number; 102 uint32_t number;
102} pabc_cred_name_map[] = { { "PABC", GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC }, 103} pabc_cred_name_map[] = { { "PABC", GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC },
103 { NULL, UINT32_MAX } }; 104 { NULL, UINT32_MAX } };
104 105
105/** 106/**
106 * Convert a type name to the corresponding number. 107 * Convert a type name to the corresponding number.
@@ -136,8 +137,8 @@ pabc_number_to_typename (void *cls, uint32_t type)
136 137
137 i = 0; 138 i = 0;
138 while ((NULL != pabc_cred_name_map[i].name) && (type != 139 while ((NULL != pabc_cred_name_map[i].name) && (type !=
139 pabc_cred_name_map[i]. 140 pabc_cred_name_map[i].
140 number)) 141 number))
141 i++; 142 i++;
142 return pabc_cred_name_map[i].name; 143 return pabc_cred_name_map[i].name;
143} 144}
@@ -152,8 +153,8 @@ pabc_number_to_typename (void *cls, uint32_t type)
152 */ 153 */
153struct GNUNET_RECLAIM_AttributeList * 154struct GNUNET_RECLAIM_AttributeList *
154pabc_parse_attributes (void *cls, 155pabc_parse_attributes (void *cls,
155 const char *data, 156 const char *data,
156 size_t data_size) 157 size_t data_size)
157{ 158{
158 const char *key; 159 const char *key;
159 struct GNUNET_RECLAIM_AttributeList *attrs; 160 struct GNUNET_RECLAIM_AttributeList *attrs;
@@ -167,7 +168,7 @@ pabc_parse_attributes (void *cls,
167 168
168 json_root = json_loads (data, JSON_DECODE_ANY, json_err); 169 json_root = json_loads (data, JSON_DECODE_ANY, json_err);
169 if ((NULL == json_root) || 170 if ((NULL == json_root) ||
170 (!json_is_object (json_root))) 171 (! json_is_object (json_root)))
171 { 172 {
172 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
173 "%s is not a valid pabc credentials (not an object)\n", 174 "%s is not a valid pabc credentials (not an object)\n",
@@ -178,7 +179,7 @@ pabc_parse_attributes (void *cls,
178 } 179 }
179 json_attrs = json_object_get (json_root, "attributes"); 180 json_attrs = json_object_get (json_root, "attributes");
180 if ((NULL == json_attrs) || 181 if ((NULL == json_attrs) ||
181 (!json_is_array (json_attrs))) 182 (! json_is_array (json_attrs)))
182 { 183 {
183 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 184 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
184 "%s is not a valid pabc credentials (attributes not an array)\n", 185 "%s is not a valid pabc credentials (attributes not an array)\n",
@@ -191,7 +192,7 @@ pabc_parse_attributes (void *cls,
191 for (int i = 0; i < json_array_size (json_attrs); i++) 192 for (int i = 0; i < json_array_size (json_attrs); i++)
192 { 193 {
193 attr = json_array_get (json_attrs, i); 194 attr = json_array_get (json_attrs, i);
194 if (!json_is_object(attr)) 195 if (! json_is_object (attr))
195 { 196 {
196 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 197 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
197 "Found json entry is not an object!\n"); 198 "Found json entry is not an object!\n");
@@ -210,12 +211,12 @@ pabc_parse_attributes (void *cls,
210 continue; 211 continue;
211 val_str = json_dumps (value, JSON_ENCODE_ANY); 212 val_str = json_dumps (value, JSON_ENCODE_ANY);
212 tmp = val_str; 213 tmp = val_str;
213 //Remove leading " from jasson conversion 214 // Remove leading " from jasson conversion
214 if (tmp[0] == '"') 215 if (tmp[0] == '"')
215 tmp++; 216 tmp++;
216 //Remove trailing " from jansson conversion 217 // Remove trailing " from jansson conversion
217 if (tmp[strlen(tmp)-1] == '"') 218 if (tmp[strlen (tmp) - 1] == '"')
218 tmp[strlen(tmp)-1] = '\0'; 219 tmp[strlen (tmp) - 1] = '\0';
219 GNUNET_RECLAIM_attribute_list_add (attrs, 220 GNUNET_RECLAIM_attribute_list_add (attrs,
220 key, 221 key,
221 NULL, 222 NULL,
@@ -239,7 +240,7 @@ pabc_parse_attributes (void *cls,
239 */ 240 */
240struct GNUNET_RECLAIM_AttributeList * 241struct GNUNET_RECLAIM_AttributeList *
241pabc_parse_attributes_c (void *cls, 242pabc_parse_attributes_c (void *cls,
242 const struct GNUNET_RECLAIM_Credential *cred) 243 const struct GNUNET_RECLAIM_Credential *cred)
243{ 244{
244 return pabc_parse_attributes (cls, cred->data, cred->data_size); 245 return pabc_parse_attributes (cls, cred->data, cred->data_size);
245} 246}
@@ -254,23 +255,26 @@ pabc_parse_attributes_c (void *cls,
254 */ 255 */
255struct GNUNET_RECLAIM_AttributeList * 256struct GNUNET_RECLAIM_AttributeList *
256pabc_parse_attributes_p (void *cls, 257pabc_parse_attributes_p (void *cls,
257 const struct GNUNET_RECLAIM_Presentation *cred) 258 const struct GNUNET_RECLAIM_Presentation *cred)
258{ 259{
259 return pabc_parse_attributes (cls, cred->data, cred->data_size); 260 return pabc_parse_attributes (cls, cred->data, cred->data_size);
260} 261}
261 262
262 263
263/** 264/**
264 * Parse a pabc and return the issuer 265 * Parse a pabc and return an attribute value.
265 * 266 *
266 * @param cls the plugin 267 * @param cls the plugin
267 * @param cred the pabc credential 268 * @param data the pabc credential data
269 * @param data_size the pabc credential size
270 * @param key the attribute key to look for.
268 * @return a string, containing the isser 271 * @return a string, containing the isser
269 */ 272 */
270char * 273char *
271pabc_get_issuer (void *cls, 274pabc_get_attribute (void *cls,
272 const char *data, 275 const char *data,
273 size_t data_size) 276 size_t data_size,
277 const char *skey)
274{ 278{
275 const char *key; 279 const char *key;
276 char *val_str = NULL; 280 char *val_str = NULL;
@@ -283,7 +287,7 @@ pabc_get_issuer (void *cls,
283 287
284 json_root = json_loads (data, JSON_DECODE_ANY, json_err); 288 json_root = json_loads (data, JSON_DECODE_ANY, json_err);
285 if ((NULL == json_root) || 289 if ((NULL == json_root) ||
286 (!json_is_object (json_root))) 290 (! json_is_object (json_root)))
287 { 291 {
288 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 292 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
289 "%s is not a valid pabc credentials (not an object)\n", 293 "%s is not a valid pabc credentials (not an object)\n",
@@ -294,7 +298,7 @@ pabc_get_issuer (void *cls,
294 } 298 }
295 json_attrs = json_object_get (json_root, "attributes"); 299 json_attrs = json_object_get (json_root, "attributes");
296 if ((NULL == json_attrs) || 300 if ((NULL == json_attrs) ||
297 (!json_is_array (json_attrs))) 301 (! json_is_array (json_attrs)))
298 { 302 {
299 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 303 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
300 "%s is not a valid pabc credentials (attributes not an array)\n", 304 "%s is not a valid pabc credentials (attributes not an array)\n",
@@ -306,23 +310,23 @@ pabc_get_issuer (void *cls,
306 for (int i = 0; i < json_array_size (json_attrs); i++) 310 for (int i = 0; i < json_array_size (json_attrs); i++)
307 { 311 {
308 attr = json_array_get (json_attrs, i); 312 attr = json_array_get (json_attrs, i);
309 if (!json_is_object(attr)) 313 if (! json_is_object (attr))
310 continue; 314 continue;
311 /** 315 /**
312 * This *should* only contain a single pair. 316 * This *should* only contain a single pair.
313 */ 317 */
314 json_object_foreach (attr, key, value) 318 json_object_foreach (attr, key, value)
315 { 319 {
316 if (0 != strcmp ("issuer", key)) 320 if (0 != strcmp (skey, key))
317 continue; 321 continue;
318 val_str = json_dumps (value, JSON_ENCODE_ANY); 322 val_str = json_dumps (value, JSON_ENCODE_ANY);
319 tmp = val_str; 323 tmp = val_str;
320 //Remove leading " from jasson conversion 324 // Remove leading " from jasson conversion
321 if (tmp[0] == '"') 325 if (tmp[0] == '"')
322 tmp++; 326 tmp++;
323 //Remove trailing " from jansson conversion 327 // Remove trailing " from jansson conversion
324 if (tmp[strlen(tmp)-1] == '"') 328 if (tmp[strlen (tmp) - 1] == '"')
325 tmp[strlen(tmp)-1] = '\0'; 329 tmp[strlen (tmp) - 1] = '\0';
326 GNUNET_free (val_str); 330 GNUNET_free (val_str);
327 json_decref (json_root); 331 json_decref (json_root);
328 return tmp; 332 return tmp;
@@ -340,9 +344,25 @@ pabc_get_issuer (void *cls,
340 * @param cred the pabc credential 344 * @param cred the pabc credential
341 * @return a string, containing the isser 345 * @return a string, containing the isser
342 */ 346 */
347char*
348pabc_get_issuer (void *cls,
349 const char *data,
350 size_t data_size)
351{
352 return pabc_get_attribute (cls, data, data_size, "issuer");
353}
354
355
356/**
357 * Parse a pabc and return the issuer
358 *
359 * @param cls the plugin
360 * @param cred the pabc credential
361 * @return a string, containing the isser
362 */
343char * 363char *
344pabc_get_issuer_c (void *cls, 364pabc_get_issuer_c (void *cls,
345 const struct GNUNET_RECLAIM_Credential *cred) 365 const struct GNUNET_RECLAIM_Credential *cred)
346{ 366{
347 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type) 367 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type)
348 return NULL; 368 return NULL;
@@ -359,7 +379,7 @@ pabc_get_issuer_c (void *cls,
359 */ 379 */
360char * 380char *
361pabc_get_issuer_p (void *cls, 381pabc_get_issuer_p (void *cls,
362 const struct GNUNET_RECLAIM_Presentation *cred) 382 const struct GNUNET_RECLAIM_Presentation *cred)
363{ 383{
364 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type) 384 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type)
365 return NULL; 385 return NULL;
@@ -376,20 +396,20 @@ pabc_get_issuer_p (void *cls,
376 */ 396 */
377int 397int
378pabc_get_expiration (void *cls, 398pabc_get_expiration (void *cls,
379 const char *data, 399 const char *data,
380 size_t data_size, 400 size_t data_size,
381 struct GNUNET_TIME_Absolute *exp) 401 struct GNUNET_TIME_Absolute *exp)
382{ 402{
383 json_t *json_root; 403 json_t *json_root;
384 json_t *json_attrs; 404 json_t *json_attrs;
385 json_t *value; 405 json_t *value;
386 json_t *attr; 406 json_t *attr;
387 json_error_t *json_err = NULL; 407 json_error_t *json_err = NULL;
388 const char* key; 408 const char*key;
389 409
390 json_root = json_loads (data, JSON_DECODE_ANY, json_err); 410 json_root = json_loads (data, JSON_DECODE_ANY, json_err);
391 if ((NULL == json_root) || 411 if ((NULL == json_root) ||
392 (!json_is_object (json_root))) 412 (! json_is_object (json_root)))
393 { 413 {
394 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 414 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
395 "%s is not a valid pabc credentials (not an object)\n", 415 "%s is not a valid pabc credentials (not an object)\n",
@@ -401,7 +421,7 @@ pabc_get_expiration (void *cls,
401 for (int i = 0; i < json_array_size (json_attrs); i++) 421 for (int i = 0; i < json_array_size (json_attrs); i++)
402 { 422 {
403 attr = json_array_get (json_attrs, i); 423 attr = json_array_get (json_attrs, i);
404 if (!json_is_object(attr)) 424 if (! json_is_object (attr))
405 continue; 425 continue;
406 /** 426 /**
407 * This *should* only contain a single pair. 427 * This *should* only contain a single pair.
@@ -410,7 +430,7 @@ pabc_get_expiration (void *cls,
410 { 430 {
411 if (0 != strcmp ("expiration", key)) 431 if (0 != strcmp ("expiration", key))
412 continue; 432 continue;
413 if (!json_is_integer (value)) 433 if (! json_is_integer (value))
414 continue; 434 continue;
415 exp->abs_value_us = json_integer_value (value) * 1000 * 1000; 435 exp->abs_value_us = json_integer_value (value) * 1000 * 1000;
416 json_decref (json_root); 436 json_decref (json_root);
@@ -431,8 +451,8 @@ pabc_get_expiration (void *cls,
431 */ 451 */
432int 452int
433pabc_get_expiration_c (void *cls, 453pabc_get_expiration_c (void *cls,
434 const struct GNUNET_RECLAIM_Credential *cred, 454 const struct GNUNET_RECLAIM_Credential *cred,
435 struct GNUNET_TIME_Absolute *exp) 455 struct GNUNET_TIME_Absolute *exp)
436{ 456{
437 return pabc_get_expiration (cls, cred->data, cred->data_size, exp); 457 return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
438} 458}
@@ -447,8 +467,8 @@ pabc_get_expiration_c (void *cls,
447 */ 467 */
448int 468int
449pabc_get_expiration_p (void *cls, 469pabc_get_expiration_p (void *cls,
450 const struct GNUNET_RECLAIM_Presentation *cred, 470 const struct GNUNET_RECLAIM_Presentation *cred,
451 struct GNUNET_TIME_Absolute *exp) 471 struct GNUNET_TIME_Absolute *exp)
452{ 472{
453 return pabc_get_expiration (cls, cred->data, cred->data_size, exp); 473 return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
454} 474}
@@ -456,9 +476,9 @@ pabc_get_expiration_p (void *cls,
456 476
457int 477int
458pabc_create_presentation (void *cls, 478pabc_create_presentation (void *cls,
459 const struct GNUNET_RECLAIM_Credential *credential, 479 const struct GNUNET_RECLAIM_Credential *credential,
460 const struct GNUNET_RECLAIM_AttributeList *attrs, 480 const struct GNUNET_RECLAIM_AttributeList *attrs,
461 struct GNUNET_RECLAIM_Presentation **pres) 481 struct GNUNET_RECLAIM_Presentation **pres)
462{ 482{
463 struct pabc_context *ctx = NULL; 483 struct pabc_context *ctx = NULL;
464 struct pabc_user_context *usr_ctx = NULL; 484 struct pabc_user_context *usr_ctx = NULL;
@@ -466,6 +486,8 @@ pabc_create_presentation (void *cls,
466 struct pabc_credential *cred = NULL; 486 struct pabc_credential *cred = NULL;
467 struct pabc_blinded_proof *proof = NULL; 487 struct pabc_blinded_proof *proof = NULL;
468 struct GNUNET_RECLAIM_AttributeListEntry *ale; 488 struct GNUNET_RECLAIM_AttributeListEntry *ale;
489 char *issuer;
490 char *subject;
469 enum pabc_status status; 491 enum pabc_status status;
470 492
471 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != credential->type) 493 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != credential->type)
@@ -478,16 +500,28 @@ pabc_create_presentation (void *cls,
478 * Ideal would be an API that allows us to load pp by 500 * Ideal would be an API that allows us to load pp by
479 * issuer name. 501 * issuer name.
480 */ 502 */
481 //status = load_public_parameters (ctx, "issuerXY", &pp); 503 issuer = pabc_get_issuer_c (cls, credential);
504 if (NULL == issuer)
505 {
506 pabc_free_ctx (&ctx);
507 return GNUNET_SYSERR;
508 }
509 status = PABC_load_public_parameters (ctx, issuer, &pp);
482 if (status != PABC_OK) 510 if (status != PABC_OK)
483 { 511 {
484 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 512 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
485 "Failed to read public parameters.\n"); 513 "Failed to read public parameters.\n");
486 pabc_free_ctx (&ctx); 514 pabc_free_ctx (&ctx);
515 GNUNET_free (issuer);
487 return GNUNET_SYSERR; 516 return GNUNET_SYSERR;
488 } 517 }
489 //FIXME needs API 518 subject = pabc_get_attribute (cls,
490 //status = read_usr_ctx (usr_name, pp_name, ctx, pp, &usr_ctx); 519 credential->data,
520 credential->data_size,
521 "subject");
522 status = PABC_read_usr_ctx (subject, issuer, ctx, pp, &usr_ctx);
523 GNUNET_free (issuer);
524 GNUNET_free (subject);
491 if (PABC_OK != status) 525 if (PABC_OK != status)
492 { 526 {
493 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 527 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/reclaim/plugin_rest_pabc.c b/src/reclaim/plugin_rest_pabc.c
index c3bb8847f..e5099a012 100644
--- a/src/reclaim/plugin_rest_pabc.c
+++ b/src/reclaim/plugin_rest_pabc.c
@@ -33,6 +33,7 @@
33#include "gnunet_rest_lib.h" 33#include "gnunet_rest_lib.h"
34#include "gnunet_rest_plugin.h" 34#include "gnunet_rest_plugin.h"
35#include "gnunet_signatures.h" 35#include "gnunet_signatures.h"
36#include "pabc_helper.h"
36 37
37/** 38/**
38 * REST root namespace 39 * REST root namespace
@@ -221,15 +222,44 @@ set_attributes_from_idtoken (const struct pabc_context *ctx,
221{ 222{
222 json_t *payload_json; 223 json_t *payload_json;
223 json_t *value; 224 json_t *value;
225 json_error_t json_err;
224 const char *key; 226 const char *key;
227 const char *jwt_body;
228 char *decoded_jwt;
229 char delim[] = ".";
230 char *jwt_string;
231 const char *pabc_key;
225 enum pabc_status status; 232 enum pabc_status status;
226 233
227 //FIXME parse JWT 234 //FIXME parse JWT
235 jwt_string = GNUNET_strndup (id_token, strlen (id_token));
236 jwt_body = strtok (jwt_string, delim);
237 jwt_body = strtok (NULL, delim);
238 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
239 (void **) &decoded_jwt);
240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded ID Token: %s\n", decoded_jwt);
241 payload_json = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
242 GNUNET_free (decoded_jwt);
243
228 json_object_foreach(payload_json, key, value) 244 json_object_foreach(payload_json, key, value)
229 { 245 {
230 //FIXME skip metadata in JWT, map attributes to PP 246 pabc_key = key;
247 if (0 == strcmp ("iss", key))
248 pabc_key = "issuer"; //rename
249 if (0 == strcmp ("sub", key))
250 pabc_key = "subject"; //rename
251 if (0 == strcmp ("jti", key))
252 continue;
253 if (0 == strcmp ("exp", key))
254 pabc_key = "expiration"; //rename
255 if (0 == strcmp ("iat", key))
256 continue;
257 if (0 == strcmp ("nbf", key))
258 continue;
259 if (0 == strcmp ("aud", key))
260 continue;
231 status = pabc_set_attribute_value_by_name (ctx, pp, usr_ctx, 261 status = pabc_set_attribute_value_by_name (ctx, pp, usr_ctx,
232 key, 262 pabc_key,
233 json_string_value (value)); 263 json_string_value (value));
234 if (PABC_OK != status) 264 if (PABC_OK != status)
235 { 265 {
@@ -254,6 +284,8 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
254 json_t *nonce_json; 284 json_t *nonce_json;
255 json_t *pp_json; 285 json_t *pp_json;
256 json_t *idtoken_json; 286 json_t *idtoken_json;
287 json_t *iss_json;
288 json_t *identity_json;
257 json_error_t err; 289 json_error_t err;
258 struct pabc_public_parameters *pp = NULL; 290 struct pabc_public_parameters *pp = NULL;
259 struct pabc_context *ctx = NULL; 291 struct pabc_context *ctx = NULL;
@@ -302,6 +334,24 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
302 GNUNET_SCHEDULER_add_now (&do_error, handle); 334 GNUNET_SCHEDULER_add_now (&do_error, handle);
303 return; 335 return;
304 } 336 }
337 iss_json = json_object_get (data_json, "issuer");
338 if (NULL == iss_json)
339 {
340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
341 "Unable to parse issuer\n");
342 json_decref (data_json);
343 GNUNET_SCHEDULER_add_now (&do_error, handle);
344 return;
345 }
346 identity_json = json_object_get (data_json, "identity");
347 if (NULL == identity_json)
348 {
349 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
350 "Unable to parse identity\n");
351 json_decref (data_json);
352 GNUNET_SCHEDULER_add_now (&do_error, handle);
353 return;
354 }
305 idtoken_json = json_object_get (idtoken_json, "id_token"); 355 idtoken_json = json_object_get (idtoken_json, "id_token");
306 if (NULL == idtoken_json) 356 if (NULL == idtoken_json)
307 { 357 {
@@ -322,8 +372,9 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
322 } 372 }
323 373
324 PABC_ASSERT (pabc_new_ctx (&ctx)); 374 PABC_ASSERT (pabc_new_ctx (&ctx));
325 // load stuff FIXME: Needs helper 375 status = PABC_load_public_parameters (ctx,
326 //status = load_public_parameters (ctx, pp_name, &pp); 376 json_string_value (iss_json),
377 &pp);
327 if (status != PABC_OK) 378 if (status != PABC_OK)
328 { 379 {
329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to read public parameters.\n"); 380 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to read public parameters.\n");
@@ -332,9 +383,9 @@ cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
332 return; 383 return;
333 } 384 }
334 385
335 /*FIXME: Needs helper 386 status = PABC_read_usr_ctx (json_string_value (identity_json),
336 * status = read_usr_ctx (usr_name, pp_name, ctx, pp, &usr_ctx); 387 json_string_value (iss_json),
337 */ 388 ctx, pp, &usr_ctx);
338 if (PABC_OK != status) 389 if (PABC_OK != status)
339 { 390 {
340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to read user context.\n"); 391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to read user context.\n");