aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/handbook/chapters/user.texi66
-rw-r--r--src/reclaim/gnunet-service-reclaim.c411
-rw-r--r--src/reclaim/gnunet-service-reclaim_tickets.c1
-rw-r--r--src/reclaim/oidc_helper.c23
-rw-r--r--src/reclaim/plugin_reclaim_attribute_basic.c2
-rw-r--r--src/reclaim/plugin_reclaim_credential_jwt.c49
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c40
-rw-r--r--src/reclaim/plugin_rest_reclaim.c2
-rw-r--r--src/reclaim/reclaim_attribute.c31
-rw-r--r--src/reclaim/reclaim_credential.c36
10 files changed, 486 insertions, 175 deletions
diff --git a/doc/handbook/chapters/user.texi b/doc/handbook/chapters/user.texi
index 4ae9aa951..ebc1a7979 100644
--- a/doc/handbook/chapters/user.texi
+++ b/doc/handbook/chapters/user.texi
@@ -2000,9 +2000,11 @@ integrate reclaimID as an Identity Provider with little effort.
2000 2000
2001@menu 2001@menu
2002* Managing Attributes:: 2002* Managing Attributes::
2003* Managing Credentials::
2003* Sharing Attributes with Third Parties:: 2004* Sharing Attributes with Third Parties::
2004* Revoking Authorizations of Third Parties:: 2005* Revoking Authorizations of Third Parties::
2005* OpenID Connect:: 2006* OpenID Connect::
2007* Providing Third Party Attestation::
2006@end menu 2008@end menu
2007 2009
2008@node Managing Attributes 2010@node Managing Attributes
@@ -2032,13 +2034,51 @@ $ gnunet-reclaim -e "user" -D
2032Currently, and by default, attribute values are interpreted as plain text. 2034Currently, and by default, attribute values are interpreted as plain text.
2033In the future there might be more value types such as X.509 certificate credentials. 2035In the future there might be more value types such as X.509 certificate credentials.
2034 2036
2037@node Managing Credentials
2038@subsection Managing Credentials
2039
2040Attribute values may reference a claim in a third party attested credential.
2041Such a credential can have a variety of formats such as JSON-Web-Tokens or
2042X.509 certificates.
2043Currently, reclaimID only supports JSON-Web-Token credentials.
2044
2045To add a credential to your user profile, invoke the @command{gnunet-reclaim} command line tool as follows:
2046
2047@example
2048$ gnunet-reclaim -e "user"\
2049 --credential-name="email"\
2050 --credential-type="JWT"\
2051 --value="ey..."
2052@end example
2053
2054All of your credentials can be listed using the @command{gnunet-reclaim}
2055command line tool as well:
2056
2057@example
2058$ gnunet-reclaim -e "user" --credentials
2059@end example
2060
2061In order to add an attribe backed by a credential, specify the attribute
2062value as the claim name in the credential to reference along with the credential
2063ID:
2064
2065@example
2066$ gnunet-reclaim -e "user"\
2067 --add="email"\
2068 --value="verified_email"\
2069 --credential-id="<CREDENTIAL_ID>"
2070@end example
2071
2072
2035@node Sharing Attributes with Third Parties 2073@node Sharing Attributes with Third Parties
2036@subsection Sharing Attributes with Third Parties 2074@subsection Sharing Attributes with Third Parties
2037 2075
2038If you want to allow a third party such as a website or friend to access to your attributes (or a subset thereof) execute: 2076If you want to allow a third party such as a website or friend to access to your attributes (or a subset thereof) execute:
2039 2077
2040@example 2078@example
2041$ TICKET=$(gnunet-reclaim -e "user" -r "$RP_KEY" -i "attribute1,attribute2,...") 2079$ TICKET=$(gnunet-reclaim -e "user"\
2080 -r "$RP_KEY"\
2081 -i "attribute1,attribute2,...")
2042@end example 2082@end example
2043 2083
2044The command will return a "ticket" string. 2084The command will return a "ticket" string.
@@ -2173,6 +2213,30 @@ The authorization code flow optionally supports @uref{https://tools.ietf.org/htm
2173If PKCE is used, the client does not need to authenticate against the token 2213If PKCE is used, the client does not need to authenticate against the token
2174endpoint. 2214endpoint.
2175 2215
2216@node Providing Third Party Attestation
2217@subsection Providing Third Party Attestation
2218
2219If you are running an identity provider (IdP) service you may be able to
2220support providing credentials for re:claimID users.
2221IdPs can issue JWT credentials as long as they support OpenID Connect and
2222@uref{https://openid.net/specs/openid-connect-discovery-1_0.html,OpenID Connect Discovery}.
2223
2224In order to allow users to import attributes through the re:claimID user interface,
2225you need to register the following public OAuth2/OIDC client:
2226
2227@itemize @bullet
2228@item client_id: reclaimid
2229@item client_secret: none
2230@item redirect_uri: https://ui.reclaim (The URI of the re:claimID webextension)
2231@item grant_type: authorization_code with PKCE (@uref{https://tools.ietf.org/html/rfc7636, RFC7636})
2232@item scopes: all you want to offer.
2233@item id_token: JWT
2234@end itemize
2235
2236When your users add an attribute with name "email" which supports webfinger
2237discovery they will be prompted with the option to retrieve the OpenID Connect
2238ID Token through the user interface.
2239
2176@node Using the Virtual Public Network 2240@node Using the Virtual Public Network
2177@section Using the Virtual Public Network 2241@section Using the Virtual Public Network
2178 2242
diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c
index 5614f05db..913b667b7 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -300,6 +300,16 @@ struct AttributeDeleteHandle
300 struct TicketRecordsEntry *tickets_to_update_tail; 300 struct TicketRecordsEntry *tickets_to_update_tail;
301 301
302 /** 302 /**
303 * Existing attributes
304 */
305 struct GNUNET_RECLAIM_AttributeList *existing_attributes;
306
307 /**
308 * Existing credentials
309 */
310 struct GNUNET_RECLAIM_CredentialList *existing_credentials;
311
312 /**
303 * Attribute label 313 * Attribute label
304 */ 314 */
305 char *label; 315 char *label;
@@ -490,6 +500,10 @@ cleanup_adh (struct AttributeDeleteHandle *adh)
490 GNUNET_free (adh->claim); 500 GNUNET_free (adh->claim);
491 if (NULL != adh->credential) 501 if (NULL != adh->credential)
492 GNUNET_free (adh->credential); 502 GNUNET_free (adh->credential);
503 if (NULL != adh->existing_credentials)
504 GNUNET_RECLAIM_credential_list_destroy (adh->existing_credentials);
505 if (NULL != adh->existing_attributes)
506 GNUNET_RECLAIM_attribute_list_destroy (adh->existing_attributes);
493 while (NULL != (le = adh->tickets_to_update_head)) 507 while (NULL != (le = adh->tickets_to_update_head))
494 { 508 {
495 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head, 509 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
@@ -1301,7 +1315,7 @@ send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
1301 * @param rd record data 1315 * @param rd record data
1302 */ 1316 */
1303static void 1317static void
1304ticket_iter (void *cls, 1318consistency_iter (void *cls,
1305 const struct GNUNET_IDENTITY_PrivateKey *zone, 1319 const struct GNUNET_IDENTITY_PrivateKey *zone,
1306 const char *label, 1320 const char *label,
1307 unsigned int rd_count, 1321 unsigned int rd_count,
@@ -1309,26 +1323,42 @@ ticket_iter (void *cls,
1309{ 1323{
1310 struct AttributeDeleteHandle *adh = cls; 1324 struct AttributeDeleteHandle *adh = cls;
1311 struct TicketRecordsEntry *le; 1325 struct TicketRecordsEntry *le;
1312 int has_changed = GNUNET_NO; 1326 struct GNUNET_RECLAIM_AttributeListEntry *ale;
1327 struct GNUNET_RECLAIM_CredentialListEntry *cle;
1328 int is_ticket = GNUNET_NO;
1313 for (int i = 0; i < rd_count; i++) 1329 for (int i = 0; i < rd_count; i++)
1314 { 1330 {
1315 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF != rd[i].record_type) 1331 switch (rd[i].record_type) {
1316 continue; 1332 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE:
1317 if (adh->claim != NULL) 1333 ale = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
1318 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data, 1334 GNUNET_RECLAIM_attribute_deserialize (rd[i].data,
1319 &adh->claim->id)) 1335 rd[i].data_size,
1320 continue; 1336 &ale->attribute);
1321 if (adh->credential != NULL) 1337 GNUNET_CONTAINER_DLL_insert (adh->existing_attributes->list_head,
1322 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data, 1338 adh->existing_attributes->list_tail,
1323 &adh->credential->id)) 1339 ale);
1324 continue; 1340 break;
1325 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1341 case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL:
1326 "Attribute to delete found (%s)\n", 1342 cle = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry);
1327 adh->label); 1343 cle->credential = GNUNET_RECLAIM_credential_deserialize (rd[i].data,
1328 has_changed = GNUNET_YES; 1344 rd[i].data_size);
1329 break; 1345 GNUNET_CONTAINER_DLL_insert (adh->existing_credentials->list_head,
1346 adh->existing_credentials->list_tail,
1347 cle);
1348 break;
1349 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
1350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1351 "Ticket to delete found (%s)\n",
1352 label);
1353 is_ticket = GNUNET_YES;
1354 break;
1355 default:
1356 break;
1357 }
1358 if (GNUNET_YES == is_ticket)
1359 break;
1330 } 1360 }
1331 if (GNUNET_YES == has_changed) 1361 if (GNUNET_YES == is_ticket)
1332 { 1362 {
1333 le = GNUNET_new (struct TicketRecordsEntry); 1363 le = GNUNET_new (struct TicketRecordsEntry);
1334 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd); 1364 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
@@ -1384,15 +1414,12 @@ update_tickets (void *cls)
1384 1414
1385 if (NULL == adh->tickets_to_update_head) 1415 if (NULL == adh->tickets_to_update_head)
1386 { 1416 {
1387 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1388 "Finished updating tickets, success\n"); 1418 "Finished updating tickets, success\n");
1389 send_delete_response (adh, GNUNET_OK); 1419 send_delete_response (adh, GNUNET_OK);
1390 cleanup_adh (adh); 1420 cleanup_adh (adh);
1391 return; 1421 return;
1392 } 1422 }
1393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1394 "Updating %s\n",
1395 adh->tickets_to_update_head->label);
1396 le = adh->tickets_to_update_head; 1423 le = adh->tickets_to_update_head;
1397 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head, 1424 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
1398 adh->tickets_to_update_tail, 1425 adh->tickets_to_update_tail,
@@ -1411,21 +1438,53 @@ update_tickets (void *cls)
1411 return; 1438 return;
1412 } 1439 }
1413 int j = 0; 1440 int j = 0;
1414 for (int i = 0; i < le->rd_count; i++) 1441 int i = 0;
1442 struct GNUNET_RECLAIM_AttributeListEntry *ale;
1443 struct GNUNET_RECLAIM_CredentialListEntry *cle;
1444 struct GNUNET_RECLAIM_Presentation *presentation;
1445 for (i = 0; i < le->rd_count; i++)
1415 { 1446 {
1416 if (adh->claim != NULL) 1447 switch (rd[i].record_type) {
1417 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type) 1448 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF:
1418 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data, 1449 for (ale = adh->existing_attributes->list_head; NULL != ale; ale = ale->next) {
1419 &adh->claim->id))) 1450 if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1420 continue; 1451 &ale->attribute->id)) {
1421 if (adh->credential != NULL) 1452 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1422 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type) 1453 "Found attribute %s, readding...\n",
1423 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data, 1454 ale->attribute->name);
1424 &adh->credential->id))) 1455 rd_new[j] = rd[i];
1425 continue; 1456 j++;
1426 rd_new[j] = rd[i]; 1457 break; //Found and added
1427 j++; 1458 }
1459 }
1460 break;
1461 case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION:
1462 presentation = GNUNET_RECLAIM_presentation_deserialize (rd[i].data,
1463 rd[i].data_size);
1464 for (cle = adh->existing_credentials->list_head; NULL != cle; cle = cle->next) {
1465 if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (&presentation->credential_id,
1466 &cle->credential->id)) {
1467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1468 "Found presentation for credential %s, readding...\n",
1469 cle->credential->name);
1470 rd_new[j] = rd[i];
1471 j++;
1472 break; //Found and added
1473 }
1474 }
1475 GNUNET_free (presentation);
1476 break;
1477 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
1478 rd_new[j] = rd[i];
1479 j++;
1480 break; //Found and added
1481 default:
1482 GNUNET_break (0);
1483 }
1428 } 1484 }
1485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1486 "Updating ticket with %d entries (%d before)...\n",
1487 j, i);
1429 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, 1488 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1430 &adh->identity, 1489 &adh->identity,
1431 le->label, 1490 le->label,
@@ -1438,6 +1497,90 @@ update_tickets (void *cls)
1438 GNUNET_free (le); 1497 GNUNET_free (le);
1439} 1498}
1440 1499
1500/**
1501 * Delete all attributes which reference credentials
1502 * that no longer exist
1503 */
1504static void
1505purge_attributes (void *cls);;
1506
1507static void
1508offending_attr_delete_cont (void *cls, int32_t success, const char *emsg)
1509{
1510 struct AttributeDeleteHandle *adh = cls;
1511
1512 adh->ns_qe = NULL;
1513 if (GNUNET_SYSERR == success)
1514 {
1515 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1516 "Error deleting attribute %s\n",
1517 adh->label);
1518 send_delete_response (adh, GNUNET_SYSERR);
1519 cleanup_adh (adh);
1520 return;
1521 }
1522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continuing consistency check...\n");
1523 GNUNET_SCHEDULER_add_now (&purge_attributes, adh);
1524}
1525
1526
1527
1528/**
1529 * Delete all attributes which reference credentials
1530 * that no longer exist
1531 */
1532static void
1533purge_attributes (void *cls)
1534{
1535 struct AttributeDeleteHandle *adh = cls;
1536 struct GNUNET_RECLAIM_AttributeListEntry *ale;
1537 struct GNUNET_RECLAIM_CredentialListEntry *cle;
1538
1539 for (ale = adh->existing_attributes->list_head; NULL != ale; ale = ale->next)
1540 {
1541 if (GNUNET_YES ==
1542 GNUNET_RECLAIM_id_is_zero (&ale->attribute->credential))
1543 continue;
1544
1545 for (cle = adh->existing_credentials->list_head;
1546 NULL != cle; cle = cle->next) {
1547 if (GNUNET_YES !=
1548 GNUNET_RECLAIM_id_is_equal (&cle->credential->id,
1549 &ale->attribute->credential))
1550 continue;
1551 break;
1552 }
1553 if (NULL == cle) {
1554 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1555 "Found attribute with missing credential\n");
1556 break;
1557 }
1558 }
1559 if (NULL == ale) {
1560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1561 "Attributes consistent, updating tickets.\n");
1562 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1563 return;
1564 }
1565 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1566 "Attributes inconsistent, deleting offending attribute.\n");
1567 char *label
1568 = GNUNET_STRINGS_data_to_string_alloc (&ale->attribute->id,
1569 sizeof(ale->attribute->id));
1570
1571 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1572 &adh->identity,
1573 label,
1574 0,
1575 NULL,
1576 &offending_attr_delete_cont,
1577 adh);
1578 GNUNET_CONTAINER_DLL_remove (adh->existing_attributes->list_head,
1579 adh->existing_attributes->list_tail,
1580 ale);
1581 GNUNET_free (ale);
1582 GNUNET_free (label);
1583}
1441 1584
1442/** 1585/**
1443 * Done collecting affected tickets, start updating. 1586 * Done collecting affected tickets, start updating.
@@ -1445,11 +1588,11 @@ update_tickets (void *cls)
1445 * @param cls our attribute deletion handle 1588 * @param cls our attribute deletion handle
1446 */ 1589 */
1447static void 1590static void
1448ticket_iter_fin (void *cls) 1591consistency_iter_fin (void *cls)
1449{ 1592{
1450 struct AttributeDeleteHandle *adh = cls; 1593 struct AttributeDeleteHandle *adh = cls;
1451 adh->ns_it = NULL; 1594 adh->ns_it = NULL;
1452 GNUNET_SCHEDULER_add_now (&update_tickets, adh); 1595 GNUNET_SCHEDULER_add_now (&purge_attributes, adh);
1453} 1596}
1454 1597
1455 1598
@@ -1459,14 +1602,13 @@ ticket_iter_fin (void *cls)
1459 * @param cls our attribute deletion handle 1602 * @param cls our attribute deletion handle
1460 */ 1603 */
1461static void 1604static void
1462ticket_iter_err (void *cls) 1605consistency_iter_err (void *cls)
1463{ 1606{
1464 struct AttributeDeleteHandle *adh = cls; 1607 struct AttributeDeleteHandle *adh = cls;
1465 1608
1466 adh->ns_it = NULL; 1609 adh->ns_it = NULL;
1467 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1610 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1468 "Namestore error on delete %s\n", 1611 "Namestore error on consistency check\n");
1469 adh->label);
1470 send_delete_response (adh, GNUNET_SYSERR); 1612 send_delete_response (adh, GNUNET_SYSERR);
1471 cleanup_adh (adh); 1613 cleanup_adh (adh);
1472} 1614}
@@ -1479,17 +1621,20 @@ ticket_iter_err (void *cls)
1479 * @param cls attribute deletion handle 1621 * @param cls attribute deletion handle
1480 */ 1622 */
1481static void 1623static void
1482start_ticket_update (void *cls) 1624start_consistency_update (void *cls)
1483{ 1625{
1484 struct AttributeDeleteHandle *adh = cls; 1626 struct AttributeDeleteHandle *adh = cls;
1485 1627
1628 adh->existing_attributes = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1629 adh->existing_credentials = GNUNET_new (struct GNUNET_RECLAIM_CredentialList);
1630
1486 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh, 1631 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1487 &adh->identity, 1632 &adh->identity,
1488 &ticket_iter_err, 1633 &consistency_iter_err,
1489 adh, 1634 adh,
1490 &ticket_iter, 1635 &consistency_iter,
1491 adh, 1636 adh,
1492 &ticket_iter_fin, 1637 &consistency_iter_fin,
1493 adh); 1638 adh);
1494} 1639}
1495 1640
@@ -1517,7 +1662,7 @@ attr_delete_cont (void *cls, int32_t success, const char *emsg)
1517 return; 1662 return;
1518 } 1663 }
1519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n"); 1664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1520 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh); 1665 GNUNET_SCHEDULER_add_now (&start_consistency_update, adh);
1521} 1666}
1522 1667
1523 1668
@@ -1586,12 +1731,12 @@ handle_attribute_delete_message (void *cls,
1586 1731
1587 1732
1588/** 1733/**
1589 * Credential deleted callback 1734 * Credential deleted callback
1590 * 1735 *
1591 * @param cls our handle 1736 * @param cls our handle
1592 * @param success success status 1737 * @param success success status
1593 * @param emsg error message (NULL if success=GNUNET_OK) 1738 * @param emsg error message (NULL if success=GNUNET_OK)
1594 */ 1739 */
1595static void 1740static void
1596cred_delete_cont (void *cls, int32_t success, const char *emsg) 1741cred_delete_cont (void *cls, int32_t success, const char *emsg)
1597{ 1742{
@@ -1608,7 +1753,7 @@ cred_delete_cont (void *cls, int32_t success, const char *emsg)
1608 return; 1753 return;
1609 } 1754 }
1610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n"); 1755 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1611 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh); 1756 GNUNET_SCHEDULER_add_now (&start_consistency_update, adh);
1612} 1757}
1613 1758
1614 1759
@@ -1642,7 +1787,7 @@ check_credential_delete_message (void *cls,
1642 */ 1787 */
1643static void 1788static void
1644handle_credential_delete_message (void *cls, 1789handle_credential_delete_message (void *cls,
1645 const struct AttributeDeleteMessage *dam) 1790 const struct AttributeDeleteMessage *dam)
1646{ 1791{
1647 struct AttributeDeleteHandle *adh; 1792 struct AttributeDeleteHandle *adh;
1648 struct IdpClient *idp = cls; 1793 struct IdpClient *idp = cls;
@@ -1676,8 +1821,8 @@ handle_credential_delete_message (void *cls,
1676 1821
1677 1822
1678/************************************************* 1823/*************************************************
1679* Attrubute iteration 1824 * Attrubute iteration
1680*************************************************/ 1825 *************************************************/
1681 1826
1682 1827
1683/** 1828/**
@@ -1860,8 +2005,8 @@ handle_iteration_next (void *cls,
1860 2005
1861 2006
1862/************************************************* 2007/*************************************************
1863* Credential iteration 2008 * Credential iteration
1864*************************************************/ 2009 *************************************************/
1865 2010
1866 2011
1867/** 2012/**
@@ -2050,8 +2195,8 @@ handle_credential_iteration_next (void *cls,
2050 2195
2051 2196
2052/****************************************************** 2197/******************************************************
2053* Ticket iteration 2198 * Ticket iteration
2054******************************************************/ 2199 ******************************************************/
2055 2200
2056/** 2201/**
2057 * Got a ticket. Return to client 2202 * Got a ticket. Return to client
@@ -2094,8 +2239,8 @@ ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
2094 */ 2239 */
2095static void 2240static void
2096handle_ticket_iteration_start ( 2241handle_ticket_iteration_start (
2097 void *cls, 2242 void *cls,
2098 const struct TicketIterationStartMessage *tis_msg) 2243 const struct TicketIterationStartMessage *tis_msg)
2099{ 2244{
2100 struct IdpClient *client = cls; 2245 struct IdpClient *client = cls;
2101 struct TicketIteration *ti; 2246 struct TicketIteration *ti;
@@ -2267,76 +2412,76 @@ client_connect_cb (void *cls,
2267 * Define "main" method using service macro. 2412 * Define "main" method using service macro.
2268 */ 2413 */
2269GNUNET_SERVICE_MAIN ( 2414GNUNET_SERVICE_MAIN (
2270 "reclaim", 2415 "reclaim",
2271 GNUNET_SERVICE_OPTION_NONE, 2416 GNUNET_SERVICE_OPTION_NONE,
2272 &run, 2417 &run,
2273 &client_connect_cb, 2418 &client_connect_cb,
2274 &client_disconnect_cb, 2419 &client_disconnect_cb,
2275 NULL, 2420 NULL,
2276 GNUNET_MQ_hd_var_size (attribute_store_message, 2421 GNUNET_MQ_hd_var_size (attribute_store_message,
2277 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE, 2422 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2278 struct AttributeStoreMessage, 2423 struct AttributeStoreMessage,
2279 NULL), 2424 NULL),
2280 GNUNET_MQ_hd_var_size (credential_store_message, 2425 GNUNET_MQ_hd_var_size (credential_store_message,
2281 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE, 2426 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE,
2282 struct AttributeStoreMessage, 2427 struct AttributeStoreMessage,
2283 NULL), 2428 NULL),
2284 GNUNET_MQ_hd_var_size (attribute_delete_message, 2429 GNUNET_MQ_hd_var_size (attribute_delete_message,
2285 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE, 2430 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
2286 struct AttributeDeleteMessage, 2431 struct AttributeDeleteMessage,
2287 NULL), 2432 NULL),
2288 GNUNET_MQ_hd_var_size (credential_delete_message, 2433 GNUNET_MQ_hd_var_size (credential_delete_message,
2289 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE, 2434 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE,
2290 struct AttributeDeleteMessage, 2435 struct AttributeDeleteMessage,
2291 NULL), 2436 NULL),
2292 GNUNET_MQ_hd_fixed_size (iteration_start, 2437 GNUNET_MQ_hd_fixed_size (iteration_start,
2293 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START, 2438 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2294 struct AttributeIterationStartMessage, 2439 struct AttributeIterationStartMessage,
2295 NULL), 2440 NULL),
2296 GNUNET_MQ_hd_fixed_size (iteration_next, 2441 GNUNET_MQ_hd_fixed_size (iteration_next,
2297 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT, 2442 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2298 struct AttributeIterationNextMessage, 2443 struct AttributeIterationNextMessage,
2299 NULL), 2444 NULL),
2300 GNUNET_MQ_hd_fixed_size (iteration_stop, 2445 GNUNET_MQ_hd_fixed_size (iteration_stop,
2301 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP, 2446 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2302 struct AttributeIterationStopMessage, 2447 struct AttributeIterationStopMessage,
2303 NULL), 2448 NULL),
2304 GNUNET_MQ_hd_fixed_size (credential_iteration_start, 2449 GNUNET_MQ_hd_fixed_size (credential_iteration_start,
2305 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START, 2450 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START,
2306 struct CredentialIterationStartMessage, 2451 struct CredentialIterationStartMessage,
2307 NULL), 2452 NULL),
2308 GNUNET_MQ_hd_fixed_size (credential_iteration_next, 2453 GNUNET_MQ_hd_fixed_size (credential_iteration_next,
2309 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT, 2454 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT,
2310 struct CredentialIterationNextMessage, 2455 struct CredentialIterationNextMessage,
2311 NULL), 2456 NULL),
2312 GNUNET_MQ_hd_fixed_size (credential_iteration_stop, 2457 GNUNET_MQ_hd_fixed_size (credential_iteration_stop,
2313 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP, 2458 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP,
2314 struct CredentialIterationStopMessage, 2459 struct CredentialIterationStopMessage,
2315 NULL), 2460 NULL),
2316 2461
2317 GNUNET_MQ_hd_var_size (issue_ticket_message, 2462 GNUNET_MQ_hd_var_size (issue_ticket_message,
2318 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET, 2463 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2319 struct IssueTicketMessage, 2464 struct IssueTicketMessage,
2320 NULL), 2465 NULL),
2321 GNUNET_MQ_hd_var_size (consume_ticket_message, 2466 GNUNET_MQ_hd_var_size (consume_ticket_message,
2322 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET, 2467 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2323 struct ConsumeTicketMessage, 2468 struct ConsumeTicketMessage,
2324 NULL), 2469 NULL),
2325 GNUNET_MQ_hd_fixed_size (ticket_iteration_start, 2470 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2326 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START, 2471 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2327 struct TicketIterationStartMessage, 2472 struct TicketIterationStartMessage,
2328 NULL), 2473 NULL),
2329 GNUNET_MQ_hd_fixed_size (ticket_iteration_next, 2474 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2330 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT, 2475 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2331 struct TicketIterationNextMessage, 2476 struct TicketIterationNextMessage,
2332 NULL), 2477 NULL),
2333 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop, 2478 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2334 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP, 2479 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2335 struct TicketIterationStopMessage, 2480 struct TicketIterationStopMessage,
2336 NULL), 2481 NULL),
2337 GNUNET_MQ_hd_var_size (revoke_ticket_message, 2482 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2338 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET, 2483 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2339 struct RevokeTicketMessage, 2484 struct RevokeTicketMessage,
2340 NULL), 2485 NULL),
2341 GNUNET_MQ_handler_end ()); 2486 GNUNET_MQ_handler_end ());
2342/* end of gnunet-service-reclaim.c */ 2487/* end of gnunet-service-reclaim.c */
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c
index 0b1730bec..ef2303bd7 100644
--- a/src/reclaim/gnunet-service-reclaim_tickets.c
+++ b/src/reclaim/gnunet-service-reclaim_tickets.c
@@ -1542,6 +1542,7 @@ filter_tickets_cb (void *cls,
1542 tih->presentations->list_tail, 1542 tih->presentations->list_tail,
1543 ple); 1543 ple);
1544 GNUNET_free (cred); 1544 GNUNET_free (cred);
1545 break;
1545 } 1546 }
1546 } 1547 }
1547 if (GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION == rd[i].record_type) 1548 if (GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION == rd[i].record_type)
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index a90d02d68..84a90833c 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -193,6 +193,7 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
193 json_object_set_new (body, "iss", json_string (SERVER_ADDRESS)); 193 json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
194 // sub REQUIRED public key identity, not exceed 255 ASCII length 194 // sub REQUIRED public key identity, not exceed 255 ASCII length
195 json_object_set_new (body, "sub", json_string (subject)); 195 json_object_set_new (body, "sub", json_string (subject));
196 GNUNET_free (subject);
196 pres_val_str = NULL; 197 pres_val_str = NULL;
197 source_name = NULL; 198 source_name = NULL;
198 int i = 0; 199 int i = 0;
@@ -202,11 +203,15 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
202 GNUNET_asprintf (&source_name, 203 GNUNET_asprintf (&source_name,
203 "src%d", 204 "src%d",
204 i); 205 i);
206 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
207 "Adding new presentation source #%d\n", i);
205 aggr_sources_jwt = json_object (); 208 aggr_sources_jwt = json_object ();
206 pres_val_str = 209 pres_val_str =
207 GNUNET_RECLAIM_presentation_value_to_string (ple->presentation->type, 210 GNUNET_RECLAIM_presentation_value_to_string (ple->presentation->type,
208 ple->presentation->data, 211 ple->presentation->data,
209 ple->presentation->data_size); 212 ple->presentation->data_size);
213 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
214 "Presentation is: %s\n", pres_val_str);
210 json_object_set_new (aggr_sources_jwt, 215 json_object_set_new (aggr_sources_jwt,
211 GNUNET_RECLAIM_presentation_number_to_typename ( 216 GNUNET_RECLAIM_presentation_number_to_typename (
212 ple->presentation->type), 217 ple->presentation->type),
@@ -220,7 +225,9 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
220 225
221 for (le = attrs->list_head; NULL != le; le = le->next) 226 for (le = attrs->list_head; NULL != le; le = le->next)
222 { 227 {
223 228 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
229 "Processing %s for userinfo body\n",
230 le->attribute->name);
224 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&le->attribute->credential)) 231 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&le->attribute->credential))
225 { 232 {
226 233
@@ -256,18 +263,6 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
256 int j = 0; 263 int j = 0;
257 for (ple = presentations->list_head; NULL != ple; ple = ple->next) 264 for (ple = presentations->list_head; NULL != ple; ple = ple->next)
258 { 265 {
259 char *tmp;
260 tmp = GNUNET_STRINGS_data_to_string_alloc (&le->attribute->credential,
261 sizeof (le->attribute->credential));
262 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
263 "Checking : %s\n", tmp);
264 GNUNET_free (tmp);
265
266 tmp = GNUNET_STRINGS_data_to_string_alloc (&ple->presentation->credential_id,
267 sizeof (ple->presentation->credential_id));
268 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
269 " against: %s\n", tmp);
270 GNUNET_free (tmp);
271 if (GNUNET_YES == 266 if (GNUNET_YES ==
272 GNUNET_RECLAIM_id_is_equal (&ple->presentation->credential_id, 267 GNUNET_RECLAIM_id_is_equal (&ple->presentation->credential_id,
273 &le->attribute->credential)) 268 &le->attribute->credential))
@@ -285,7 +280,7 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
285 GNUNET_asprintf (&source_name, 280 GNUNET_asprintf (&source_name,
286 "src%d", 281 "src%d",
287 j); 282 j);
288 json_object_set_new (aggr_names, le->attribute->data, 283 json_object_set_new (aggr_names, le->attribute->name,
289 json_string (source_name)); 284 json_string (source_name));
290 GNUNET_free (source_name); 285 GNUNET_free (source_name);
291 } 286 }
diff --git a/src/reclaim/plugin_reclaim_attribute_basic.c b/src/reclaim/plugin_reclaim_attribute_basic.c
index 286186a93..c87922886 100644
--- a/src/reclaim/plugin_reclaim_attribute_basic.c
+++ b/src/reclaim/plugin_reclaim_attribute_basic.c
@@ -82,7 +82,7 @@ basic_string_to_value (void *cls,
82 { 82 {
83 case GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING: 83 case GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING:
84 *data = GNUNET_strdup (s); 84 *data = GNUNET_strdup (s);
85 *data_size = strlen (s); 85 *data_size = strlen (s) + 1;
86 return GNUNET_OK; 86 return GNUNET_OK;
87 87
88 default: 88 default:
diff --git a/src/reclaim/plugin_reclaim_credential_jwt.c b/src/reclaim/plugin_reclaim_credential_jwt.c
index 6f52f3a4e..c1e12f4a0 100644
--- a/src/reclaim/plugin_reclaim_credential_jwt.c
+++ b/src/reclaim/plugin_reclaim_credential_jwt.c
@@ -81,7 +81,7 @@ jwt_string_to_value (void *cls,
81 { 81 {
82 case GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT: 82 case GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT:
83 *data = GNUNET_strdup (s); 83 *data = GNUNET_strdup (s);
84 *data_size = strlen (s); 84 *data_size = strlen (s) + 1;
85 return GNUNET_OK; 85 return GNUNET_OK;
86 86
87 default: 87 default:
@@ -151,7 +151,8 @@ jwt_number_to_typename (void *cls, uint32_t type)
151 */ 151 */
152struct GNUNET_RECLAIM_AttributeList * 152struct GNUNET_RECLAIM_AttributeList *
153jwt_parse_attributes (void *cls, 153jwt_parse_attributes (void *cls,
154 const char *data) 154 const char *data,
155 size_t data_size)
155{ 156{
156 char *jwt_string; 157 char *jwt_string;
157 struct GNUNET_RECLAIM_AttributeList *attrs; 158 struct GNUNET_RECLAIM_AttributeList *attrs;
@@ -164,7 +165,7 @@ jwt_parse_attributes (void *cls,
164 165
165 attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); 166 attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
166 167
167 jwt_string = GNUNET_strdup (data); 168 jwt_string = GNUNET_strndup (data, data_size);
168 const char *jwt_body = strtok (jwt_string, delim); 169 const char *jwt_body = strtok (jwt_string, delim);
169 jwt_body = strtok (NULL, delim); 170 jwt_body = strtok (NULL, delim);
170 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), 171 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
@@ -172,6 +173,7 @@ jwt_parse_attributes (void *cls,
172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt); 173 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt);
173 GNUNET_assert (NULL != decoded_jwt); 174 GNUNET_assert (NULL != decoded_jwt);
174 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); 175 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
176 GNUNET_free (decoded_jwt);
175 const char *key; 177 const char *key;
176 json_t *value; 178 json_t *value;
177 json_object_foreach (json_val, key, value) { 179 json_object_foreach (json_val, key, value) {
@@ -196,6 +198,7 @@ jwt_parse_attributes (void *cls,
196 strlen (val_str)); 198 strlen (val_str));
197 GNUNET_free (val_str); 199 GNUNET_free (val_str);
198 } 200 }
201 json_decref (json_val);
199 GNUNET_free (jwt_string); 202 GNUNET_free (jwt_string);
200 return attrs; 203 return attrs;
201} 204}
@@ -212,7 +215,7 @@ struct GNUNET_RECLAIM_AttributeList *
212jwt_parse_attributes_c (void *cls, 215jwt_parse_attributes_c (void *cls,
213 const struct GNUNET_RECLAIM_Credential *cred) 216 const struct GNUNET_RECLAIM_Credential *cred)
214{ 217{
215 return jwt_parse_attributes (cls, cred->data); 218 return jwt_parse_attributes (cls, cred->data, cred->data_size);
216} 219}
217 220
218 221
@@ -227,7 +230,7 @@ struct GNUNET_RECLAIM_AttributeList *
227jwt_parse_attributes_p (void *cls, 230jwt_parse_attributes_p (void *cls,
228 const struct GNUNET_RECLAIM_Presentation *cred) 231 const struct GNUNET_RECLAIM_Presentation *cred)
229{ 232{
230 return jwt_parse_attributes (cls, cred->data); 233 return jwt_parse_attributes (cls, cred->data, cred->data_size);
231} 234}
232 235
233 236
@@ -240,7 +243,8 @@ jwt_parse_attributes_p (void *cls,
240 */ 243 */
241char * 244char *
242jwt_get_issuer (void *cls, 245jwt_get_issuer (void *cls,
243 const char *data) 246 const char *data,
247 size_t data_size)
244{ 248{
245 const char *jwt_body; 249 const char *jwt_body;
246 char *jwt_string; 250 char *jwt_string;
@@ -252,17 +256,23 @@ jwt_get_issuer (void *cls,
252 json_t *json_val; 256 json_t *json_val;
253 json_error_t *json_err = NULL; 257 json_error_t *json_err = NULL;
254 258
255 jwt_string = GNUNET_strdup (data); 259 jwt_string = GNUNET_strndup (data, data_size);
256 jwt_body = strtok (jwt_string, delim); 260 jwt_body = strtok (jwt_string, delim);
257 jwt_body = strtok (NULL, delim); 261 jwt_body = strtok (NULL, delim);
258 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), 262 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
259 (void **) &decoded_jwt); 263 (void **) &decoded_jwt);
260 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); 264 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
265 GNUNET_free (decoded_jwt);
266 GNUNET_free (jwt_string);
267 if (NULL == json_val)
268 return NULL;
261 issuer_json = json_object_get (json_val, "iss"); 269 issuer_json = json_object_get (json_val, "iss");
262 if ((NULL == issuer_json) || (! json_is_string (issuer_json))) 270 if ((NULL == issuer_json) || (! json_is_string (issuer_json))) {
271 json_decref (json_val);
263 return NULL; 272 return NULL;
273 }
264 issuer = GNUNET_strdup (json_string_value (issuer_json)); 274 issuer = GNUNET_strdup (json_string_value (issuer_json));
265 GNUNET_free (jwt_string); 275 json_decref (json_val);
266 return issuer; 276 return issuer;
267} 277}
268 278
@@ -280,7 +290,7 @@ jwt_get_issuer_c (void *cls,
280{ 290{
281 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type) 291 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type)
282 return NULL; 292 return NULL;
283 return jwt_get_issuer (cls, cred->data); 293 return jwt_get_issuer (cls, cred->data, cred->data_size);
284} 294}
285 295
286 296
@@ -297,7 +307,7 @@ jwt_get_issuer_p (void *cls,
297{ 307{
298 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type) 308 if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type)
299 return NULL; 309 return NULL;
300 return jwt_get_issuer (cls, cred->data); 310 return jwt_get_issuer (cls, cred->data, cred->data_size);
301} 311}
302 312
303 313
@@ -311,6 +321,7 @@ jwt_get_issuer_p (void *cls,
311int 321int
312jwt_get_expiration (void *cls, 322jwt_get_expiration (void *cls,
313 const char *data, 323 const char *data,
324 size_t data_size,
314 struct GNUNET_TIME_Absolute *exp) 325 struct GNUNET_TIME_Absolute *exp)
315{ 326{
316 const char *jwt_body; 327 const char *jwt_body;
@@ -322,17 +333,23 @@ jwt_get_expiration (void *cls,
322 json_t *json_val; 333 json_t *json_val;
323 json_error_t *json_err = NULL; 334 json_error_t *json_err = NULL;
324 335
325 jwt_string = GNUNET_strdup (data); 336 jwt_string = GNUNET_strndup (data, data_size);
326 jwt_body = strtok (jwt_string, delim); 337 jwt_body = strtok (jwt_string, delim);
327 jwt_body = strtok (NULL, delim); 338 jwt_body = strtok (NULL, delim);
328 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), 339 GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
329 (void **) &decoded_jwt); 340 (void **) &decoded_jwt);
330 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); 341 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
342 GNUNET_free (decoded_jwt);
343 GNUNET_free (jwt_string);
344 if (NULL == json_val)
345 return GNUNET_SYSERR;
331 exp_json = json_object_get (json_val, "exp"); 346 exp_json = json_object_get (json_val, "exp");
332 if ((NULL == exp_json) || (! json_is_integer (exp_json))) 347 if ((NULL == exp_json) || (! json_is_integer (exp_json))) {
348 json_decref (json_val);
333 return GNUNET_SYSERR; 349 return GNUNET_SYSERR;
350 }
334 exp->abs_value_us = json_integer_value (exp_json) * 1000 * 1000; 351 exp->abs_value_us = json_integer_value (exp_json) * 1000 * 1000;
335 GNUNET_free (jwt_string); 352 json_decref (json_val);
336 return GNUNET_OK; 353 return GNUNET_OK;
337} 354}
338 355
@@ -349,7 +366,7 @@ jwt_get_expiration_c (void *cls,
349 const struct GNUNET_RECLAIM_Credential *cred, 366 const struct GNUNET_RECLAIM_Credential *cred,
350 struct GNUNET_TIME_Absolute *exp) 367 struct GNUNET_TIME_Absolute *exp)
351{ 368{
352 return jwt_get_expiration (cls, cred->data, exp); 369 return jwt_get_expiration (cls, cred->data, cred->data_size, exp);
353} 370}
354 371
355 372
@@ -365,7 +382,7 @@ jwt_get_expiration_p (void *cls,
365 const struct GNUNET_RECLAIM_Presentation *cred, 382 const struct GNUNET_RECLAIM_Presentation *cred,
366 struct GNUNET_TIME_Absolute *exp) 383 struct GNUNET_TIME_Absolute *exp)
367{ 384{
368 return jwt_get_expiration (cls, cred->data, exp); 385 return jwt_get_expiration (cls, cred->data, cred->data_size, exp);
369} 386}
370 387
371 388
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index 5eb1ff093..0ee61755b 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -610,6 +610,10 @@ cleanup_handle (struct RequestHandle *handle)
610 GNUNET_free (handle->oidc->response_type); 610 GNUNET_free (handle->oidc->response_type);
611 GNUNET_free (handle->oidc->scope); 611 GNUNET_free (handle->oidc->scope);
612 GNUNET_free (handle->oidc->state); 612 GNUNET_free (handle->oidc->state);
613 if (NULL != handle->oidc->claims)
614 GNUNET_free (handle->oidc->claims);
615 if (NULL != handle->oidc->code_challenge)
616 GNUNET_free (handle->oidc->code_challenge);
613 GNUNET_free (handle->oidc); 617 GNUNET_free (handle->oidc);
614 } 618 }
615 if (NULL!=handle->attr_idtoken_list) 619 if (NULL!=handle->attr_idtoken_list)
@@ -1193,8 +1197,7 @@ attr_in_claims_request (struct RequestHandle *handle,
1193 return GNUNET_YES; 1197 return GNUNET_YES;
1194 1198
1195 /** Try claims parameter if not in scope */ 1199 /** Try claims parameter if not in scope */
1196 if ((NULL != handle->oidc->claims) && 1200 if (NULL != handle->oidc->claims)
1197 (GNUNET_YES != ret))
1198 { 1201 {
1199 root = json_loads (handle->oidc->claims, JSON_DECODE_ANY, &error); 1202 root = json_loads (handle->oidc->claims, JSON_DECODE_ANY, &error);
1200 claims_j = json_object_get (root, claims_parameter); 1203 claims_j = json_object_get (root, claims_parameter);
@@ -1708,8 +1711,6 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1708 handle->ego_entry = ego_tail; 1711 handle->ego_entry = ego_tail;
1709 } 1712 }
1710 } 1713 }
1711 handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scope: %s\n", handle->oidc->scope);
1713 if (NULL == handle->tld) 1714 if (NULL == handle->tld)
1714 GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle); 1715 GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle);
1715 if (NULL == handle->tld) 1716 if (NULL == handle->tld)
@@ -1872,11 +1873,18 @@ parse_credentials_post_body (struct RequestHandle *handle,
1872 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 1873 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
1873 ->url_param_map, 1874 ->url_param_map,
1874 &cache_key)) 1875 &cache_key))
1876 {
1877 GNUNET_free (*client_id);
1878 *client_id = NULL;
1875 return GNUNET_SYSERR; 1879 return GNUNET_SYSERR;
1880 }
1876 pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, 1881 pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
1877 &cache_key); 1882 &cache_key);
1878 if (NULL == pass) 1883 if (NULL == pass) {
1884 GNUNET_free (*client_id);
1885 *client_id = NULL;
1879 return GNUNET_SYSERR; 1886 return GNUNET_SYSERR;
1887 }
1880 *client_secret = strdup (pass); 1888 *client_secret = strdup (pass);
1881 return GNUNET_OK; 1889 return GNUNET_OK;
1882} 1890}
@@ -1938,12 +1946,16 @@ check_authorization (struct RequestHandle *handle,
1938 GNUNET_free (expected_pass); 1946 GNUNET_free (expected_pass);
1939 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1947 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1940 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1948 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1949 GNUNET_free (received_cpw);
1950 GNUNET_free (received_cid);
1941 return GNUNET_SYSERR; 1951 return GNUNET_SYSERR;
1942 } 1952 }
1943 GNUNET_free (expected_pass); 1953 GNUNET_free (expected_pass);
1944 } 1954 }
1945 else 1955 else
1946 { 1956 {
1957 GNUNET_free (received_cpw);
1958 GNUNET_free (received_cid);
1947 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 1959 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR);
1948 handle->edesc = GNUNET_strdup ("gnunet configuration failed"); 1960 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1949 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1961 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
@@ -2102,9 +2114,13 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2102 handle->edesc = GNUNET_strdup ("invalid code"); 2114 handle->edesc = GNUNET_strdup ("invalid code");
2103 handle->response_code = MHD_HTTP_BAD_REQUEST; 2115 handle->response_code = MHD_HTTP_BAD_REQUEST;
2104 GNUNET_free (code); 2116 GNUNET_free (code);
2117 if (NULL != code_verifier)
2118 GNUNET_free (code_verifier);
2105 GNUNET_SCHEDULER_add_now (&do_error, handle); 2119 GNUNET_SCHEDULER_add_now (&do_error, handle);
2106 return; 2120 return;
2107 } 2121 }
2122 if (NULL != code_verifier)
2123 GNUNET_free (code_verifier);
2108 2124
2109 // create jwt 2125 // create jwt
2110 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, 2126 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
@@ -2116,6 +2132,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2116 handle->edesc = GNUNET_strdup ("gnunet configuration failed"); 2132 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
2117 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 2133 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2118 GNUNET_free (code); 2134 GNUNET_free (code);
2135 if (NULL != nonce)
2136 GNUNET_free (nonce);
2119 GNUNET_SCHEDULER_add_now (&do_error, handle); 2137 GNUNET_SCHEDULER_add_now (&do_error, handle);
2120 return; 2138 return;
2121 } 2139 }
@@ -2131,6 +2149,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2131 handle->edesc = GNUNET_strdup ("No signing secret configured!"); 2149 handle->edesc = GNUNET_strdup ("No signing secret configured!");
2132 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 2150 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2133 GNUNET_free (code); 2151 GNUNET_free (code);
2152 if (NULL != nonce)
2153 GNUNET_free (nonce);
2134 GNUNET_SCHEDULER_add_now (&do_error, handle); 2154 GNUNET_SCHEDULER_add_now (&do_error, handle);
2135 return; 2155 return;
2136 } 2156 }
@@ -2141,6 +2161,9 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2141 &expiration_time, 2161 &expiration_time,
2142 (NULL != nonce) ? nonce : NULL, 2162 (NULL != nonce) ? nonce : NULL,
2143 jwt_secret); 2163 jwt_secret);
2164 GNUNET_free (jwt_secret);
2165 if (NULL != nonce)
2166 GNUNET_free (nonce);
2144 access_token = OIDC_access_token_new (&ticket); 2167 access_token = OIDC_access_token_new (&ticket);
2145 /* Store mapping from access token to code so we can later 2168 /* Store mapping from access token to code so we can later
2146 * fall back on the provided attributes in userinfo 2169 * fall back on the provided attributes in userinfo
@@ -2293,6 +2316,8 @@ consume_timeout (void*cls)
2293 handle->edesc = GNUNET_strdup ("invalid code"); 2316 handle->edesc = GNUNET_strdup ("invalid code");
2294 handle->response_code = MHD_HTTP_BAD_REQUEST; 2317 handle->response_code = MHD_HTTP_BAD_REQUEST;
2295 GNUNET_free (cached_code); 2318 GNUNET_free (cached_code);
2319 if (NULL != nonce)
2320 GNUNET_free (nonce);
2296 GNUNET_SCHEDULER_add_now (&do_error, handle); 2321 GNUNET_SCHEDULER_add_now (&do_error, handle);
2297 return; 2322 return;
2298 } 2323 }
@@ -2337,7 +2362,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2337 const struct EgoEntry *aud_ego; 2362 const struct EgoEntry *aud_ego;
2338 const struct GNUNET_IDENTITY_PrivateKey *privkey; 2363 const struct GNUNET_IDENTITY_PrivateKey *privkey;
2339 2364
2340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Getting userinfo\n"); 2365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n");
2341 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, 2366 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
2342 strlen (OIDC_AUTHORIZATION_HEADER_KEY), 2367 strlen (OIDC_AUTHORIZATION_HEADER_KEY),
2343 &cache_key); 2368 &cache_key);
@@ -2403,7 +2428,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2403 GNUNET_free (authorization); 2428 GNUNET_free (authorization);
2404 return; 2429 return;
2405 } 2430 }
2406 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Consuming ticket\n"); 2431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n");
2407 privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); 2432 privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego);
2408 handle->attr_userinfo_list = 2433 handle->attr_userinfo_list =
2409 GNUNET_new (struct GNUNET_RECLAIM_AttributeList); 2434 GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
@@ -2617,6 +2642,7 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2617 oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1)); 2642 oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1));
2618 resp = GNUNET_REST_create_response (oidc_config_str); 2643 resp = GNUNET_REST_create_response (oidc_config_str);
2619 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 2644 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2645 json_decref (oidc_config);
2620 GNUNET_free (oidc_config_str); 2646 GNUNET_free (oidc_config_str);
2621 cleanup_handle (handle); 2647 cleanup_handle (handle);
2622} 2648}
diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c
index 022744c82..84456b386 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -974,9 +974,11 @@ attr_collect (void *cls,
974 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, 974 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id,
975 sizeof(attr->id)); 975 sizeof(attr->id));
976 json_object_set_new (attr_obj, "id", json_string (id_str)); 976 json_object_set_new (attr_obj, "id", json_string (id_str));
977 GNUNET_free (id_str);
977 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->credential, 978 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->credential,
978 sizeof(attr->credential)); 979 sizeof(attr->credential));
979 json_object_set_new (attr_obj, "credential", json_string (id_str)); 980 json_object_set_new (attr_obj, "credential", json_string (id_str));
981 GNUNET_free (id_str);
980 json_array_append (handle->resp_object, attr_obj); 982 json_array_append (handle->resp_object, attr_obj);
981 json_decref (attr_obj); 983 json_decref (attr_obj);
982 GNUNET_free (tmp_value); 984 GNUNET_free (tmp_value);
diff --git a/src/reclaim/reclaim_attribute.c b/src/reclaim/reclaim_attribute.c
index 2217987ac..14690d7c9 100644
--- a/src/reclaim/reclaim_attribute.c
+++ b/src/reclaim/reclaim_attribute.c
@@ -102,6 +102,37 @@ init ()
102 NULL); 102 NULL);
103} 103}
104 104
105/**
106 * Dual function to #init().
107 */
108void __attribute__ ((destructor))
109RECLAIM_ATTRIBUTE_fini ()
110{
111 struct Plugin *plugin;
112 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
113 const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
114
115 if (pd != dpd)
116 GNUNET_OS_init (dpd);
117
118 for (unsigned int i = 0; i < num_plugins; i++)
119 {
120 plugin = attr_plugins[i];
121 GNUNET_break (NULL ==
122 GNUNET_PLUGIN_unload (plugin->library_name,
123 plugin->api));
124 GNUNET_free (plugin->library_name);
125 GNUNET_free (plugin);
126 }
127 GNUNET_free (attr_plugins);
128
129 if (pd != dpd)
130 GNUNET_OS_init (pd);
131
132 attr_plugins = NULL;
133}
134
135
105 136
106/** 137/**
107 * Convert a type name to the corresponding number 138 * Convert a type name to the corresponding number
diff --git a/src/reclaim/reclaim_credential.c b/src/reclaim/reclaim_credential.c
index 5c8974400..05601c3d3 100644
--- a/src/reclaim/reclaim_credential.c
+++ b/src/reclaim/reclaim_credential.c
@@ -104,6 +104,38 @@ init ()
104 104
105 105
106/** 106/**
107 * Dual function to #init().
108 */
109void __attribute__ ((destructor))
110RECLAIM_CREDENTIAL_fini ()
111{
112 struct Plugin *plugin;
113 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
114 const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
115
116 if (pd != dpd)
117 GNUNET_OS_init (dpd);
118
119 for (unsigned int i = 0; i < num_plugins; i++)
120 {
121 plugin = credential_plugins[i];
122 GNUNET_break (NULL ==
123 GNUNET_PLUGIN_unload (plugin->library_name,
124 plugin->api));
125 GNUNET_free (plugin->library_name);
126 GNUNET_free (plugin);
127 }
128 GNUNET_free (credential_plugins);
129
130 if (pd != dpd)
131 GNUNET_OS_init (pd);
132
133 credential_plugins = NULL;
134}
135
136
137
138/**
107 * Convert an credential type name to the corresponding number 139 * Convert an credential type name to the corresponding number
108 * 140 *
109 * @param typename name to convert 141 * @param typename name to convert
@@ -721,7 +753,6 @@ GNUNET_RECLAIM_presentation_list_serialize_get_size (
721 { 753 {
722 GNUNET_assert (NULL != le->presentation); 754 GNUNET_assert (NULL != le->presentation);
723 len += GNUNET_RECLAIM_presentation_serialize_get_size (le->presentation); 755 len += GNUNET_RECLAIM_presentation_serialize_get_size (le->presentation);
724 len += sizeof(struct GNUNET_RECLAIM_PresentationListEntry);
725 } 756 }
726 return len; 757 return len;
727} 758}
@@ -774,8 +805,7 @@ GNUNET_RECLAIM_presentation_list_deserialize (const char *data, size_t
774 805
775 al = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); 806 al = GNUNET_new (struct GNUNET_RECLAIM_PresentationList);
776 807
777 if ((data_size < sizeof(struct Presentation) 808 if (data_size < sizeof(struct Presentation))
778 + sizeof(struct GNUNET_RECLAIM_PresentationListEntry)))
779 return al; 809 return al;
780 810
781 read_ptr = data; 811 read_ptr = data;