gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: RECLAIM: Added libpabc credential suppor


From: gnunet
Subject: [gnunet] branch master updated: RECLAIM: Added libpabc credential support.
Date: Sat, 24 Apr 2021 01:02:53 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 3cd248236 RECLAIM: Added libpabc credential support.
3cd248236 is described below

commit 3cd24823660a0447e590ff352e9da7eb076b292b
Author: Martin Schanzenbach <mschanzenbach@posteo.de>
AuthorDate: Mon Feb 22 10:16:16 2021 +0100

    RECLAIM: Added libpabc credential support.
---
 configure.ac                                 |  24 +
 contrib/Makefile.inc                         |   3 +-
 po/POTFILES.in                               | 125 ++---
 src/reclaim/Makefile.am                      |  40 ++
 src/reclaim/json_reclaim.c                   |  16 +-
 src/reclaim/pabc_helper.c                    | 364 +++++++++++++++
 src/reclaim/pabc_helper.h                    |  41 ++
 src/reclaim/plugin_reclaim_credential_jwt.c  |  32 +-
 src/reclaim/plugin_reclaim_credential_pabc.c | 639 +++++++++++++++++++++++++
 src/reclaim/plugin_rest_pabc.c               | 666 +++++++++++++++++++++++++++
 src/reclaim/reclaim_credential.c             |   1 -
 11 files changed, 1871 insertions(+), 80 deletions(-)

diff --git a/configure.ac b/configure.ac
index e66103b58..4a2f148ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -791,6 +791,30 @@ AS_IF([test "x$zbar" = x1],
       [AC_DEFINE([HAVE_ZBAR],[1],[Have zbar library])],
       [AC_DEFINE([HAVE_ZBAR],[0],[Lacking zbar library])])
 
+# check for libpabc library
+pabc=0
+AC_MSG_CHECKING(for libpabc)
+AC_ARG_WITH(pabc,
+   [  --with-pabc=PREFIX (base of libpabc installation)],
+   [AC_MSG_RESULT([$with_pabc])
+    AS_CASE([$with_pabc],
+      [no],[],
+      [yes],[
+        CHECK_LIBHEADER(PABC, pabc, pabc_new_ctx, pabc/pabc.h,pabc=1,)
+      ],[
+        LDFLAGS="-L$with_pabc/lib $LDFLAGS"
+        CPPFLAGS="-I$with_pabc/include $CPPFLAGS"
+        AC_CHECK_HEADERS(pabc/pabc.h,
+          AC_CHECK_LIB([pabc], [pabc_new_ctx],
+            EXT_LIB_PATH="-L$with_pabc/lib $EXT_LIB_PATH"
+            pabc=1))
+      ])
+   ],
+   [AC_MSG_RESULT([--with-pabc not specified])
+    CHECK_LIBHEADER(PABC, pabc, pabc_new_ctx, pabc/pabc.h,pabc=1,)])
+AM_CONDITIONAL(HAVE_PABC, [test x$pabc = x1])
+
+
 # check for jansson library
 jansson=0
 AC_MSG_CHECKING(for libjansson)
diff --git a/contrib/Makefile.inc b/contrib/Makefile.inc
index c737a07f8..a563ef4a1 100644
--- a/contrib/Makefile.inc
+++ b/contrib/Makefile.inc
@@ -8,7 +8,8 @@ BUILDCOMMON_SHLIB_FILES = \
     build-common/sh/lib.sh/existence_python.sh \
     build-common/sh/lib.sh/msg.sh \
     build-common/sh/lib.sh/progname.sh \
-    build-common/sh/lib.sh/version_gnunet.sh
+    build-common/sh/lib.sh/version_gnunet.sh \
+    build-common/LICENSE
 
 BUILDCOMMON_CONF_FILES = \
     build-common/conf/.dir-locals.el \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9d1e3427c..dd36b7411 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,13 +10,21 @@ src/arm/arm_monitor_api.c
 src/arm/gnunet-arm.c
 src/arm/gnunet-service-arm.c
 src/arm/mockup-service.c
+src/ats-tests/ats-testing-experiment.c
+src/ats-tests/ats-testing-log.c
+src/ats-tests/ats-testing-preferences.c
+src/ats-tests/ats-testing-traffic.c
+src/ats-tests/ats-testing.c
+src/ats-tests/gnunet-ats-sim.c
+src/ats-tests/gnunet-solver-eval.c
+src/ats-tool/gnunet-ats.c
 src/ats/ats_api_connectivity.c
 src/ats/ats_api_performance.c
 src/ats/ats_api_scanner.c
 src/ats/ats_api_scheduling.c
 src/ats/gnunet-ats-solver-eval.c
-src/ats/gnunet-service-ats_addresses.c
 src/ats/gnunet-service-ats.c
+src/ats/gnunet-service-ats_addresses.c
 src/ats/gnunet-service-ats_connectivity.c
 src/ats/gnunet-service-ats_normalization.c
 src/ats/gnunet-service-ats_performance.c
@@ -25,14 +33,6 @@ src/ats/gnunet-service-ats_preferences.c
 src/ats/gnunet-service-ats_reservations.c
 src/ats/gnunet-service-ats_scheduling.c
 src/ats/plugin_ats_proportional.c
-src/ats-tests/ats-testing.c
-src/ats-tests/ats-testing-experiment.c
-src/ats-tests/ats-testing-log.c
-src/ats-tests/ats-testing-preferences.c
-src/ats-tests/ats-testing-traffic.c
-src/ats-tests/gnunet-ats-sim.c
-src/ats-tests/gnunet-solver-eval.c
-src/ats-tool/gnunet-ats.c
 src/auction/gnunet-auction-create.c
 src/auction/gnunet-auction-info.c
 src/auction/gnunet-auction-join.c
@@ -50,8 +50,8 @@ src/cadet/cadet_api_list_peers.c
 src/cadet/cadet_api_list_tunnels.c
 src/cadet/cadet_test_lib.c
 src/cadet/desirability_table.c
-src/cadet/gnunet-cadet.c
 src/cadet/gnunet-cadet-profiler.c
+src/cadet/gnunet-cadet.c
 src/cadet/gnunet-service-cadet.c
 src/cadet/gnunet-service-cadet_channel.c
 src/cadet/gnunet-service-cadet_connection.c
@@ -67,15 +67,15 @@ src/consensus/gnunet-service-consensus.c
 src/consensus/plugin_block_consensus.c
 src/conversation/conversation_api.c
 src/conversation/conversation_api_call.c
-src/conversation/gnunet-conversation.c
 src/conversation/gnunet-conversation-test.c
-src/conversation/gnunet_gst.c
-src/conversation/gnunet_gst_test.c
-src/conversation/gnunet-helper-audio-playback.c
+src/conversation/gnunet-conversation.c
 src/conversation/gnunet-helper-audio-playback-gst.c
-src/conversation/gnunet-helper-audio-record.c
+src/conversation/gnunet-helper-audio-playback.c
 src/conversation/gnunet-helper-audio-record-gst.c
+src/conversation/gnunet-helper-audio-record.c
 src/conversation/gnunet-service-conversation.c
+src/conversation/gnunet_gst.c
+src/conversation/gnunet_gst_test.c
 src/conversation/microphone.c
 src/conversation/plugin_gnsrecord_conversation.c
 src/conversation/speaker.c
@@ -105,7 +105,6 @@ src/dht/dht_api.c
 src/dht/dht_test_lib.c
 src/dht/gnunet-dht-get.c
 src/dht/gnunet-dht-monitor.c
-src/dht/gnunet_dht_profiler.c
 src/dht/gnunet-dht-put.c
 src/dht/gnunet-service-dht.c
 src/dht/gnunet-service-dht_clients.c
@@ -114,6 +113,7 @@ src/dht/gnunet-service-dht_hello.c
 src/dht/gnunet-service-dht_neighbours.c
 src/dht/gnunet-service-dht_nse.c
 src/dht/gnunet-service-dht_routing.c
+src/dht/gnunet_dht_profiler.c
 src/dht/plugin_block_dht.c
 src/dns/dns_api.c
 src/dns/gnunet-dns-monitor.c
@@ -148,8 +148,8 @@ src/fs/gnunet-auto-share.c
 src/fs/gnunet-daemon-fsprofiler.c
 src/fs/gnunet-directory.c
 src/fs/gnunet-download.c
-src/fs/gnunet-fs.c
 src/fs/gnunet-fs-profiler.c
+src/fs/gnunet-fs.c
 src/fs/gnunet-helper-fs-publish.c
 src/fs/gnunet-publish.c
 src/fs/gnunet-search.c
@@ -169,9 +169,9 @@ src/gns/gns_tld_api.c
 src/gns/gnunet-bcd.c
 src/gns/gnunet-dns2gns.c
 src/gns/gnunet-gns-benchmark.c
-src/gns/gnunet-gns.c
 src/gns/gnunet-gns-import.c
 src/gns/gnunet-gns-proxy.c
+src/gns/gnunet-gns.c
 src/gns/gnunet-service-gns.c
 src/gns/gnunet-service-gns_interceptor.c
 src/gns/gnunet-service-gns_resolver.c
@@ -189,8 +189,8 @@ src/gnsrecord/json_gnsrecord.c
 src/gnsrecord/plugin_gnsrecord_dns.c
 src/hello/address.c
 src/hello/gnunet-hello.c
-src/hello/hello.c
 src/hello/hello-ng.c
+src/hello/hello.c
 src/hostlist/gnunet-daemon-hostlist.c
 src/hostlist/gnunet-daemon-hostlist_client.c
 src/hostlist/gnunet-daemon-hostlist_server.c
@@ -205,8 +205,8 @@ src/json/json_generator.c
 src/json/json_helper.c
 src/json/json_mhd.c
 src/messenger/gnunet-messenger.c
-src/messenger/gnunet-service-messenger_basement.c
 src/messenger/gnunet-service-messenger.c
+src/messenger/gnunet-service-messenger_basement.c
 src/messenger/gnunet-service-messenger_ego_store.c
 src/messenger/gnunet-service-messenger_handle.c
 src/messenger/gnunet-service-messenger_list_handles.c
@@ -245,8 +245,8 @@ src/namecache/namecache_api.c
 src/namecache/plugin_namecache_flat.c
 src/namecache/plugin_namecache_postgres.c
 src/namecache/plugin_namecache_sqlite.c
-src/namestore/gnunet-namestore.c
 src/namestore/gnunet-namestore-fcfsd.c
+src/namestore/gnunet-namestore.c
 src/namestore/gnunet-service-namestore.c
 src/namestore/gnunet-zoneimport.c
 src/namestore/namestore_api.c
@@ -272,17 +272,17 @@ src/nat/gnunet-service-nat_mini.c
 src/nat/gnunet-service-nat_stun.c
 src/nat/nat_api.c
 src/nat/nat_api_stun.c
-src/nse/gnunet-nse.c
 src/nse/gnunet-nse-profiler.c
+src/nse/gnunet-nse.c
 src/nse/gnunet-service-nse.c
 src/nse/nse_api.c
 src/nt/nt.c
-src/peerinfo/gnunet-service-peerinfo.c
-src/peerinfo/peerinfo_api.c
-src/peerinfo/peerinfo_api_notify.c
 src/peerinfo-tool/gnunet-peerinfo.c
 src/peerinfo-tool/gnunet-peerinfo_plugins.c
 src/peerinfo-tool/plugin_rest_peerinfo.c
+src/peerinfo/gnunet-service-peerinfo.c
+src/peerinfo/peerinfo_api.c
+src/peerinfo/peerinfo_api_notify.c
 src/peerstore/gnunet-peerstore.c
 src/peerstore/gnunet-service-peerstore.c
 src/peerstore/peerstore_api.c
@@ -302,10 +302,13 @@ src/reclaim/gnunet-service-reclaim.c
 src/reclaim/gnunet-service-reclaim_tickets.c
 src/reclaim/json_reclaim.c
 src/reclaim/oidc_helper.c
+src/reclaim/pabc_helper.c
 src/reclaim/plugin_gnsrecord_reclaim.c
 src/reclaim/plugin_reclaim_attribute_basic.c
 src/reclaim/plugin_reclaim_credential_jwt.c
+src/reclaim/plugin_reclaim_credential_pabc.c
 src/reclaim/plugin_rest_openid_connect.c
+src/reclaim/plugin_rest_pabc.c
 src/reclaim/plugin_rest_reclaim.c
 src/reclaim/reclaim_api.c
 src/reclaim/reclaim_attribute.c
@@ -328,27 +331,27 @@ src/rest/gnunet-rest-server.c
 src/rest/plugin_rest_config.c
 src/rest/plugin_rest_copying.c
 src/rest/rest.c
-src/revocation/gnunet-revocation.c
 src/revocation/gnunet-revocation-tvg.c
+src/revocation/gnunet-revocation.c
 src/revocation/gnunet-service-revocation.c
 src/revocation/plugin_block_revocation.c
 src/revocation/revocation_api.c
-src/rps/gnunet-rps.c
 src/rps/gnunet-rps-profiler.c
+src/rps/gnunet-rps.c
 src/rps/gnunet-service-rps.c
 src/rps/gnunet-service-rps_custommap.c
 src/rps/gnunet-service-rps_sampler.c
 src/rps/gnunet-service-rps_sampler_elem.c
 src/rps/gnunet-service-rps_view.c
-src/rps/rps_api.c
 src/rps/rps-sampler_client.c
 src/rps/rps-sampler_common.c
 src/rps/rps-test_util.c
+src/rps/rps_api.c
 src/scalarproduct/gnunet-scalarproduct.c
-src/scalarproduct/gnunet-service-scalarproduct_alice.c
-src/scalarproduct/gnunet-service-scalarproduct_bob.c
 src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
 src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
+src/scalarproduct/gnunet-service-scalarproduct_alice.c
+src/scalarproduct/gnunet-service-scalarproduct_bob.c
 src/scalarproduct/scalarproduct_api.c
 src/secretsharing/gnunet-secretsharing-profiler.c
 src/secretsharing/gnunet-service-secretsharing.c
@@ -362,12 +365,12 @@ src/set/gnunet-set-ibf-profiler.c
 src/set/gnunet-set-profiler.c
 src/set/ibf.c
 src/set/ibf_sim.c
+src/set/plugin_block_set_test.c
+src/set/set_api.c
 src/seti/gnunet-service-seti.c
 src/seti/gnunet-seti-profiler.c
 src/seti/plugin_block_seti_test.c
 src/seti/seti_api.c
-src/set/plugin_block_set_test.c
-src/set/set_api.c
 src/setu/gnunet-service-setu.c
 src/setu/gnunet-service-setu_strata_estimator.c
 src/setu/gnunet-setu-ibf-profiler.c
@@ -386,15 +389,16 @@ src/statistics/gnunet-statistics.c
 src/statistics/statistics_api.c
 src/template/gnunet-service-template.c
 src/template/gnunet-template.c
+src/testbed-logger/gnunet-service-testbed-logger.c
+src/testbed-logger/testbed_logger_api.c
 src/testbed/generate-underlay-topology.c
 src/testbed/gnunet-daemon-latency-logger.c
 src/testbed/gnunet-daemon-testbed-blacklist.c
 src/testbed/gnunet-daemon-testbed-underlay.c
 src/testbed/gnunet-helper-testbed.c
-src/testbed/gnunet_mpi_test.c
 src/testbed/gnunet-service-test-barriers.c
-src/testbed/gnunet-service-testbed_barriers.c
 src/testbed/gnunet-service-testbed.c
+src/testbed/gnunet-service-testbed_barriers.c
 src/testbed/gnunet-service-testbed_cache.c
 src/testbed/gnunet-service-testbed_connectionpool.c
 src/testbed/gnunet-service-testbed_cpustatus.c
@@ -402,69 +406,81 @@ src/testbed/gnunet-service-testbed_links.c
 src/testbed/gnunet-service-testbed_meminfo.c
 src/testbed/gnunet-service-testbed_oc.c
 src/testbed/gnunet-service-testbed_peers.c
-src/testbed/gnunet_testbed_mpi_spawn.c
 src/testbed/gnunet-testbed-profiler.c
-src/testbed-logger/gnunet-service-testbed-logger.c
-src/testbed-logger/testbed_logger_api.c
-src/testbed/testbed_api_barriers.c
+src/testbed/gnunet_mpi_test.c
+src/testbed/gnunet_testbed_mpi_spawn.c
 src/testbed/testbed_api.c
+src/testbed/testbed_api_barriers.c
 src/testbed/testbed_api_cmd_controller.c
 src/testbed/testbed_api_cmd_peer.c
-src/testbed/testbed_api_cmd_service.c
+src/testbed/testbed_api_cmd_peer_store.c
+src/testbed/testbed_api_cmd_tng_connect.c
+src/testbed/testbed_api_cmd_tng_service.c
 src/testbed/testbed_api_hosts.c
 src/testbed/testbed_api_operations.c
 src/testbed/testbed_api_peers.c
 src/testbed/testbed_api_sd.c
 src/testbed/testbed_api_services.c
 src/testbed/testbed_api_statistics.c
-src/testbed/testbed_api_testbed.c
 src/testbed/testbed_api_test.c
+src/testbed/testbed_api_testbed.c
 src/testbed/testbed_api_topology.c
 src/testbed/testbed_api_underlay.c
 src/testing/gnunet-testing.c
 src/testing/list-keys.c
+src/testing/testing.c
 src/testing/testing_api_cmd_batch.c
-src/testing/testing_api_cmd_hello_world_birth.c
 src/testing/testing_api_cmd_hello_world.c
+src/testing/testing_api_cmd_hello_world_birth.c
 src/testing/testing_api_loop.c
 src/testing/testing_api_trait_cmd.c
 src/testing/testing_api_trait_process.c
 src/testing/testing_api_traits.c
-src/testing/testing.c
 src/topology/friends.c
 src/topology/gnunet-daemon-topology.c
 src/transport/gnunet-communicator-tcp.c
 src/transport/gnunet-communicator-udp.c
 src/transport/gnunet-communicator-unix.c
 src/transport/gnunet-helper-transport-bluetooth.c
-src/transport/gnunet-helper-transport-wlan.c
 src/transport/gnunet-helper-transport-wlan-dummy.c
+src/transport/gnunet-helper-transport-wlan.c
 src/transport/gnunet-service-tng.c
-src/transport/gnunet-service-transport_ats.c
 src/transport/gnunet-service-transport.c
+src/transport/gnunet-service-transport_ats.c
 src/transport/gnunet-service-transport_hello.c
 src/transport/gnunet-service-transport_manipulation.c
 src/transport/gnunet-service-transport_neighbours.c
 src/transport/gnunet-service-transport_plugins.c
 src/transport/gnunet-service-transport_validation.c
-src/transport/gnunet-transport.c
 src/transport/gnunet-transport-profiler.c
 src/transport/gnunet-transport-wlan-receiver.c
 src/transport/gnunet-transport-wlan-sender.c
+src/transport/gnunet-transport.c
 src/transport/plugin_transport_http_client.c
 src/transport/plugin_transport_http_common.c
 src/transport/plugin_transport_http_server.c
 src/transport/plugin_transport_smtp.c
 src/transport/plugin_transport_tcp.c
 src/transport/plugin_transport_template.c
-src/transport/plugin_transport_udp_broadcasting.c
 src/transport/plugin_transport_udp.c
+src/transport/plugin_transport_udp_broadcasting.c
 src/transport/plugin_transport_unix.c
 src/transport/plugin_transport_wlan.c
 src/transport/tcp_connection_legacy.c
 src/transport/tcp_server_legacy.c
 src/transport/tcp_server_mst_legacy.c
 src/transport/tcp_service_legacy.c
+src/transport/transport-testing-communicator.c
+src/transport/transport-testing-filenames.c
+src/transport/transport-testing-filenames2.c
+src/transport/transport-testing-loggers.c
+src/transport/transport-testing-loggers2.c
+src/transport/transport-testing-main.c
+src/transport/transport-testing-main2.c
+src/transport/transport-testing-send.c
+src/transport/transport-testing-send2.c
+src/transport/transport-testing.c
+src/transport/transport-testing2.c
 src/transport/transport_api2_application.c
 src/transport/transport_api2_communication.c
 src/transport/transport_api2_core.c
@@ -477,17 +493,6 @@ src/transport/transport_api_manipulation.c
 src/transport/transport_api_monitor_peers.c
 src/transport/transport_api_monitor_plugins.c
 src/transport/transport_api_offer_hello.c
-src/transport/transport-testing2.c
-src/transport/transport-testing.c
-src/transport/transport-testing-communicator.c
-src/transport/transport-testing-filenames2.c
-src/transport/transport-testing-filenames.c
-src/transport/transport-testing-loggers2.c
-src/transport/transport-testing-loggers.c
-src/transport/transport-testing-main2.c
-src/transport/transport-testing-main.c
-src/transport/transport-testing-send2.c
-src/transport/transport-testing-send.c
 src/util/bandwidth.c
 src/util/benchmark.c
 src/util/bio.c
@@ -502,8 +507,8 @@ src/util/consttime_memcmp.c
 src/util/container_bloomfilter.c
 src/util/container_heap.c
 src/util/container_meta_data.c
-src/util/container_multihashmap32.c
 src/util/container_multihashmap.c
+src/util/container_multihashmap32.c
 src/util/container_multipeermap.c
 src/util/container_multishortmap.c
 src/util/container_multiuuidmap.c
@@ -528,8 +533,8 @@ src/util/dnsstub.c
 src/util/getopt.c
 src/util/getopt_helpers.c
 src/util/gnunet-base32.c
-src/util/gnunet-config.c
 src/util/gnunet-config-diff.c
+src/util/gnunet-config.c
 src/util/gnunet-crypto-tvg.c
 src/util/gnunet-ecc.c
 src/util/gnunet-qr.c
@@ -567,8 +572,8 @@ src/vpn/gnunet-helper-vpn.c
 src/vpn/gnunet-service-vpn.c
 src/vpn/gnunet-vpn.c
 src/vpn/vpn_api.c
-src/zonemaster/gnunet-service-zonemaster.c
 src/zonemaster/gnunet-service-zonemaster-monitor.c
+src/zonemaster/gnunet-service-zonemaster.c
 src/fs/fs_api.h
 src/testbed/testbed_api.h
 src/testbed/testbed_api_operations.h
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 9463f19d9..1a0b7fae4 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -16,6 +16,11 @@ REST_PLUGIN = \
 CREDENTIAL_PLUGIN = \
   libgnunet_plugin_reclaim_credential_jwt.la
 
+if HAVE_PABC
+  CREDENTIAL_PLUGIN += libgnunet_plugin_reclaim_credential_pabc.la
+  REST_PLUGIN += libgnunet_plugin_rest_pabc.la
+endif
+
 EXTRA_DIST = \
   reclaim.conf \
   test_reclaim_defaults.conf \
@@ -87,6 +92,26 @@ libgnunet_plugin_rest_openid_connect_la_LDFLAGS = \
   $(GN_PLUGIN_LDFLAGS)
 libgnunet_plugin_rest_openid_connect_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
 
+if HAVE_PABC
+libgnunet_plugin_rest_pabc_la_SOURCES = \
+  plugin_rest_pabc.c \
+  pabc_helper.c
+libgnunet_plugin_rest_pabc_la_LIBADD = \
+  libgnunetreclaim.la \
+  $(top_builddir)/src/json/libgnunetjson.la \
+  $(top_builddir)/src/rest/libgnunetrest.la \
+  $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
+  $(LTLIBINTL) -ljansson -lpabc $(MHD_LIBS)
+libgnunet_plugin_rest_pabc_la_DEPENDENCIES = \
+  libgnunetreclaim.la \
+  $(top_builddir)/src/json/libgnunetjson.la \
+  $(top_builddir)/src/rest/libgnunetrest.la \
+  $(top_builddir)/src/util/libgnunetutil.la
+libgnunet_plugin_rest_pabc_la_LDFLAGS = \
+  $(GN_PLUGIN_LDFLAGS)
+libgnunet_plugin_rest_pabc_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
+endif
+
 
 libgnunet_plugin_gnsrecord_reclaim_la_SOURCES = \
   plugin_gnsrecord_reclaim.c
@@ -134,6 +159,21 @@ libgnunet_plugin_reclaim_attribute_basic_la_LIBADD = \
 libgnunet_plugin_reclaim_attribute_basic_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
 
+if HAVE_PABC
+libgnunet_plugin_reclaim_credential_pabc_la_SOURCES = \
+  plugin_reclaim_credential_pabc.c \
+  pabc_helper.c
+libgnunet_plugin_reclaim_credential_pabc_la_LIBADD = \
+  $(top_builddir)/src/util/libgnunetutil.la \
+  libgnunetreclaim.la \
+  -ljansson\
+  -lpabc \
+  $(LTLIBINTL)
+libgnunet_plugin_reclaim_credential_pabc_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
+endif
+
+
 libgnunet_plugin_reclaim_credential_jwt_la_SOURCES = \
   plugin_reclaim_credential_jwt.c
 libgnunet_plugin_reclaim_credential_jwt_la_LIBADD = \
diff --git a/src/reclaim/json_reclaim.c b/src/reclaim/json_reclaim.c
index 4eeb22bee..b1ca7a4a5 100644
--- a/src/reclaim/json_reclaim.c
+++ b/src/reclaim/json_reclaim.c
@@ -290,10 +290,11 @@ parse_credential (void *cls, json_t *root, struct 
GNUNET_JSON_Specification *spe
 {
   struct GNUNET_RECLAIM_Credential *cred;
   const char *name_str = NULL;
-  const char *val_str = NULL;
   const char *type_str = NULL;
   const char *id_str = NULL;
-  char *data;
+  json_t *val_json;
+  char *data = NULL;
+  char *val_str = NULL;
   int unpack_state;
   uint32_t type;
   size_t data_size;
@@ -308,7 +309,7 @@ parse_credential (void *cls, json_t *root, struct 
GNUNET_JSON_Specification *spe
   }
   // interpret single attribute
   unpack_state = json_unpack (root,
-                              "{s:s, s?s, s:s, s:s!}",
+                              "{s:s, s?s, s:s, s:o!}",
                               "name",
                               &name_str,
                               "id",
@@ -316,14 +317,19 @@ parse_credential (void *cls, json_t *root, struct 
GNUNET_JSON_Specification *spe
                               "type",
                               &type_str,
                               "value",
-                              &val_str);
-  if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
+                              &val_json);
+  if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_json) ||
       (NULL == type_str))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Error json object has a wrong format!\n");
     return GNUNET_SYSERR;
   }
+  if (json_is_string (val_json)) {
+    val_str = GNUNET_strdup (json_string_value (val_json));
+  } else {
+    val_str = json_dumps (val_json, JSON_COMPACT);
+  }
   type = GNUNET_RECLAIM_credential_typename_to_number (type_str);
   if (GNUNET_SYSERR ==
       (GNUNET_RECLAIM_credential_string_to_value (type,
diff --git a/src/reclaim/pabc_helper.c b/src/reclaim/pabc_helper.c
new file mode 100644
index 000000000..1b1dbea0f
--- /dev/null
+++ b/src/reclaim/pabc_helper.c
@@ -0,0 +1,364 @@
+// maximilian.kaul@aisec.fraunhofer.de
+
+// WIP implementation of
+// https://github.com/ontio/ontology-crypto/wiki/Anonymous-Credential
+// using the relic library https://github.com/relic-toolkit/relic/
+
+#include "pabc_helper.h"
+#include <pwd.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static char pabc_dir[PATH_MAX + 1];
+
+static const char *
+get_homedir ()
+{
+  const char *homedir;
+  if ((homedir = getenv ("HOME")) == NULL)
+  {
+    homedir = getpwuid (getuid ())->pw_dir;
+  }
+  return homedir;
+}
+
+
+static enum GNUNET_GenericReturnValue
+write_file (char const *const filename, const char *buffer)
+{
+  struct GNUNET_DISK_FileHandle *fh;
+  fh = GNUNET_DISK_file_open (filename,
+                              GNUNET_DISK_OPEN_WRITE
+                              | GNUNET_DISK_OPEN_TRUNCATE
+                              | GNUNET_DISK_OPEN_CREATE,
+                              GNUNET_DISK_PERM_USER_WRITE
+                              | GNUNET_DISK_PERM_USER_READ);
+  if (fh == NULL)
+    return GNUNET_SYSERR;
+  if (GNUNET_SYSERR == GNUNET_DISK_file_write (fh,
+                                               buffer, strlen (buffer) + 1))
+    goto fail;
+  GNUNET_DISK_file_close (fh);
+  return GNUNET_OK;
+
+fail:
+  GNUNET_DISK_file_close (fh);
+  return GNUNET_SYSERR;
+}
+
+
+static enum GNUNET_GenericReturnValue
+init_pabc_dir ()
+{
+  size_t filename_size = strlen (get_homedir ()) + 1 + strlen (".local") + 1
+                         + strlen ("pabc-reclaim") + 1;
+  snprintf (pabc_dir, filename_size, "%s/%s/%s",
+            get_homedir (), ".local", "pabc-reclaim");
+  return GNUNET_DISK_directory_create (pabc_dir);
+}
+
+
+static const char *
+get_pabcdir ()
+{
+  init_pabc_dir ();
+  return pabc_dir;
+}
+
+
+enum GNUNET_GenericReturnValue
+read_file (char const *const filename, char **buffer)
+{
+  struct GNUNET_DISK_FileHandle *fh;
+  if (GNUNET_YES != GNUNET_DISK_file_test (filename))
+    return GNUNET_SYSERR;
+
+  fh = GNUNET_DISK_file_open (filename,
+                              GNUNET_DISK_OPEN_READ,
+                              GNUNET_DISK_PERM_USER_READ);
+  if (fh == NULL)
+    return GNUNET_SYSERR;
+  long lSize = GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_END);
+  if (lSize < 0)
+    goto fail;
+  GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET);
+  *buffer = calloc ((size_t) lSize + 1, sizeof(char));
+  if (*buffer == NULL)
+    goto fail;
+
+  // copy the file into the buffer:
+  size_t r = GNUNET_DISK_file_read (fh, *buffer, (size_t) lSize);
+  if (r != (size_t) lSize)
+    goto fail;
+
+  GNUNET_DISK_file_close (fh);
+  return GNUNET_OK;
+
+fail:
+  GNUNET_DISK_file_close (fh);
+  return GNUNET_SYSERR;
+}
+
+
+struct pabc_public_parameters *
+PABC_read_issuer_ppfile (const char *f, struct pabc_context *const ctx)
+{
+  if (NULL == ctx)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No global context provided\n");
+    return NULL;
+  }
+  struct pabc_public_parameters *pp;
+  char *buffer;
+  int r;
+  r = read_file (f, &buffer);
+  if (GNUNET_OK != r)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading file\n");
+    return NULL;
+  }
+  if (PABC_OK != pabc_decode_and_new_public_parameters (ctx, &pp, buffer))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to decode public parameters\n");
+    PABC_FREE_NULL (buffer);
+    return NULL;
+  }
+  PABC_FREE_NULL (buffer);
+  return pp;
+}
+
+
+enum GNUNET_GenericReturnValue
+PABC_load_public_parameters (struct pabc_context *const ctx,
+                             char const *const pp_name,
+                             struct pabc_public_parameters **pp)
+{
+  char fname[PATH_MAX];
+  char *pp_filename;
+  const char *pdir = get_pabcdir ();
+
+  if (ctx == NULL)
+    return GNUNET_SYSERR;
+  if (pp_name == NULL)
+    return GNUNET_SYSERR;
+
+  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
+  if (GNUNET_YES != GNUNET_DISK_directory_test (pdir, GNUNET_YES))
+  {
+    GNUNET_free (pp_filename);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error reading %s\n", pdir);
+    return GNUNET_SYSERR;
+  }
+  snprintf (fname, PATH_MAX, "%s/%s%s", pdir, pp_filename, PABC_PP_EXT);
+  if (GNUNET_YES != GNUNET_DISK_file_test (fname))
+  {
+    GNUNET_free (pp_filename);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error testing %s\n", fname);
+    return GNUNET_SYSERR;
+  }
+  *pp = PABC_read_issuer_ppfile (fname, ctx);
+  if (*pp)
+    return GNUNET_OK;
+  else
+    return GNUNET_SYSERR;
+}
+
+
+enum GNUNET_GenericReturnValue
+PABC_write_public_parameters (char const *const pp_name,
+                              struct pabc_public_parameters *const pp)
+{
+  char *json;
+  char *filename;
+  char *pp_filename;
+  enum pabc_status status;
+  struct pabc_context *ctx = NULL;
+
+  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
+  PABC_ASSERT (pabc_new_ctx (&ctx));
+  // store in json file
+  status = pabc_encode_public_parameters (ctx, pp, &json);
+  if (status != PABC_OK)
+  {
+    GNUNET_free (pp_filename);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to encode public parameters.\n");
+    pabc_free_ctx (&ctx);
+    return GNUNET_SYSERR;
+  }
+
+  size_t filename_size =
+    strlen (get_pabcdir ()) + 1 + strlen (pp_filename) + strlen (PABC_PP_EXT)
+    + 1;
+  filename = GNUNET_malloc (filename_size);
+  if (! filename)
+  {
+    GNUNET_free (pp_filename);
+    PABC_FREE_NULL (json);
+    pabc_free_ctx (&ctx);
+    return GNUNET_SYSERR;
+  }
+  snprintf (filename, filename_size, "%s/%s%s", get_pabcdir (), pp_filename,
+            PABC_PP_EXT);
+
+  GNUNET_free (pp_filename);
+  if (GNUNET_OK != write_file (filename, json))
+  {
+    PABC_FREE_NULL (filename);
+    PABC_FREE_NULL (json);
+    pabc_free_ctx (&ctx);
+    return GNUNET_SYSERR;
+  }
+  PABC_FREE_NULL (filename);
+  PABC_FREE_NULL (json);
+  pabc_free_ctx (&ctx);
+  return GNUNET_OK;
+}
+
+
+enum GNUNET_GenericReturnValue
+PABC_write_usr_ctx (char const *const usr_name,
+                    char const *const pp_name,
+                    struct pabc_context const *const ctx,
+                    struct pabc_public_parameters const *const pp,
+                    struct pabc_user_context *const usr_ctx)
+{
+
+  char *pp_filename;
+  char *json = NULL;
+  enum pabc_status status;
+  char *fname = NULL;
+
+  if (NULL == usr_name)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == pp_name)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == ctx)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == pp)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == usr_ctx)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
+    return GNUNET_SYSERR;
+  }
+
+  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
+  status = pabc_encode_user_ctx (ctx, pp, usr_ctx, &json);
+  if (PABC_OK != status)
+  {
+    GNUNET_free (pp_filename);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
+    return status;
+  }
+
+  size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
+                      + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
+  fname = GNUNET_malloc (fname_size);
+
+  snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
+            pp_filename,
+            PABC_USR_EXT);
+
+  GNUNET_free (pp_filename);
+  if (GNUNET_OK == write_file (fname, json))
+  {
+    GNUNET_free (fname);
+    GNUNET_free (json);
+    return GNUNET_OK;
+  }
+  else
+  {
+    GNUNET_free (fname);
+    GNUNET_free (json);
+    return GNUNET_SYSERR;
+  }
+}
+
+
+enum GNUNET_GenericReturnValue
+PABC_read_usr_ctx (char const *const usr_name,
+                   char const *const pp_name,
+                   struct pabc_context const *const ctx,
+                   struct pabc_public_parameters const *const pp,
+                   struct pabc_user_context **usr_ctx)
+{
+  char *json = NULL;
+  char *pp_filename;
+  enum pabc_status status;
+
+  char *fname = NULL;
+
+  if (NULL == usr_name)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == pp_name)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == ctx)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No context given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == pp)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No public parameters given.\n");
+    return GNUNET_SYSERR;
+  }
+  if (NULL == usr_ctx)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No user context given.\n");
+    return GNUNET_SYSERR;
+  }
+  GNUNET_STRINGS_urlencode (pp_name, strlen (pp_name), &pp_filename);
+
+  size_t fname_size = strlen (get_pabcdir ()) + 1 + strlen (usr_name) + 1
+                      + strlen (pp_filename) + strlen (PABC_USR_EXT) + 1;
+  fname = GNUNET_malloc (fname_size);
+  snprintf (fname, fname_size, "%s/%s_%s%s", get_pabcdir (), usr_name,
+            pp_filename,
+            PABC_USR_EXT);
+  GNUNET_free (pp_filename);
+  if (GNUNET_OK != read_file (fname, &json))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to read `%s'\n", fname);
+    PABC_FREE_NULL (fname);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (fname);
+
+  status = pabc_new_user_context (ctx, pp, usr_ctx);
+  if (PABC_OK != status)
+  {
+    GNUNET_free (json);
+    return GNUNET_SYSERR;
+  }
+  status = pabc_decode_user_ctx (ctx, pp, *usr_ctx, json);
+  GNUNET_free (json);
+  if (PABC_OK != status)
+  {
+    pabc_free_user_context (ctx, pp, usr_ctx);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to encode user context.\n");
+    return GNUNET_SYSERR;
+  }
+
+  return GNUNET_OK;
+}
diff --git a/src/reclaim/pabc_helper.h b/src/reclaim/pabc_helper.h
new file mode 100644
index 000000000..045ad5dda
--- /dev/null
+++ b/src/reclaim/pabc_helper.h
@@ -0,0 +1,41 @@
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include <pabc/pabc.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+#define PABC_ISK_EXT ".isk"
+
+#define PABC_PP_EXT ".pp"
+
+#define PABC_USR_EXT ".usr"
+
+#define PABC_ATTR_DELIM "="
+
+enum GNUNET_GenericReturnValue
+PABC_write_public_parameters (char const *const pp_name,
+                              struct pabc_public_parameters *const pp);
+
+
+enum GNUNET_GenericReturnValue
+PABC_load_public_parameters (struct pabc_context *const ctx,
+                             char const *const pp_name,
+                             struct pabc_public_parameters **pp);
+
+enum GNUNET_GenericReturnValue
+PABC_write_usr_ctx (char const *const user_name,
+                    char const *const pp_name,
+                    struct pabc_context const *const ctx,
+                    struct pabc_public_parameters const *const
+                    pp,
+                    struct pabc_user_context *const usr_ctx);
+
+enum GNUNET_GenericReturnValue
+PABC_read_usr_ctx (char const *const user_name,
+                   char const *const pp_name,
+                   struct pabc_context const *const ctx,
+                   struct pabc_public_parameters const *const
+                   pp,
+                   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..e5dc90363 100644
--- a/src/reclaim/plugin_reclaim_credential_jwt.c
+++ b/src/reclaim/plugin_reclaim_credential_jwt.c
@@ -158,11 +158,10 @@ jwt_parse_attributes (void *cls,
   struct GNUNET_RECLAIM_AttributeList *attrs;
   char delim[] = ".";
   char *val_str = NULL;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
   char *decoded_jwt;
   char *tmp;
   json_t *json_val;
-  json_error_t *json_err = NULL;
+  json_error_t json_err;
 
   attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
 
@@ -173,7 +172,7 @@ jwt_parse_attributes (void *cls,
                                    (void **) &decoded_jwt);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt);
   GNUNET_assert (NULL != decoded_jwt);
-  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
   GNUNET_free (decoded_jwt);
   const char *key;
   const char *addr_key;
@@ -252,6 +251,8 @@ struct GNUNET_RECLAIM_AttributeList *
 jwt_parse_attributes_c (void *cls,
                         const struct GNUNET_RECLAIM_Credential *cred)
 {
+  if (cred->type != GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT)
+    return NULL;
   return jwt_parse_attributes (cls, cred->data, cred->data_size);
 }
 
@@ -267,6 +268,8 @@ struct GNUNET_RECLAIM_AttributeList *
 jwt_parse_attributes_p (void *cls,
                         const struct GNUNET_RECLAIM_Presentation *cred)
 {
+  if (cred->type != GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT)
+    return NULL;
   return jwt_parse_attributes (cls, cred->data, cred->data_size);
 }
 
@@ -291,14 +294,14 @@ jwt_get_issuer (void *cls,
   json_t *issuer_json;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
   json_t *json_val;
-  json_error_t *json_err = NULL;
+  json_error_t json_err;
 
   jwt_string = GNUNET_strndup (data, data_size);
   jwt_body = strtok (jwt_string, delim);
   jwt_body = strtok (NULL, delim);
   GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
                                    (void **) &decoded_jwt);
-  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
   GNUNET_free (decoded_jwt);
   GNUNET_free (jwt_string);
   if (NULL == json_val)
@@ -355,7 +358,7 @@ jwt_get_issuer_p (void *cls,
  * @param cred the jwt credential
  * @return a string, containing the isser
  */
-int
+enum GNUNET_GenericReturnValue
 jwt_get_expiration (void *cls,
                     const char *data,
                     size_t data_size,
@@ -368,14 +371,14 @@ jwt_get_expiration (void *cls,
   json_t *exp_json;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
   json_t *json_val;
-  json_error_t *json_err = NULL;
+  json_error_t json_err;
 
   jwt_string = GNUNET_strndup (data, data_size);
   jwt_body = strtok (jwt_string, delim);
   jwt_body = strtok (NULL, delim);
   GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
                                    (void **) &decoded_jwt);
-  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
   GNUNET_free (decoded_jwt);
   GNUNET_free (jwt_string);
   if (NULL == json_val)
@@ -396,13 +399,15 @@ jwt_get_expiration (void *cls,
  *
  * @param cls the plugin
  * @param cred the jwt credential
- * @return a string, containing the isser
+ * @return the expirati
  */
-int
+enum GNUNET_GenericReturnValue
 jwt_get_expiration_c (void *cls,
                       const struct GNUNET_RECLAIM_Credential *cred,
                       struct GNUNET_TIME_Absolute *exp)
 {
+  if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type)
+    return GNUNET_NO;
   return jwt_get_expiration (cls, cred->data, cred->data_size, exp);
 }
 
@@ -414,22 +419,23 @@ jwt_get_expiration_c (void *cls,
  * @param cred the jwt credential
  * @return a string, containing the isser
  */
-int
+enum GNUNET_GenericReturnValue
 jwt_get_expiration_p (void *cls,
                       const struct GNUNET_RECLAIM_Presentation *cred,
                       struct GNUNET_TIME_Absolute *exp)
 {
+  if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type)
+    return GNUNET_NO;
   return jwt_get_expiration (cls, cred->data, cred->data_size, exp);
 }
 
 
-int
+enum GNUNET_GenericReturnValue
 jwt_create_presentation (void *cls,
                          const struct GNUNET_RECLAIM_Credential *cred,
                          const struct GNUNET_RECLAIM_AttributeList *attrs,
                          struct GNUNET_RECLAIM_Presentation **pres)
 {
-  // FIXME sanity checks??
   if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type)
     return GNUNET_NO;
   *pres = GNUNET_RECLAIM_presentation_new (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT,
diff --git a/src/reclaim/plugin_reclaim_credential_pabc.c 
b/src/reclaim/plugin_reclaim_credential_pabc.c
new file mode 100644
index 000000000..2f6b7b8c4
--- /dev/null
+++ b/src/reclaim/plugin_reclaim_credential_pabc.c
@@ -0,0 +1,639 @@
+/*
+     This file is part of GNUnet
+     Copyright (C) 2013, 2014, 2016 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Affero General Public License for more details.
+
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file reclaim/plugin_reclaim_credential_pabc.c
+ * @brief reclaim-credential-plugin-pabc attribute plugin to provide the API 
for
+ *                                      pabc credentials.
+ *
+ * @author Martin Schanzenbach
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_reclaim_plugin.h"
+#include <inttypes.h>
+#include <jansson.h>
+#include <pabc/pabc.h>
+#include "pabc_helper.h"
+
+/**
+   * Convert the 'value' of an credential to a string.
+   *
+   * @param cls closure, unused
+   * @param type type of the credential
+   * @param data value in binary encoding
+   * @param data_size number of bytes in @a data
+   * @return NULL on error, otherwise human-readable representation of the 
value
+   */
+static char *
+pabc_value_to_string (void *cls,
+                      uint32_t type,
+                      const void *data,
+                      size_t data_size)
+{
+  switch (type)
+  {
+  case GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC:
+    return GNUNET_strndup (data, data_size);
+
+  default:
+    return NULL;
+  }
+}
+
+
+/**
+ * Convert human-readable version of a 'value' of an credential to the binary
+ * representation.
+ *
+ * @param cls closure, unused
+ * @param type type of the credential
+ * @param s human-readable string
+ * @param data set to value in binary encoding (will be allocated)
+ * @param data_size set to number of bytes in @a data
+ * @return #GNUNET_OK on success
+ */
+static int
+pabc_string_to_value (void *cls,
+                      uint32_t type,
+                      const char *s,
+                      void **data,
+                      size_t *data_size)
+{
+  if (NULL == s)
+    return GNUNET_SYSERR;
+  switch (type)
+  {
+  case GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC:
+    *data = GNUNET_strdup (s);
+    *data_size = strlen (s) + 1;
+    return GNUNET_OK;
+
+  default:
+    return GNUNET_SYSERR;
+  }
+}
+
+
+/**
+ * Mapping of credential type numbers to human-readable
+ * credential type names.
+ */
+static struct
+{
+  const char *name;
+  uint32_t number;
+} pabc_cred_name_map[] = { { "PABC", GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC },
+                           { NULL, UINT32_MAX } };
+
+/**
+   * Convert a type name to the corresponding number.
+   *
+   * @param cls closure, unused
+   * @param pabc_typename name to convert
+   * @return corresponding number, UINT32_MAX on error
+   */
+static uint32_t
+pabc_typename_to_number (void *cls, const char *pabc_typename)
+{
+  unsigned int i;
+
+  i = 0;
+  while ((NULL != pabc_cred_name_map[i].name) &&
+         (0 != strcasecmp (pabc_typename, pabc_cred_name_map[i].name)))
+    i++;
+  return pabc_cred_name_map[i].number;
+}
+
+
+/**
+ * Convert a type number (i.e. 1) to the corresponding type string
+ *
+ * @param cls closure, unused
+ * @param type number of a type to convert
+ * @return corresponding typestring, NULL on error
+ */
+static const char *
+pabc_number_to_typename (void *cls, uint32_t type)
+{
+  unsigned int i;
+
+  i = 0;
+  while ((NULL != pabc_cred_name_map[i].name) && (type !=
+                                                  pabc_cred_name_map[i].
+                                                  number))
+    i++;
+  return pabc_cred_name_map[i].name;
+}
+
+
+static void
+inspect_attrs (char const *const key,
+               char const *const value,
+               void *ctx)
+{
+  struct GNUNET_RECLAIM_AttributeList *attrs = ctx;
+
+  if (NULL == value)
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Found attribue in PABC credential: `%s': `%s'\n",
+              key, value);
+  if (0 == strcmp (key, "expiration"))
+    return;
+  if (0 == strcmp (key, "issuer"))
+    return;
+  if (0 == strcmp (key, "subject"))
+    return;
+  GNUNET_RECLAIM_attribute_list_add (attrs,
+                                     key,
+                                     NULL,
+                                     GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING,
+                                     value,
+                                     strlen (value));
+}
+
+
+/**
+ * Parse a pabc and return the respective claim value as Attribute
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a GNUNET_RECLAIM_Attribute, containing the new value
+ */
+struct GNUNET_RECLAIM_AttributeList *
+pabc_parse_attributes (void *cls,
+                       const char *data,
+                       size_t data_size)
+{
+  struct GNUNET_RECLAIM_AttributeList *attrs;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Collecting PABC attributes...\n");
+  attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
+  GNUNET_assert (PABC_OK ==
+                 pabc_cred_inspect_credential (data,
+                                               &inspect_attrs, attrs));
+  return attrs;
+}
+
+
+/**
+ * Parse a pabc and return the respective claim value as Attribute
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a GNUNET_RECLAIM_Attribute, containing the new value
+ */
+struct GNUNET_RECLAIM_AttributeList *
+pabc_parse_attributes_c (void *cls,
+                         const struct GNUNET_RECLAIM_Credential *cred)
+{
+  if (cred->type != GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC)
+    return NULL;
+  return pabc_parse_attributes (cls, cred->data, cred->data_size);
+}
+
+
+/**
+ * Parse a pabc and return the respective claim value as Attribute
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a GNUNET_RECLAIM_Attribute, containing the new value
+ */
+struct GNUNET_RECLAIM_AttributeList *
+pabc_parse_attributes_p (void *cls,
+                         const struct GNUNET_RECLAIM_Presentation *cred)
+{
+  if (cred->type != GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC)
+    return NULL;
+  return pabc_parse_attributes (cls, cred->data, cred->data_size);
+}
+
+struct Finder
+{
+  const char* target;
+  char *result;
+};
+
+static void
+find_attr (char const *const key,
+                char const *const value,
+                void *ctx)
+{
+  struct Finder *fdr = ctx;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Found `%s', looking for `%s'\n",
+              key, fdr->target);
+  if (0 == strcmp (key, fdr->target))
+    fdr->result = GNUNET_strdup (value);
+}
+
+
+
+/**
+ * Parse a pabc and return an attribute value.
+ *
+ * @param cls the plugin
+ * @param data the pabc credential data
+ * @param data_size the pabc credential size
+ * @param skey the attribute key to look for.
+ * @return a string, containing the isser
+ */
+char *
+pabc_get_attribute (void *cls,
+                    const char *data,
+                    size_t data_size,
+                    const char *skey)
+{
+
+  struct Finder fdr;
+  memset (&fdr, 0, sizeof (fdr));
+  fdr.target = skey;
+  pabc_cred_inspect_credential (data, &find_attr, &fdr);
+  return fdr.result;
+}
+
+
+/**
+ * Parse a pabc and return the issuer
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
+char*
+pabc_get_issuer (void *cls,
+                 const char *data,
+                 size_t data_size)
+{
+  char *res;
+  if (PABC_OK != pabc_cred_get_attr_by_name_from_cred (data,
+                                                       "issuer",
+                                                       &res))
+    return NULL;
+  return res;
+}
+
+
+/**
+ * Parse a pabc and return the issuer
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
+char*
+pabc_get_issuer (void *cls,
+                 const char *data,
+                 size_t data_size)
+{
+  return pabc_get_attribute (cls, data, data_size, "issuer");
+}
+
+
+/**
+ * Parse a pabc and return the issuer
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
+char *
+pabc_get_issuer_c (void *cls,
+                   const struct GNUNET_RECLAIM_Credential *cred)
+{
+  if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type)
+    return NULL;
+  return pabc_get_issuer (cls, cred->data, cred->data_size);
+}
+
+
+/**
+ * Parse a pabc and return the issuer
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
+char *
+pabc_get_issuer_p (void *cls,
+                   const struct GNUNET_RECLAIM_Presentation *cred)
+{
+  if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != cred->type)
+    return NULL;
+  return pabc_get_issuer (cls, cred->data, cred->data_size);
+}
+
+
+/**
+ * Parse a pabc and return the expiration
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
+int
+pabc_get_expiration (void *cls,
+                     const char *data,
+                     size_t data_size,
+                     struct GNUNET_TIME_Absolute *exp)
+{
+  json_t *json_root;
+  json_t *json_attrs;
+  json_t *value;
+  json_t *exp_j;
+  json_error_t *json_err = NULL;
+  const char*key;
+
+  json_root = json_loads (data, JSON_DECODE_ANY, json_err);
+  if ((NULL == json_root) ||
+      (! json_is_object (json_root)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to retrive expiration from credential\n");
+    return GNUNET_SYSERR;
+  }
+
+  if (1 != sscanf (exp_str, "%llu", &exp_i))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Invalid expiration `%s'\n", exp_str);
+    GNUNET_free (exp_str);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Converted expiration string `%s' to %llu",
+              exp_str, exp_i);
+
+  GNUNET_free (exp_str);
+  exp->abs_value_us = exp_i * 1000 * 1000;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Parse a pabc and return the expiration
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
+enum GNUNET_GenericReturnValue
+pabc_get_expiration_c (void *cls,
+                       const struct GNUNET_RECLAIM_Credential *cred,
+                       struct GNUNET_TIME_Absolute *exp)
+{
+  if (cred->type != GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC)
+    return GNUNET_NO;
+  return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
+}
+
+
+/**
+ * Parse a pabc and return the expiration
+ *
+ * @param cls the plugin
+ * @param cred the pabc credential
+ * @return a string, containing the isser
+ */
+enum GNUNET_GenericReturnValue
+pabc_get_expiration_p (void *cls,
+                       const struct GNUNET_RECLAIM_Presentation *cred,
+                       struct GNUNET_TIME_Absolute *exp)
+{
+  if (cred->type != GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC)
+    return GNUNET_NO;
+  return pabc_get_expiration (cls, cred->data, cred->data_size, exp);
+}
+
+
+int
+pabc_create_presentation (void *cls,
+                          const struct GNUNET_RECLAIM_Credential *credential,
+                          const struct GNUNET_RECLAIM_AttributeList *attrs,
+                          struct GNUNET_RECLAIM_Presentation **pres)
+{
+  struct pabc_context *ctx = NULL;
+  struct pabc_user_context *usr_ctx = NULL;
+  struct pabc_public_parameters *pp = NULL;
+  struct pabc_credential *cred = NULL;
+  struct pabc_blinded_proof *proof = NULL;
+  struct GNUNET_RECLAIM_AttributeListEntry *ale;
+  char *issuer;
+  char *subject;
+  enum pabc_status status;
+
+  if (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC != credential->type)
+    return GNUNET_NO;
+
+
+  PABC_ASSERT (pabc_new_ctx (&ctx));
+  issuer = pabc_get_issuer_c (cls, credential);
+  if (NULL == issuer)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "No issuer found in credential\n");
+    pabc_free_ctx (&ctx);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Got issuer for credential: %s\n", issuer);
+  status = PABC_load_public_parameters (ctx, issuer, &pp);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to read public parameters.\n");
+    pabc_free_ctx (&ctx);
+    GNUNET_free (issuer);
+    return GNUNET_SYSERR;
+  }
+  if (PABC_OK != pabc_cred_get_attr_by_name_from_cred (credential->data,
+                                                       "subject",
+                                                       &subject))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to get subject.\n");
+    pabc_free_ctx (&ctx);
+    GNUNET_free (issuer);
+    return GNUNET_SYSERR;
+  }
+  status = PABC_read_usr_ctx (subject, issuer, ctx, pp, &usr_ctx);
+  GNUNET_free (issuer);
+  GNUNET_free (subject);
+  if (PABC_OK != status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to read user context.\n");
+    pabc_free_public_parameters (ctx, &pp);
+    return GNUNET_SYSERR;
+  }
+
+  status = pabc_new_credential (ctx, pp, &cred);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to allocate credential.\n");
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    return GNUNET_SYSERR;
+  }
+
+  status = pabc_decode_credential (ctx, pp, cred, credential->data);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to decode credential.\n");
+    pabc_free_credential (ctx, pp, &cred);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    return GNUNET_SYSERR;
+  }
+
+  status = pabc_new_proof (ctx, pp, &proof);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to allocate proof.\n");
+    pabc_free_credential (ctx, pp, &cred);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    return GNUNET_SYSERR;
+  }
+
+  // now we can parse the attributes to disclose and configure the proof
+  for (ale = attrs->list_head; NULL != ale; ale = ale->next)
+  {
+    status = pabc_set_disclosure_by_attribute_name (ctx, pp, proof,
+                                                    ale->attribute->name,
+                                                    PABC_DISCLOSED, cred);
+    if (status != PABC_OK)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Failed to configure proof.\n");
+      pabc_free_credential (ctx, pp, &cred);
+      pabc_free_user_context (ctx, pp, &usr_ctx);
+      pabc_free_public_parameters (ctx, &pp);
+      return GNUNET_SYSERR;
+    }
+  }
+
+  // and finally -> sign the proof
+  status = pabc_gen_proof (ctx, usr_ctx, pp, proof, cred);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to sign proof.\n");
+    pabc_free_proof (ctx, pp, &proof);
+    pabc_free_credential (ctx, pp, &cred);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    return GNUNET_SYSERR;
+  }
+  // print the result
+  char *json = NULL;
+  char *ppid = NULL;
+  char *userid = NULL;
+  GNUNET_assert (PABC_OK == pabc_cred_get_userid_from_cred (credential->data,
+                                                            &userid));
+  GNUNET_assert (PABC_OK == pabc_cred_get_ppid_from_cred (credential->data,
+                                                          &ppid));
+  pabc_cred_encode_proof (ctx, pp, proof, userid, ppid,  &json);
+  GNUNET_free (ppid);
+  GNUNET_free (userid);
+  if (PABC_OK != status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to serialize proof.\n");
+    pabc_free_proof (ctx, pp, &proof);
+    pabc_free_credential (ctx, pp, &cred);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    return GNUNET_SYSERR;
+  }
+  char *json_enc;
+  GNUNET_STRINGS_base64_encode (json,
+                                strlen (json) + 1,
+                                &json_enc);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Presentation: %s\n", json_enc);
+  // clean up
+  *pres = GNUNET_RECLAIM_presentation_new (GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC,
+                                           json_enc,
+                                           strlen (json_enc) + 1);
+  GNUNET_free (json_enc);
+  PABC_FREE_NULL (json);
+  pabc_free_proof (ctx, pp, &proof);
+  pabc_free_credential (ctx, pp, &cred);
+  pabc_free_user_context (ctx, pp, &usr_ctx);
+  pabc_free_public_parameters (ctx, &pp);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Entry point for the plugin.
+ *
+ * @param cls NULL
+ * @return the exported block API
+ */
+void *
+libgnunet_plugin_reclaim_credential_pabc_init (void *cls)
+{
+  struct GNUNET_RECLAIM_CredentialPluginFunctions *api;
+
+  api = GNUNET_new (struct GNUNET_RECLAIM_CredentialPluginFunctions);
+  api->value_to_string = &pabc_value_to_string;
+  api->string_to_value = &pabc_string_to_value;
+  api->typename_to_number = &pabc_typename_to_number;
+  api->number_to_typename = &pabc_number_to_typename;
+  api->get_attributes = &pabc_parse_attributes_c;
+  api->get_issuer = &pabc_get_issuer_c;
+  api->get_expiration = &pabc_get_expiration_c;
+  api->value_to_string_p = &pabc_value_to_string;
+  api->string_to_value_p = &pabc_string_to_value;
+  api->typename_to_number_p = &pabc_typename_to_number;
+  api->number_to_typename_p = &pabc_number_to_typename;
+  api->get_attributes_p = &pabc_parse_attributes_p;
+  api->get_issuer_p = &pabc_get_issuer_p;
+  api->get_expiration_p = &pabc_get_expiration_p;
+  api->create_presentation = &pabc_create_presentation;
+  return api;
+}
+
+
+/**
+ * Exit point from the plugin.
+ *
+ * @param cls the return value from #libgnunet_plugin_block_test_init()
+ * @return NULL
+ */
+void *
+libgnunet_plugin_reclaim_credential_pabc_done (void *cls)
+{
+  struct GNUNET_RECLAIM_CredentialPluginFunctions *api = cls;
+
+  GNUNET_free (api);
+  return NULL;
+}
+
+
+/* end of plugin_reclaim_credential_type_pabc.c */
diff --git a/src/reclaim/plugin_rest_pabc.c b/src/reclaim/plugin_rest_pabc.c
new file mode 100644
index 000000000..6603fb888
--- /dev/null
+++ b/src/reclaim/plugin_rest_pabc.c
@@ -0,0 +1,666 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2012-2015 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @author Martin Schanzenbach
+ * @file reclaim/plugin_rest_pabc.c
+ * @brief GNUnet pabc REST plugin
+ *
+ */
+#include "platform.h"
+#include "microhttpd.h"
+#include <inttypes.h>
+#include <jansson.h>
+#include <pabc/pabc.h>
+#include "gnunet_reclaim_lib.h"
+#include "gnunet_reclaim_service.h"
+#include "gnunet_rest_lib.h"
+#include "gnunet_rest_plugin.h"
+#include "gnunet_signatures.h"
+#include "pabc_helper.h"
+
+/**
+ * REST root namespace
+ */
+#define GNUNET_REST_API_NS_PABC "/pabc"
+
+/**
+ * Credential request endpoint
+ */
+#define GNUNET_REST_API_NS_PABC_CR "/pabc/cr"
+
+/**
+ * The configuration handle
+ */
+const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * HTTP methods allows for this plugin
+ */
+static char *allow_methods;
+
+/**
+ * @brief struct returned by the initialization function of the plugin
+ */
+struct Plugin
+{
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+};
+
+
+struct RequestHandle
+{
+  /**
+   * DLL
+   */
+  struct RequestHandle *next;
+
+  /**
+   * DLL
+   */
+  struct RequestHandle *prev;
+
+  /**
+   * Rest connection
+   */
+  struct GNUNET_REST_RequestHandle *rest_handle;
+
+  /**
+   * Desired timeout for the lookup (default is no timeout).
+   */
+  struct GNUNET_TIME_Relative timeout;
+
+  /**
+   * ID of a task associated with the resolution process.
+   */
+  struct GNUNET_SCHEDULER_Task *timeout_task;
+
+  /**
+   * The plugin result processor
+   */
+  GNUNET_REST_ResultProcessor proc;
+
+  /**
+   * The closure of the result processor
+   */
+  void *proc_cls;
+
+  /**
+   * The url
+   */
+  char *url;
+
+  /**
+   * Error response message
+   */
+  char *emsg;
+
+  /**
+   * Reponse code
+   */
+  int response_code;
+
+  /**
+   * Response object
+   */
+  json_t *resp_object;
+};
+
+/**
+ * DLL
+ */
+static struct RequestHandle *requests_head;
+
+/**
+ * DLL
+ */
+static struct RequestHandle *requests_tail;
+
+
+/**
+ * Cleanup lookup handle
+ * @param handle Handle to clean up
+ */
+static void
+cleanup_handle (void *cls)
+{
+  struct RequestHandle *handle = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
+  if (NULL != handle->resp_object)
+    json_decref (handle->resp_object);
+  if (NULL != handle->timeout_task)
+    GNUNET_SCHEDULER_cancel (handle->timeout_task);
+  if (NULL != handle->url)
+    GNUNET_free (handle->url);
+  if (NULL != handle->emsg)
+    GNUNET_free (handle->emsg);
+  GNUNET_CONTAINER_DLL_remove (requests_head,
+                               requests_tail,
+                               handle);
+  GNUNET_free (handle);
+}
+
+
+/**
+ * Task run on error, sends error message.  Cleans up everything.
+ *
+ * @param cls the `struct RequestHandle`
+ */
+static void
+do_error (void *cls)
+{
+  struct RequestHandle *handle = cls;
+  struct MHD_Response *resp;
+  char *json_error;
+
+  GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }", handle->emsg);
+  if (0 == handle->response_code)
+  {
+    handle->response_code = MHD_HTTP_BAD_REQUEST;
+  }
+  resp = GNUNET_REST_create_response (json_error);
+  MHD_add_response_header (resp, "Content-Type", "application/json");
+  handle->proc (handle->proc_cls, resp, handle->response_code);
+  cleanup_handle (handle);
+  GNUNET_free (json_error);
+}
+
+
+/**
+ * Task run on timeout, sends error message.  Cleans up everything.
+ *
+ * @param cls the `struct RequestHandle`
+ */
+static void
+do_timeout (void *cls)
+{
+  struct RequestHandle *handle = cls;
+
+  handle->timeout_task = NULL;
+  do_error (handle);
+}
+
+
+static void
+return_response (void *cls)
+{
+  char *result_str;
+  struct RequestHandle *handle = cls;
+  struct MHD_Response *resp;
+
+  result_str = json_dumps (handle->resp_object, 0);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
+  resp = GNUNET_REST_create_response (result_str);
+  MHD_add_response_header (resp, "Access-Control-Allow-Methods", 
allow_methods);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_free (result_str);
+  cleanup_handle (handle);
+}
+
+
+static enum pabc_status
+set_attributes_from_idtoken (const struct pabc_context *ctx,
+                             const struct pabc_public_parameters *pp,
+                             struct pabc_user_context *usr_ctx,
+                             const char *id_token)
+{
+  json_t *payload_json;
+  json_t *value;
+  json_error_t json_err;
+  const char *key;
+  const char *jwt_body;
+  char *decoded_jwt;
+  char delim[] = ".";
+  char *jwt_string;
+  const char *pabc_key;
+  enum pabc_status status;
+
+  // FIXME parse JWT
+  jwt_string = GNUNET_strndup (id_token, strlen (id_token));
+  jwt_body = strtok (jwt_string, delim);
+  jwt_body = strtok (NULL, delim);
+  GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
+                                   (void **) &decoded_jwt);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded ID Token: %s\n", decoded_jwt);
+  payload_json = json_loads (decoded_jwt, JSON_DECODE_ANY, &json_err);
+  GNUNET_free (decoded_jwt);
+
+  json_object_foreach (payload_json, key, value)
+  {
+    pabc_key = key;
+    if (0 == strcmp ("iss", key))
+      pabc_key = "issuer"; // rename
+    if (0 == strcmp ("sub", key))
+      pabc_key = "subject"; // rename
+    if (0 == strcmp ("jti", key))
+      continue;
+    if (0 == strcmp ("exp", key))
+      pabc_key = "expiration"; // rename
+    if (0 == strcmp ("iat", key))
+      continue;
+    if (0 == strcmp ("nbf", key))
+      continue;
+    if (0 == strcmp ("aud", key))
+      continue;
+    char *tmp_val;
+    if (json_is_string (value))
+      tmp_val = GNUNET_strdup (json_string_value (value));
+    else
+      tmp_val = json_dumps (value, JSON_ENCODE_ANY);
+    if (NULL == tmp_val)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unable to encode JSON value for `%s'\n", key);
+      continue;
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Setting `%s' to `%s'\n", key, tmp_val);
+    status = pabc_set_attribute_value_by_name (ctx, pp, usr_ctx,
+                                               pabc_key,
+                                               tmp_val);
+    GNUNET_free (tmp_val);
+    if (PABC_OK != status)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Failed to set attribute `%s'.\n", key);
+    }
+  }
+  return PABC_OK;
+}
+
+
+static enum GNUNET_GenericReturnValue
+setup_new_user_context (struct pabc_context *ctx,
+                        struct pabc_public_parameters *pp,
+                        struct pabc_user_context **usr_ctx)
+{
+  if (PABC_OK != pabc_new_user_context (ctx, pp, usr_ctx))
+    return GNUNET_SYSERR;
+
+  if (PABC_OK != pabc_populate_user_context (ctx, *usr_ctx))
+  {
+    pabc_free_user_context (ctx, pp, usr_ctx);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+static void
+cr_cont (struct GNUNET_REST_RequestHandle *con_handle,
+         const char *url,
+         void *cls)
+{
+  struct RequestHandle *handle = cls;
+  char term_data[handle->rest_handle->data_size + 1];
+  char *response_str;
+  json_t *data_json;
+  json_t *nonce_json;
+  json_t *pp_json;
+  json_t *idtoken_json;
+  json_t *iss_json;
+  json_t *identity_json;
+  json_error_t err;
+  struct pabc_public_parameters *pp = NULL;
+  struct pabc_context *ctx = NULL;
+  struct pabc_user_context *usr_ctx = NULL;
+  struct pabc_credential_request *cr = NULL;
+  struct pabc_nonce *nonce = NULL;
+  enum pabc_status status;
+
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Credential request...\n");
+
+  if (0 >= handle->rest_handle->data_size)
+  {
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  term_data[handle->rest_handle->data_size] = '\0';
+  GNUNET_memcpy (term_data,
+                 handle->rest_handle->data,
+                 handle->rest_handle->data_size);
+  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+  if (NULL == data_json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse %s\n", term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  if (! json_is_object (data_json))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse %s\n", term_data);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  nonce_json = json_object_get (data_json, "nonce");
+  if (NULL == nonce_json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse nonce\n");
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  iss_json = json_object_get (data_json, "issuer");
+  if (NULL == iss_json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse issuer\n");
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity_json = json_object_get (data_json, "identity");
+  if (NULL == identity_json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse identity\n");
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  idtoken_json = json_object_get (data_json, "id_token");
+  if (NULL == idtoken_json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse id_token\n");
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  pp_json = json_object_get (data_json, "public_params");
+  if (NULL == pp_json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse public parameters\n");
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  PABC_ASSERT (pabc_new_ctx (&ctx));
+  char *pp_str = json_dumps (pp_json, JSON_ENCODE_ANY);
+  status = pabc_decode_and_new_public_parameters (ctx,
+                                                  &pp,
+                                                  pp_str);
+  char *ppid;
+  GNUNET_assert (PABC_OK == pabc_cred_get_ppid_from_pp (pp_str, &ppid));
+  GNUNET_free (pp_str);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to read public parameters: %s\n",
+                pp_str);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  // (Over)write parameters
+  status = PABC_write_public_parameters (json_string_value (iss_json),
+                                         pp);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to write public parameters.\n");
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  status = PABC_read_usr_ctx (json_string_value (identity_json),
+                              json_string_value (iss_json),
+                              ctx, pp, &usr_ctx);
+  if (PABC_OK != status)
+  {
+    if (GNUNET_OK != setup_new_user_context (ctx, pp, &usr_ctx))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup user context.\n");
+      pabc_free_public_parameters (ctx, &pp);
+      json_decref (data_json);
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
+    PABC_write_usr_ctx (json_string_value (identity_json),
+                        json_string_value (iss_json),
+                        ctx, pp, usr_ctx);
+  }
+
+  // Set attributes from JWT to context
+  status = set_attributes_from_idtoken (ctx,
+                                        pp,
+                                        usr_ctx,
+                                        json_string_value (idtoken_json));
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to set attributes.\n");
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+
+  // nonce
+  status = pabc_new_nonce (ctx, &nonce);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to allocate nonce.\n");
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  char *nonce_str = json_dumps (nonce_json, JSON_ENCODE_ANY);
+  status = pabc_decode_nonce (ctx, nonce, nonce_str);
+  if (status != PABC_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to decode nonce.\n");
+    pabc_free_nonce (ctx, &nonce);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  // cr
+  status = pabc_new_credential_request (ctx, pp, &cr);
+  if (PABC_OK != status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to allocate cr.\n");
+    pabc_free_nonce (ctx, &nonce);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  status = pabc_gen_credential_request (ctx, pp, usr_ctx, nonce, cr);
+  if (PABC_OK != status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to generate cr.\n");
+    pabc_free_nonce (ctx, &nonce);
+    pabc_free_credential_request (ctx, pp, &cr);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  handle->resp_object = json_object ();
+  GNUNET_assert (PABC_OK == pabc_cred_encode_cr (ctx, pp, cr,
+                                                 json_string_value (
+                                                   identity_json),
+                                                 ppid, &response_str));
+  if (PABC_OK != status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to serialize cr.\n");
+    pabc_free_nonce (ctx, &nonce);
+    pabc_free_credential_request (ctx, pp, &cr);
+    pabc_free_user_context (ctx, pp, &usr_ctx);
+    pabc_free_public_parameters (ctx, &pp);
+    json_decref (data_json);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  json_decref (handle->resp_object);
+  handle->resp_object = json_loads (response_str, JSON_DECODE_ANY, &err);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", response_str);
+  GNUNET_free (response_str);
+
+  // clean up
+  pabc_free_nonce (ctx, &nonce);
+  pabc_free_credential_request (ctx, pp, &cr);
+  pabc_free_user_context (ctx, pp, &usr_ctx);
+  pabc_free_public_parameters (ctx, &pp);
+  GNUNET_SCHEDULER_add_now (&return_response, handle);
+  json_decref (data_json);
+}
+
+
+/**
+ * Respond to OPTIONS request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+options_cont (struct GNUNET_REST_RequestHandle *con_handle,
+              const char *url,
+              void *cls)
+{
+  struct MHD_Response *resp;
+  struct RequestHandle *handle = cls;
+
+  // For now, independent of path return all options
+  resp = GNUNET_REST_create_response (NULL);
+  MHD_add_response_header (resp, "Access-Control-Allow-Methods", 
allow_methods);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  cleanup_handle (handle);
+  return;
+}
+
+
+static enum GNUNET_GenericReturnValue
+rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
+                               GNUNET_REST_ResultProcessor proc,
+                               void *proc_cls)
+{
+  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  struct GNUNET_REST_RequestHandlerError err;
+  static const struct GNUNET_REST_RequestHandler handlers[] = {
+    {MHD_HTTP_METHOD_POST,
+     GNUNET_REST_API_NS_PABC_CR, &cr_cont },
+    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PABC, &options_cont },
+    GNUNET_REST_HANDLER_END
+  };
+
+  handle->response_code = 0;
+  handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
+  handle->proc_cls = proc_cls;
+  handle->proc = proc;
+  handle->rest_handle = rest_handle;
+
+  handle->url = GNUNET_strdup (rest_handle->url);
+  if (handle->url[strlen (handle->url) - 1] == '/')
+    handle->url[strlen (handle->url) - 1] = '\0';
+  handle->timeout_task =
+    GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
+  GNUNET_CONTAINER_DLL_insert (requests_head,
+                               requests_tail,
+                               handle);
+  if (GNUNET_NO ==
+      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
+  {
+    cleanup_handle (handle);
+    return GNUNET_NO;
+  }
+
+  return GNUNET_YES;
+}
+
+
+/**
+ * Entry point for the plugin.
+ *
+ * @param cls Config info
+ * @return NULL on error, otherwise the plugin context
+ */
+void *
+libgnunet_plugin_rest_pabc_init (void *cls)
+{
+  static struct Plugin plugin;
+  struct GNUNET_REST_Plugin *api;
+
+  cfg = cls;
+  if (NULL != plugin.cfg)
+    return NULL; /* can only initialize once! */
+  memset (&plugin, 0, sizeof(struct Plugin));
+  plugin.cfg = cfg;
+  api = GNUNET_new (struct GNUNET_REST_Plugin);
+  api->cls = &plugin;
+  api->name = GNUNET_REST_API_NS_PABC;
+  api->process_request = &rest_identity_process_request;
+  GNUNET_asprintf (&allow_methods,
+                   "%s, %s",
+                   MHD_HTTP_METHOD_POST,
+                   MHD_HTTP_METHOD_OPTIONS);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              _ ("Identity Provider REST API initialized\n"));
+  return api;
+}
+
+
+/**
+ * Exit point from the plugin.
+ *
+ * @param cls the plugin context (as returned by "init")
+ * @return always NULL
+ */
+void *
+libgnunet_plugin_rest_reclaim_done (void *cls)
+{
+  struct GNUNET_REST_Plugin *api = cls;
+  struct Plugin *plugin = api->cls;
+  struct RequestHandle *request;
+
+  plugin->cfg = NULL;
+  while (NULL != (request = requests_head))
+    do_error (request);
+
+  GNUNET_free (allow_methods);
+  GNUNET_free (api);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "PABC REST plugin is finished\n");
+  return NULL;
+}
+
+
+/* end of plugin_rest_reclaim.c */
diff --git a/src/reclaim/reclaim_credential.c b/src/reclaim/reclaim_credential.c
index c8c0d397c..da5cee988 100644
--- a/src/reclaim/reclaim_credential.c
+++ b/src/reclaim/reclaim_credential.c
@@ -1033,7 +1033,6 @@ GNUNET_RECLAIM_presentation_get_expiration (const struct
 /**
  * Create a presentation from a credential and a lift of (selected)
  * attributes in the credential.
- * FIXME not yet implemented
  *
  * @param cred the credential to use
  * @param attrs the attributes to present from the credential

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]