aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2021-02-22 13:30:19 +0100
committerMartin Schanzenbach <mschanzenbach@posteo.de>2021-04-20 10:50:33 +0200
commitbc3ee32f932c63ffd012318d8c9847aff9efd5ef (patch)
tree4c9d3956bc56f4cc05748012ae8cdb30412adc58
parentfe1e96aacc071b9b568843a77a95803908f9f74d (diff)
downloadgnunet-bc3ee32f932c63ffd012318d8c9847aff9efd5ef.tar.gz
gnunet-bc3ee32f932c63ffd012318d8c9847aff9efd5ef.zip
RECLAIM: Support PABC presentation generation
-rw-r--r--src/reclaim/plugin_reclaim_credential_pabc.c361
1 files changed, 229 insertions, 132 deletions
diff --git a/src/reclaim/plugin_reclaim_credential_pabc.c b/src/reclaim/plugin_reclaim_credential_pabc.c
index 765652355..422d7c82b 100644
--- a/src/reclaim/plugin_reclaim_credential_pabc.c
+++ b/src/reclaim/plugin_reclaim_credential_pabc.c
@@ -99,7 +99,7 @@ static struct
99{ 99{
100 const char *name; 100 const char *name;
101 uint32_t number; 101 uint32_t number;
102} pabc_cred_name_map[] = { { "pabc", GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC }, 102} pabc_cred_name_map[] = { { "PABC", GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC },
103 { NULL, UINT32_MAX } }; 103 { NULL, UINT32_MAX } };
104 104
105/** 105/**
@@ -155,89 +155,73 @@ pabc_parse_attributes (void *cls,
155 const char *data, 155 const char *data,
156 size_t data_size) 156 size_t data_size)
157{ 157{
158 char *pabc_string; 158 const char *key;
159 struct GNUNET_RECLAIM_AttributeList *attrs; 159 struct GNUNET_RECLAIM_AttributeList *attrs;
160 char delim[] = ".";
161 char *val_str = NULL; 160 char *val_str = NULL;
162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing pabc attributes.\n");
163 char *decoded_pabc;
164 char *tmp; 161 char *tmp;
165 json_t *json_val; 162 json_t *value;
163 json_t *attr;
164 json_t *json_attrs;
165 json_t *json_root;
166 json_error_t *json_err = NULL; 166 json_error_t *json_err = NULL;
167 167
168 attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); 168 json_root = json_loads (data, JSON_DECODE_ANY, json_err);
169 if ((NULL == json_root) ||
170 (!json_is_object (json_root)))
171 {
172 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
173 "%s is not a valid pabc credentials (not an object)\n",
174 data);
175 if (NULL != json_root)
176 json_decref (json_root);
177 return NULL;
178 }
179 json_attrs = json_object_get (json_root, "attributes");
180 if ((NULL == json_attrs) ||
181 (!json_is_array (json_attrs)))
182 {
183 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
184 "%s is not a valid pabc credentials (attributes not an array)\n",
185 data);
186 json_decref (json_root);
187 return NULL;
188 }
169 189
170 pabc_string = GNUNET_strndup (data, data_size); 190 attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
171 const char *pabc_body = strtok (pabc_string, delim); 191 for (int i = 0; i < json_array_size (json_attrs); i++)
172 pabc_body = strtok (NULL, delim); 192 {
173 GNUNET_STRINGS_base64url_decode (pabc_body, strlen (pabc_body), 193 attr = json_array_get (json_attrs, i);
174 (void **) &decoded_pabc); 194 if (!json_is_object(attr))
175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded pabc: %s\n", decoded_pabc);
176 GNUNET_assert (NULL != decoded_pabc);
177 json_val = json_loads (decoded_pabc, JSON_DECODE_ANY, json_err);
178 GNUNET_free (decoded_pabc);
179 const char *key;
180 const char *addr_key;
181 json_t *value;
182 json_t *addr_value;
183
184 json_object_foreach (json_val, key, value) {
185 if (0 == strcmp ("iss", key))
186 continue;
187 if (0 == strcmp ("jti", key))
188 continue;
189 if (0 == strcmp ("exp", key))
190 continue;
191 if (0 == strcmp ("iat", key))
192 continue;
193 if (0 == strcmp ("nbf", key))
194 continue;
195 if (0 == strcmp ("aud", key))
196 continue;
197 if (0 == strcmp ("address", key))
198 { 195 {
199 if (!json_is_object(value)) { 196 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
200 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 197 "Found json entry is not an object!\n");
201 "address claim in wrong format!"); 198 GNUNET_RECLAIM_attribute_list_destroy (attrs);
202 continue; 199 json_decref (json_root);
203 } 200 return NULL;
204 json_object_foreach (value, addr_key, addr_value) { 201 }
205 val_str = json_dumps (addr_value, JSON_ENCODE_ANY); 202 /**
206 tmp = val_str; 203 * This *should* only contain a single pair.
207 //Remove leading " from jasson conversion 204 */
208 if (tmp[0] == '"') 205 json_object_foreach (attr, key, value)
209 tmp++; 206 {
210 //Remove trailing " from jansson conversion 207 val_str = json_dumps (value, JSON_ENCODE_ANY);
211 if (tmp[strlen(tmp)-1] == '"') 208 tmp = val_str;
212 tmp[strlen(tmp)-1] = '\0'; 209 //Remove leading " from jasson conversion
213 GNUNET_RECLAIM_attribute_list_add (attrs, 210 if (tmp[0] == '"')
214 addr_key, 211 tmp++;
215 NULL, 212 //Remove trailing " from jansson conversion
216 GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING, 213 if (tmp[strlen(tmp)-1] == '"')
217 tmp, 214 tmp[strlen(tmp)-1] = '\0';
218 strlen (val_str)); 215 GNUNET_RECLAIM_attribute_list_add (attrs,
219 GNUNET_free (val_str); 216 key,
220 } 217 NULL,
221 continue; 218 GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING,
219 tmp,
220 strlen (tmp));
221 GNUNET_free (val_str);
222 } 222 }
223 val_str = json_dumps (value, JSON_ENCODE_ANY);
224 tmp = val_str;
225 //Remove leading " from jasson conversion
226 if (tmp[0] == '"')
227 tmp++;
228 //Remove trailing " from jansson conversion
229 if (tmp[strlen(tmp)-1] == '"')
230 tmp[strlen(tmp)-1] = '\0';
231 GNUNET_RECLAIM_attribute_list_add (attrs,
232 key,
233 NULL,
234 GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING,// FIXME
235 tmp,
236 strlen (val_str));
237 GNUNET_free (val_str);
238 } 223 }
239 json_decref (json_val); 224 json_decref (json_root);
240 GNUNET_free (pabc_string);
241 return attrs; 225 return attrs;
242} 226}
243 227
@@ -284,34 +268,41 @@ pabc_get_issuer (void *cls,
284 const char *data, 268 const char *data,
285 size_t data_size) 269 size_t data_size)
286{ 270{
287 const char *pabc_body; 271 char *val_str = NULL;
288 char *pabc_string; 272 char *tmp;
289 char delim[] = "."; 273 json_t *json_iss;
290 char *issuer = NULL; 274 json_t *json_root;
291 char *decoded_pabc;
292 json_t *issuer_json;
293 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing pabc attributes.\n");
294 json_t *json_val;
295 json_error_t *json_err = NULL; 275 json_error_t *json_err = NULL;
296 276
297 pabc_string = GNUNET_strndup (data, data_size); 277 json_root = json_loads (data, JSON_DECODE_ANY, json_err);
298 pabc_body = strtok (pabc_string, delim); 278 if ((NULL == json_root) ||
299 pabc_body = strtok (NULL, delim); 279 (!json_is_object (json_root)))
300 GNUNET_STRINGS_base64url_decode (pabc_body, strlen (pabc_body), 280 {
301 (void **) &decoded_pabc); 281 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
302 json_val = json_loads (decoded_pabc, JSON_DECODE_ANY, json_err); 282 "%s is not a valid pabc credentials (not an object)\n",
303 GNUNET_free (decoded_pabc); 283 data);
304 GNUNET_free (pabc_string); 284 if (NULL != json_root)
305 if (NULL == json_val) 285 json_decref (json_root);
306 return NULL; 286 return NULL;
307 issuer_json = json_object_get (json_val, "iss"); 287 }
308 if ((NULL == issuer_json) || (! json_is_string (issuer_json))) { 288 json_iss = json_object_get (json_root, "issuer");
309 json_decref (json_val); 289 if (NULL == json_iss)
290 {
291 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
292 "%s is not a valid pabc credential (issuer malformed or missing)\n",
293 data);
294 json_decref (json_root);
310 return NULL; 295 return NULL;
311 } 296 }
312 issuer = GNUNET_strdup (json_string_value (issuer_json)); 297 val_str = json_dumps (json_iss, JSON_ENCODE_ANY);
313 json_decref (json_val); 298 tmp = val_str;
314 return issuer; 299 //Remove leading " from jasson conversion
300 if (tmp[0] == '"')
301 tmp++;
302 //Remove trailing " from jansson conversion
303 if (tmp[strlen(tmp)-1] == '"')
304 tmp[strlen(tmp)-1] = '\0';
305 return tmp;
315} 306}
316 307
317 308
@@ -362,32 +353,32 @@ pabc_get_expiration (void *cls,
362 size_t data_size, 353 size_t data_size,
363 struct GNUNET_TIME_Absolute *exp) 354 struct GNUNET_TIME_Absolute *exp)
364{ 355{
365 const char *pabc_body; 356 json_t *json_exp;
366 char *pabc_string; 357 json_t *json_root;
367 char delim[] = ".";
368 char *decoded_pabc;
369 json_t *exp_json;
370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing pabc attributes.\n");
371 json_t *json_val;
372 json_error_t *json_err = NULL; 358 json_error_t *json_err = NULL;
373 359
374 pabc_string = GNUNET_strndup (data, data_size); 360 json_root = json_loads (data, JSON_DECODE_ANY, json_err);
375 pabc_body = strtok (pabc_string, delim); 361 if ((NULL == json_root) ||
376 pabc_body = strtok (NULL, delim); 362 (!json_is_object (json_root)))
377 GNUNET_STRINGS_base64url_decode (pabc_body, strlen (pabc_body), 363 {
378 (void **) &decoded_pabc); 364 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
379 json_val = json_loads (decoded_pabc, JSON_DECODE_ANY, json_err); 365 "%s is not a valid pabc credentials (not an object)\n",
380 GNUNET_free (decoded_pabc); 366 data);
381 GNUNET_free (pabc_string); 367 if (NULL != json_root)
382 if (NULL == json_val) 368 json_decref (json_root);
383 return GNUNET_SYSERR; 369 return GNUNET_SYSERR;
384 exp_json = json_object_get (json_val, "exp"); 370 }
385 if ((NULL == exp_json) || (! json_is_integer (exp_json))) { 371 json_exp = json_object_get (json_root, "expiration");
386 json_decref (json_val); 372 if ((NULL == json_exp) || (! json_is_integer (json_exp)))
373 {
374 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
375 "%s is not a valid pabc credential (expiration malformed or missing)\n",
376 data);
377 json_decref (json_root);
387 return GNUNET_SYSERR; 378 return GNUNET_SYSERR;
388 } 379 }
389 exp->abs_value_us = json_integer_value (exp_json) * 1000 * 1000; 380 exp->abs_value_us = json_integer_value (json_exp) * 1000 * 1000;
390 json_decref (json_val); 381 json_decref (json_root);
391 return GNUNET_OK; 382 return GNUNET_OK;
392} 383}
393 384
@@ -426,16 +417,130 @@ pabc_get_expiration_p (void *cls,
426 417
427int 418int
428pabc_create_presentation (void *cls, 419pabc_create_presentation (void *cls,
429 const struct GNUNET_RECLAIM_Credential *cred, 420 const struct GNUNET_RECLAIM_Credential *credential,
430 const struct GNUNET_RECLAIM_AttributeList *attrs, 421 const struct GNUNET_RECLAIM_AttributeList *attrs,
431 struct GNUNET_RECLAIM_Presentation **pres) 422 struct GNUNET_RECLAIM_Presentation **pres)
432{ 423{
433 // FIXME sanity checks?? 424 struct pabc_context *ctx = NULL;
434 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type) 425 struct pabc_user_context *usr_ctx = NULL;
426 struct pabc_public_parameters *pp = NULL;
427 struct pabc_credential *cred = NULL;
428 struct pabc_blinded_proof *proof = NULL;
429 struct GNUNET_RECLAIM_AttributeListEntry *ale;
430 enum pabc_status status;
431
432 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != credential->type)
435 return GNUNET_NO; 433 return GNUNET_NO;
434
435
436 PABC_ASSERT (pabc_new_ctx (&ctx));
437 /**
438 * FIXME, how to get pp_name.
439 * Ideal would be an API that allows us to load pp by
440 * issuer name.
441 */
442 //status = load_public_parameters (ctx, "issuerXY", &pp);
443 if (status != PABC_OK)
444 {
445 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
446 "Failed to read public parameters.\n");
447 pabc_free_ctx (&ctx);
448 return GNUNET_SYSERR;
449 }
450 //FIXME needs API
451 //status = read_usr_ctx (usr_name, pp_name, ctx, pp, &usr_ctx);
452 if (PABC_OK != status)
453 {
454 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
455 "Failed to read user context.\n");
456 pabc_free_public_parameters (ctx, &pp);
457 return GNUNET_SYSERR;
458 }
459
460 status = pabc_new_credential (ctx, pp, &cred);
461 if (status != PABC_OK)
462 {
463 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
464 "Failed to allocate credential.\n");
465 pabc_free_user_context (ctx, pp, &usr_ctx);
466 pabc_free_public_parameters (ctx, &pp);
467 return GNUNET_SYSERR;
468 }
469
470 status = pabc_decode_credential (ctx, pp, cred, credential->data);
471 if (status != PABC_OK)
472 {
473 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
474 "Failed to decode credential.\n");
475 pabc_free_credential (ctx, pp, &cred);
476 pabc_free_user_context (ctx, pp, &usr_ctx);
477 pabc_free_public_parameters (ctx, &pp);
478 return GNUNET_SYSERR;
479 }
480
481 status = pabc_new_proof (ctx, pp, &proof);
482 if (status != PABC_OK)
483 {
484 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
485 "Failed to allocate proof.\n");
486 pabc_free_credential (ctx, pp, &cred);
487 pabc_free_user_context (ctx, pp, &usr_ctx);
488 pabc_free_public_parameters (ctx, &pp);
489 return GNUNET_SYSERR;
490 }
491
492 // now we can parse the attributes to disclose and configure the proof
493 for (ale = attrs->list_head; NULL != ale; ale = ale->next)
494 {
495 status = pabc_set_disclosure_by_attribute_name (ctx, pp, proof,
496 ale->attribute->name,
497 PABC_DISCLOSED, cred);
498 if (status != PABC_OK)
499 {
500 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
501 "Failed to configure proof.\n");
502 pabc_free_credential (ctx, pp, &cred);
503 pabc_free_user_context (ctx, pp, &usr_ctx);
504 pabc_free_public_parameters (ctx, &pp);
505 return GNUNET_SYSERR;
506 }
507 }
508
509 // and finally -> sign the proof
510 status = pabc_gen_proof (ctx, usr_ctx, pp, proof, cred);
511 if (status != PABC_OK)
512 {
513 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
514 "Failed to sign proof.\n");
515 pabc_free_proof (ctx, pp, &proof);
516 pabc_free_credential (ctx, pp, &cred);
517 pabc_free_user_context (ctx, pp, &usr_ctx);
518 pabc_free_public_parameters (ctx, &pp);
519 return GNUNET_SYSERR;
520 }
521 // print the result
522 char *json = NULL;
523 pabc_encode_proof (ctx, pp, proof, &json);
524 if (PABC_OK != status)
525 {
526 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
527 "Failed to serialize proof.\n");
528 pabc_free_proof (ctx, pp, &proof);
529 pabc_free_credential (ctx, pp, &cred);
530 pabc_free_user_context (ctx, pp, &usr_ctx);
531 pabc_free_public_parameters (ctx, &pp);
532 return GNUNET_SYSERR;
533 }
534 printf ("%s", json);
535 // clean up
436 *pres = GNUNET_RECLAIM_presentation_new (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC, 536 *pres = GNUNET_RECLAIM_presentation_new (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC,
437 cred->data, 537 json,
438 cred->data_size); 538 strlen (json) + 1);
539 PABC_FREE_NULL (json);
540 pabc_free_proof (ctx, pp, &proof);
541 pabc_free_credential (ctx, pp, &cred);
542 pabc_free_user_context (ctx, pp, &usr_ctx);
543 pabc_free_public_parameters (ctx, &pp);
439 return GNUNET_OK; 544 return GNUNET_OK;
440} 545}
441 546
@@ -450,14 +555,6 @@ void *
450libgnunet_plugin_reclaim_credential_pabc_init (void *cls) 555libgnunet_plugin_reclaim_credential_pabc_init (void *cls)
451{ 556{
452 struct GNUNET_RECLAIM_CredentialPluginFunctions *api; 557 struct GNUNET_RECLAIM_CredentialPluginFunctions *api;
453 struct pabc_context *ctx;
454
455 if (PABC_OK != pabc_new_ctx (&ctx))
456 {
457 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
458 "Unable to initialize pabc context\n");
459 return NULL;
460 }
461 558
462 api = GNUNET_new (struct GNUNET_RECLAIM_CredentialPluginFunctions); 559 api = GNUNET_new (struct GNUNET_RECLAIM_CredentialPluginFunctions);
463 api->value_to_string = &pabc_value_to_string; 560 api->value_to_string = &pabc_value_to_string;