Merge branch 'master' of ssh://git.gnunet.org/gnunet
authorxrs <xrs@mail36.net>
Thu, 16 Jan 2020 16:12:09 +0000 (17:12 +0100)
committerxrs <xrs@mail36.net>
Thu, 16 Jan 2020 16:12:09 +0000 (17:12 +0100)
56 files changed:
Makefile.am
configure.ac
contrib/scripts/build-install-gnunet-debian10.sh
po/de.po
po/es.po
po/fr.po
po/it.po
po/sv.po
po/vi.po
po/zh_CN.po
src/Makefile.am
src/curl/curl.c
src/gns/gns.h
src/gns/gns_api.c
src/gns/gnunet-service-gns.c
src/gns/gnunet-service-gns_interceptor.c
src/gns/gnunet-service-gns_resolver.c
src/gns/gnunet-service-gns_resolver.h
src/include/Makefile.am
src/include/gnunet_buffer_lib.h [new file with mode: 0644]
src/include/gnunet_curl_lib.h
src/include/gnunet_gns_service.h
src/include/gnunet_gnsrecord_lib.h
src/include/gnunet_protocols.h
src/include/gnunet_reclaim_attribute_lib.h
src/include/gnunet_reclaim_attribute_plugin.h
src/include/gnunet_reclaim_service.h
src/include/gnunet_util_taler_wallet_lib.h [deleted file]
src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
src/reclaim-attribute/reclaim_attribute.c
src/reclaim-attribute/reclaim_attribute.h
src/reclaim/gnunet-reclaim.c
src/reclaim/gnunet-service-reclaim.c
src/reclaim/gnunet-service-reclaim_tickets.c
src/reclaim/json_reclaim.c
src/reclaim/json_reclaim.h
src/reclaim/oidc_helper.c
src/reclaim/oidc_helper.h
src/reclaim/plugin_gnsrecord_reclaim.c
src/reclaim/plugin_rest_openid_connect.c
src/reclaim/plugin_rest_reclaim.c
src/reclaim/reclaim.h
src/reclaim/reclaim_api.c
src/transport/Makefile.am
src/transport/test_communicator_unix_basic_peer1.conf [new file with mode: 0644]
src/transport/test_communicator_unix_peer1.conf [deleted file]
src/util/.gitignore
src/util/Makefile.am
src/util/buffer.c [new file with mode: 0644]
src/util/common_logging.c
src/util/crypto_ecc.c
src/util/gnunet-crypto-tvg.c [new file with mode: 0644]
src/util/test_crypto_ecdh_ecdsa.c [new file with mode: 0644]
src/util/tweetnacl-gnunet.c
src/util/tweetnacl-gnunet.h
src/vpn/gnunet-service-vpn.c

index 62c46cb2bb5ce26ca415736117849138e26c4fa2..f072d0cae57d809ae9f4369d0e1e846765b42c3b 100644 (file)
@@ -18,9 +18,7 @@ if INCLUDE_MANPAGES
   SUBDIRS += doc
 endif
 
-if !TALER_ONLY
-  SUBDIRS += contrib
-endif
+SUBDIRS += contrib
 
 EXTRA_DIST = \
  ABOUT-NLS \
index 3f1450ba2d4985bdbb51747ba0b3917cd26bc5f8..23ca78dbb021f897668f793ab7a7d5b664c4a18d 100644 (file)
@@ -21,7 +21,7 @@
 #
 AC_PREREQ(2.61)
 # Checks for programs.
-AC_INIT([gnunet], [0.12.1], [bug-gnunet@gnu.org])
+AC_INIT([gnunet], [0.12.2], [bug-gnunet@gnu.org])
 AC_CONFIG_AUX_DIR([build-aux])
 
 # check for legacy option that is no longer supported (#5627) and fail hard
@@ -212,7 +212,7 @@ AC_SEARCH_LIBS([memrchr], [],
                AC_DEFINE(HAVE_MEMRCHR,1,[memrchr supported]), [])
 AC_SEARCH_LIBS([memset_s], [],
                AC_DEFINE(HAVE_MEMSET_S,1,[memset_s supported]), [])
-AC_SEARCH_LIBS([memset_s], [],
+AC_SEARCH_LIBS([explicit_bzero], [],
                AC_DEFINE(HAVE_EXPLICIT_BZERO,1,[explicit_bzero supported]), [])
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(m, log)
@@ -1026,23 +1026,6 @@ AC_CHECK_LIB([kvm],[kvm_open])
 AC_CHECK_LIB([kstat],[kstat_open])
 
 
-# should the build process be restricted to the code required
-# for GNU Taler wallets?
-AC_MSG_CHECKING(whether to compile GNU Taler Wallet library ONLY)
-AC_ARG_ENABLE([taler-wallet],
-   [AS_HELP_STRING([--enable-taler-wallet], [only compile for Taler wallet])],
-   [taler_only=${enableval}],
-   [taler_only=no])
-AC_MSG_RESULT($taler_only)
-AS_IF([test "x$taler_only" = "xyes"],
-[
-  AM_CONDITIONAL([TALER_ONLY],true)
-  AC_DEFINE([TALER_WALLET_ONLY],[1],[Compiling for Taler wallet])
-],[
-  AM_CONDITIONAL([TALER_ONLY],false)
-  AC_DEFINE([TALER_WALLET_ONLY],[0],[Canonical compilation])
-])
-
 # test for libextractor
 extractor=0
 AC_MSG_CHECKING(for libextractor)
@@ -1081,9 +1064,6 @@ AS_IF([test "$extractor" != 1],
  ])
 
 
-AS_IF([test "$taler_only" != yes],[
-
-
 # Check for libltdl header (#2999)
 ltdl=0
 AC_MSG_CHECKING(for libltdl)
@@ -1250,10 +1230,6 @@ AS_IF([test "$enable_shared" = "no"],
 LIBS=$SAVE_LIBS
 
 
-# end of taler-only being false
-])
-
-
 # check for iconv
 AM_ICONV
 
@@ -1262,12 +1238,8 @@ gl_LIBUNISTRING
 AS_IF([test $HAVE_LIBUNISTRING != yes],
       [AC_MSG_ERROR([GNUnet requires libunistring])])
 
-# under emscripten, $gl_libunistring_hexversion is undefined
-if test "$taler_only" != yes; then
-
 AS_IF([test "x$gl_libunistring_hexversion" = "x" || test "$gl_libunistring_hexversion" -le 2305],
       [AC_MSG_ERROR([GNUnet requires libunistring >= 0.9.1.1])])
-fi
 AC_CHECK_HEADERS([unistr.h],
                  ,
                  AC_MSG_ERROR([Compiling GNUnet requires unistr.h (from libunistring) to be installed]))
@@ -1340,14 +1312,12 @@ CPPFLAGS=$SAVE_CPPFLAGS
 
 # test for postgres:
 postgres=false
-# even running the check for postgres breaks emscripten
-AS_IF([test "$taler_only" != yes],
-      [AX_LIB_POSTGRESQL([9.5],
-        [CPPFLAGS="$CPPFLAGS $POSTGRESQL_CPPFLAGS"
-         AC_CHECK_HEADERS([libpq-fe.h],
-         postgres=true)
-        ],
-        [AC_MSG_RESULT([no postgres])])])
+AX_LIB_POSTGRESQL([9.5],
+  [CPPFLAGS="$CPPFLAGS $POSTGRESQL_CPPFLAGS"
+   AC_CHECK_HEADERS([libpq-fe.h],
+   postgres=true)
+  ],
+  [AC_MSG_RESULT([no postgres])])
 
 AM_CONDITIONAL(HAVE_POSTGRESQL, test x$postgres = xtrue)
 AS_IF([test "x$postgres" = xtrue],
index 863ed5e2ddb17cea236d0dd6dd2ac41bc266c331..8ac7ce8bb74a1f83dbda2223649370116db9daff 100755 (executable)
@@ -2,13 +2,15 @@
 set -exo
 set -u pipefail
 
-if test -z "$USER" = "root"; then
+if [ "$USER" = "root" ]; then
   export SUDO_CMD=""
 else
   SUDO_CMD="sudo"
 fi
 
-$SUDO_CMD apt update && $SUDO_CMD apt install -y git libtool autoconf \
+$SUDO_CMD apt update
+
+$SUDO_CMD apt install -y git libtool autoconf \
 autopoint libmicrohttpd-dev build-essential libgcrypt-dev \
 libidn11-dev zlib1g-dev libunistring-dev libglpk-dev miniupnpc \
 libextractor-dev libjansson-dev libcurl4-gnutls-dev gnutls-bin \
@@ -24,7 +26,7 @@ cd ~/gnunet_installation/gnunet
 
 ./bootstrap
 
-export GNUNET_PREFIX=/usr/local
+export GNUNET_PREFIX=/usr
 export CFLAGS="-g -Wall -O0"
 
 ./configure --prefix=$GNUNET_PREFIX --enable-logging=verbose --disable-documentation
index f8c9d25e0e654dcd585edb02632d4e9557657653..216f67f683b17d9e02e5593b221702c929aee8b4 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnunet 0.10.1\n"
 "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
-"POT-Creation-Date: 2019-12-25 13:08+0100\n"
+"POT-Creation-Date: 2020-01-13 14:01+0000\n"
 "PO-Revision-Date: 2015-03-08 16:16+0100\n"
 "Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n"
 "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
@@ -4204,29 +4204,29 @@ msgstr ""
 msgid "GNUnet GNS resolver tool"
 msgstr "GNUnet Netzwerk Topologie tracen."
 
-#: src/gns/gnunet-service-gns.c:504
+#: src/gns/gnunet-service-gns.c:505
 #, fuzzy
 msgid "Properly base32-encoded public key required"
 msgstr "# Bytes empfangen über TCP"
 
-#: src/gns/gnunet-service-gns.c:540
+#: src/gns/gnunet-service-gns.c:541
 #, fuzzy
 msgid "Failed to connect to the namecache!\n"
 msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
 
-#: src/gns/gnunet-service-gns.c:559
+#: src/gns/gnunet-service-gns.c:560
 #: src/zonemaster/gnunet-service-zonemaster-monitor.c:444
 #: src/zonemaster/gnunet-service-zonemaster.c:887
 #, fuzzy
 msgid "Could not connect to DHT!\n"
 msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:273
+#: src/gns/gnunet-service-gns_interceptor.c:279
 #, fuzzy
 msgid "Error converting GNS response to DNS response!\n"
 msgstr "Fehler beim Konvertieren von Parametern in URI!\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:380
+#: src/gns/gnunet-service-gns_interceptor.c:387
 #, fuzzy
 msgid "Failed to connect to the DNS service!\n"
 msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
@@ -4261,36 +4261,36 @@ msgstr ""
 msgid "VPN returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1895
+#: src/gns/gnunet-service-gns_resolver.c:1896
 #, c-format
 msgid "Name `%s' cannot be converted to IDNA."
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1908
+#: src/gns/gnunet-service-gns_resolver.c:1909
 #, c-format
 msgid "GNS lookup resulted in DNS name that is too long (`%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1951
+#: src/gns/gnunet-service-gns_resolver.c:1952
 #, fuzzy, c-format
 msgid "GNS lookup failed (zero records found for `%s')\n"
 msgstr "Dienst `%s' konnte nicht ordentlich entladen werden!\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2375
+#: src/gns/gnunet-service-gns_resolver.c:2376
 msgid "GNS lookup recursion failed (no delegation record found)\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2398
+#: src/gns/gnunet-service-gns_resolver.c:2399
 #, fuzzy, c-format
 msgid "Failed to cache GNS resolution: %s\n"
 msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2566
+#: src/gns/gnunet-service-gns_resolver.c:2567
 #, c-format
 msgid "GNS namecache returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2706
+#: src/gns/gnunet-service-gns_resolver.c:2707
 #, c-format
 msgid "Zone %s was revoked, resolution fails\n"
 msgstr ""
@@ -5866,79 +5866,79 @@ msgstr ""
 msgid "Daemon to run to perform IP protocol translation to GNUnet"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:613
+#: src/reclaim/gnunet-reclaim.c:617
 #, fuzzy, c-format
 msgid "Ego is required\n"
 msgstr "Option `%s' macht keinen Sinn ohne die Option `%s'.\n"
 
-#: src/reclaim/gnunet-reclaim.c:620
+#: src/reclaim/gnunet-reclaim.c:624
 #, c-format
 msgid "Attribute value missing!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:627
+#: src/reclaim/gnunet-reclaim.c:631
 #, fuzzy, c-format
 msgid "Requesting party key is required!\n"
 msgstr "Option `%s' macht keinen Sinn ohne die Option `%s'.\n"
 
-#: src/reclaim/gnunet-reclaim.c:645
+#: src/reclaim/gnunet-reclaim.c:649
 msgid "Add an attribute NAME"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:650
+#: src/reclaim/gnunet-reclaim.c:654
 msgid "Delete the attribute with ID"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:655
+#: src/reclaim/gnunet-reclaim.c:659
 msgid "The attribute VALUE"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:660
+#: src/reclaim/gnunet-reclaim.c:664
 msgid "The EGO to use"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:666
+#: src/reclaim/gnunet-reclaim.c:670
 msgid "Specify the relying party for issue"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:670
+#: src/reclaim/gnunet-reclaim.c:674
 msgid "List attributes for EGO"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:677
+#: src/reclaim/gnunet-reclaim.c:681
 msgid "Issue a ticket for a set of attributes separated by comma"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:682
+#: src/reclaim/gnunet-reclaim.c:686
 msgid "Consume a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:687
+#: src/reclaim/gnunet-reclaim.c:691
 msgid "Revoke a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:692
+#: src/reclaim/gnunet-reclaim.c:696
 msgid "Type of attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:696
+#: src/reclaim/gnunet-reclaim.c:700
 msgid "List tickets of ego"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:702
+#: src/reclaim/gnunet-reclaim.c:706
 msgid "Expiration interval of the attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:710
+#: src/reclaim/gnunet-reclaim.c:714
 msgid "re:claimID command line tool"
 msgstr ""
 
-#: src/reclaim/plugin_rest_openid_connect.c:2192
+#: src/reclaim/plugin_rest_openid_connect.c:2340
 #, fuzzy
 msgid "OpenID Connect REST API initialized\n"
 msgstr " Verbindung fehlgeschlagen\n"
 
-#: src/reclaim/plugin_rest_reclaim.c:1110
+#: src/reclaim/plugin_rest_reclaim.c:1899
 #, fuzzy
 msgid "Identity Provider REST API initialized\n"
 msgstr " Verbindung fehlgeschlagen\n"
@@ -6927,18 +6927,18 @@ msgstr "# HELLO-Meldungen empfangen"
 msgid "GNUnet topology control"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2196
-#: src/transport/gnunet-communicator-udp.c:2680
+#: src/transport/gnunet-communicator-tcp.c:2227
+#: src/transport/gnunet-communicator-udp.c:2712
 #: src/transport/gnunet-service-tng.c:10024
 #: src/transport/gnunet-service-transport.c:2627
 msgid "Transport service is lacking key configuration settings. Exiting.\n"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2254
+#: src/transport/gnunet-communicator-tcp.c:2285
 msgid "GNUnet TCP communicator"
 msgstr ""
 
-#: src/transport/gnunet-communicator-udp.c:2752
+#: src/transport/gnunet-communicator-udp.c:2784
 msgid "GNUnet UDP communicator"
 msgstr ""
 
@@ -8024,7 +8024,7 @@ msgid "do daemonize (detach from terminal)"
 msgstr ""
 
 #: src/transport/tcp_service_legacy.c:1397
-#: src/transport/transport-testing2.c:814 src/util/service.c:2073
+#: src/transport/transport-testing2.c:906 src/util/service.c:2073
 #: src/util/service.c:2085
 #, fuzzy, c-format
 msgid "Malformed configuration file `%s', exit ...\n"
@@ -8040,7 +8040,7 @@ msgstr "GNUnet Konfiguration"
 msgid "Could not access configuration file `%s'\n"
 msgstr "Konfigurationsdatei `%s' konnte nicht geparst werden.\n"
 
-#: src/transport/transport_api2_communication.c:705
+#: src/transport/transport_api2_communication.c:704
 msgid "Dropped backchanel message: handler not provided by communicator\n"
 msgstr ""
 
@@ -8188,12 +8188,12 @@ msgid ""
 "%llu)\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:719
+#: src/util/crypto_ecc.c:705
 #, fuzzy, c-format
 msgid "ECC signing failed at %s:%d: %s\n"
 msgstr "`%s' schlug fehl bei %s:%d mit dem Fehler: `%s'.\n"
 
-#: src/util/crypto_ecc.c:836
+#: src/util/crypto_ecc.c:822
 #, fuzzy, c-format
 msgid "ECDSA signature verification failed at %s:%d: %s\n"
 msgstr "RSA Signaturüberprüfung fehlgeschlagen bei %s:%d: %s\n"
@@ -8982,23 +8982,23 @@ msgstr ""
 msgid "Must specify valid IPv6 address"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3035
+#: src/vpn/gnunet-service-vpn.c:3036
 msgid "Must specify valid IPv6 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3044
+#: src/vpn/gnunet-service-vpn.c:3046
 msgid "IPv6 support disabled as this system does not support IPv6\n"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3060
+#: src/vpn/gnunet-service-vpn.c:3062
 msgid "Must specify valid IPv4 address"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3076
+#: src/vpn/gnunet-service-vpn.c:3079
 msgid "Must specify valid IPv4 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3087
+#: src/vpn/gnunet-service-vpn.c:3091
 msgid "IPv4 support disabled as this system does not support IPv4\n"
 msgstr ""
 
index a285d3fcee2cbaf04b2b060595e8b7bb6cb25e92..be0d5926ea5b675d4816dacd5a88c5b5de64b575 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnunet 0.9.5a\n"
 "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
-"POT-Creation-Date: 2019-12-25 13:08+0100\n"
+"POT-Creation-Date: 2020-01-13 14:01+0000\n"
 "PO-Revision-Date: 2013-02-23 17:50+0100\n"
 "Last-Translator: Miguel Ángel Arruga Vivas <rosen644835@gmail.com>\n"
 "Language-Team: Spanish <es@li.org>\n"
@@ -4331,28 +4331,28 @@ msgstr ""
 msgid "GNUnet GNS resolver tool"
 msgstr "Herramienta de acceso GNUnet GNS"
 
-#: src/gns/gnunet-service-gns.c:504
+#: src/gns/gnunet-service-gns.c:505
 #, fuzzy
 msgid "Properly base32-encoded public key required"
 msgstr "Tipo requerido\n"
 
-#: src/gns/gnunet-service-gns.c:540
+#: src/gns/gnunet-service-gns.c:541
 #, fuzzy
 msgid "Failed to connect to the namecache!\n"
 msgstr "¡Se produjo un fallo al conectar con el almacén de nombres!\n"
 
-#: src/gns/gnunet-service-gns.c:559
+#: src/gns/gnunet-service-gns.c:560
 #: src/zonemaster/gnunet-service-zonemaster-monitor.c:444
 #: src/zonemaster/gnunet-service-zonemaster.c:887
 msgid "Could not connect to DHT!\n"
 msgstr "¡No se pudo conectar a la DHT!\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:273
+#: src/gns/gnunet-service-gns_interceptor.c:279
 #, fuzzy
 msgid "Error converting GNS response to DNS response!\n"
 msgstr "¡Se produjo un error al convertir los argumentos a una URI!\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:380
+#: src/gns/gnunet-service-gns_interceptor.c:387
 #, fuzzy
 msgid "Failed to connect to the DNS service!\n"
 msgstr "¡Se produjo un fallo al conectar con el servicio GNS!\n"
@@ -4387,36 +4387,36 @@ msgstr ""
 msgid "VPN returned empty result for `%s'\n"
 msgstr "El ATS devolvió resultados para %u direcciones\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:1895
+#: src/gns/gnunet-service-gns_resolver.c:1896
 #, c-format
 msgid "Name `%s' cannot be converted to IDNA."
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1908
+#: src/gns/gnunet-service-gns_resolver.c:1909
 #, c-format
 msgid "GNS lookup resulted in DNS name that is too long (`%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1951
+#: src/gns/gnunet-service-gns_resolver.c:1952
 #, fuzzy, c-format
 msgid "GNS lookup failed (zero records found for `%s')\n"
 msgstr "No se han encontrado ficheros en «%s»\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2375
+#: src/gns/gnunet-service-gns_resolver.c:2376
 msgid "GNS lookup recursion failed (no delegation record found)\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2398
+#: src/gns/gnunet-service-gns_resolver.c:2399
 #, fuzzy, c-format
 msgid "Failed to cache GNS resolution: %s\n"
 msgstr "Se produjo un fallo al mandar la petición DNS a %s\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2566
+#: src/gns/gnunet-service-gns_resolver.c:2567
 #, c-format
 msgid "GNS namecache returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2706
+#: src/gns/gnunet-service-gns_resolver.c:2707
 #, c-format
 msgid "Zone %s was revoked, resolution fails\n"
 msgstr ""
@@ -6050,80 +6050,80 @@ msgid "Daemon to run to perform IP protocol translation to GNUnet"
 msgstr ""
 "Demonio a ejecutar para realizar la traducción de protocolo IP a GNUnet"
 
-#: src/reclaim/gnunet-reclaim.c:613
+#: src/reclaim/gnunet-reclaim.c:617
 #, fuzzy, c-format
 msgid "Ego is required\n"
 msgstr "Las opción «%s» o «%s» es necesaria.\n"
 
-#: src/reclaim/gnunet-reclaim.c:620
+#: src/reclaim/gnunet-reclaim.c:624
 #, c-format
 msgid "Attribute value missing!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:627
+#: src/reclaim/gnunet-reclaim.c:631
 #, fuzzy, c-format
 msgid "Requesting party key is required!\n"
 msgstr "el parámetro --section es necesario\n"
 
-#: src/reclaim/gnunet-reclaim.c:645
+#: src/reclaim/gnunet-reclaim.c:649
 msgid "Add an attribute NAME"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:650
+#: src/reclaim/gnunet-reclaim.c:654
 msgid "Delete the attribute with ID"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:655
+#: src/reclaim/gnunet-reclaim.c:659
 msgid "The attribute VALUE"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:660
+#: src/reclaim/gnunet-reclaim.c:664
 #, fuzzy
 msgid "The EGO to use"
 msgstr "tamaño del mensaje"
 
-#: src/reclaim/gnunet-reclaim.c:666
+#: src/reclaim/gnunet-reclaim.c:670
 msgid "Specify the relying party for issue"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:670
+#: src/reclaim/gnunet-reclaim.c:674
 msgid "List attributes for EGO"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:677
+#: src/reclaim/gnunet-reclaim.c:681
 msgid "Issue a ticket for a set of attributes separated by comma"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:682
+#: src/reclaim/gnunet-reclaim.c:686
 msgid "Consume a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:687
+#: src/reclaim/gnunet-reclaim.c:691
 msgid "Revoke a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:692
+#: src/reclaim/gnunet-reclaim.c:696
 msgid "Type of attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:696
+#: src/reclaim/gnunet-reclaim.c:700
 msgid "List tickets of ego"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:702
+#: src/reclaim/gnunet-reclaim.c:706
 msgid "Expiration interval of the attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:710
+#: src/reclaim/gnunet-reclaim.c:714
 msgid "re:claimID command line tool"
 msgstr ""
 
-#: src/reclaim/plugin_rest_openid_connect.c:2192
+#: src/reclaim/plugin_rest_openid_connect.c:2340
 #, fuzzy
 msgid "OpenID Connect REST API initialized\n"
 msgstr "Conexión fallida\n"
 
-#: src/reclaim/plugin_rest_reclaim.c:1110
+#: src/reclaim/plugin_rest_reclaim.c:1899
 #, fuzzy
 msgid "Identity Provider REST API initialized\n"
 msgstr "Conexión fallida\n"
@@ -7164,8 +7164,8 @@ msgstr "# mensajes «HELLO» recibidos"
 msgid "GNUnet topology control"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2196
-#: src/transport/gnunet-communicator-udp.c:2680
+#: src/transport/gnunet-communicator-tcp.c:2227
+#: src/transport/gnunet-communicator-udp.c:2712
 #: src/transport/gnunet-service-tng.c:10024
 #: src/transport/gnunet-service-transport.c:2627
 #, fuzzy
@@ -7174,12 +7174,12 @@ msgstr ""
 "El servicio de transporte carece de opciones de configuración de clave.  "
 "Saliendo.\n"
 
-#: src/transport/gnunet-communicator-tcp.c:2254
+#: src/transport/gnunet-communicator-tcp.c:2285
 #, fuzzy
 msgid "GNUnet TCP communicator"
 msgstr "Configurador Gtk de GNUnet"
 
-#: src/transport/gnunet-communicator-udp.c:2752
+#: src/transport/gnunet-communicator-udp.c:2784
 #, fuzzy
 msgid "GNUnet UDP communicator"
 msgstr "Configurador Gtk de GNUnet"
@@ -8329,7 +8329,7 @@ msgid "do daemonize (detach from terminal)"
 msgstr "demonizar (desasociar del terminal)"
 
 #: src/transport/tcp_service_legacy.c:1397
-#: src/transport/transport-testing2.c:814 src/util/service.c:2073
+#: src/transport/transport-testing2.c:906 src/util/service.c:2073
 #: src/util/service.c:2085
 #, fuzzy, c-format
 msgid "Malformed configuration file `%s', exit ...\n"
@@ -8345,7 +8345,7 @@ msgstr "Se produjo un fallo al borrar el fichero de configuración %s\n"
 msgid "Could not access configuration file `%s'\n"
 msgstr "No se pudo acceder al fichero de configuración «%s»\n"
 
-#: src/transport/transport_api2_communication.c:705
+#: src/transport/transport_api2_communication.c:704
 msgid "Dropped backchanel message: handler not provided by communicator\n"
 msgstr ""
 
@@ -8496,12 +8496,12 @@ msgstr ""
 "El tamaño del fichero en disco es incorrecto para este «Bloom "
 "filter» (esperado %llu, tiene %llu)\n"
 
-#: src/util/crypto_ecc.c:719
+#: src/util/crypto_ecc.c:705
 #, c-format
 msgid "ECC signing failed at %s:%d: %s\n"
 msgstr "El firmado ECC falló en %s:%d: %s\n"
 
-#: src/util/crypto_ecc.c:836
+#: src/util/crypto_ecc.c:822
 #, fuzzy, c-format
 msgid "ECDSA signature verification failed at %s:%d: %s\n"
 msgstr "La verificación de la firma RSA fallo en %s:%d: %s\n"
@@ -9315,25 +9315,25 @@ msgstr ""
 msgid "Must specify valid IPv6 address"
 msgstr "«%s» no es una dirección IP válida.\n"
 
-#: src/vpn/gnunet-service-vpn.c:3035
+#: src/vpn/gnunet-service-vpn.c:3036
 msgid "Must specify valid IPv6 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3044
+#: src/vpn/gnunet-service-vpn.c:3046
 msgid "IPv6 support disabled as this system does not support IPv6\n"
 msgstr ""
 "El soporte de IPv6 se deshabilita porque este sistema no soporta IPv6\n"
 
-#: src/vpn/gnunet-service-vpn.c:3060
+#: src/vpn/gnunet-service-vpn.c:3062
 #, fuzzy
 msgid "Must specify valid IPv4 address"
 msgstr "«%s» no es una dirección IP válida.\n"
 
-#: src/vpn/gnunet-service-vpn.c:3076
+#: src/vpn/gnunet-service-vpn.c:3079
 msgid "Must specify valid IPv4 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3087
+#: src/vpn/gnunet-service-vpn.c:3091
 msgid "IPv4 support disabled as this system does not support IPv4\n"
 msgstr ""
 "El soporte de IPv4 se deshabilita porque este sistema no soporta IPv4\n"
index 31e4406d5c65737121f19b9e0f29d1e216fb0808..d6a932d36195f195d3c1e8452bdaa73c008253a8 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnunet 0.10.1\n"
 "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
-"POT-Creation-Date: 2019-12-25 13:08+0100\n"
+"POT-Creation-Date: 2020-01-13 14:01+0000\n"
 "PO-Revision-Date: 2015-12-24 01:20+0100\n"
 "Last-Translator: Stéphane  Aulery <lkppo@free.fr>\n"
 "Language-Team: French <traduc@traduc.org>\n"
@@ -4018,25 +4018,25 @@ msgstr ""
 msgid "GNUnet GNS resolver tool"
 msgstr ""
 
-#: src/gns/gnunet-service-gns.c:504
+#: src/gns/gnunet-service-gns.c:505
 msgid "Properly base32-encoded public key required"
 msgstr ""
 
-#: src/gns/gnunet-service-gns.c:540
+#: src/gns/gnunet-service-gns.c:541
 msgid "Failed to connect to the namecache!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns.c:559
+#: src/gns/gnunet-service-gns.c:560
 #: src/zonemaster/gnunet-service-zonemaster-monitor.c:444
 #: src/zonemaster/gnunet-service-zonemaster.c:887
 msgid "Could not connect to DHT!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_interceptor.c:273
+#: src/gns/gnunet-service-gns_interceptor.c:279
 msgid "Error converting GNS response to DNS response!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_interceptor.c:380
+#: src/gns/gnunet-service-gns_interceptor.c:387
 msgid "Failed to connect to the DNS service!\n"
 msgstr ""
 
@@ -4069,36 +4069,36 @@ msgstr ""
 msgid "VPN returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1895
+#: src/gns/gnunet-service-gns_resolver.c:1896
 #, c-format
 msgid "Name `%s' cannot be converted to IDNA."
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1908
+#: src/gns/gnunet-service-gns_resolver.c:1909
 #, c-format
 msgid "GNS lookup resulted in DNS name that is too long (`%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1951
+#: src/gns/gnunet-service-gns_resolver.c:1952
 #, c-format
 msgid "GNS lookup failed (zero records found for `%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2375
+#: src/gns/gnunet-service-gns_resolver.c:2376
 msgid "GNS lookup recursion failed (no delegation record found)\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2398
+#: src/gns/gnunet-service-gns_resolver.c:2399
 #, c-format
 msgid "Failed to cache GNS resolution: %s\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2566
+#: src/gns/gnunet-service-gns_resolver.c:2567
 #, c-format
 msgid "GNS namecache returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2706
+#: src/gns/gnunet-service-gns_resolver.c:2707
 #, c-format
 msgid "Zone %s was revoked, resolution fails\n"
 msgstr ""
@@ -5625,78 +5625,78 @@ msgstr ""
 msgid "Daemon to run to perform IP protocol translation to GNUnet"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:613
+#: src/reclaim/gnunet-reclaim.c:617
 #, c-format
 msgid "Ego is required\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:620
+#: src/reclaim/gnunet-reclaim.c:624
 #, c-format
 msgid "Attribute value missing!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:627
+#: src/reclaim/gnunet-reclaim.c:631
 #, c-format
 msgid "Requesting party key is required!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:645
+#: src/reclaim/gnunet-reclaim.c:649
 msgid "Add an attribute NAME"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:650
+#: src/reclaim/gnunet-reclaim.c:654
 msgid "Delete the attribute with ID"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:655
+#: src/reclaim/gnunet-reclaim.c:659
 msgid "The attribute VALUE"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:660
+#: src/reclaim/gnunet-reclaim.c:664
 msgid "The EGO to use"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:666
+#: src/reclaim/gnunet-reclaim.c:670
 msgid "Specify the relying party for issue"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:670
+#: src/reclaim/gnunet-reclaim.c:674
 msgid "List attributes for EGO"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:677
+#: src/reclaim/gnunet-reclaim.c:681
 msgid "Issue a ticket for a set of attributes separated by comma"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:682
+#: src/reclaim/gnunet-reclaim.c:686
 msgid "Consume a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:687
+#: src/reclaim/gnunet-reclaim.c:691
 msgid "Revoke a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:692
+#: src/reclaim/gnunet-reclaim.c:696
 msgid "Type of attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:696
+#: src/reclaim/gnunet-reclaim.c:700
 msgid "List tickets of ego"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:702
+#: src/reclaim/gnunet-reclaim.c:706
 msgid "Expiration interval of the attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:710
+#: src/reclaim/gnunet-reclaim.c:714
 msgid "re:claimID command line tool"
 msgstr ""
 
-#: src/reclaim/plugin_rest_openid_connect.c:2192
+#: src/reclaim/plugin_rest_openid_connect.c:2340
 msgid "OpenID Connect REST API initialized\n"
 msgstr ""
 
-#: src/reclaim/plugin_rest_reclaim.c:1110
+#: src/reclaim/plugin_rest_reclaim.c:1899
 msgid "Identity Provider REST API initialized\n"
 msgstr ""
 
@@ -6661,18 +6661,18 @@ msgstr ""
 msgid "GNUnet topology control"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2196
-#: src/transport/gnunet-communicator-udp.c:2680
+#: src/transport/gnunet-communicator-tcp.c:2227
+#: src/transport/gnunet-communicator-udp.c:2712
 #: src/transport/gnunet-service-tng.c:10024
 #: src/transport/gnunet-service-transport.c:2627
 msgid "Transport service is lacking key configuration settings. Exiting.\n"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2254
+#: src/transport/gnunet-communicator-tcp.c:2285
 msgid "GNUnet TCP communicator"
 msgstr ""
 
-#: src/transport/gnunet-communicator-udp.c:2752
+#: src/transport/gnunet-communicator-udp.c:2784
 msgid "GNUnet UDP communicator"
 msgstr ""
 
@@ -7714,7 +7714,7 @@ msgid "do daemonize (detach from terminal)"
 msgstr ""
 
 #: src/transport/tcp_service_legacy.c:1397
-#: src/transport/transport-testing2.c:814 src/util/service.c:2073
+#: src/transport/transport-testing2.c:906 src/util/service.c:2073
 #: src/util/service.c:2085
 #, c-format
 msgid "Malformed configuration file `%s', exit ...\n"
@@ -7729,7 +7729,7 @@ msgstr ""
 msgid "Could not access configuration file `%s'\n"
 msgstr ""
 
-#: src/transport/transport_api2_communication.c:705
+#: src/transport/transport_api2_communication.c:704
 msgid "Dropped backchanel message: handler not provided by communicator\n"
 msgstr ""
 
@@ -7873,12 +7873,12 @@ msgid ""
 "%llu)\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:719
+#: src/util/crypto_ecc.c:705
 #, c-format
 msgid "ECC signing failed at %s:%d: %s\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:836
+#: src/util/crypto_ecc.c:822
 #, c-format
 msgid "ECDSA signature verification failed at %s:%d: %s\n"
 msgstr ""
@@ -8643,23 +8643,23 @@ msgstr ""
 msgid "Must specify valid IPv6 address"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3035
+#: src/vpn/gnunet-service-vpn.c:3036
 msgid "Must specify valid IPv6 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3044
+#: src/vpn/gnunet-service-vpn.c:3046
 msgid "IPv6 support disabled as this system does not support IPv6\n"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3060
+#: src/vpn/gnunet-service-vpn.c:3062
 msgid "Must specify valid IPv4 address"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3076
+#: src/vpn/gnunet-service-vpn.c:3079
 msgid "Must specify valid IPv4 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3087
+#: src/vpn/gnunet-service-vpn.c:3091
 msgid "IPv4 support disabled as this system does not support IPv4\n"
 msgstr ""
 
index a4d67c41295cd66506a4cf50f63b29b1ca596230..58c8b81ac2992da92b6852f7a617e309b04f6e83 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnunet 0.10.1\n"
 "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
-"POT-Creation-Date: 2019-12-25 13:08+0100\n"
+"POT-Creation-Date: 2020-01-13 14:01+0000\n"
 "PO-Revision-Date: 2019-10-16 11:00+0200\n"
 "Last-Translator: Sebastiano Pistore <sebastianopistore.info@protonmail.ch>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
@@ -4043,26 +4043,26 @@ msgstr ""
 msgid "GNUnet GNS resolver tool"
 msgstr ""
 
-#: src/gns/gnunet-service-gns.c:504
+#: src/gns/gnunet-service-gns.c:505
 #, fuzzy
 msgid "Properly base32-encoded public key required"
 msgstr "# messaggi PONG ricevuti"
 
-#: src/gns/gnunet-service-gns.c:540
+#: src/gns/gnunet-service-gns.c:541
 msgid "Failed to connect to the namecache!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns.c:559
+#: src/gns/gnunet-service-gns.c:560
 #: src/zonemaster/gnunet-service-zonemaster-monitor.c:444
 #: src/zonemaster/gnunet-service-zonemaster.c:887
 msgid "Could not connect to DHT!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_interceptor.c:273
+#: src/gns/gnunet-service-gns_interceptor.c:279
 msgid "Error converting GNS response to DNS response!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_interceptor.c:380
+#: src/gns/gnunet-service-gns_interceptor.c:387
 msgid "Failed to connect to the DNS service!\n"
 msgstr ""
 
@@ -4095,36 +4095,36 @@ msgstr ""
 msgid "VPN returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1895
+#: src/gns/gnunet-service-gns_resolver.c:1896
 #, c-format
 msgid "Name `%s' cannot be converted to IDNA."
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1908
+#: src/gns/gnunet-service-gns_resolver.c:1909
 #, c-format
 msgid "GNS lookup resulted in DNS name that is too long (`%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1951
+#: src/gns/gnunet-service-gns_resolver.c:1952
 #, c-format
 msgid "GNS lookup failed (zero records found for `%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2375
+#: src/gns/gnunet-service-gns_resolver.c:2376
 msgid "GNS lookup recursion failed (no delegation record found)\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2398
+#: src/gns/gnunet-service-gns_resolver.c:2399
 #, c-format
 msgid "Failed to cache GNS resolution: %s\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2566
+#: src/gns/gnunet-service-gns_resolver.c:2567
 #, c-format
 msgid "GNS namecache returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2706
+#: src/gns/gnunet-service-gns_resolver.c:2707
 #, c-format
 msgid "Zone %s was revoked, resolution fails\n"
 msgstr ""
@@ -5652,78 +5652,78 @@ msgstr ""
 msgid "Daemon to run to perform IP protocol translation to GNUnet"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:613
+#: src/reclaim/gnunet-reclaim.c:617
 #, c-format
 msgid "Ego is required\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:620
+#: src/reclaim/gnunet-reclaim.c:624
 #, c-format
 msgid "Attribute value missing!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:627
+#: src/reclaim/gnunet-reclaim.c:631
 #, c-format
 msgid "Requesting party key is required!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:645
+#: src/reclaim/gnunet-reclaim.c:649
 msgid "Add an attribute NAME"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:650
+#: src/reclaim/gnunet-reclaim.c:654
 msgid "Delete the attribute with ID"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:655
+#: src/reclaim/gnunet-reclaim.c:659
 msgid "The attribute VALUE"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:660
+#: src/reclaim/gnunet-reclaim.c:664
 msgid "The EGO to use"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:666
+#: src/reclaim/gnunet-reclaim.c:670
 msgid "Specify the relying party for issue"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:670
+#: src/reclaim/gnunet-reclaim.c:674
 msgid "List attributes for EGO"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:677
+#: src/reclaim/gnunet-reclaim.c:681
 msgid "Issue a ticket for a set of attributes separated by comma"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:682
+#: src/reclaim/gnunet-reclaim.c:686
 msgid "Consume a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:687
+#: src/reclaim/gnunet-reclaim.c:691
 msgid "Revoke a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:692
+#: src/reclaim/gnunet-reclaim.c:696
 msgid "Type of attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:696
+#: src/reclaim/gnunet-reclaim.c:700
 msgid "List tickets of ego"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:702
+#: src/reclaim/gnunet-reclaim.c:706
 msgid "Expiration interval of the attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:710
+#: src/reclaim/gnunet-reclaim.c:714
 msgid "re:claimID command line tool"
 msgstr ""
 
-#: src/reclaim/plugin_rest_openid_connect.c:2192
+#: src/reclaim/plugin_rest_openid_connect.c:2340
 msgid "OpenID Connect REST API initialized\n"
 msgstr ""
 
-#: src/reclaim/plugin_rest_reclaim.c:1110
+#: src/reclaim/plugin_rest_reclaim.c:1899
 msgid "Identity Provider REST API initialized\n"
 msgstr ""
 
@@ -6689,18 +6689,18 @@ msgstr ""
 msgid "GNUnet topology control"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2196
-#: src/transport/gnunet-communicator-udp.c:2680
+#: src/transport/gnunet-communicator-tcp.c:2227
+#: src/transport/gnunet-communicator-udp.c:2712
 #: src/transport/gnunet-service-tng.c:10024
 #: src/transport/gnunet-service-transport.c:2627
 msgid "Transport service is lacking key configuration settings. Exiting.\n"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2254
+#: src/transport/gnunet-communicator-tcp.c:2285
 msgid "GNUnet TCP communicator"
 msgstr ""
 
-#: src/transport/gnunet-communicator-udp.c:2752
+#: src/transport/gnunet-communicator-udp.c:2784
 msgid "GNUnet UDP communicator"
 msgstr ""
 
@@ -7764,7 +7764,7 @@ msgid "do daemonize (detach from terminal)"
 msgstr ""
 
 #: src/transport/tcp_service_legacy.c:1397
-#: src/transport/transport-testing2.c:814 src/util/service.c:2073
+#: src/transport/transport-testing2.c:906 src/util/service.c:2073
 #: src/util/service.c:2085
 #, c-format
 msgid "Malformed configuration file `%s', exit ...\n"
@@ -7779,7 +7779,7 @@ msgstr ""
 msgid "Could not access configuration file `%s'\n"
 msgstr ""
 
-#: src/transport/transport_api2_communication.c:705
+#: src/transport/transport_api2_communication.c:704
 msgid "Dropped backchanel message: handler not provided by communicator\n"
 msgstr ""
 
@@ -7923,12 +7923,12 @@ msgid ""
 "%llu)\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:719
+#: src/util/crypto_ecc.c:705
 #, c-format
 msgid "ECC signing failed at %s:%d: %s\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:836
+#: src/util/crypto_ecc.c:822
 #, c-format
 msgid "ECDSA signature verification failed at %s:%d: %s\n"
 msgstr ""
@@ -8695,23 +8695,23 @@ msgstr ""
 msgid "Must specify valid IPv6 address"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3035
+#: src/vpn/gnunet-service-vpn.c:3036
 msgid "Must specify valid IPv6 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3044
+#: src/vpn/gnunet-service-vpn.c:3046
 msgid "IPv6 support disabled as this system does not support IPv6\n"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3060
+#: src/vpn/gnunet-service-vpn.c:3062
 msgid "Must specify valid IPv4 address"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3076
+#: src/vpn/gnunet-service-vpn.c:3079
 msgid "Must specify valid IPv4 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3087
+#: src/vpn/gnunet-service-vpn.c:3091
 msgid "IPv4 support disabled as this system does not support IPv4\n"
 msgstr ""
 
index 6b3f679e630b7527a6f1c83cb74257fa1bead3ae..8631b6f137bde32cea0b3be0ae4fdfa313743711 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: GNUnet 0.7.0b\n"
 "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
-"POT-Creation-Date: 2019-12-25 13:08+0100\n"
+"POT-Creation-Date: 2020-01-13 14:01+0000\n"
 "PO-Revision-Date: 2006-01-21 17:16+0100\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -4235,28 +4235,28 @@ msgstr ""
 msgid "GNUnet GNS resolver tool"
 msgstr "Spåra GNUnets nätverkstopologi."
 
-#: src/gns/gnunet-service-gns.c:504
+#: src/gns/gnunet-service-gns.c:505
 #, fuzzy
 msgid "Properly base32-encoded public key required"
 msgstr "Ogiltigt argument: \"%s\"\n"
 
-#: src/gns/gnunet-service-gns.c:540
+#: src/gns/gnunet-service-gns.c:541
 #, fuzzy
 msgid "Failed to connect to the namecache!\n"
 msgstr "Misslyckades att ansluta till gnunetd.\n"
 
-#: src/gns/gnunet-service-gns.c:559
+#: src/gns/gnunet-service-gns.c:560
 #: src/zonemaster/gnunet-service-zonemaster-monitor.c:444
 #: src/zonemaster/gnunet-service-zonemaster.c:887
 #, fuzzy
 msgid "Could not connect to DHT!\n"
 msgstr "Kunde inte ansluta till gnunetd.\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:273
+#: src/gns/gnunet-service-gns_interceptor.c:279
 msgid "Error converting GNS response to DNS response!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_interceptor.c:380
+#: src/gns/gnunet-service-gns_interceptor.c:387
 #, fuzzy
 msgid "Failed to connect to the DNS service!\n"
 msgstr "Misslyckades att ansluta till gnunetd.\n"
@@ -4291,36 +4291,36 @@ msgstr ""
 msgid "VPN returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1895
+#: src/gns/gnunet-service-gns_resolver.c:1896
 #, c-format
 msgid "Name `%s' cannot be converted to IDNA."
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1908
+#: src/gns/gnunet-service-gns_resolver.c:1909
 #, c-format
 msgid "GNS lookup resulted in DNS name that is too long (`%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1951
+#: src/gns/gnunet-service-gns_resolver.c:1952
 #, fuzzy, c-format
 msgid "GNS lookup failed (zero records found for `%s')\n"
 msgstr "%d filer hittades i katalog.\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2375
+#: src/gns/gnunet-service-gns_resolver.c:2376
 msgid "GNS lookup recursion failed (no delegation record found)\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2398
+#: src/gns/gnunet-service-gns_resolver.c:2399
 #, fuzzy, c-format
 msgid "Failed to cache GNS resolution: %s\n"
 msgstr "Misslyckades att skicka HTTP-begäran till värd \"%s\": %s\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2566
+#: src/gns/gnunet-service-gns_resolver.c:2567
 #, c-format
 msgid "GNS namecache returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2706
+#: src/gns/gnunet-service-gns_resolver.c:2707
 #, c-format
 msgid "Zone %s was revoked, resolution fails\n"
 msgstr ""
@@ -5907,80 +5907,80 @@ msgstr "Misslyckades att initiera tjänsten \"%s\".\n"
 msgid "Daemon to run to perform IP protocol translation to GNUnet"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:613
+#: src/reclaim/gnunet-reclaim.c:617
 #, fuzzy, c-format
 msgid "Ego is required\n"
 msgstr "%s: flagga \"%s\" är tvetydig\n"
 
-#: src/reclaim/gnunet-reclaim.c:620
+#: src/reclaim/gnunet-reclaim.c:624
 #, c-format
 msgid "Attribute value missing!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:627
+#: src/reclaim/gnunet-reclaim.c:631
 #, fuzzy, c-format
 msgid "Requesting party key is required!\n"
 msgstr "%s: flagga \"%s\" är tvetydig\n"
 
-#: src/reclaim/gnunet-reclaim.c:645
+#: src/reclaim/gnunet-reclaim.c:649
 msgid "Add an attribute NAME"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:650
+#: src/reclaim/gnunet-reclaim.c:654
 msgid "Delete the attribute with ID"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:655
+#: src/reclaim/gnunet-reclaim.c:659
 msgid "The attribute VALUE"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:660
+#: src/reclaim/gnunet-reclaim.c:664
 #, fuzzy
 msgid "The EGO to use"
 msgstr "meddelandestorlek"
 
-#: src/reclaim/gnunet-reclaim.c:666
+#: src/reclaim/gnunet-reclaim.c:670
 msgid "Specify the relying party for issue"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:670
+#: src/reclaim/gnunet-reclaim.c:674
 msgid "List attributes for EGO"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:677
+#: src/reclaim/gnunet-reclaim.c:681
 msgid "Issue a ticket for a set of attributes separated by comma"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:682
+#: src/reclaim/gnunet-reclaim.c:686
 msgid "Consume a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:687
+#: src/reclaim/gnunet-reclaim.c:691
 msgid "Revoke a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:692
+#: src/reclaim/gnunet-reclaim.c:696
 msgid "Type of attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:696
+#: src/reclaim/gnunet-reclaim.c:700
 msgid "List tickets of ego"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:702
+#: src/reclaim/gnunet-reclaim.c:706
 msgid "Expiration interval of the attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:710
+#: src/reclaim/gnunet-reclaim.c:714
 msgid "re:claimID command line tool"
 msgstr ""
 
-#: src/reclaim/plugin_rest_openid_connect.c:2192
+#: src/reclaim/plugin_rest_openid_connect.c:2340
 #, fuzzy
 msgid "OpenID Connect REST API initialized\n"
 msgstr " Anslutning misslyckades\n"
 
-#: src/reclaim/plugin_rest_reclaim.c:1110
+#: src/reclaim/plugin_rest_reclaim.c:1899
 #, fuzzy
 msgid "Identity Provider REST API initialized\n"
 msgstr " Anslutning misslyckades\n"
@@ -6983,19 +6983,19 @@ msgstr "# krypterade PONG-meddelanden mottagna"
 msgid "GNUnet topology control"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2196
-#: src/transport/gnunet-communicator-udp.c:2680
+#: src/transport/gnunet-communicator-tcp.c:2227
+#: src/transport/gnunet-communicator-udp.c:2712
 #: src/transport/gnunet-service-tng.c:10024
 #: src/transport/gnunet-service-transport.c:2627
 #, fuzzy
 msgid "Transport service is lacking key configuration settings. Exiting.\n"
 msgstr "GNUnet-konfiguration"
 
-#: src/transport/gnunet-communicator-tcp.c:2254
+#: src/transport/gnunet-communicator-tcp.c:2285
 msgid "GNUnet TCP communicator"
 msgstr ""
 
-#: src/transport/gnunet-communicator-udp.c:2752
+#: src/transport/gnunet-communicator-udp.c:2784
 msgid "GNUnet UDP communicator"
 msgstr ""
 
@@ -8123,7 +8123,7 @@ msgid "do daemonize (detach from terminal)"
 msgstr ""
 
 #: src/transport/tcp_service_legacy.c:1397
-#: src/transport/transport-testing2.c:814 src/util/service.c:2073
+#: src/transport/transport-testing2.c:906 src/util/service.c:2073
 #: src/util/service.c:2085
 #, fuzzy, c-format
 msgid "Malformed configuration file `%s', exit ...\n"
@@ -8139,7 +8139,7 @@ msgstr "Kunde inte spara konfigurationsfil \"%s\":"
 msgid "Could not access configuration file `%s'\n"
 msgstr "Kunde inte tolka konfigurationsfil \"%s\".\n"
 
-#: src/transport/transport_api2_communication.c:705
+#: src/transport/transport_api2_communication.c:704
 msgid "Dropped backchanel message: handler not provided by communicator\n"
 msgstr ""
 
@@ -8285,12 +8285,12 @@ msgid ""
 "%llu)\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:719
+#: src/util/crypto_ecc.c:705
 #, fuzzy, c-format
 msgid "ECC signing failed at %s:%d: %s\n"
 msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n"
 
-#: src/util/crypto_ecc.c:836
+#: src/util/crypto_ecc.c:822
 #, fuzzy, c-format
 msgid "ECDSA signature verification failed at %s:%d: %s\n"
 msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n"
@@ -9077,24 +9077,24 @@ msgstr ""
 msgid "Must specify valid IPv6 address"
 msgstr "\"%s\" är inte tillgänglig."
 
-#: src/vpn/gnunet-service-vpn.c:3035
+#: src/vpn/gnunet-service-vpn.c:3036
 msgid "Must specify valid IPv6 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3044
+#: src/vpn/gnunet-service-vpn.c:3046
 msgid "IPv6 support disabled as this system does not support IPv6\n"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3060
+#: src/vpn/gnunet-service-vpn.c:3062
 #, fuzzy
 msgid "Must specify valid IPv4 address"
 msgstr "\"%s\" är inte tillgänglig."
 
-#: src/vpn/gnunet-service-vpn.c:3076
+#: src/vpn/gnunet-service-vpn.c:3079
 msgid "Must specify valid IPv4 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3087
+#: src/vpn/gnunet-service-vpn.c:3091
 msgid "IPv4 support disabled as this system does not support IPv4\n"
 msgstr ""
 
index 0e5f864358ac5dbf85feb8ec3059a23bcd5fddf5..4f14469f86e99582eccaba18bacf4efa50fbfd41 100644 (file)
--- a/po/vi.po
+++ b/po/vi.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnunet 0.8.0a\n"
 "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
-"POT-Creation-Date: 2019-12-25 13:08+0100\n"
+"POT-Creation-Date: 2020-01-13 14:01+0000\n"
 "PO-Revision-Date: 2008-09-10 22:05+0930\n"
 "Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
 "Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
@@ -4282,29 +4282,29 @@ msgstr ""
 msgid "GNUnet GNS resolver tool"
 msgstr "Bản ghi lỗi GNUnet"
 
-#: src/gns/gnunet-service-gns.c:504
+#: src/gns/gnunet-service-gns.c:505
 #, fuzzy
 msgid "Properly base32-encoded public key required"
 msgstr "Đối số không hợp lệ cho « %s ».\n"
 
-#: src/gns/gnunet-service-gns.c:540
+#: src/gns/gnunet-service-gns.c:541
 #, fuzzy
 msgid "Failed to connect to the namecache!\n"
 msgstr "Không kết nối được đến trình nền gnunetd."
 
-#: src/gns/gnunet-service-gns.c:559
+#: src/gns/gnunet-service-gns.c:560
 #: src/zonemaster/gnunet-service-zonemaster-monitor.c:444
 #: src/zonemaster/gnunet-service-zonemaster.c:887
 #, fuzzy
 msgid "Could not connect to DHT!\n"
 msgstr "Không thể kết nối tới %s:%u: %s\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:273
+#: src/gns/gnunet-service-gns_interceptor.c:279
 #, fuzzy
 msgid "Error converting GNS response to DNS response!\n"
 msgstr "Gặp lỗi khi chuyển đổi các đối số sang URI.\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:380
+#: src/gns/gnunet-service-gns_interceptor.c:387
 #, fuzzy
 msgid "Failed to connect to the DNS service!\n"
 msgstr "Lỗi kết nối đến gnunetd.\n"
@@ -4339,36 +4339,36 @@ msgstr ""
 msgid "VPN returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1895
+#: src/gns/gnunet-service-gns_resolver.c:1896
 #, c-format
 msgid "Name `%s' cannot be converted to IDNA."
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1908
+#: src/gns/gnunet-service-gns_resolver.c:1909
 #, c-format
 msgid "GNS lookup resulted in DNS name that is too long (`%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1951
+#: src/gns/gnunet-service-gns_resolver.c:1952
 #, fuzzy, c-format
 msgid "GNS lookup failed (zero records found for `%s')\n"
 msgstr "Vẫn còn không tìm thấy đồng đẳng trong « %s ».\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2375
+#: src/gns/gnunet-service-gns_resolver.c:2376
 msgid "GNS lookup recursion failed (no delegation record found)\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2398
+#: src/gns/gnunet-service-gns_resolver.c:2399
 #, fuzzy, c-format
 msgid "Failed to cache GNS resolution: %s\n"
 msgstr "Lỗi mở tập tin ghi sự kiện « %s »: %s\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2566
+#: src/gns/gnunet-service-gns_resolver.c:2567
 #, c-format
 msgid "GNS namecache returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2706
+#: src/gns/gnunet-service-gns_resolver.c:2707
 #, c-format
 msgid "Zone %s was revoked, resolution fails\n"
 msgstr ""
@@ -5964,80 +5964,80 @@ msgstr "Lỗi sơ khởi dịch vụ « %s ».\n"
 msgid "Daemon to run to perform IP protocol translation to GNUnet"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:613
+#: src/reclaim/gnunet-reclaim.c:617
 #, fuzzy, c-format
 msgid "Ego is required\n"
 msgstr "Bị từ chối đặt tùy chọn « %s » trong phần « %s » thành « %s ».\n"
 
-#: src/reclaim/gnunet-reclaim.c:620
+#: src/reclaim/gnunet-reclaim.c:624
 #, c-format
 msgid "Attribute value missing!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:627
+#: src/reclaim/gnunet-reclaim.c:631
 #, fuzzy, c-format
 msgid "Requesting party key is required!\n"
 msgstr "đặt tên hiệu cần dùng (cần thiết)"
 
-#: src/reclaim/gnunet-reclaim.c:645
+#: src/reclaim/gnunet-reclaim.c:649
 msgid "Add an attribute NAME"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:650
+#: src/reclaim/gnunet-reclaim.c:654
 msgid "Delete the attribute with ID"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:655
+#: src/reclaim/gnunet-reclaim.c:659
 msgid "The attribute VALUE"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:660
+#: src/reclaim/gnunet-reclaim.c:664
 #, fuzzy
 msgid "The EGO to use"
 msgstr "kích cỡ tin nhắn"
 
-#: src/reclaim/gnunet-reclaim.c:666
+#: src/reclaim/gnunet-reclaim.c:670
 msgid "Specify the relying party for issue"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:670
+#: src/reclaim/gnunet-reclaim.c:674
 msgid "List attributes for EGO"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:677
+#: src/reclaim/gnunet-reclaim.c:681
 msgid "Issue a ticket for a set of attributes separated by comma"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:682
+#: src/reclaim/gnunet-reclaim.c:686
 msgid "Consume a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:687
+#: src/reclaim/gnunet-reclaim.c:691
 msgid "Revoke a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:692
+#: src/reclaim/gnunet-reclaim.c:696
 msgid "Type of attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:696
+#: src/reclaim/gnunet-reclaim.c:700
 msgid "List tickets of ego"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:702
+#: src/reclaim/gnunet-reclaim.c:706
 msgid "Expiration interval of the attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:710
+#: src/reclaim/gnunet-reclaim.c:714
 msgid "re:claimID command line tool"
 msgstr ""
 
-#: src/reclaim/plugin_rest_openid_connect.c:2192
+#: src/reclaim/plugin_rest_openid_connect.c:2340
 #, fuzzy
 msgid "OpenID Connect REST API initialized\n"
 msgstr "Lỗi sơ khởi lõi.\n"
 
-#: src/reclaim/plugin_rest_reclaim.c:1110
+#: src/reclaim/plugin_rest_reclaim.c:1899
 #, fuzzy
 msgid "Identity Provider REST API initialized\n"
 msgstr "Lỗi sơ khởi lõi.\n"
@@ -7045,19 +7045,19 @@ msgstr "# các thông báo PONG đã mật mã được nhận"
 msgid "GNUnet topology control"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2196
-#: src/transport/gnunet-communicator-udp.c:2680
+#: src/transport/gnunet-communicator-tcp.c:2227
+#: src/transport/gnunet-communicator-udp.c:2712
 #: src/transport/gnunet-service-tng.c:10024
 #: src/transport/gnunet-service-transport.c:2627
 #, fuzzy
 msgid "Transport service is lacking key configuration settings. Exiting.\n"
 msgstr "Lưu cấu hình ngay bây giờ không?"
 
-#: src/transport/gnunet-communicator-tcp.c:2254
+#: src/transport/gnunet-communicator-tcp.c:2285
 msgid "GNUnet TCP communicator"
 msgstr ""
 
-#: src/transport/gnunet-communicator-udp.c:2752
+#: src/transport/gnunet-communicator-udp.c:2784
 msgid "GNUnet UDP communicator"
 msgstr ""
 
@@ -8179,7 +8179,7 @@ msgid "do daemonize (detach from terminal)"
 msgstr ""
 
 #: src/transport/tcp_service_legacy.c:1397
-#: src/transport/transport-testing2.c:814 src/util/service.c:2073
+#: src/transport/transport-testing2.c:906 src/util/service.c:2073
 #: src/util/service.c:2085
 #, fuzzy, c-format
 msgid "Malformed configuration file `%s', exit ...\n"
@@ -8195,7 +8195,7 @@ msgstr "Không thể lưu tập tin cấu hình « %s »:"
 msgid "Could not access configuration file `%s'\n"
 msgstr "Không thể truy cập đến tập tin gnunet-directory « %s »\n"
 
-#: src/transport/transport_api2_communication.c:705
+#: src/transport/transport_api2_communication.c:704
 msgid "Dropped backchanel message: handler not provided by communicator\n"
 msgstr ""
 
@@ -8344,12 +8344,12 @@ msgid ""
 "%llu)\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:719
+#: src/util/crypto_ecc.c:705
 #, fuzzy, c-format
 msgid "ECC signing failed at %s:%d: %s\n"
 msgstr "%s bị lỗi tại %s:%d: « %s »\n"
 
-#: src/util/crypto_ecc.c:836
+#: src/util/crypto_ecc.c:822
 #, fuzzy, c-format
 msgid "ECDSA signature verification failed at %s:%d: %s\n"
 msgstr "Lỗi thẩm tra chữ ký RSA tại %s:%d: %s\n"
@@ -9136,24 +9136,24 @@ msgstr ""
 msgid "Must specify valid IPv6 address"
 msgstr "« %s » không sẵn sàng.\n"
 
-#: src/vpn/gnunet-service-vpn.c:3035
+#: src/vpn/gnunet-service-vpn.c:3036
 msgid "Must specify valid IPv6 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3044
+#: src/vpn/gnunet-service-vpn.c:3046
 msgid "IPv6 support disabled as this system does not support IPv6\n"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3060
+#: src/vpn/gnunet-service-vpn.c:3062
 #, fuzzy
 msgid "Must specify valid IPv4 address"
 msgstr "« %s » không sẵn sàng.\n"
 
-#: src/vpn/gnunet-service-vpn.c:3076
+#: src/vpn/gnunet-service-vpn.c:3079
 msgid "Must specify valid IPv4 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3087
+#: src/vpn/gnunet-service-vpn.c:3091
 msgid "IPv4 support disabled as this system does not support IPv4\n"
 msgstr ""
 
index e5fc30d0410fc401b98b155f3fea926611036c33..f2889d5023facef2337df5f0bb8c154df1690da1 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnunet-0.8.1\n"
 "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n"
-"POT-Creation-Date: 2019-12-25 13:08+0100\n"
+"POT-Creation-Date: 2020-01-13 14:01+0000\n"
 "PO-Revision-Date: 2011-07-09 12:12+0800\n"
 "Last-Translator: Wylmer Wang <wantinghard@gmail.com>\n"
 "Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
@@ -4086,28 +4086,28 @@ msgstr ""
 msgid "GNUnet GNS resolver tool"
 msgstr "GNUnet 错误日志"
 
-#: src/gns/gnunet-service-gns.c:504
+#: src/gns/gnunet-service-gns.c:505
 #, fuzzy
 msgid "Properly base32-encoded public key required"
 msgstr "“%s”的参数无效。\n"
 
-#: src/gns/gnunet-service-gns.c:540
+#: src/gns/gnunet-service-gns.c:541
 #, fuzzy
 msgid "Failed to connect to the namecache!\n"
 msgstr "初始化“%s”服务失败。\n"
 
-#: src/gns/gnunet-service-gns.c:559
+#: src/gns/gnunet-service-gns.c:560
 #: src/zonemaster/gnunet-service-zonemaster-monitor.c:444
 #: src/zonemaster/gnunet-service-zonemaster.c:887
 #, fuzzy
 msgid "Could not connect to DHT!\n"
 msgstr "无法连接到 %s:%u:%s\n"
 
-#: src/gns/gnunet-service-gns_interceptor.c:273
+#: src/gns/gnunet-service-gns_interceptor.c:279
 msgid "Error converting GNS response to DNS response!\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_interceptor.c:380
+#: src/gns/gnunet-service-gns_interceptor.c:387
 #, fuzzy
 msgid "Failed to connect to the DNS service!\n"
 msgstr "初始化“%s”服务失败。\n"
@@ -4142,36 +4142,36 @@ msgstr ""
 msgid "VPN returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1895
+#: src/gns/gnunet-service-gns_resolver.c:1896
 #, c-format
 msgid "Name `%s' cannot be converted to IDNA."
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1908
+#: src/gns/gnunet-service-gns_resolver.c:1909
 #, c-format
 msgid "GNS lookup resulted in DNS name that is too long (`%s')\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:1951
+#: src/gns/gnunet-service-gns_resolver.c:1952
 #, fuzzy, c-format
 msgid "GNS lookup failed (zero records found for `%s')\n"
 msgstr "运行 %s失败:%s %d\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2375
+#: src/gns/gnunet-service-gns_resolver.c:2376
 msgid "GNS lookup recursion failed (no delegation record found)\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2398
+#: src/gns/gnunet-service-gns_resolver.c:2399
 #, fuzzy, c-format
 msgid "Failed to cache GNS resolution: %s\n"
 msgstr "打开日志文件“%s”失败:%s\n"
 
-#: src/gns/gnunet-service-gns_resolver.c:2566
+#: src/gns/gnunet-service-gns_resolver.c:2567
 #, c-format
 msgid "GNS namecache returned empty result for `%s'\n"
 msgstr ""
 
-#: src/gns/gnunet-service-gns_resolver.c:2706
+#: src/gns/gnunet-service-gns_resolver.c:2707
 #, c-format
 msgid "Zone %s was revoked, resolution fails\n"
 msgstr ""
@@ -5726,79 +5726,79 @@ msgstr "初始化“%s”服务失败。\n"
 msgid "Daemon to run to perform IP protocol translation to GNUnet"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:613
+#: src/reclaim/gnunet-reclaim.c:617
 #, fuzzy, c-format
 msgid "Ego is required\n"
 msgstr "%s:选项“%s”有歧义\n"
 
-#: src/reclaim/gnunet-reclaim.c:620
+#: src/reclaim/gnunet-reclaim.c:624
 #, c-format
 msgid "Attribute value missing!\n"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:627
+#: src/reclaim/gnunet-reclaim.c:631
 #, fuzzy, c-format
 msgid "Requesting party key is required!\n"
 msgstr "设置要使用的昵称(必须)"
 
-#: src/reclaim/gnunet-reclaim.c:645
+#: src/reclaim/gnunet-reclaim.c:649
 msgid "Add an attribute NAME"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:650
+#: src/reclaim/gnunet-reclaim.c:654
 msgid "Delete the attribute with ID"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:655
+#: src/reclaim/gnunet-reclaim.c:659
 msgid "The attribute VALUE"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:660
+#: src/reclaim/gnunet-reclaim.c:664
 #, fuzzy
 msgid "The EGO to use"
 msgstr "消息尺寸"
 
-#: src/reclaim/gnunet-reclaim.c:666
+#: src/reclaim/gnunet-reclaim.c:670
 msgid "Specify the relying party for issue"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:670
+#: src/reclaim/gnunet-reclaim.c:674
 msgid "List attributes for EGO"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:677
+#: src/reclaim/gnunet-reclaim.c:681
 msgid "Issue a ticket for a set of attributes separated by comma"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:682
+#: src/reclaim/gnunet-reclaim.c:686
 msgid "Consume a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:687
+#: src/reclaim/gnunet-reclaim.c:691
 msgid "Revoke a ticket"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:692
+#: src/reclaim/gnunet-reclaim.c:696
 msgid "Type of attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:696
+#: src/reclaim/gnunet-reclaim.c:700
 msgid "List tickets of ego"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:702
+#: src/reclaim/gnunet-reclaim.c:706
 msgid "Expiration interval of the attribute"
 msgstr ""
 
-#: src/reclaim/gnunet-reclaim.c:710
+#: src/reclaim/gnunet-reclaim.c:714
 msgid "re:claimID command line tool"
 msgstr ""
 
-#: src/reclaim/plugin_rest_openid_connect.c:2192
+#: src/reclaim/plugin_rest_openid_connect.c:2340
 msgid "OpenID Connect REST API initialized\n"
 msgstr ""
 
-#: src/reclaim/plugin_rest_reclaim.c:1110
+#: src/reclaim/plugin_rest_reclaim.c:1899
 msgid "Identity Provider REST API initialized\n"
 msgstr ""
 
@@ -6792,19 +6792,19 @@ msgstr ""
 msgid "GNUnet topology control"
 msgstr ""
 
-#: src/transport/gnunet-communicator-tcp.c:2196
-#: src/transport/gnunet-communicator-udp.c:2680
+#: src/transport/gnunet-communicator-tcp.c:2227
+#: src/transport/gnunet-communicator-udp.c:2712
 #: src/transport/gnunet-service-tng.c:10024
 #: src/transport/gnunet-service-transport.c:2627
 #, fuzzy
 msgid "Transport service is lacking key configuration settings. Exiting.\n"
 msgstr "立即保存配置?"
 
-#: src/transport/gnunet-communicator-tcp.c:2254
+#: src/transport/gnunet-communicator-tcp.c:2285
 msgid "GNUnet TCP communicator"
 msgstr ""
 
-#: src/transport/gnunet-communicator-udp.c:2752
+#: src/transport/gnunet-communicator-udp.c:2784
 msgid "GNUnet UDP communicator"
 msgstr ""
 
@@ -7873,7 +7873,7 @@ msgid "do daemonize (detach from terminal)"
 msgstr ""
 
 #: src/transport/tcp_service_legacy.c:1397
-#: src/transport/transport-testing2.c:814 src/util/service.c:2073
+#: src/transport/transport-testing2.c:906 src/util/service.c:2073
 #: src/util/service.c:2085
 #, fuzzy, c-format
 msgid "Malformed configuration file `%s', exit ...\n"
@@ -7889,7 +7889,7 @@ msgstr "解析配置文件“%s”失败\n"
 msgid "Could not access configuration file `%s'\n"
 msgstr "找不到接口“%s”的一个 IP 地址。\n"
 
-#: src/transport/transport_api2_communication.c:705
+#: src/transport/transport_api2_communication.c:704
 msgid "Dropped backchanel message: handler not provided by communicator\n"
 msgstr ""
 
@@ -8034,12 +8034,12 @@ msgid ""
 "%llu)\n"
 msgstr ""
 
-#: src/util/crypto_ecc.c:719
+#: src/util/crypto_ecc.c:705
 #, fuzzy, c-format
 msgid "ECC signing failed at %s:%d: %s\n"
 msgstr "对驱动器“%2$s”的“%1$s”操作失败:%3$u\n"
 
-#: src/util/crypto_ecc.c:836
+#: src/util/crypto_ecc.c:822
 #, fuzzy, c-format
 msgid "ECDSA signature verification failed at %s:%d: %s\n"
 msgstr "对驱动器“%2$s”的“%1$s”操作失败:%3$u\n"
@@ -8815,24 +8815,24 @@ msgstr ""
 msgid "Must specify valid IPv6 address"
 msgstr "“%s”不可用。\n"
 
-#: src/vpn/gnunet-service-vpn.c:3035
+#: src/vpn/gnunet-service-vpn.c:3036
 msgid "Must specify valid IPv6 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3044
+#: src/vpn/gnunet-service-vpn.c:3046
 msgid "IPv6 support disabled as this system does not support IPv6\n"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3060
+#: src/vpn/gnunet-service-vpn.c:3062
 #, fuzzy
 msgid "Must specify valid IPv4 address"
 msgstr "“%s”不可用。\n"
 
-#: src/vpn/gnunet-service-vpn.c:3076
+#: src/vpn/gnunet-service-vpn.c:3079
 msgid "Must specify valid IPv4 mask"
 msgstr ""
 
-#: src/vpn/gnunet-service-vpn.c:3087
+#: src/vpn/gnunet-service-vpn.c:3091
 msgid "IPv4 support disabled as this system does not support IPv4\n"
 msgstr ""
 
index 1bcc1ae7b150db3885a45553d228edddce518547..7b73a4bb8f686ed8250bdc2d77c28127758d5235 100644 (file)
@@ -66,12 +66,6 @@ endif
 endif
 
 
-if TALER_ONLY
-SUBDIRS = \
- include \
- util
-else
-
 SUBDIRS = \
   include $(INTLEMU_SUBDIRS) \
   util \
@@ -128,5 +122,3 @@ SUBDIRS = \
   $(RECLAIM_DIR) \
   $(EXP_DIR) \
   integration-tests
-
-endif
index dcbb43f58d2c3b2649a6f2ab1e59129331857191..82eb28ed9a0ce536edf265930c59b5163e18f4c5 100644 (file)
@@ -680,7 +680,7 @@ do_benchmark (CURLMsg *cmsg)
 
 
 /**
- * Run the main event loop for the Taler interaction.
+ * Run the main event loop for the HTTP interaction.
  *
  * @param ctx the library context
  * @param rp parses the raw response returned from
index 1fa812c23962fc12b7c624162cf9c02927093540..5f51b710843aaf222550045422c2e84d79279069 100644 (file)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      Copyright (C) 2012-2013 GNUnet e.V.
+      Copyright (C) 2012-2020 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
@@ -57,9 +57,11 @@ struct LookupMessage
   int16_t options GNUNET_PACKED;
 
   /**
-   * Always 0.
+   * Recursion depth limit, i.e. how many more 
+   * GNS zones may be traversed during the resolution
+   * of this name.
    */
-  int16_t reserved GNUNET_PACKED;
+  uint16_t recursion_depth_limit GNUNET_PACKED;
 
   /**
    * the type of record to look up
index 4a4003b2ac9d083569e3960e91b99265986a4633..0d99d822e8c4a1d6c04e1fec9c9ba67766caae0d 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009-2013, 2016, 2018 GNUnet e.V.
+     Copyright (C) 2009-2020 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
 
 #define LOG(kind, ...) GNUNET_log_from (kind, "gns-api", __VA_ARGS__)
 
+/**
+ * Default recursion depth limit to apply if
+ * the application does not specify any.
+ */
+#define DEFAULT_LIMIT 128
+
 /**
  * Handle to a lookup request
  */
@@ -325,21 +331,24 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr)
  *
  * @param handle handle to the GNS service
  * @param name the name to look up (in UTF-8 encoding)
- * @param zone the zone to start the resolution in
- * @param type the record type to look up
+ * @param zone zone to look in
+ * @param type the GNS record type to look for
  * @param options local options for the lookup
- * @param proc processor to call on result
+ * @param recursion_depth_limit maximum number of zones
+ *        that the lookup may (still) traverse
+ * @param proc function to call on result
  * @param proc_cls closure for @a proc
- * @return handle to the get request
+ * @return handle to the queued request
  */
-struct GNUNET_GNS_LookupRequest*
-GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
-                   const char *name,
-                   const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
-                   uint32_t type,
-                   enum GNUNET_GNS_LocalOptions options,
-                   GNUNET_GNS_LookupResultProcessor proc,
-                   void *proc_cls)
+struct GNUNET_GNS_LookupRequest *
+GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle,
+                           const char *name,
+                           const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
+                           uint32_t type,
+                           enum GNUNET_GNS_LocalOptions options,
+                           uint16_t recursion_depth_limit,
+                           GNUNET_GNS_LookupResultProcessor proc,
+                           void *proc_cls)
 {
   /* IPC to shorten gns names, return shorten_handle */
   struct LookupMessage *lookup_msg;
@@ -370,6 +379,8 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
                                  GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
   lookup_msg->id = htonl (lr->r_id);
   lookup_msg->options = htons ((uint16_t) options);
+  lookup_msg->recursion_depth_limit
+    = htons (recursion_depth_limit);
   lookup_msg->zone = *zone;
   lookup_msg->type = htonl (type);
   GNUNET_memcpy (&lookup_msg[1],
@@ -385,4 +396,35 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
 }
 
 
+/**
+ * Perform an asynchronous lookup operation on the GNS.
+ *
+ * @param handle handle to the GNS service
+ * @param name the name to look up (in UTF-8 encoding)
+ * @param zone the zone to start the resolution in
+ * @param type the record type to look up
+ * @param options local options for the lookup
+ * @param proc processor to call on result
+ * @param proc_cls closure for @a proc
+ * @return handle to the get request
+ */
+struct GNUNET_GNS_LookupRequest*
+GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
+                   const char *name,
+                   const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
+                   uint32_t type,
+                   enum GNUNET_GNS_LocalOptions options,
+                   GNUNET_GNS_LookupResultProcessor proc,
+                   void *proc_cls)
+{
+  return GNUNET_GNS_lookup_limited (handle,
+                                    name,
+                                    zone,
+                                    type,
+                                    options,
+                                    DEFAULT_LIMIT,
+                                    proc,
+                                    proc_cls);
+}
+
 /* end of gns_api.c */
index 99cdbfe4ed2854a08f0b633ee26c2e1f8e2f0575..8c5b2d6c432d8172dfbd698e987778b73e243893 100644 (file)
@@ -463,6 +463,7 @@ handle_lookup (void *cls,
                                      name,
                                      (enum GNUNET_GNS_LocalOptions) ntohs (
                                        sh_msg->options),
+                                     ntohs (sh_msg->recursion_depth_limit),
                                      &send_lookup_response, clh);
   GNUNET_STATISTICS_update (statistics,
                             "Lookup attempts",
index dd97782ae993e4fb132875e09d5a7724414e77ea..9d6636e84e8ccb53f30654fbba535e2f643357e8 100644 (file)
 #include "gns.h"
 
 
+/**
+ * How deep do we allow recursions to go before we abort?
+ */
+#define MAX_RECURSION 256
+
+
 /**
  * Handle to a DNS intercepted
  * reslution request
@@ -347,6 +353,7 @@ handle_dns_request (void *cls,
                                        p->queries[0].type,
                                        p->queries[0].name,
                                        GNUNET_NO,
+                                       MAX_RECURSION,
                                        &reply_to_dns, ilh);
     return;
   }
index 2c2263e585465b46f39ca3039e5f7c3264b4ab67..735742283587d14133e47f3772a57e497e9d53a9 100644 (file)
  */
 #define DHT_GNS_REPLICATION_LEVEL 10
 
-/**
- * How deep do we allow recursions to go before we abort?
- */
-#define MAX_RECURSION 256
-
 
 /**
  * DLL to hold the authority chain we had to pass in the resolution
@@ -320,7 +315,7 @@ struct GNS_ResolverHandle
   /**
    * closure passed to @e proc
    */
-  void*proc_cls;
+  void *proc_cls;
 
   /**
    * Handle for DHT lookups. should be NULL if no lookups are in progress
@@ -395,7 +390,7 @@ struct GNS_ResolverHandle
   struct DnsResult *dns_result_tail;
 
   /**
-   * Current offset in 'name' where we are resolving.
+   * Current offset in @e name where we are resolving.
    */
   size_t name_resolution_pos;
 
@@ -423,11 +418,16 @@ struct GNS_ResolverHandle
 
   /**
    * We increment the loop limiter for each step in a recursive
-   * resolution.  If it passes our threshold (i.e. due to
+   * resolution.  If it passes our @e loop_threshold (i.e. due to
    * self-recursion in the resolution, i.e CNAME fun), we stop.
    */
   unsigned int loop_limiter;
 
+  /**
+   * Maximum value of @e loop_limiter allowed by client.
+   */
+  unsigned int loop_threshold;
+
   /**
    * 16 bit random ID we used in the @e dns_request.
    */
@@ -1856,6 +1856,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
     gp->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY;
     gp->rh->options = GNUNET_GNS_LO_DEFAULT;
     gp->rh->loop_limiter = rh->loop_limiter + 1;
+    gp->rh->loop_threshold = rh->loop_threshold;
     gp->rh->task_id
       = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
                                   gp->rh);
@@ -2744,7 +2745,7 @@ recursive_resolution (void *cls)
   struct GNS_ResolverHandle *rh = cls;
 
   rh->task_id = NULL;
-  if (MAX_RECURSION < rh->loop_limiter++)
+  if (rh->loop_threshold < rh->loop_limiter++)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Encountered unbounded recursion resolving `%s'\n",
@@ -2840,6 +2841,8 @@ start_resolver_lookup (void *cls)
  * @param record_type the record type to look up
  * @param name the name to look up
  * @param options local options to control local lookup
+ * @param recursion_depth_limit how many zones to traverse
+ *        at most
  * @param proc the processor to call on result
  * @param proc_cls the closure to pass to @a proc
  * @return handle to cancel operation
@@ -2849,6 +2852,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
                      uint32_t record_type,
                      const char *name,
                      enum GNUNET_GNS_LocalOptions options,
+                     uint16_t recursion_depth_limit,
                      GNS_ResultProcessor proc,
                      void *proc_cls)
 {
@@ -2868,6 +2872,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
   rh->record_type = record_type;
   rh->name = GNUNET_strdup (name);
   rh->name_resolution_pos = strlen (name);
+  rh->loop_threshold = recursion_depth_limit;
   rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
                                           rh);
   return rh;
index cc918fd901e0a631caffca4072b89aa0f5b15588..3dab3c91ae1ecadfa464e7bfd09e91608846fe2c 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009-2013 GNUnet e.V.
+     Copyright (C) 2009-2020 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
@@ -79,6 +79,8 @@ typedef void
  * @param record_type the record type to look up
  * @param name the name to look up
  * @param options options set to control local lookup
+ * @param recursion_depth_limit how many zones to traverse
+ *        at most
  * @param proc the processor to call
  * @param proc_cls the closure to pass to @a proc
  * @return handle to cancel operation
@@ -88,6 +90,7 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
                      uint32_t record_type,
                      const char *name,
                      enum GNUNET_GNS_LocalOptions options,
+                     uint16_t recursion_depth_limit,
                      GNS_ResultProcessor proc,
                      void *proc_cls);
 
index c81f8e7d8f4f59dd24ef95bc499ad2547894d178..b53f2420dec059c0e807e34bf8f097553c547434 100644 (file)
@@ -9,17 +9,6 @@ EXTRA_DIST = \
   block_dns.h \
   block_regex.h
 
-if TALER_ONLY
-gnunetinclude_HEADERS = \
-  platform.h gettext.h \
-  gnunet_common.h \
-  gnunet_container_lib.h \
-  gnunet_crypto_lib.h \
-  gnunet_strings_lib.h \
-  gnunet_time_lib.h \
-  gnunet_util_taler_wallet_lib.h
-else
-
 gnunetinclude_HEADERS = \
   platform.h gettext.h \
   compat.h \
@@ -35,6 +24,7 @@ gnunetinclude_HEADERS = \
   gnunet_block_lib.h \
   gnunet_block_group_lib.h \
   gnunet_block_plugin.h \
+  gnunet_buffer_lib.h \
   gnunet_client_lib.h \
   gnunet_common.h \
   gnunet_constants.h \
@@ -101,7 +91,7 @@ gnunetinclude_HEADERS = \
   gnunet_regex_service.h \
   gnunet_rest_lib.h \
   gnunet_rest_plugin.h \
-       gnunet_rps_service.h \
+  gnunet_rps_service.h \
   gnunet_revocation_service.h \
   gnunet_scalarproduct_service.h \
   gnunet_scheduler_lib.h \
@@ -130,5 +120,3 @@ gnunetinclude_HEADERS = \
   gnunet_tun_lib.h \
   gnunet_util_lib.h \
   gnunet_vpn_service.h
-
-endif
diff --git a/src/include/gnunet_buffer_lib.h b/src/include/gnunet_buffer_lib.h
new file mode 100644 (file)
index 0000000..c0ae06d
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2020 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
+ */
+
+/**
+ * Common buffer management functions.
+ *
+ * @author Florian Dold
+ */
+
+#ifndef GNUNET_BUFFER_LIB_H
+#define GNUNET_BUFFER_LIB_H
+
+/**
+ * Dynamically growing buffer.  Can be used to construct
+ * strings and other objects with dynamic size.
+ *
+ * This structure should, in most cases, be stack-allocated and
+ * zero-initialized, like:
+ *
+ *   struct GNUNET_Buffer my_buffer = { 0 };
+ */
+struct GNUNET_Buffer
+{
+  /**
+   * Capacity of the buffer.
+   */
+  size_t capacity;
+
+  /**
+   * Current write position.
+   */
+  size_t position;
+
+  /**
+   * Backing memory.
+   */
+  char *mem;
+
+  /**
+   * Log a warning if the buffer is grown over its initially allocated capacity.
+   */
+  int warn_grow;
+};
+
+
+/**
+ * Initialize a buffer with the given capacity.
+ *
+ * When a buffer is allocated with this function, a warning is logged
+ * when the buffer exceeds the initial capacity.
+ *
+ * @param buf the buffer to initialize
+ * @param capacity the capacity (in bytes) to allocate for @a buf
+ */
+void
+GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity);
+
+
+/**
+ * Make sure that at least @a n bytes remaining in the buffer.
+ *
+ * @param buf buffer to potentially grow
+ * @param n number of bytes that should be available to write
+ */
+void
+GNUNET_buffer_ensure_remaining (struct GNUNET_Buffer *buf, size_t n);
+
+
+/**
+ * Write bytes to the buffer.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf buffer to write to
+ * @param data data to read from
+ * @param len number of bytes to copy from @a data to @a buf
+ *
+ */
+void
+GNUNET_buffer_write (struct GNUNET_Buffer *buf, const char *data, size_t len);
+
+
+/**
+ * Write a 0-terminated string to a buffer, excluding the 0-terminator.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf the buffer to write to
+ * @param str the string to write to @a buf
+ */
+void
+GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str);
+
+
+/**
+ * Write a path component to a buffer, ensuring that
+ * there is exactly one slash between the previous contents
+ * of the buffer and the new string.
+ *
+ * @param buf buffer to write to
+ * @param str string containing the new path component
+ */
+void
+GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str);
+
+
+/**
+ * Write a 0-terminated formatted string to a buffer, excluding the
+ * 0-terminator.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf the buffer to write to
+ * @param fmt format string
+ * @param ... format arguments
+ */
+void
+GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...);
+
+
+/**
+ * Write a 0-terminated formatted string to a buffer, excluding the
+ * 0-terminator.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf the buffer to write to
+ * @param fmt format string
+ * @param args format argument list
+ */
+void
+GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf, const char *fmt, va_list
+                          args);
+
+
+/**
+ * Clear the buffer and return the string it contained.
+ * The caller is responsible to eventually #GNUNET_free
+ * the returned string.
+ *
+ * The returned string is always 0-terminated.
+ *
+ * @param buf the buffer to reap the string from
+ * @returns the buffer contained in the string
+ */
+char *
+GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf);
+
+
+/**
+ * Free the backing memory of the given buffer.
+ * Does not free the memory of the buffer control structure,
+ * which is typically stack-allocated.
+ */
+void
+GNUNET_buffer_clear (struct GNUNET_Buffer *buf);
+
+
+#endif
index 48eb7e490bd9f4a4b34996775e113cfdb454b5ac..8e981e91e7630c6a6fdf2321d34bf55075fa8398 100644 (file)
@@ -164,7 +164,7 @@ GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx);
 
 
 /**
- * Run the main event loop for the Taler interaction.
+ * Run the main event loop for the HTTP interaction.
  *
  * @param ctx the library context
  * @param rp parses the raw response returned from
index 5d2b7246a2bbda93f536d0baee01aecd52bcb46f..ef81e9a8831145d13479a4eea655c2d3e9ee5650 100644 (file)
@@ -146,6 +146,31 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
                    void *proc_cls);
 
 
+/**
+ * Perform an asynchronous lookup operation on the GNS.
+ *
+ * @param handle handle to the GNS service
+ * @param name the name to look up (in UTF-8 encoding)
+ * @param zone zone to look in
+ * @param type the GNS record type to look for
+ * @param options local options for the lookup
+ * @param recursion_depth_limit maximum number of zones
+ *        that the lookup may (still) traverse
+ * @param proc function to call on result
+ * @param proc_cls closure for @a proc
+ * @return handle to the queued request
+ */
+struct GNUNET_GNS_LookupRequest *
+GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle,
+                           const char *name,
+                           const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
+                           uint32_t type,
+                           enum GNUNET_GNS_LocalOptions options,
+                           uint16_t recursion_depth_limit,
+                           GNUNET_GNS_LookupResultProcessor proc,
+                           void *proc_cls);
+
+
 /**
  * Cancel pending lookup request
  *
index 3a49d98b9fc286ba0081812c984a6d56765d4941..797c713809d1f1742f29d1b954630ef1dbd6d52b 100644 (file)
@@ -140,6 +140,17 @@ extern "C" {
  */
 #define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT 65553
 
+/**
+ * Record type for reclaim identity attestation
+ */
+#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR 65554
+
+/**
+ * Record type for reclaim identity references
+ */
+#define GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE 65555
+
+
 /**
  * Flags that can be set for a record.
  */
index cd7cb50dea5d5ca9e2fd108b5235fb2e8f7c124c..8091fb3671af8ba01503ba119d19614cd3566b64 100644 (file)
@@ -2714,6 +2714,14 @@ extern "C" {
 
 #define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE 976
 
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE 977
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE 978
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT 979
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE 980
+
 /**************************************************
  *
  * ABD MESSAGE TYPES
@@ -3301,6 +3309,9 @@ extern "C" {
 /**
  * Next available: 1500
  */
+#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE 1500
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT 1501
 
 
 /**
index 4563a5f67ea17e7b03e705cee6b31db889e2ce41..004f2bd10cf2a3b3d41d3d4295b14f9020be51c9 100644 (file)
@@ -50,6 +50,15 @@ extern "C" {
  */
 #define GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING 1
 
+/**
+* No value attestation.
+*/
+#define GNUNET_RECLAIM_ATTESTATION_TYPE_NONE 10
+
+/**
+* A JSON Web Token attestation.
+*/
+#define GNUNET_RECLAIM_ATTESTATION_TYPE_JWT 11
 
 /**
  * An attribute.
@@ -66,10 +75,49 @@ struct GNUNET_RECLAIM_ATTRIBUTE_Claim
    */
   uint32_t type;
 
+  /**
+   * Flags
+   */
+  uint32_t flag;
+  /**
+   * The name of the attribute. Note "name" must never be individually
+   * free'd
+   */
+  const char *name;
+
+  /**
+   * Number of bytes in @e data.
+   */
+  size_t data_size;
+
+  /**
+   * Binary value stored as attribute value.  Note: "data" must never
+   * be individually 'malloc'ed, but instead always points into some
+   * existing data area.
+   */
+  const void *data;
+};
+
+/**
+ * An attestation.
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim
+{
+  /**
+   * ID
+   */
+  uint64_t id;
+
+  /**
+   * Type/Format of Claim
+   */
+  uint32_t type;
+
   /**
    * Version
    */
   uint32_t version;
+
   /**
    * The name of the attribute. Note "name" must never be individually
    * free'd
@@ -89,6 +137,33 @@ struct GNUNET_RECLAIM_ATTRIBUTE_Claim
   const void *data;
 };
 
+/**
+ * A reference to an Attestatiom.
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE
+{
+  /**
+   * ID
+   */
+  uint64_t id;
+
+  /**
+   * Referenced ID of Attestation
+   */
+  uint64_t id_attest;
+
+  /**
+   * The name of the attribute/attestation reference value. Note "name" must never be individually
+   * free'd
+   */
+  const char *name;
+
+  /**
+   * The name of the attribute/attestation reference value. Note "name" must never be individually
+   * free'd
+   */
+  const char *reference_value;
+};
 
 /**
  * A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
@@ -123,6 +198,20 @@ struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry
    * The attribute claim
    */
   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+  /**
+   * The attestation claim
+   */
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+  /**
+  * The reference
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
+};
+
+struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType
+{
+  uint32_t type;
 };
 
 
@@ -203,6 +292,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size);
 
+/**
+ * Count attestations in claim list
+ *
+ * @param attrs list
+ */
+int
+GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (
+  const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
 
 /**
  * Get required size for serialization buffer
@@ -299,6 +396,154 @@ GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
 const char *
 GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type);
 
+/**
+   * Get required size for serialization buffer
+   * FIXME:
+   * 1. The naming convention is violated here.
+   * It should GNUNET_RECLAIM_ATTRIBUTE_<lowercase from here>.
+   * It might make sense to refactor attestations into a separate folder.
+   * 2. The struct should be called GNUNET_RECLAIM_ATTESTATION_Data or
+   * GNUNET_RECLAIM_ATTRIBUTE_Attestation depending on location in source.
+   *
+   * @param attr the attestation to serialize
+   * @return the required buffer size
+   */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr);
+
+
+/**
+ * Serialize an attestation
+ *
+ * @param attr the attestation to serialize
+ * @param result the serialized attestation
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  char *result);
+
+
+/**
+ * Deserialize an attestation
+ *
+ * @param data the serialized attestation
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size);
+
+
+/**
+   * Create a new attestation.
+   *
+   * @param attr_name the attestation name
+   * @param type the attestation type
+   * @param data the attestation value
+   * @param data_size the attestation value size
+   * @return the new attestation
+   */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
+                                      uint32_t type,
+                                      const void *data,
+                                      size_t data_size);
+
+/**
+ * Convert the 'claim' of an attestation to a string
+ *
+ * @param type the type of attestation
+ * @param data claim in binary encoding
+ * @param data_size number of bytes in @a data
+ * @return NULL on error, otherwise human-readable representation of the claim
+ */
+char *
+GNUNET_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
+                                            const void *data,
+                                            size_t data_size);
+
+/**
+ * Convert human-readable version of a 'claim' of an attestation to the binary
+ * representation
+ *
+ * @param type type of the claim
+ * @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
+ */
+int
+GNUNET_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
+                                            const char *s,
+                                            void **data,
+                                            size_t *data_size);
+
+/**
+ * Convert an attestation type number to the corresponding attestation type string
+ *
+ * @param type number of a type
+ * @return corresponding typestring, NULL on error
+ */
+const char *
+GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type);
+
+/**
+ * Convert an attestation type name to the corresponding number
+ *
+ * @param typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+uint32_t
+GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename);
+
+/**
+ * Create a new attestation reference.
+ *
+ * @param attr_name the referenced claim name
+ * @param ref_value the claim name in the attestation
+ * @return the new reference
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
+                                          const char *ref_value);
+
+
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the reference to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr);
+
+/**
+ * Serialize a reference
+ *
+ * @param attr the reference to serialize
+ * @param result the serialized reference
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  char *result);
+
+/**
+ * Deserialize a reference
+ *
+ * @param data the serialized reference
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t data_size);
 
 #if 0 /* keep Emacsens' auto-indent happy */
 {
index 26a4bb4f2dda01edb1ec488bbc9159f1eda4e38d..e61cca5b22f420799669e521eea019732e34add2 100644 (file)
@@ -134,6 +134,33 @@ struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions
    * Number to typename.
    */
   GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename;
+
+  /**
+   * FIXME: It is odd that attestation functions are withing the attribute
+   * plugin. An attribute type may be backed by an attestation, but not
+   * necessarily.
+   * Maybe it would make more sense to refactor this into an attestation
+   * plugin?
+   *
+   * Attestation Conversion to string.
+   */
+  GNUNET_RECLAIM_ATTRIBUTE_ValueToStringFunction value_to_string_attest;
+
+  /**
+  * Attestation Conversion to binary.
+  */
+  GNUNET_RECLAIM_ATTRIBUTE_StringToValueFunction string_to_value_attest;
+
+  /**
+  * Attestation Typename to number.
+  */
+  GNUNET_RECLAIM_ATTRIBUTE_TypenameToNumberFunction typename_to_number_attest;
+
+  /**
+  * Attestation Number to typename.
+  */
+  GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename_attest;
+
 };
 
 
index 237d791d9aed02c4e28a346ee89781f21a91767f..214cdba690dc7ff2f4979e779bd7dfcd681e96a4 100644 (file)
@@ -117,7 +117,9 @@ typedef void (*GNUNET_RECLAIM_ContinuationWithStatus) (void *cls,
  */
 typedef void (*GNUNET_RECLAIM_AttributeResult) (
   void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr);
+  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference);
 
 
 /**
@@ -151,6 +153,28 @@ GNUNET_RECLAIM_attribute_store (
   GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls);
 
 
+/**
+   * Store an attestation.  If the attestation is already present,
+   * it is replaced with the new attestation.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey private key of the identity
+   * @param attr the attestation value
+   * @param exp_interval the relative expiration interval for the attestation
+   * @param cont continuation to call when done
+   * @param cont_cls closure for @a cont
+   * @return handle to abort the request
+   */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_store (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  const struct GNUNET_TIME_Relative *exp_interval,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls);
+
+
 /**
  * Delete an attribute. Tickets used to share this attribute are updated
  * accordingly.
@@ -169,7 +193,43 @@ GNUNET_RECLAIM_attribute_delete (
   const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
   GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls);
 
+/**
+ * Delete an attestation. Tickets used to share this attestation are updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to add an attribute to
+ * @param attr The attestation
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls);
 
+/**
+ * Delete an attestation reference. Tickets used to share this reference are updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to delete the reference from
+ * @param attr The reference
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls);
 /**
  * List all attributes for a local identity.
  * This MUST lock the `struct GNUNET_RECLAIM_Handle`
@@ -202,6 +262,26 @@ GNUNET_RECLAIM_get_attributes_start (
   GNUNET_RECLAIM_AttributeResult proc, void *proc_cls,
   GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls);
 
+/**
+   * Store an attestation reference.  If the reference is already present,
+   * it is replaced with the new reference.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey private key of the identity
+   * @param attr the reference value
+   * @param exp_interval the relative expiration interval for the reference
+   * @param cont continuation to call when done
+   * @param cont_cls closure for @a cont
+   * @return handle to abort the request
+   */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_store (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  const struct GNUNET_TIME_Relative *exp_interval,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls);
 
 /**
  * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
diff --git a/src/include/gnunet_util_taler_wallet_lib.h b/src/include/gnunet_util_taler_wallet_lib.h
deleted file mode 100644 (file)
index a036824..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-      This file is part of GNUnet
-      Copyright (C) 2009, 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 Christian Grothoff
- *
- * @file
- * Convenience header including all headers of subsystems in
- * gnunet_util_taler_wallet library.  Note that (due to the structure of the
- * original headers), not all symbols declared by the included headers are
- * actually included in the gnunet_util_taler_wallet library!  The library
- * excludes anything relating to the GNUnet installation location, scheduler,
- * networking or OS-specific logic that would not apply to Apps/Browser
- * extensions.
- */
-
-#ifndef GNUNET_UTIL_TALER_WALLET_LIB_H
-#define GNUNET_UTIL_TALER_WALLET_LIB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include "gnunet_crypto_lib.h"
-#include "gnunet_container_lib.h"
-#include "gnunet_strings_lib.h"
-
-#if 0                           /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif
index bb60909d92ae0f3bda61d8f54ee03094d54f7c1c..ade2a27bbddbd29fec83459e81a74d8b54c74cb3 100644 (file)
@@ -90,6 +90,63 @@ gnuid_string_to_value (void *cls,
   }
 }
 
+/**
+   * Convert the 'value' of an attestation to a string.
+   *
+   * @param cls closure, unused
+   * @param type type of the attestation
+   * @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 *
+gnuid_value_to_string_attest (void *cls,
+                              uint32_t type,
+                              const void *data,
+                              size_t data_size)
+{
+  switch (type)
+  {
+  case GNUNET_RECLAIM_ATTESTATION_TYPE_JWT:
+    return GNUNET_strndup (data, data_size);
+
+  default:
+    return NULL;
+  }
+}
+
+
+/**
+ * Convert human-readable version of a 'value' of an attestation to the binary
+ * representation.
+ *
+ * @param cls closure, unused
+ * @param type type of the attestation
+ * @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
+gnuid_string_to_value_attest (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_ATTESTATION_TYPE_JWT:
+    *data = GNUNET_strdup (s);
+    *data_size = strlen (s);
+    return GNUNET_OK;
+
+  default:
+    return GNUNET_SYSERR;
+  }
+}
 
 /**
  * Mapping of attribute type numbers to human-readable
@@ -102,6 +159,16 @@ static struct
 } gnuid_name_map[] = { { "STRING", GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING },
                        { NULL, UINT32_MAX } };
 
+/**
+ * Mapping of attestation type numbers to human-readable
+ * attestation type names.
+ */
+static struct
+{
+  const char *name;
+  uint32_t number;
+} gnuid_attest_name_map[] = { { "JWT", GNUNET_RECLAIM_ATTESTATION_TYPE_JWT },
+                              { NULL, UINT32_MAX } };
 
 /**
  * Convert a type name to the corresponding number.
@@ -141,6 +208,44 @@ gnuid_number_to_typename (void *cls, uint32_t type)
   return gnuid_name_map[i].name;
 }
 
+/**
+   * Convert a type name to the corresponding number.
+   *
+   * @param cls closure, unused
+   * @param gnuid_typename name to convert
+   * @return corresponding number, UINT32_MAX on error
+   */
+static uint32_t
+gnuid_typename_to_number_attest (void *cls, const char *gnuid_typename)
+{
+  unsigned int i;
+
+  i = 0;
+  while ((NULL != gnuid_attest_name_map[i].name) &&
+         (0 != strcasecmp (gnuid_typename, gnuid_attest_name_map[i].name)))
+    i++;
+  return gnuid_attest_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 *
+gnuid_number_to_typename_attest (void *cls, uint32_t type)
+{
+  unsigned int i;
+
+  i = 0;
+  while ((NULL != gnuid_attest_name_map[i].name) && (type !=
+                                                     gnuid_attest_name_map[i].
+                                                     number))
+    i++;
+  return gnuid_attest_name_map[i].name;
+}
 
 /**
  * Entry point for the plugin.
@@ -158,6 +263,10 @@ libgnunet_plugin_reclaim_attribute_gnuid_init (void *cls)
   api->string_to_value = &gnuid_string_to_value;
   api->typename_to_number = &gnuid_typename_to_number;
   api->number_to_typename = &gnuid_number_to_typename;
+  api->value_to_string_attest = &gnuid_value_to_string_attest;
+  api->string_to_value_attest = &gnuid_string_to_value_attest;
+  api->typename_to_number_attest = &gnuid_typename_to_number_attest;
+  api->number_to_typename_attest = &gnuid_number_to_typename_attest;
   return api;
 }
 
index b81394ad28413f1966b14f7b80b5881264ed13c4..43199c1081770af61817513b0bd1e4190f69b7ac 100644 (file)
@@ -217,6 +217,116 @@ GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
   return NULL;
 }
 
+/**
+   * Convert an attestation type name to the corresponding number
+   *
+   * @param typename name to convert
+   * @return corresponding number, UINT32_MAX on error
+   */
+uint32_t
+GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+  uint32_t ret;
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (UINT32_MAX !=
+        (ret = plugin->api->typename_to_number_attest (plugin->api->cls,
+                                                       typename)))
+      return ret;
+  }
+  return UINT32_MAX;
+}
+
+/**
+ * Convert an attestation type number to the corresponding attestation type string
+ *
+ * @param type number of a type
+ * @return corresponding typestring, NULL on error
+ */
+const char *
+GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+  const char *ret;
+
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (NULL !=
+        (ret = plugin->api->number_to_typename_attest (plugin->api->cls, type)))
+      return ret;
+  }
+  return NULL;
+}
+/**
+ * Convert human-readable version of a 'claim' of an attestation to the binary
+ * representation
+ *
+ * @param type type of the claim
+ * @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
+ */
+int
+GNUNET_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
+                                            const char *s,
+                                            void **data,
+                                            size_t *data_size)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (GNUNET_OK == plugin->api->string_to_value_attest (plugin->api->cls,
+                                                          type,
+                                                          s,
+                                                          data,
+                                                          data_size))
+      return GNUNET_OK;
+  }
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Convert the 'claim' of an attestation to a string
+ *
+ * @param type the type of attestation
+ * @param data claim in binary encoding
+ * @param data_size number of bytes in @a data
+ * @return NULL on error, otherwise human-readable representation of the claim
+ */
+char *
+GNUNET_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
+                                            const void *data,
+                                            size_t data_size)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+  char *ret;
+
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (NULL != (ret = plugin->api->value_to_string_attest (plugin->api->cls,
+                                                            type,
+                                                            data,
+                                                            data_size)))
+      return ret;
+  }
+  return NULL;
+}
 
 /**
  * Create a new attribute.
@@ -243,6 +353,42 @@ GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
                         + strlen (attr_name_tmp) + 1 + data_size);
   attr->type = type;
   attr->data_size = data_size;
+  attr->flag = 0;
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
+  attr->name = write_ptr;
+  write_ptr += strlen (attr->name) + 1;
+  GNUNET_memcpy (write_ptr, data, data_size);
+  attr->data = write_ptr;
+  GNUNET_free (attr_name_tmp);
+  return attr;
+}
+
+/**
+   * Create a new attestation.
+   *
+   * @param attr_name the attestation name
+   * @param type the attestation type
+   * @param data the attestation value
+   * @param data_size the attestation value size
+   * @return the new attestation
+   */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
+                                      uint32_t type,
+                                      const void *data,
+                                      size_t data_size)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+  char *write_ptr;
+  char *attr_name_tmp = GNUNET_strdup (attr_name);
+
+  GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
+
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
+                        + strlen (attr_name_tmp) + 1 + data_size);
+  attr->type = type;
+  attr->data_size = data_size;
   attr->version = 0;
   write_ptr = (char *) &attr[1];
   GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
@@ -254,6 +400,40 @@ GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
   return attr;
 }
 
+/**
+ * Create a new attestation reference.
+ *
+ * @param attr_name the referenced claim name
+ * @param ref_value the claim name in the attestation
+ * @return the new reference
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
+                                          const char *ref_value)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  char *write_ptr;
+  char *attr_name_tmp = GNUNET_strdup (attr_name);
+  char *ref_value_tmp = GNUNET_strdup (ref_value);
+
+  GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
+  GNUNET_STRINGS_utf8_tolower (ref_value, ref_value_tmp);
+
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE)
+                        + strlen (attr_name_tmp) + strlen (ref_value_tmp) + 2);
+
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
+  attr->name = write_ptr;
+
+  write_ptr += strlen (attr_name) + 1;
+  GNUNET_memcpy (write_ptr, ref_value_tmp, strlen (ref_value_tmp) + 1);
+  attr->reference_value = write_ptr;
+
+  GNUNET_free (attr_name_tmp);
+  GNUNET_free (ref_value_tmp);
+  return attr;
+}
 
 /**
  * Add a new attribute to a claim list
@@ -296,7 +476,30 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (
   size_t len = 0;
 
   for (le = attrs->list_head; NULL != le; le = le->next)
-    len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
+  {
+    if (NULL != le->claim)
+    {
+      len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
+    }
+    else if (NULL != le->attest )
+    {
+      len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len += GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest);
+    }
+    else if (NULL != le->reference)
+    {
+      len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len += GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (le->reference);
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unserialized Claim List Entry Type for size not known.\n");
+      break;
+    }
+    len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+  }
   return len;
 }
 
@@ -317,14 +520,50 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
   size_t len;
   size_t total_len;
   char *write_ptr;
-
   write_ptr = result;
   total_len = 0;
   for (le = attrs->list_head; NULL != le; le = le->next)
   {
-    len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr);
-    total_len += len;
-    write_ptr += len;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type;
+    if (NULL != le->claim)
+    {
+      list_type = (struct
+                   GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
+      list_type->type = htons (1);
+      total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr);
+      total_len += len;
+      write_ptr += len;
+    }
+    else if (NULL != le->attest )
+    {
+      list_type = (struct
+                   GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
+      list_type->type = htons (2);
+      total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len = GNUNET_RECLAIM_ATTESTATION_serialize (le->attest, write_ptr);
+      total_len += len;
+      write_ptr += len;
+    }
+    else if (NULL != le->reference)
+    {
+      list_type = (struct
+                   GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
+      list_type->type = htons (3);
+      total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len = GNUNET_RECLAIM_ATTESTATION_REF_serialize (le->reference, write_ptr);
+      total_len += len;
+      write_ptr += len;
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unserialized Claim List Entry Type not known.\n");
+      continue;
+    }
   }
   return total_len;
 }
@@ -345,23 +584,75 @@ GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size)
   size_t attr_len;
   const char *read_ptr;
 
-  if (data_size < sizeof(struct Attribute))
+  if ((data_size < sizeof(struct Attribute) + sizeof(struct
+                                                     GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry))
+      && (data_size < sizeof(struct
+                             Attestation)
+          + sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) &&
+      (data_size < sizeof(struct Attestation_Reference) + sizeof(struct
+                                                                 GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) )
     return NULL;
 
   attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
   read_ptr = data;
   while (((data + data_size) - read_ptr) >= sizeof(struct Attribute))
   {
-    le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-    le->claim =
-      GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
-                                            data_size - (read_ptr - data));
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Deserialized attribute %s\n",
-                le->claim->name);
-    GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
-    attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
-    read_ptr += attr_len;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type;
+    list_type = (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) read_ptr;
+    if (1 == ntohs (list_type->type))
+    {
+      le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      if (((data + data_size) - read_ptr) < sizeof(struct Attribute))
+        break;
+      le->attest = NULL;
+      le->reference = NULL;
+      le->claim =
+        GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
+                                              data_size - (read_ptr - data));
+      GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
+      attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
+      read_ptr += attr_len;
+    }
+    else if (2 == ntohs (list_type->type))
+    {
+      le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      if (((data + data_size) - read_ptr) < sizeof(struct Attestation))
+        break;
+      le->claim = NULL;
+      le->reference = NULL;
+      le->attest =
+        GNUNET_RECLAIM_ATTESTATION_deserialize (read_ptr,
+                                                data_size - (read_ptr - data));
+      GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
+      attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest);
+      read_ptr += attr_len;
+    }
+    else if (3 == ntohs (list_type->type))
+    {
+      le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      if (((data + data_size) - read_ptr) < sizeof(struct
+                                                   Attestation_Reference))
+        break;
+      le->claim = NULL;
+      le->attest = NULL;
+      le->reference =
+        GNUNET_RECLAIM_ATTESTATION_REF_deserialize (read_ptr,
+                                                    data_size - (read_ptr
+                                                                 - data));
+      GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
+      attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+        le->reference);
+      read_ptr += attr_len;
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Serialized Claim List Entry Type not known.\n");
+      break;
+    }
   }
   return attrs;
 }
@@ -381,16 +672,45 @@ GNUNET_RECLAIM_ATTRIBUTE_list_dup (
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result;
 
   result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
+  if (NULL == attrs->list_head)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Duplicating empty List\n");
+  }
   for (le = attrs->list_head; NULL != le; le = le->next)
   {
     result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-    result_le->claim =
-      GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
-                                          le->claim->type,
-                                          le->claim->data,
-                                          le->claim->data_size);
-    result_le->claim->version = le->claim->version;
-    result_le->claim->id = le->claim->id;
+    result_le->claim = NULL;
+    result_le->attest = NULL;
+    result_le->reference = NULL;
+    if (NULL != le->claim)
+    {
+      result_le->claim =
+        GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
+                                            le->claim->type,
+                                            le->claim->data,
+                                            le->claim->data_size);
+
+      result_le->claim->id = le->claim->id;
+      result_le->claim->flag = le->claim->flag;
+    }
+    if ( NULL != le->attest)
+    {
+      result_le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (
+        le->attest->name,
+        le->attest->type,
+        le->attest->data,
+        le->attest->
+        data_size);
+      result_le->attest->id = le->attest->id;
+    }
+    if (NULL !=le->reference)
+    {
+      result_le->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (
+        le->reference->name,
+        le->reference->reference_value);
+      result_le->reference->id = le->reference->id;
+      result_le->reference->id_attest = le->reference->id_attest;
+    }
     GNUNET_CONTAINER_DLL_insert (result->list_head,
                                  result->list_tail,
                                  result_le);
@@ -411,9 +731,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le;
 
-  for (le = attrs->list_head; NULL != le;)
+  for (le = attrs->list_head; NULL != le; le = le->next)
   {
-    GNUNET_free (le->claim);
+    if (NULL != le->claim)
+      GNUNET_free (le->claim);
+    if (NULL != le->attest)
+      GNUNET_free (le->attest);
+    if (NULL != le->reference)
+      GNUNET_free (le->reference);
     tmp_le = le;
     le = le->next;
     GNUNET_free (tmp_le);
@@ -421,7 +746,24 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
   GNUNET_free (attrs);
 }
 
-
+/**
+ * Count attestations in claim list
+ *
+ * @param attrs list
+ */
+int
+GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (
+  const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
+{
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
+  int i = 0;
+  for (le = attrs->list_head; NULL != le; le = le->next)
+  {
+    if (NULL != le->attest)
+      i++;
+  }
+  return i;
+}
 /**
  * Get required size for serialization buffer
  *
@@ -455,7 +797,7 @@ GNUNET_RECLAIM_ATTRIBUTE_serialize (
 
   attr_ser = (struct Attribute *) result;
   attr_ser->attribute_type = htons (attr->type);
-  attr_ser->attribute_version = htonl (attr->version);
+  attr_ser->attribute_version = htonl (attr->flag);
   attr_ser->attribute_id = GNUNET_htonll (attr->id);
   name_len = strlen (attr->name);
   attr_ser->name_len = htons (name_len);
@@ -505,7 +847,7 @@ GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, size_t data_size)
   attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim)
                         + data_len + name_len + 1);
   attr->type = ntohs (attr_ser->attribute_type);
-  attr->version = ntohl (attr_ser->attribute_version);
+  attr->flag = ntohl (attr_ser->attribute_version);
   attr->id = GNUNET_ntohll (attr_ser->attribute_id);
   attr->data_size = data_len;
 
@@ -521,4 +863,193 @@ GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, size_t data_size)
 }
 
 
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the attestation to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr)
+{
+  return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
+}
+
+/**
+ * Serialize an attestation
+ *
+ * @param attr the attestation to serialize
+ * @param result the serialized attestation
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  char *result)
+{
+  size_t data_len_ser;
+  size_t name_len;
+  struct Attestation *attr_ser;
+  char *write_ptr;
+
+  attr_ser = (struct Attestation *) result;
+  attr_ser->attestation_type = htons (attr->type);
+  attr_ser->attestation_version = htonl (attr->version);
+  attr_ser->attestation_id = GNUNET_htonll (attr->id);
+  name_len = strlen (attr->name);
+  attr_ser->name_len = htons (name_len);
+  write_ptr = (char *) &attr_ser[1];
+  GNUNET_memcpy (write_ptr, attr->name, name_len);
+  write_ptr += name_len;
+  // TODO plugin-ize
+  // data_len_ser = plugin->serialize_attribute_value (attr,
+  //                                                  &attr_ser[1]);
+  data_len_ser = attr->data_size;
+  GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
+  attr_ser->data_size = htons (data_len_ser);
+
+  return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
+}
+
+/**
+ * Deserialize an attestation
+ *
+ * @param data the serialized attestation
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+  struct Attestation *attr_ser;
+  size_t data_len;
+  size_t name_len;
+  char *write_ptr;
+
+  if (data_size < sizeof(struct Attestation))
+    return NULL;
+
+  attr_ser = (struct Attestation *) data;
+  data_len = ntohs (attr_ser->data_size);
+  name_len = ntohs (attr_ser->name_len);
+  if (data_size < sizeof(struct Attestation) + data_len + name_len)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Buffer too small to deserialize\n");
+    return NULL;
+  }
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
+                        + data_len + name_len + 1);
+  attr->type = ntohs (attr_ser->attestation_type);
+  attr->version = ntohl (attr_ser->attestation_version);
+  attr->id = GNUNET_ntohll (attr_ser->attestation_id);
+  attr->data_size = data_len;
+
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
+  write_ptr[name_len] = '\0';
+  attr->name = write_ptr;
+
+  write_ptr += name_len + 1;
+  GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, attr->data_size);
+  attr->data = write_ptr;
+  return attr;
+}
+
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the reference to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr)
+{
+  return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
+    attr->reference_value);
+}
+
+
+/**
+ * Serialize a reference
+ *
+ * @param attr the reference to serialize
+ * @param result the serialized reference
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  char *result)
+{
+  size_t name_len;
+  size_t refval_len;
+  struct Attestation_Reference *attr_ser;
+  char *write_ptr;
+  attr_ser = (struct Attestation_Reference *) result;
+  attr_ser->reference_id = GNUNET_htonll (attr->id);
+  attr_ser->attestation_id = GNUNET_htonll (attr->id_attest);
+  name_len = strlen (attr->name);
+  refval_len = strlen (attr->reference_value);
+  attr_ser->name_len = htons (name_len);
+  attr_ser->ref_value_len = htons (refval_len);
+  write_ptr = (char *) &attr_ser[1];
+  GNUNET_memcpy (write_ptr, attr->name, name_len);
+  write_ptr += name_len;
+  GNUNET_memcpy (write_ptr, attr->reference_value, refval_len);
+
+  return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
+    attr->reference_value);
+}
+
+
+/**
+ * Deserialize a reference
+ *
+ * @param data the serialized reference
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t data_size)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  struct Attestation_Reference *attr_ser;
+  size_t name_len;
+  size_t refval_len;
+  char *write_ptr;
+
+  if (data_size < sizeof(struct Attestation_Reference))
+    return NULL;
+  attr_ser = (struct Attestation_Reference *) data;
+  name_len = ntohs (attr_ser->name_len);
+  refval_len = ntohs (attr_ser->ref_value_len);
+  if (data_size < sizeof(struct Attestation_Reference) + refval_len + name_len)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Buffer too small to deserialize\n");
+    return NULL;
+  }
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE)
+                        + refval_len + name_len + 2);
+
+  attr->id = GNUNET_ntohll (attr_ser->reference_id);
+  attr->id_attest = GNUNET_ntohll (attr_ser->attestation_id);
+
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
+  write_ptr[name_len] = '\0';
+  attr->name = write_ptr;
+
+  write_ptr += name_len + 1;
+  GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, refval_len);
+  write_ptr[refval_len] = '\0';
+  attr->reference_value = write_ptr;
+  return attr;
+}
 /* end of reclaim_attribute.c */
index d7358847ee53ed2585698ac0032c5cc691ac1a27..80f1e5aacfdc5c291f23cad21e24033ab6e2876e 100644 (file)
@@ -61,4 +61,66 @@ struct Attribute
   // followed by data_size Attribute value data
 };
 
+/**
+ * Serialized attestation claim
+ */
+struct Attestation
+{
+  /**
+   * Attestation type
+   */
+  uint32_t attestation_type;
+
+  /**
+   * Attestation version
+   */
+  uint32_t attestation_version;
+
+  /**
+   * Attestation ID
+   */
+  uint64_t attestation_id;
+
+  /**
+   * Name length
+   */
+  uint32_t name_len;
+
+  /**
+   * Data size
+   */
+  uint32_t data_size;
+
+  // followed by data_size Attestation value data
+};
+
+/**
+ * Serialized attestation reference
+ */
+struct Attestation_Reference
+{
+  /**
+   * Reference ID
+   */
+  uint64_t reference_id;
+
+  /**
+   * The ID of the referenced attestation
+   */
+  uint64_t attestation_id;
+
+  /**
+   * Claim Name length
+   */
+  uint32_t name_len;
+
+    /**
+   * Length of the referenced value
+   */
+  uint32_t ref_value_len;
+
+
+  // followed by the name and referenced value
+};
+
 #endif
index 58f8cd6e2d795f664b7801b5e7043c340c7aa76f..5f9170f059b38cc9d5f9ca799084bce1a77c3d2a 100644 (file)
@@ -226,7 +226,9 @@ store_attr_cont (void *cls, int32_t success, const char *emsg)
 static void
 process_attrs (void *cls,
                const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-               const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+               const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+               const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, 
+               const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   char *value_str;
   char *id;
@@ -253,7 +255,7 @@ process_attrs (void *cls,
            attr->name,
            value_str,
            attr_type,
-           attr->version,
+           attr->flag,
            id);
   GNUNET_free (id);
 }
@@ -445,7 +447,9 @@ iter_finished (void *cls)
 static void
 iter_cb (void *cls,
          const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-         const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+         const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+         const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+         const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
   char *attrs_tmp;
@@ -480,7 +484,7 @@ iter_cb (void *cls,
                                                       attr->type,
                                                       attr->data,
                                                       attr->data_size);
-      le->claim->version = attr->version;
+      le->claim->flag = attr->flag;
       le->claim->id = attr->id;
       GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
                                    attr_list->list_tail,
@@ -514,7 +518,7 @@ iter_cb (void *cls,
              attr->name,
              attr_str,
              attr_type,
-             attr->version,
+             attr->flag,
              id);
     GNUNET_free (id);
   }
index a83ea05a645f94d3a5fffc38fbda1652c190d553..556006af08f7a8beeabd6aa1755c53651e6c0b6d 100644 (file)
@@ -265,6 +265,15 @@ struct AttributeDeleteHandle
    */
   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
 
+  /**
+   * The attestation to delete
+   */
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+  /**
+  * The reference to delete
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
   /**
    * Tickets to update
    */
@@ -327,6 +336,16 @@ struct AttributeStoreHandle
    */
   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
 
+  /**
+  * The attestation to store
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+  /**
+  * The reference to store
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
+
   /**
    * The attribute expiration interval
    */
@@ -459,6 +478,10 @@ cleanup_adh (struct AttributeDeleteHandle *adh)
     GNUNET_free (adh->label);
   if (NULL != adh->claim)
     GNUNET_free (adh->claim);
+  if (NULL != adh->attest)
+    GNUNET_free (adh->attest);
+  if (NULL != adh->reference)
+    GNUNET_free (adh->reference);
   while (NULL != (le = adh->tickets_to_update_head))
   {
     GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
@@ -486,6 +509,10 @@ cleanup_as_handle (struct AttributeStoreHandle *ash)
     GNUNET_NAMESTORE_cancel (ash->ns_qe);
   if (NULL != ash->claim)
     GNUNET_free (ash->claim);
+  if (NULL != ash->attest)
+    GNUNET_free (ash->attest);
+  if (NULL != ash->reference)
+    GNUNET_free (ash->reference);
   GNUNET_free (ash);
 }
 
@@ -1022,6 +1049,478 @@ handle_attribute_store_message (void *cls,
 }
 
 
+/**
+ * Attestation store result handler
+ *
+ * @param cls our attribute store handle
+ * @param success GNUNET_OK if successful
+ * @param emsg error message (NULL if success=GNUNET_OK)
+ */
+static void
+attest_store_cont (void *cls, int32_t success, const char *emsg)
+{
+  struct AttributeStoreHandle *ash = cls;
+  struct GNUNET_MQ_Envelope *env;
+  struct SuccessResultMessage *acr_msg;
+
+  ash->ns_qe = NULL;
+  GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
+                               ash->client->store_op_tail,
+                               ash);
+
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to store attestation %s\n",
+                emsg);
+    cleanup_as_handle (ash);
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
+  env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
+  acr_msg->id = htonl (ash->r_id);
+  acr_msg->op_result = htonl (GNUNET_OK);
+  GNUNET_MQ_send (ash->client->mq, env);
+  cleanup_as_handle (ash);
+}
+
+/**
+     * Send a reference error response
+     *
+     * @param ash our attribute store handle
+     * @param success the success status
+     */
+static void
+send_ref_error (struct AttributeStoreHandle  *ash)
+{
+  struct GNUNET_MQ_Envelope *env;
+  struct SuccessResultMessage *acr_msg;
+
+  ash->ns_qe = NULL;
+  GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
+                               ash->client->store_op_tail,
+                               ash);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
+  env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
+  acr_msg->id = htonl (ash->r_id);
+  acr_msg->op_result = htonl (GNUNET_SYSERR);
+  GNUNET_MQ_send (ash->client->mq, env);
+  cleanup_as_handle (ash);
+}
+
+/**
+ * Error looking up potential attestation. Abort.
+ *
+ * @param cls our attribute store handle
+ */
+static void
+attest_error (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Failed to check for existing Attestation\n");
+  cleanup_as_handle (ash);
+  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+  return;
+}
+
+/**
+* Check for existing record before storing reference
+*
+* @param cls our attribute store handle
+* @param zone zone we are iterating
+* @param label label of the records
+* @param rd_count record count
+* @param rd records
+*/
+static void
+attest_add_cb (void *cls,
+               const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+               const char *label,
+               unsigned int rd_count,
+               const struct GNUNET_GNSRECORD_Data *rd)
+{
+  struct AttributeStoreHandle *ash = cls;
+  char *buf;
+  size_t buf_size;
+  buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
+  buf = GNUNET_malloc (buf_size);
+  GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
+  if (0 == rd_count )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Storing new Attestation\n");
+    struct GNUNET_GNSRECORD_Data rd_new[1];
+    rd_new[0].data_size = buf_size;
+    rd_new[0].data = buf;
+    rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
+    rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+    rd_new[0].expiration_time = ash->exp.rel_value_us;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
+    ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                                 &ash->identity,
+                                                 label,
+                                                 1,
+                                                 rd_new,
+                                                 &attest_store_cont,
+                                                 ash);
+    GNUNET_free (buf);
+    return;
+  }
+  if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Existing Attestation location is not an Attestation\n");
+    send_ref_error (ash);
+    return;
+  }
+  struct GNUNET_GNSRECORD_Data rd_new[rd_count];
+  for (int i = 0; i<rd_count; i++)
+  {
+    rd_new[i] = rd[i];
+  }
+  rd_new[0].data_size = buf_size;
+  rd_new[0].data = buf;
+  rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
+  rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+  rd_new[0].expiration_time = ash->exp.rel_value_us;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
+  ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &ash->identity,
+                                               label,
+                                               rd_count,
+                                               rd_new,
+                                               &attest_store_cont,
+                                               ash);
+  GNUNET_free (buf);
+}
+
+/**
+ * Add a new attestation
+ *
+ * @param cls the AttributeStoreHandle
+ */
+static void
+attest_store_task (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  char *label;
+
+  // Give the ash a new id if unset
+  if (0 == ash->attest->id)
+    ash->attest->id
+      = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
+                                               sizeof(uint64_t));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Looking up existing data under label %s\n", label);
+// Test for the content of the existing ID
+  ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
+                                                &ash->identity,
+                                                label,
+                                                &attest_error,
+                                                ash,
+                                                &attest_add_cb,
+                                                ash);
+  GNUNET_free (label);
+}
+
+/**
+ * Check an attestation store message
+ *
+ * @param cls unused
+ * @param sam the message to check
+ */
+static int
+check_attestation_store_message (void *cls,
+                                 const struct AttributeStoreMessage *sam)
+{
+  uint16_t size;
+
+  size = ntohs (sam->header.size);
+  if (size <= sizeof(struct AttributeStoreMessage))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+/**
+* Handle an attestation store message
+*
+* @param cls our client
+* @param sam the message to handle
+*/
+static void
+handle_attestation_store_message (void *cls,
+                                  const struct AttributeStoreMessage *sam)
+{
+  struct AttributeStoreHandle *ash;
+  struct IdpClient *idp = cls;
+  size_t data_len;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
+
+  data_len = ntohs (sam->attr_len);
+
+  ash = GNUNET_new (struct AttributeStoreHandle);
+  ash->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &sam[1],
+                                                        data_len);
+
+  ash->r_id = ntohl (sam->id);
+  ash->identity = sam->identity;
+  ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
+  GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
+
+  GNUNET_SERVICE_client_continue (idp->client);
+  ash->client = idp;
+  GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
+  GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
+}
+
+/**
+ * Error looking up potential reference value. Abort.
+ *
+ * @param cls our attribute store handle
+ */
+static void
+ref_error (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Failed to find Attestation entry for Attestation reference\n");
+  cleanup_as_handle (ash);
+  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+  return;
+}
+
+/**
+ * Error looking up potential reference value. Abort.
+ *
+ * @param cls our attribute delete handle
+ */
+static void
+ref_del_error (void *cls)
+{
+  struct AttributeDeleteHandle *adh = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Failed to find Attestation entry for Attestation reference\n");
+  cleanup_adh (adh);
+  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+  return;
+}
+/**
+* Reference store result handler
+*
+* @param cls our attribute store handle
+* @param success GNUNET_OK if successful
+* @param emsg error message (NULL if success=GNUNET_OK)
+*/
+static void
+reference_store_cont (void *cls, int32_t success, const char *emsg)
+{
+  struct AttributeStoreHandle *ash = cls;
+  struct GNUNET_MQ_Envelope *env;
+  struct SuccessResultMessage *acr_msg;
+
+  ash->ns_qe = NULL;
+  GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
+                               ash->client->store_op_tail,
+                               ash);
+
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to store reference %s\n",
+                emsg);
+    cleanup_as_handle (ash);
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
+  env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
+  acr_msg->id = htonl (ash->r_id);
+  acr_msg->op_result = htonl (GNUNET_OK);
+  GNUNET_MQ_send (ash->client->mq, env);
+  cleanup_as_handle (ash);
+}
+
+
+/**
+* Check for existing record before storing reference
+*
+* @param cls our attribute store handle
+* @param zone zone we are iterating
+* @param label label of the records
+* @param rd_count record count
+* @param rd records
+*/
+static void
+ref_add_cb (void *cls,
+            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+            const char *label,
+            unsigned int rd_count,
+            const struct GNUNET_GNSRECORD_Data *rd)
+{
+  struct AttributeStoreHandle *ash = cls;
+  char *buf;
+  size_t buf_size;
+  buf_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (ash->reference);
+  buf = GNUNET_malloc (buf_size);
+  GNUNET_RECLAIM_ATTESTATION_REF_serialize (ash->reference, buf);
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
+  char *data_tmp;
+  if (0 == rd_count )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to find Attestation entry for Attestation reference\n");
+    send_ref_error (ash);
+    return;
+  }
+  if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Intended Reference storage location is not an attestation\n");
+    send_ref_error (ash);
+    return;
+  }
+  struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
+  int i;
+  for (i = 0; i<rd_count; i++)
+  {
+    data_tmp = GNUNET_malloc (rd[i].data_size);
+    GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+    ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, htons (
+                                                        rd[i].data_size));
+    rd_new[i] = rd[i];
+    if ((strcmp (ash->reference->name,ref->name) == 0)&&
+        (strcmp (ash->reference->reference_value,ref->reference_value)==0) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Reference already stored\n");
+      reference_store_cont (ash,GNUNET_OK, NULL);
+      return;
+    }
+  }
+  rd_new[rd_count].data_size = buf_size;
+  rd_new[rd_count].data = buf;
+  rd_new[rd_count].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE;
+  rd_new[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+  rd_new[rd_count].expiration_time = ash->exp.rel_value_us;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
+  ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &ash->identity,
+                                               label,
+                                               rd_count + 1,
+                                               rd_new,
+                                               &reference_store_cont,
+                                               ash);
+  GNUNET_free (buf);
+}
+
+/**
+ * Add a new reference
+ *
+ * @param cls the AttributeStoreHandle
+ */
+static void
+reference_store_task (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  char *label;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing reference\n");
+
+  // Give the ash a new id if unset
+  if (0 == ash->reference->id)
+  {
+    if (0 == ash->reference->id_attest)
+    {
+      ash->reference->id = GNUNET_CRYPTO_random_u64 (
+        GNUNET_CRYPTO_QUALITY_STRONG,
+        UINT64_MAX);
+    }
+    else
+    {
+      ash->reference->id = ash->reference->id_attest;
+    }
+  }
+
+  label = GNUNET_STRINGS_data_to_string_alloc (&ash->reference->id,
+                                               sizeof(uint64_t));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Looking up existing data under label %s\n", label);
+// Test for the content of the existing ID
+
+  ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
+                                                &ash->identity,
+                                                label,
+                                                &ref_error,
+                                                ash,
+                                                &ref_add_cb,
+                                                ash);
+  GNUNET_free (label);
+}
+
+/**
+     * Check an attestation reference store message
+     *
+     * @param cls unused
+     * @param sam the message to check
+     */
+static int
+check_reference_store_message (void *cls,
+                               const struct
+                               AttributeStoreMessage *sam)
+{
+  uint16_t size;
+
+  size = ntohs (sam->header.size);
+  if (size <= sizeof(struct AttributeStoreMessage))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+    * Handle an attestation reference store message
+    *
+    * @param cls our client
+    * @param sam the message to handle
+    */
+static void
+handle_reference_store_message (void *cls,
+                                const struct AttributeStoreMessage *sam)
+{
+  struct AttributeStoreHandle *ash;
+  struct IdpClient *idp = cls;
+  size_t data_len;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_STORE message\n");
+
+  data_len = ntohs (sam->attr_len);
+  ash = GNUNET_new (struct AttributeStoreHandle);
+  ash->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &sam[1],
+                                                               data_len);
+  ash->r_id = ntohl (sam->id);
+  ash->identity = sam->identity;
+  ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
+  GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
+
+
+  GNUNET_SERVICE_client_continue (idp->client);
+  ash->client = idp;
+  GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
+  GNUNET_SCHEDULER_add_now (&reference_store_task, ash);
+}
 /**
  * Send a deletion success response
  *
@@ -1066,15 +1565,21 @@ ticket_iter (void *cls,
   struct AttributeDeleteHandle *adh = cls;
   struct TicketRecordsEntry *le;
   int has_changed = GNUNET_NO;
-
   for (int i = 0; i < rd_count; i++)
   {
     if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
       continue;
-    if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
-      continue;
+    if (adh->claim != NULL)
+      if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
+        continue;
+    if (adh->attest != NULL)
+      if (0 != memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t)))
+        continue;
+    if (adh->reference != NULL)
+      if (0 != memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t)))
+        continue;
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Attribute to delete found (%s)\n",
+                "Attribute or Attestation/Reference to delete found (%s)\n",
                 adh->label);
     has_changed = GNUNET_YES;
     break;
@@ -1136,7 +1641,7 @@ update_tickets (void *cls)
   if (NULL == adh->tickets_to_update_head)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Finished updatding tickets, success\n");
+                "Finished updating tickets, success\n");
     send_delete_response (adh, GNUNET_OK);
     cleanup_adh (adh);
     return;
@@ -1164,9 +1669,18 @@ update_tickets (void *cls)
   int j = 0;
   for (int i = 0; i < le->rd_count; i++)
   {
-    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
-        && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))))
-      continue;
+    if (adh->claim != NULL)
+      if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
+          && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))))
+        continue;
+    if (adh->attest != NULL)
+      if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
+          && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t))))
+        continue;
+    if (adh->reference != NULL)
+      if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
+          && (0 == memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t))))
+        continue;
     rd_new[j] = rd[i];
     j++;
   }
@@ -1192,7 +1706,6 @@ static void
 ticket_iter_fin (void *cls)
 {
   struct AttributeDeleteHandle *adh = cls;
-
   adh->ns_it = NULL;
   GNUNET_SCHEDULER_add_now (&update_tickets, adh);
 }
@@ -1309,6 +1822,8 @@ handle_attribute_delete_message (void *cls,
   adh = GNUNET_new (struct AttributeDeleteHandle);
   adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &dam[1],
                                                      data_len);
+  adh->reference = NULL;
+  adh->attest = NULL;
 
   adh->r_id = ntohl (dam->id);
   adh->identity = dam->identity;
@@ -1326,6 +1841,256 @@ handle_attribute_delete_message (void *cls,
                                                adh);
 }
 
+/**
+   * Attestation deleted callback
+   *
+   * @param cls our handle
+   * @param success success status
+   * @param emsg error message (NULL if success=GNUNET_OK)
+   */
+static void
+attest_delete_cont (void *cls, int32_t success, const char *emsg)
+{
+  struct AttributeDeleteHandle *adh = cls;
+
+  adh->ns_qe = NULL;
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error deleting attestation %s\n",
+                adh->label);
+    send_delete_response (adh, GNUNET_SYSERR);
+    cleanup_adh (adh);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
+  GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+}
+
+/**
+ * Check attestation delete message format
+ *
+ * @cls unused
+ * @dam message to check
+ */
+static int
+check_attestation_delete_message (void *cls,
+                                  const struct AttributeDeleteMessage *dam)
+{
+  uint16_t size;
+
+  size = ntohs (dam->header.size);
+  if (size <= sizeof(struct AttributeDeleteMessage))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handle attestation deletion
+ *
+ * @param cls our client
+ * @param dam deletion message
+ */
+static void
+handle_attestation_delete_message (void *cls,
+                                   const struct AttributeDeleteMessage *dam)
+{
+  struct AttributeDeleteHandle *adh;
+  struct IdpClient *idp = cls;
+  size_t data_len;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE message\n");
+
+  data_len = ntohs (dam->attr_len);
+
+  adh = GNUNET_new (struct AttributeDeleteHandle);
+  adh->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &dam[1],
+                                                        data_len);
+  adh->reference = NULL;
+  adh->claim = NULL;
+
+  adh->r_id = ntohl (dam->id);
+  adh->identity = dam->identity;
+  adh->label
+    = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id, sizeof(uint64_t));
+  GNUNET_SERVICE_client_continue (idp->client);
+  adh->client = idp;
+  GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
+  adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &adh->identity,
+                                               adh->label,
+                                               0,
+                                               NULL,
+                                               &attest_delete_cont,
+                                               adh);
+}
+
+
+
+/**
+* Reference deleted callback
+*
+* @param cls our handle
+* @param success success status
+* @param emsg error message (NULL if success=GNUNET_OK)
+*/
+static void
+reference_delete_cont (void *cls, int32_t success, const char *emsg)
+{
+  struct AttributeDeleteHandle *adh = cls;
+
+  adh->ns_qe = NULL;
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error deleting reference %s\n",
+                adh->label);
+    send_delete_response (adh, GNUNET_SYSERR);
+    cleanup_adh (adh);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
+  //GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+  send_delete_response (adh, GNUNET_OK);
+  cleanup_adh (adh);
+  return;
+}
+
+static void
+ref_del_cb (void *cls,
+            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+            const char *label,
+            unsigned int rd_count,
+            const struct GNUNET_GNSRECORD_Data *rd)
+{
+
+  struct AttributeDeleteHandle *adh = cls;
+  char *data_tmp;
+  struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
+  size_t attr_len;
+
+  if (0 == rd_count )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to find Attestation entry for Attestation reference\n");
+    cleanup_adh (adh);
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    return;
+  }
+  if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Intended Reference location is not an attestation\n");
+    cleanup_adh (adh);
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    return;
+  }
+  rd_new[0] = rd[0];
+  int i;
+  int j = 1;
+  for (i = 1; i<rd_count; i++)
+  {
+    data_tmp = GNUNET_malloc (rd[i].data_size);
+    GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+    attr_len = htons (rd[i].data_size);
+    ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len);
+    if (NULL == ref )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unable to parse attestation reference from %s\n",
+                  data_tmp);
+      rd_new[j] = rd[i];
+      j += 1;
+      continue;
+    }
+    if ((strcmp (adh->reference->name,ref->name) == 0)&&
+        (strcmp (adh->reference->reference_value,ref->reference_value)==0) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Found reference to delete.\n");
+    }
+    else
+    {
+      rd_new[j] = rd[i];
+      j += 1;
+    }
+    GNUNET_free (data_tmp);
+  }
+  adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &adh->identity,
+                                               label,
+                                               j,
+                                               rd_new,
+                                               &reference_delete_cont,
+                                               adh);
+}
+
+/**
+ * Check an attestation reference delete message
+ *
+ * @param cls unused
+ * @param sam the message to check
+ */
+static int
+check_reference_delete_message (void *cls,
+                                const struct AttributeDeleteMessage *dam)
+{
+  uint16_t size;
+
+  size = ntohs (dam->header.size);
+  if (size <= sizeof(struct AttributeDeleteMessage))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+/**
+ * Handle reference deletion
+ *
+ * @param cls our client
+ * @param dam deletion message
+ */
+static void
+handle_reference_delete_message (void *cls,
+                                 const struct AttributeDeleteMessage *dam)
+{
+  struct AttributeDeleteHandle *adh;
+  struct IdpClient *idp = cls;
+  size_t data_len;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_DELETE message\n");
+  data_len = ntohs (dam->attr_len);
+  adh = GNUNET_new (struct AttributeDeleteHandle);
+  adh->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &dam[1],
+                                                               data_len);
+  adh->attest = NULL;
+  adh->claim = NULL;
+
+  adh->r_id = ntohl (dam->id);
+  adh->identity = dam->identity;
+  adh->label
+    = GNUNET_STRINGS_data_to_string_alloc (&adh->reference->id,
+                                           sizeof(uint64_t));
+  GNUNET_SERVICE_client_continue (idp->client);
+  adh->client = idp;
+  GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
+  adh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
+                                                &adh->identity,
+                                                adh->label,
+                                                &ref_del_error,
+                                                adh,
+                                                &ref_del_cb,
+                                                adh);
+}
+
+
 
 /*************************************************
 * Attrubute iteration
@@ -1372,7 +2137,7 @@ attr_iter_error (void *cls)
 
 
 /**
- * Got record. Return if it is an attribute.
+ * Got record. Return if it is an attribute or attestation/reference.
  *
  * @param cls our attribute iterator
  * @param zone zone we are iterating
@@ -1388,35 +2153,103 @@ attr_iter_cb (void *cls,
               const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct AttributeIterator *ai = cls;
-  struct AttributeResultMessage *arm;
   struct GNUNET_MQ_Envelope *env;
   char *data_tmp;
 
-  if (rd_count != 1)
+  if (rd_count == 0)
   {
     GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
     return;
   }
+  if (rd_count > 1)
+  {
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[0].record_type)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Found Ticket. Ignoring.\n");
+      GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+      return;
+    }
+    else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Non-Attestation record with multiple entries found: %u\n",
+                  rd[0].record_type);
+      GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+      return;
+    }
+  }
 
-  if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type)
+  for (int i = 0; i<rd_count; i++)
   {
-    GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
-    return;
+    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd[i].record_type) &&
+        (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type) &&
+        (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE != rd[i].record_type))
+    {
+      GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+      return;
+    }
+
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type )
+    {
+      struct AttributeResultMessage *arm;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
+                  label);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Sending ATTRIBUTE_RESULT message\n");
+      env = GNUNET_MQ_msg_extra (arm,
+                                 rd[i].data_size,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
+      arm->id = htonl (ai->request_id);
+      arm->attr_len = htons (rd[i].data_size);
+      GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
+      data_tmp = (char *) &arm[1];
+      GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+      GNUNET_MQ_send (ai->client->mq, env);
+    }
+    else
+    {
+      if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type )
+      {
+        struct AttributeResultMessage *arm;
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
+                    label);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Sending ATTESTATION_RESULT message\n");
+        env = GNUNET_MQ_msg_extra (arm,
+                                   rd[i].data_size,
+                                   GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
+        arm->id = htonl (ai->request_id);
+        arm->attr_len = htons (rd[i].data_size);
+        GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
+        data_tmp = (char *) &arm[1];
+        GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+        GNUNET_MQ_send (ai->client->mq, env);
+      }
+      else
+      {
+        struct ReferenceResultMessage *rrm;
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found reference under: %s\n",
+                    label);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Sending REFERENCE_RESULT message\n");
+        env = GNUNET_MQ_msg_extra (rrm,
+                                   rd[i].data_size + rd[0].data_size,
+                                   GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT);
+        rrm->id = htonl (ai->request_id);
+        rrm->attest_len = htons (rd[0].data_size);
+        rrm->ref_len = htons (rd[i].data_size);
+        GNUNET_CRYPTO_ecdsa_key_get_public (zone, &rrm->identity);
+        data_tmp = (char *) &rrm[1];
+        GNUNET_memcpy (data_tmp, rd[0].data, rd[0].data_size);
+        data_tmp += rd[0].data_size;
+        GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+        GNUNET_MQ_send (ai->client->mq, env);
+      }
+    }
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
-  env = GNUNET_MQ_msg_extra (arm,
-                             rd->data_size,
-                             GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
-  arm->id = htonl (ai->request_id);
-  arm->attr_len = htons (rd->data_size);
-  GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
-  data_tmp = (char *) &arm[1];
-  GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
-  GNUNET_MQ_send (ai->client->mq, env);
 }
 
-
 /**
  * Iterate over zone to get attributes
  *
@@ -1742,10 +2575,26 @@ GNUNET_SERVICE_MAIN (
                          GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
                          struct AttributeStoreMessage,
                          NULL),
+  GNUNET_MQ_hd_var_size (attestation_store_message,
+                         GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
+                         struct AttributeStoreMessage,
+                         NULL),
   GNUNET_MQ_hd_var_size (attribute_delete_message,
                          GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
                          struct AttributeDeleteMessage,
                          NULL),
+  GNUNET_MQ_hd_var_size (attestation_delete_message,
+                         GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
+                         struct AttributeDeleteMessage,
+                         NULL),
+  GNUNET_MQ_hd_var_size (reference_store_message,
+                         GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE,
+                         struct AttributeStoreMessage,
+                         NULL),
+  GNUNET_MQ_hd_var_size (reference_delete_message,
+                         GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE,
+                         struct AttributeDeleteMessage,
+                         NULL),
   GNUNET_MQ_hd_fixed_size (
     iteration_start,
     GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
index 4d1a26333d4fdb53aa9d7bb57c0be08092608f91..b022225b886d81eaa392b0928f8b9c535c2fa997 100644 (file)
@@ -667,8 +667,7 @@ rvk_move_attr_cb (void *cls,
                   const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
-  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
-  struct GNUNET_GNSRECORD_Data new_rd;
+  struct GNUNET_GNSRECORD_Data new_rd[rd_count];
   struct RevokedAttributeEntry *le;
   char *new_label;
   char *attr_data;
@@ -677,7 +676,7 @@ rvk_move_attr_cb (void *cls,
   if (0 == rd_count)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "The attribute %s no longer exists!\n",
+                "The claim %s no longer exists!\n",
                 label);
     le = rvk->move_attr;
     rvk->move_attr = le->next;
@@ -686,32 +685,82 @@ rvk_move_attr_cb (void *cls,
     GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
     return;
   }
-  /** find a new place for this attribute **/
-  rvk->move_attr->new_id =
-    GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
-  new_rd = *rd;
-  claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
-              claim->name,
-              claim->id);
-  claim->id = rvk->move_attr->new_id;
-  new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
-  attr_data = GNUNET_malloc (rd->data_size);
-  new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
-  new_rd.data = attr_data;
-  new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
-                                                   sizeof(uint64_t));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
+  rvk->move_attr->new_id =GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  new_label=NULL;
+  attr_data=NULL;
+  //new_rd = *rd;
+  for (int i = 0; i < rd_count; i++)
+  {
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type)
+    {
+      /** find a new place for this attribute **/
+      struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+      claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, rd[i].data_size);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
+                  claim->name,
+                  claim->id);
+      claim->id = rvk->move_attr->new_id;
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
+      attr_data = GNUNET_malloc (rd[i].data_size);
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
+      new_rd[i].data = attr_data;
+      new_rd[i].record_type = rd[i].record_type;
+      new_rd[i].flags = rd[i].flags;
+      new_rd[i].expiration_time = rd[i].expiration_time;
+      new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
+                                                       sizeof(uint64_t));
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
+      GNUNET_free (claim);
+    } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type) 
+    {
+      struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+      attest=GNUNET_RECLAIM_ATTESTATION_deserialize(rd[i].data, rd[i].data_size);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attestation to update: Name=%s, ID=%" PRIu64 "\n",
+                  attest->name,
+                  attest->id);
+      attest->id = rvk->move_attr->new_id;
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attest);
+      attr_data = GNUNET_malloc (rd[i].data_size);
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize (attest, attr_data);
+      new_rd[i].data = attr_data;
+      new_rd[i].record_type = rd[i].record_type;
+      new_rd[i].flags = rd[i].flags;
+      new_rd[i].expiration_time = rd[i].expiration_time;
+      new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, sizeof(uint64_t));
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation %s\n", new_label);
+      GNUNET_free (attest);
+    } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type)
+    {
+      struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
+      reference=GNUNET_RECLAIM_ATTESTATION_REF_deserialize(rd[i].data, rd[i].data_size);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Reference to update: Name=%s, ID=%" PRIu64 "\n",
+                  reference->name,
+                  reference->id);
+      reference->id = rvk->move_attr->new_id;
+      reference->id_attest = rvk->move_attr->new_id;
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (reference);
+      attr_data = GNUNET_malloc (rd[i].data_size);
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize (reference, attr_data);
+      new_rd[i].data = attr_data;
+      new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, sizeof(uint64_t));
+      new_rd[i].record_type = rd[i].record_type;
+      new_rd[i].flags = rd[i].flags;
+      new_rd[i].expiration_time = rd[i].expiration_time;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference %s\n", new_label);
+      GNUNET_free (reference);
+    }
+  }
   rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
-                                               &rvk->identity,
-                                               new_label,
-                                               1,
-                                               &new_rd,
-                                               &move_attr_finished,
-                                               rvk);
+                                           &rvk->identity,
+                                           new_label,
+                                           rd_count,
+                                           new_rd,
+                                           &move_attr_finished,
+                                           rvk);
   GNUNET_free (new_label);
-  GNUNET_free (claim);
   GNUNET_free (attr_data);
 }
 
@@ -745,7 +794,7 @@ move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
   }
   label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
                                                sizeof(uint64_t));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving claim %s\n", label);
 
   rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
                                                 &rvk->identity,
@@ -982,21 +1031,70 @@ process_parallel_lookup_result (void *cls,
 
 
   GNUNET_free (parallel_lookup);
-  if (1 != rd_count)
-    GNUNET_break (0); // FIXME: We should never find this.
-  if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR)
+  if (0 == rd_count)
+    GNUNET_break (0);
+  // REMARK: It is possible now to find rd_count > 1
+  for (int i = 0; i < rd_count; i++)
   {
-    attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-    attr_le->claim =
-      GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
-    GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
-                                 cth->attrs->list_tail,
-                                 attr_le);
-  }
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type)
+    {
+      attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      attr_le->claim =
+        GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, rd[i].data_size);
+      GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+                                   cth->attrs->list_tail,
+                                   attr_le);
+      attr_le->reference = NULL;
+      attr_le->attest = NULL;
+    }
+    else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type)
+    {
+      /**Ignore all plain attestations
+      *attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      *attr_le->attest =
+      *  GNUNET_RECLAIM_ATTESTATION_deserialize (rd[i].data, rd[i].data_size);
+      *GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+      *                             cth->attrs->list_tail,
+      *                             attr_le);
+      */
+      continue;
+    }
+    else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type)
+    {
+      struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le2;
+      attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      attr_le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[0].record_type)
+      {
+        attr_le->attest = GNUNET_RECLAIM_ATTESTATION_deserialize (rd[0].data,
+                                                                  rd[0].
+                                                                  data_size);
+        attr_le2->reference =
+          GNUNET_RECLAIM_ATTESTATION_REF_deserialize (rd[i].data,
+                                                      rd[i].data_size);
+        attr_le->claim = NULL;
+        attr_le->reference = NULL;
+        attr_le2->claim = NULL;
+        attr_le2->attest = NULL;
+        GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+                                     cth->attrs->list_tail,
+                                     attr_le);
+        GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+                                     cth->attrs->list_tail,
+                                     attr_le2);
+      }
+      else
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Parallel Lookup of Reference without Attestation");
+        continue;
+      }
 
+
+    }
+  }
   if (NULL != cth->parallel_lookups_head)
     return; // Wait for more
-
   /* Else we are done */
   cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
   cleanup_cth (cth);
@@ -1076,7 +1174,7 @@ lookup_authz_cb (void *cls,
       GNUNET_GNS_lookup (gns,
                          lbl,
                          &cth->ticket.identity,
-                         GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
+                         GNUNET_GNSRECORD_TYPE_ANY,
                          GNUNET_GNS_LO_DEFAULT,
                          &process_parallel_lookup_result,
                          parallel_lookup);
@@ -1223,6 +1321,7 @@ issue_ticket (struct TicketIssueHandle *ih)
   char *label;
   size_t list_len = 1;
   int i;
+  char *attest_string;
 
   for (le = ih->attrs->list_head; NULL != le; le = le->next)
     list_len++;
@@ -1232,8 +1331,51 @@ issue_ticket (struct TicketIssueHandle *ih)
   i = 0;
   for (le = ih->attrs->list_head; NULL != le; le = le->next)
   {
-    attrs_record[i].data = &le->claim->id;
-    attrs_record[i].data_size = sizeof(le->claim->id);
+    if (NULL != le->claim)
+    {
+      attrs_record[i].data = &le->claim->id;
+      attrs_record[i].data_size = sizeof(le->claim->id);
+    }
+    else if (NULL != le->attest)
+    {
+      // REMARK: Since we only store IDs, the references are irrelevant
+      int j = 0;
+      GNUNET_asprintf (&attest_string,"%d",le->attest->id);
+      while (j<i)
+      {
+        if (0 == strcmp (attest_string,GNUNET_STRINGS_data_to_string_alloc (
+                           attrs_record[j].data, attrs_record[j].data_size)))
+          break;
+        j++;
+      }
+      if (j < i)
+      {
+        list_len--;
+        continue;
+      }
+      attrs_record[i].data = &le->attest->id;
+      attrs_record[i].data_size = sizeof(le->attest->id);
+    }
+    else if (NULL != le->reference)
+    {
+      list_len--;
+      continue;
+      /*
+      int j = 0;
+      GNUNET_asprintf (&attest_string,"%d",le->attest->id);
+      while (j<i)
+      {
+        if (strcmp(attest_string, GNUNET_STRINGS_data_to_string_alloc (
+              attrs_record[j].data, attrs_record[j].data_size)))
+          break;
+        j++;
+      }
+      if (j < i)
+        continue;
+      attrs_record[i].data = &le->reference->id;
+      attrs_record[i].data_size = sizeof(le->reference->id);
+      */
+    }
     /**
      * FIXME: Should this be the attribute expiration time or ticket
      * refresh interval? Probably min(attrs.expiration)
@@ -1344,14 +1486,34 @@ filter_tickets_cb (void *cls,
     for (le = tih->attrs->list_head; NULL != le; le = le->next)
     {
       // cmp attr_ref id with requested attr id
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  " %" PRIu64 "\n  %" PRIu64 "\n",
-                  *((uint64_t *) rd[i].data),
-                  le->claim->id);
-
+      if (NULL !=le->claim)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    " %" PRIu64 "\n  %" PRIu64 "\n",
+                    *((uint64_t *) rd[i].data),
+                    le->claim->id);
+        if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t)))
+          found_attrs_cnt++;
+      }
+      else if (NULL !=le->attest)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    " %" PRIu64 "\n  %" PRIu64 "\n",
+                    *((uint64_t *) rd[i].data),
+                    le->attest->id);
+        if (0 == memcmp (rd[i].data, &le->attest->id, sizeof(uint64_t)))
+          found_attrs_cnt++;
+      }
+      else if (NULL != le->reference)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    " %" PRIu64 "\n  %" PRIu64 "\n",
+                    *((uint64_t *) rd[i].data),
+                    le->reference->id);
+        if (0 == memcmp (rd[i].data, &le->reference->id, sizeof(uint64_t)))
+          found_attrs_cnt++;
+      }
 
-      if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t)))
-        found_attrs_cnt++;
     }
   }
 
index e029fdfb68a0c41e7e5e078449d99f58677d737e..a464a9088c37ae49afb7d91931e8850d76409869 100644 (file)
@@ -48,6 +48,7 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
   const char *val_str = NULL;
   const char *type_str = NULL;
   const char *id_str = NULL;
+  const char *flag_str = NULL;
   char *data;
   int unpack_state;
   uint32_t type;
@@ -63,7 +64,7 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
   }
   // interpret single attribute
   unpack_state = json_unpack (root,
-                              "{s:s, s?s, s:s, s:s!}",
+                              "{s:s, s?s, s:s, s:s, s?s!}",
                               "name",
                               &name_str,
                               "id",
@@ -71,7 +72,9 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
                               "type",
                               &type_str,
                               "value",
-                              &val_str);
+                              &val_str,
+                              "flag",
+                              &flag_str);
   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
       (NULL == type_str))
   {
@@ -264,3 +267,217 @@ GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
   *ticket = NULL;
   return ret;
 }
+
+/**
+   * Parse given JSON object to an attestation claim
+   *
+   * @param cls closure, NULL
+   * @param root the json object representing data
+   * @param spec where to write the data
+   * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+   */
+static int
+parse_attest (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+  const char *name_str = NULL;
+  const char *val_str = NULL;
+  const char *type_str = NULL;
+  const char *id_str = NULL;
+  char *data;
+  int unpack_state;
+  uint32_t type;
+  size_t data_size;
+
+  GNUNET_assert (NULL != root);
+
+  if (! json_is_object (root))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json is not array nor object!\n");
+    return GNUNET_SYSERR;
+  }
+  // interpret single attribute
+  unpack_state = json_unpack (root,
+                              "{s:s, s?s, s:s, s:s!}",
+                              "name",
+                              &name_str,
+                              "id",
+                              &id_str,
+                              "type",
+                              &type_str,
+                              "value",
+                              &val_str);
+  if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
+      (NULL == type_str))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json object has a wrong format!\n");
+    return GNUNET_SYSERR;
+  }
+  type = GNUNET_RECLAIM_ATTESTATION_typename_to_number (type_str);
+  if (GNUNET_SYSERR ==
+      (GNUNET_RECLAIM_ATTESTATION_string_to_value (type,
+                                                   val_str,
+                                                   (void **) &data,
+                                                   &data_size)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attestation value invalid!\n");
+    return GNUNET_SYSERR;
+  }
+  attr = GNUNET_RECLAIM_ATTESTATION_claim_new (name_str, type, data, data_size);
+  if ((NULL == id_str) || (0 == strlen (id_str)))
+    attr->id = 0;
+  else
+    GNUNET_STRINGS_string_to_data (id_str,
+                                   strlen (id_str),
+                                   &attr->id,
+                                   sizeof(uint64_t));
+
+  *(struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr = attr;
+  return GNUNET_OK;
+}
+
+/**
+ * Cleanup data left from parsing RSA public key.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_attest (void *cls, struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim **attr;
+
+  attr = (struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr;
+  if (NULL != *attr)
+  {
+    GNUNET_free (*attr);
+    *attr = NULL;
+  }
+}
+/**
+ * JSON Specification for Reclaim attestation claims.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest (struct
+                                       GNUNET_RECLAIM_ATTESTATION_Claim **attr)
+{
+  struct GNUNET_JSON_Specification ret = { .parser = &parse_attest,
+                                           .cleaner = &clean_attest,
+                                           .cls = NULL,
+                                           .field = NULL,
+                                           .ptr = attr,
+                                           .ptr_size = 0,
+                                           .size_ptr = NULL };
+
+  *attr = NULL;
+  return ret;
+}
+
+/**
+   * Parse given JSON object to an attestation claim
+   *
+   * @param cls closure, NULL
+   * @param root the json object representing data
+   * @param spec where to write the data
+   * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+   */
+static int
+parse_attest_ref (void *cls, json_t *root, struct
+                  GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  const char *name_str = NULL;
+  const char *ref_val_str = NULL;
+  const char *ref_id_str = NULL;
+  const char *id_str = NULL;
+  int unpack_state;
+
+  GNUNET_assert (NULL != root);
+
+  if (! json_is_object (root))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json is not array nor object!\n");
+    return GNUNET_SYSERR;
+  }
+  // interpret single reference
+  unpack_state = json_unpack (root,
+                              "{s:s, s?s, s:s, s:s!}",
+                              "name",
+                              &name_str,
+                              "id",
+                              &id_str,
+                              "ref_id",
+                              &ref_id_str,
+                              "ref_value",
+                              &ref_val_str);
+  if ((0 != unpack_state) || (NULL == name_str) || (NULL == ref_val_str) ||
+      (NULL == ref_id_str))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json object has a wrong format!\n");
+    return GNUNET_SYSERR;
+  }
+
+  attr = GNUNET_RECLAIM_ATTESTATION_reference_new (name_str, ref_val_str);
+
+  attr->id = 0;
+
+  if ((NULL == ref_id_str) || (0 == strlen (ref_id_str)))
+    attr->id_attest = 0;
+  else
+    GNUNET_STRINGS_string_to_data (ref_id_str,
+                                   strlen (ref_id_str),
+                                   &attr->id_attest,
+                                   sizeof(uint64_t));
+
+  *(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr = attr;
+  return GNUNET_OK;
+}
+
+/**
+ * Cleanup data left from parsing RSA public key.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_attest_ref (void *cls, struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr;
+
+  attr = (struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr;
+  if (NULL != *attr)
+  {
+    GNUNET_free (*attr);
+    *attr = NULL;
+  }
+}
+
+/**
+ * JSON Specification for Reclaim attestation references.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest_ref (struct
+                                           GNUNET_RECLAIM_ATTESTATION_REFERENCE
+                                           **attr)
+{
+  struct GNUNET_JSON_Specification ret = { .parser = &parse_attest_ref,
+                                           .cleaner = &clean_attest_ref,
+                                           .cls = NULL,
+                                           .field = NULL,
+                                           .ptr = attr,
+                                           .ptr_size = 0,
+                                           .size_ptr = NULL };
+
+  *attr = NULL;
+  return ret;
+}
\ No newline at end of file
index 3fd26167f629a14644cb8f9844432f7384f51e63..9e6479e5ed6862220685feea9986d04fb6b1f01b 100644 (file)
@@ -46,3 +46,22 @@ GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr);
  */
 struct GNUNET_JSON_Specification
 GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket);
+
+/**
+    * JSON Specification for Reclaim attestation claims.
+    *
+    * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
+    * @return JSON Specification
+    */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest (struct
+                                       GNUNET_RECLAIM_ATTESTATION_Claim **attr);
+
+  /**
+   * JSON Specification for Reclaim attestation references.
+   *
+   * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
+   * @return JSON Specification
+   */
+  struct GNUNET_JSON_Specification
+  GNUNET_RECLAIM_JSON_spec_claim_attest_ref(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr);
index 1c3d65f3569494d58165e8e9ec5651fd4d73cbef..2ce4628546486a9ebe085f978e25481845d4cdbe 100644 (file)
@@ -118,7 +118,7 @@ fix_base64 (char *str)
 char *
 OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
-                   const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
                    const struct GNUNET_TIME_Relative *expiration_time,
                    const char *nonce,
                    const char *secret_key)
@@ -131,13 +131,22 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
   char *subject;
   char *header;
   char *body_str;
+  char *aggr_names_str;
+  char *aggr_sources_str;
+  char *aggr_sources_jwt_str;
+  char *source_name;
   char *result;
   char *header_base64;
   char *body_base64;
   char *signature_target;
   char *signature_base64;
   char *attr_val_str;
+  char *attest_val_str;
   json_t *body;
+  json_t *aggr_names;
+  json_t *aggr_sources;
+  json_t *aggr_sources_jwt;
+  uint64_t attest_arr[GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (attrs)];
 
   // iat REQUIRED time now
   time_now = GNUNET_TIME_absolute_get ();
@@ -156,6 +165,8 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
                                                 GNUNET_CRYPTO_EcdsaPublicKey));
   header = create_jwt_header ();
   body = json_object ();
+  aggr_names = json_object ();
+  aggr_sources = json_object ();
 
   // iss REQUIRED case sensitive server uri with https
   // The issuer is the local reclaim instance (e.g.
@@ -180,18 +191,111 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
   // nonce
   if (NULL != nonce)
     json_object_set_new (body, "nonce", json_string (nonce));
-
+  int i = 0;
+  attest_val_str = NULL;
+  aggr_names_str = NULL;
+  aggr_sources_str = NULL;
+  aggr_sources_jwt_str = NULL;
+  source_name = NULL;
   for (le = attrs->list_head; NULL != le; le = le->next)
   {
-    attr_val_str =
-      GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type,
-                                                le->claim->data,
-                                                le->claim->data_size);
-    json_object_set_new (body, le->claim->name, json_string (attr_val_str));
-    GNUNET_free (attr_val_str);
+
+    if (le->claim != NULL)
+    {
+
+      attr_val_str =
+        GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type,
+                                                  le->claim->data,
+                                                  le->claim->data_size);
+      json_object_set_new (body, le->claim->name, json_string (attr_val_str));
+      GNUNET_free (attr_val_str);
+    }
+    else if (NULL != le->reference)
+    {
+      // Check if attest is there
+      int j = 0;
+      while (j<i)
+      {
+        if (attest_arr[j] == le->reference->id_attest)
+          break;
+        j++;
+      }
+      if (j==i)
+      {
+        // Attest not yet existent. Append to the end of the list
+        GNUNET_CONTAINER_DLL_remove (attrs->list_head, attrs->list_tail, le);
+        GNUNET_CONTAINER_DLL_insert_tail (attrs->list_head, attrs->list_tail,
+                                          le);
+        continue;
+      }
+      else
+      {
+        // Attestation is existing, hence take the respective source str
+        GNUNET_asprintf (&source_name,
+                         "src%d",
+                         j);
+        json_object_set_new (aggr_names, le->reference->name, json_string (
+                               source_name));
+      }
+
+    }
+    else if (NULL != le->attest)
+    {
+      // We assume that at max 99 different attestations
+      int j = 0;
+      while (j<i)
+      {
+        if (attest_arr[j] == le->attest->id)
+          break;
+        j++;
+      }
+      if (j==i)
+      {
+        // New Attestation
+        attest_arr[i] = le->attest->id;
+        GNUNET_asprintf (&source_name,
+                         "src%d",
+                         i);
+        aggr_sources_jwt = json_object ();
+        attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (
+          le->attest->type, le->attest->data, le->attest->data_size);
+        json_object_set_new (aggr_sources_jwt, "JWT",json_string (
+                               attest_val_str) );
+        aggr_sources_jwt_str = json_dumps (aggr_sources_jwt, JSON_INDENT (0)
+                                           | JSON_COMPACT);
+        json_object_set_new (aggr_sources, source_name,json_string (
+                               aggr_sources_jwt_str));
+        i++;
+      }
+      else
+      {
+        // Attestation already existent. Ignore
+        continue;
+      }
+
+    }
+  }
+  if (NULL != attest_val_str)
+    GNUNET_free (attest_val_str);
+  if (NULL != source_name)
+    GNUNET_free (source_name);
+  if (0!=i)
+  {
+    aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT);
+    aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0)
+                                   | JSON_COMPACT);
+    json_object_set_new (body, "_claim_names", json_string (aggr_names_str));
+    json_object_set_new (body, "_claim_sources", json_string (
+                           aggr_sources_str));
   }
+
+  json_decref (aggr_names);
+  json_decref (aggr_sources);
+  json_decref (aggr_sources_jwt);
+
   body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
   json_decref (body);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str);
 
   GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64);
   fix_base64 (header_base64);
@@ -226,6 +330,12 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
   GNUNET_free (signature_target);
   GNUNET_free (header);
   GNUNET_free (body_str);
+  if (NULL != aggr_sources_str)
+    GNUNET_free (aggr_sources_str);
+  if (NULL != aggr_names_str)
+    GNUNET_free (aggr_names_str);
+  if (NULL != aggr_sources_jwt_str)
+    GNUNET_free (aggr_sources_jwt_str);
   GNUNET_free (signature_base64);
   GNUNET_free (body_base64);
   GNUNET_free (header_base64);
index 1774618e880ef716534717b5e1a1235d43685672..a7072755b51342d7390036c7ed2ae0d0db1be160 100644 (file)
@@ -51,7 +51,7 @@
 char*
 OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
-                   const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
                    const struct GNUNET_TIME_Relative *expiration_time,
                    const char *nonce,
                    const char *secret_key);
index d530ef01d9309c93d987a6e86eca9675cbd64ddb..f7145a27278ff27b38ff56f72b02a3ce08c4e0f1 100644 (file)
@@ -54,6 +54,8 @@ value_to_string (void *cls, uint32_t type, const void *data, size_t data_size)
   case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE:
     return GNUNET_STRINGS_data_to_string_alloc (data, data_size);
 
   default:
@@ -93,6 +95,8 @@ string_to_value (void *cls, uint32_t type, const char *s, void **data,
   case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE:
     return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size);
 
   default:
@@ -112,10 +116,12 @@ static struct
 } name_map[] = {
   { "RECLAIM_ATTR", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR },
   { "RECLAIM_ATTR_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF },
+  { "RECLAIM_ATTEST", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR },
   { "RECLAIM_MASTER", GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER },
   { "RECLAIM_OIDC_CLIENT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT },
   { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT },
   { "RECLAIM_TICKET", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET },
+  { "RECLAIM_REFERENCE", GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE },
   { NULL, UINT32_MAX }
 };
 
index 92a1de6210a0644d3f7425e47306a3d6e3b9273c..741094f21fa0b369e891d85bec30c792e992f3a8 100644 (file)
  */
 #define OIDC_NONCE_KEY "nonce"
 
+/**
+ * OIDC claims key
+ */
+#define OIDC_CLAIMS_KEY "claims"
+
 /**
  * OIDC PKCE code challenge
  */
@@ -290,6 +295,11 @@ struct OIDC_Variables
    */
   char *nonce;
 
+  /**
+   * The OIDC claims
+   */
+  char *claims;
+
   /**
    * The OIDC response type
    */
@@ -560,7 +570,12 @@ cleanup_handle (struct RequestHandle *handle)
     {
       claim_tmp = claim_entry;
       claim_entry = claim_entry->next;
-      GNUNET_free (claim_tmp->claim);
+      if (NULL != claim_tmp->claim)
+        GNUNET_free (claim_tmp->claim);
+      if (NULL != claim_tmp->attest)
+        GNUNET_free (claim_tmp->attest);
+      if (NULL != claim_tmp->reference)
+        GNUNET_free (claim_tmp->reference);
       GNUNET_free (claim_tmp);
     }
     GNUNET_free (handle->attr_list);
@@ -697,7 +712,7 @@ return_userinfo_response (void *cls)
   struct MHD_Response *resp;
 
   result_str = json_dumps (handle->oidc->response, 0);
-
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str);
   resp = GNUNET_REST_create_response (result_str);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   GNUNET_free (result_str);
@@ -838,7 +853,7 @@ login_redirect (void *cls)
                                                           &login_base_url))
   {
     GNUNET_asprintf (&new_redirect,
-                     "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
+                     "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
                      login_base_url,
                      OIDC_RESPONSE_TYPE_KEY,
                      handle->oidc->response_type,
@@ -854,7 +869,10 @@ login_redirect (void *cls)
                      (NULL != handle->oidc->code_challenge) ?
                      handle->oidc->code_challenge : "",
                      OIDC_NONCE_KEY,
-                     (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
+                     (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "",
+                     OIDC_CLAIMS_KEY,
+                     (NULL != handle->oidc->claims) ? handle->oidc->claims :
+                     "");
     resp = GNUNET_REST_create_response ("");
     MHD_add_response_header (resp, "Location", new_redirect);
     GNUNET_free (login_base_url);
@@ -973,12 +991,14 @@ oidc_collect_finished_cb (void *cls)
 
 
 /**
- * Collects all attributes for an ego if in scope parameter
+ * Collects all attributes/references for an ego if in scope parameter
  */
 static void
 oidc_attr_collect (void *cls,
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-                   const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+                   const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+                   const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+                   const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
@@ -986,39 +1006,92 @@ oidc_attr_collect (void *cls,
   char *scope_variable;
   char delimiter[] = " ";
 
-  if ((NULL == attr->name) || (NULL == attr->data))
+  if ((NULL == attr) && (NULL == reference))
   {
     GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
     return;
   }
-
-  scope_variables = GNUNET_strdup (handle->oidc->scope);
-  scope_variable = strtok (scope_variables, delimiter);
-  while (NULL != scope_variable)
-  {
-    if (0 == strcmp (attr->name, scope_variable))
-      break;
-    scope_variable = strtok (NULL, delimiter);
-  }
-  if (NULL == scope_variable)
+  if (NULL != reference)
   {
-    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    if ((NULL == reference->name) || (NULL == reference->reference_value))
+    {
+      return;
+    }
+    scope_variables = GNUNET_strdup (handle->oidc->scope);
+    scope_variable = strtok (scope_variables, delimiter);
+    while (NULL != scope_variable)
+    {
+      if (0 == strcmp (reference->name, scope_variable))
+        break;
+      scope_variable = strtok (NULL, delimiter);
+    }
+    if (NULL == scope_variable)
+    {
+      GNUNET_free (scope_variables);
+      return;
+    }
     GNUNET_free (scope_variables);
-    return;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
+    le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+    le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+    le->claim = NULL;
+    le->reference = NULL;
+    le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (attest->name,
+                                                       attest->type,
+                                                       attest->data,
+                                                       attest->data_size);
+    le->attest->id = attest->id;
+    le2->attest = NULL;
+    le2->claim = NULL;
+    le2->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (reference->name,
+                                                               reference->
+                                                               reference_value);
+    le2->reference->id = reference->id;
+    le2->reference->id_attest = reference->id_attest;
+    GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
+                                 handle->attr_list->list_tail,
+                                 le);
+    GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
+                                 handle->attr_list->list_tail,
+                                 le2);
+  }
+  else if (NULL != attr)
+  {
+    if ((NULL == attr->name) || (NULL == attr->data))
+    {
+      GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+      return;
+    }
+    scope_variables = GNUNET_strdup (handle->oidc->scope);
+    scope_variable = strtok (scope_variables, delimiter);
+    while (NULL != scope_variable)
+    {
+      if (0 == strcmp (attr->name, scope_variable))
+        break;
+      scope_variable = strtok (NULL, delimiter);
+    }
+    if (NULL == scope_variable)
+    {
+      GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+      GNUNET_free (scope_variables);
+      return;
+    }
+    GNUNET_free (scope_variables);
+    le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+    le->reference = NULL;
+    le->attest = NULL;
+    le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
+                                                    attr->type,
+                                                    attr->data,
+                                                    attr->data_size);
+    le->claim->id = attr->id;
+    le->claim->flag = attr->flag;
+
+    GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
+                                 handle->attr_list->list_tail,
+                                 le);
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
   }
-  GNUNET_free (scope_variables);
-
-  le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-  le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
-                                                  attr->type,
-                                                  attr->data,
-                                                  attr->data_size);
-  le->claim->id = attr->id;
-  le->claim->version = attr->version;
-  GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
-                               handle->attr_list->list_tail,
-                               le);
-  GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
 }
 
 
@@ -1304,6 +1377,9 @@ build_authz_response (void *cls)
   // OPTIONAL value: nonce
   handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
 
+  // OPTIONAL value: claims
+  handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY);
+
   // TODO check other values if needed
   number_of_ignored_parameter =
     sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
@@ -1454,6 +1530,9 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
       handle->ego_entry = handle->ego_tail;
     }
   }
+  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scope: %s\n",GNUNET_strdup (
+                handle->oidc->scope));
   if (NULL == handle->tld)
     GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle);
   if (NULL == handle->tld)
@@ -1857,28 +1936,97 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
 
 
 /**
- * Collects claims and stores them in handle
- */
    * Collects claims and stores them in handle
    */
 static void
 consume_ticket (void *cls,
                 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-                const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+                const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+                const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+                const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
-  char *tmp_value;
-  json_t *value;
-
   if (NULL == identity)
   {
     GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle);
     return;
   }
-  tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
-                                                        attr->data,
-                                                        attr->data_size);
-  value = json_string (tmp_value);
-  json_object_set_new (handle->oidc->response, attr->name, value);
-  GNUNET_free (tmp_value);
+  if (NULL != attr)
+  {
+    char *tmp_value;
+    json_t *value;
+    tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
+                                                          attr->data,
+                                                          attr->data_size);
+    value = json_string (tmp_value);
+    json_object_set_new (handle->oidc->response, attr->name, value);
+    GNUNET_free (tmp_value);
+  }
+  else if ((NULL != attest) && (NULL != reference))
+  {
+    json_t *claim_sources;
+    json_t *claim_sources_jwt;
+    json_t *claim_names;
+    char *attest_val_str;
+    claim_sources=json_object_get(handle->oidc->response,"_claim_sources");
+    claim_names=json_object_get(handle->oidc->response,"_claim_names");
+    attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
+                                                                 attest->data,
+                                                                 attest->
+                                                                 data_size);
+    if ((NULL == claim_sources) && (NULL == claim_names) )
+    {
+      claim_sources = json_object ();
+      claim_names = json_object ();
+    }
+    char *source_name;
+    int i = 0;
+    GNUNET_asprintf (&source_name,"src%d",i);
+    while (NULL != (claim_sources_jwt = json_object_get (claim_sources,
+                                                         source_name)))
+    {
+      if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt,
+                                                           "JWT")),
+                       attest_val_str))
+      {
+        // Adapt only the claim names
+        json_object_set_new (claim_names, reference->name, json_string (
+                               source_name));
+        json_object_set (handle->oidc->response, "_claim_names",claim_names);
+        handle->oidc->response = json_deep_copy(handle->oidc->response);
+        break;
+      }
+      i++;
+      GNUNET_asprintf (&source_name,"src%d",i);
+    }
+
+    // Create new one
+    if (NULL == claim_sources_jwt)
+    {
+      claim_sources_jwt = json_object ();
+      // Set the JWT for names
+      json_object_set_new (claim_names, reference->name, json_string (
+                             source_name));
+      // Set the JWT for the inner source
+      json_object_set_new (claim_sources_jwt, "JWT", json_string (
+                             attest_val_str));
+      // Set the JWT for the source
+      json_object_set_new (claim_sources, source_name,claim_sources_jwt);
+      // Set as claims
+      json_object_set (handle->oidc->response, "_claim_names", claim_names);
+      json_object_set (handle->oidc->response, "_claim_sources",claim_sources);
+      handle->oidc->response = json_deep_copy(handle->oidc->response);
+    }
+
+    json_decref (claim_sources);
+    json_decref (claim_names);
+    json_decref (claim_sources_jwt);
+    GNUNET_free (attest_val_str);
+  }
+  else
+  {
+    // REMARK: We should not find any claim, one of attest/ref is NULL
+  }
 }
 
 
index 9a75b2d16cb2281bfb43605907c0fc8d9ab3312b..dcda75b657ece93323bb4d36a6a517219364e16d 100644 (file)
@@ -37,7 +37,6 @@
 #include "gnunet_rest_plugin.h"
 #include "gnunet_signatures.h"
 #include "json_reclaim.h"
-
 /**
  * REST root namespace
  */
  */
 #define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
 
+/**
+   * Attestation namespace
+   */
+#define GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE "/reclaim/attestation"
+
 /**
  * Ticket namespace
  */
@@ -272,6 +276,8 @@ cleanup_handle (struct RequestHandle *handle)
       claim_tmp = claim_entry;
       claim_entry = claim_entry->next;
       GNUNET_free (claim_tmp->claim);
+      GNUNET_free (claim_tmp->attest);
+      GNUNET_free (claim_tmp->reference);
       GNUNET_free (claim_tmp);
     }
     GNUNET_free (handle->attr_list);
@@ -360,6 +366,21 @@ finished_cont (void *cls, int32_t success, const char *emsg)
   GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
 }
 
+static void
+delete_finished_cb (void *cls, int32_t success, const char *emsg)
+{
+  struct RequestHandle *handle = cls;
+  struct MHD_Response *resp;
+
+  resp = GNUNET_REST_create_response (emsg);
+  if (GNUNET_OK != success)
+  {
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+}
 
 /**
  * Return attributes for identity
@@ -434,88 +455,205 @@ ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
 }
 
 
-/**
- * List tickets for identity request
- *
- * @param con_handle the connection handle
- * @param url the url
- * @param cls the RequestHandle
- */
 static void
-list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
-                   const char *url,
-                   void *cls)
+add_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                          const char *url,
+                          void *cls)
 {
-  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
   struct RequestHandle *handle = cls;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
+  const char *identity;
   struct EgoEntry *ego_entry;
-  char *identity;
-
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attribute;
+  struct GNUNET_TIME_Relative exp;
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+  struct GNUNET_JSON_Specification attrspec[] =
+  { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attribute),
+    GNUNET_JSON_spec_end () };
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Getting tickets for %s.\n",
+              "Adding an attestation reference for %s.\n",
               handle->url);
-  if (strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= strlen (handle->url))
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+        "reference/") + 1 >= strlen (
+        handle->url))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
-
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
+             + 1;
   for (ego_entry = handle->ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
-  handle->resp_object = json_array ();
-
   if (NULL == ego_entry)
   {
-    // Done
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
-    GNUNET_SCHEDULER_add_now (&return_response, handle);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
     return;
   }
-  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  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);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+  json_decref (data_json);
+  if (NULL == attribute)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse attestation reference from %s\n",
+                term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  /**
+   * New ID for attribute
+   */
+  if (0 == attribute->id)
+    attribute->id = attribute->id_attest;
   handle->idp = GNUNET_RECLAIM_connect (cfg);
-  handle->ticket_it =
-    GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
-                                           priv_key,
-                                           &collect_error_cb,
-                                           handle,
-                                           &ticket_collect,
-                                           handle,
-                                           &collect_finished_cb,
-                                           handle);
+  exp = GNUNET_TIME_UNIT_HOURS;
+  handle->idp_op = GNUNET_RECLAIM_attestation_reference_store (handle->idp,
+                                                               identity_priv,
+                                                               attribute,
+                                                               &exp,
+                                                               &finished_cont,
+                                                               handle);
+  GNUNET_JSON_parse_free (attrspec);
 }
 
+static void
+parse_attestation_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];
+  json_t *data_json;
+  json_error_t err;
+  int unpack_state;
+  struct MHD_Response *resp;
+  char *val_str = NULL;
+  const char *type_str = NULL;
+  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);
+  GNUNET_assert (NULL != data_json);
+  if (! json_is_object (data_json))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json is not array nor object!\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  unpack_state = json_unpack (data_json,
+                              "{s:s, s:s!}",
+                              "value",
+                              &val_str,
+                              "type",
+                              &type_str);
+  if ((0 != unpack_state) || (NULL == val_str) || (NULL == type_str))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json object has a wrong format!\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  if (0 == strcmp (type_str, "JWT"))
+  {
+  // The value is a JWT
+  char *decoded_jwt;
+  char delim[] = ".";
+  char *jwt_body = strtok (val_str, delim);
+  jwt_body = strtok (NULL, delim);
+  GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
+                                (void **) &decoded_jwt);
+  resp = GNUNET_REST_create_response (decoded_jwt);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_free (decoded_jwt);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error requested parsing type not supported!\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  cleanup_handle (handle);
+  json_decref (data_json);
+}
 
 static void
-add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
-                    const char *url,
-                    void *cls)
+add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                      const char *url,
+                      void *cls)
 {
+  struct RequestHandle *handle = cls;
+  /* Check for substring "reference" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+        handle->url))
+  {
+    if ( strncmp ("reference/", (handle->url + strlen (
+                                   GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                                 + 1), strlen (
+                    "reference/")) == 0)
+    {
+      add_attestation_ref_cont (con_handle,url,cls);
+      return;
+    }
+  }
+  /* Check for substring "parse" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+      handle->url))
+      {
+        if ( strncmp ("parse", (handle->url + strlen (
+                          GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                        + 1), strlen (
+            "parse")) == 0)
+        {
+          parse_attestation_cont (con_handle,url,cls);
+          return;
+        }
+      }
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
   const char *identity;
-  struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
-  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attribute;
   struct GNUNET_TIME_Relative exp;
   char term_data[handle->rest_handle->data_size + 1];
   json_t *data_json;
   json_error_t err;
   struct GNUNET_JSON_Specification attrspec[] =
-  { GNUNET_RECLAIM_JSON_spec_claim (&attribute), GNUNET_JSON_spec_end () };
+  { GNUNET_RECLAIM_JSON_spec_claim_attest (&attribute),
+    GNUNET_JSON_spec_end () };
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Adding an attribute for %s.\n",
+              "Adding an attestation for %s.\n",
               handle->url);
-  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
+        handle->url))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
 
   for (ego_entry = handle->ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
@@ -546,7 +684,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
   if (NULL == attribute)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unable to parse attribute from %s\n",
+                "Unable to parse attestation from %s\n",
                 term_data);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
@@ -559,66 +697,67 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
   handle->idp = GNUNET_RECLAIM_connect (cfg);
   exp = GNUNET_TIME_UNIT_HOURS;
-  handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
-                                                   identity_priv,
-                                                   attribute,
-                                                   &exp,
-                                                   &finished_cont,
-                                                   handle);
+  handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp,
+                                                     identity_priv,
+                                                     attribute,
+                                                     &exp,
+                                                     &finished_cont,
+                                                     handle);
   GNUNET_JSON_parse_free (attrspec);
 }
 
-
 /**
- * Collect all attributes for an ego
+ * Collect all references for an ego
  *
  */
 static void
-attr_collect (void *cls,
-              const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+ref_collect (void *cls,
+             const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+             const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+             const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+             const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
   json_t *attr_obj;
-  const char *type;
-  char *tmp_value;
   char *id_str;
+  char *id_attest_str;
 
-  if ((NULL == attr->name) || (NULL == attr->data))
+  if (NULL == reference)
   {
     GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
     return;
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
-
-  tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
-                                                        attr->data,
-                                                        attr->data_size);
+  if ((NULL == reference->name) || (NULL == reference->reference_value))
+  {
+    return;
+  }
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference: %s\n",
+              reference->name);
   attr_obj = json_object ();
-  json_object_set_new (attr_obj, "value", json_string (tmp_value));
-  json_object_set_new (attr_obj, "name", json_string (attr->name));
-  type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
-  json_object_set_new (attr_obj, "type", json_string (type));
-  id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
+  json_object_set_new (attr_obj, "name", json_string (reference->name));
+  json_object_set_new (attr_obj, "ref_value", json_string (
+                         reference->reference_value));
+  id_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id,
+                                                sizeof(uint64_t));
+  id_attest_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id_attest,
+                                                       sizeof(uint64_t));
   json_object_set_new (attr_obj, "id", json_string (id_str));
+  json_object_set_new (attr_obj, "ref_id", json_string (id_attest_str));
   json_array_append (handle->resp_object, attr_obj);
   json_decref (attr_obj);
-  GNUNET_free (tmp_value);
-  GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
 }
 
-
 /**
- * List attributes for identity request
+ * Lists references for identity request
  *
  * @param con_handle the connection handle
  * @param url the url
  * @param cls the RequestHandle
  */
 static void
-list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+list_reference_cont (struct GNUNET_REST_RequestHandle *con_handle,
                      const char *url,
                      void *cls)
 {
@@ -628,23 +767,25 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
   char *identity;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Getting attributes for %s.\n",
+              "Getting references for %s.\n",
               handle->url);
-  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+        "reference/") + 1 >= strlen (
+        handle->url))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
-
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
+             + 1;
   for (ego_entry = handle->ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
   handle->resp_object = json_array ();
 
-
   if (NULL == ego_entry)
   {
     // Done
@@ -658,100 +799,737 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
                                                          priv_key,
                                                          &collect_error_cb,
                                                          handle,
-                                                         &attr_collect,
+                                                         &ref_collect,
                                                          handle,
                                                          &collect_finished_cb,
                                                          handle);
 }
 
-
+/**
+ * Collect all attestations for an ego
+ *
+ */
 static void
-delete_finished_cb (void *cls, int32_t success, const char *emsg)
+attest_collect (void *cls,
+                const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+                const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+                const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+                const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
-  struct MHD_Response *resp;
+  json_t *attr_obj;
+  const char *type;
+  char *tmp_value;
+  char *id_str;
 
-  resp = GNUNET_REST_create_response (emsg);
-  if (GNUNET_OK != success)
+
+  if (NULL != reference)
   {
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attestation Collection with Reference\n");
     return;
   }
-  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+  if (NULL == attest)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attestation Collection with empty Attestation\n");
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    return;
+  }
+
+  if ((NULL == attest->name) || (NULL == attest->data))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attestation Collection with empty Name/Value\n");
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation: %s\n",
+              attest->name);
+
+  tmp_value = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
+                                                          attest->data,
+                                                          attest->data_size);
+  attr_obj = json_object ();
+  json_object_set_new (attr_obj, "value", json_string (tmp_value));
+  json_object_set_new (attr_obj, "name", json_string (attest->name));
+  type = GNUNET_RECLAIM_ATTESTATION_number_to_typename (attest->type);
+  json_object_set_new (attr_obj, "type", json_string (type));
+  id_str = GNUNET_STRINGS_data_to_string_alloc (&attest->id, sizeof(uint64_t));
+  json_object_set_new (attr_obj, "id", json_string (id_str));
+  json_array_append (handle->resp_object, attr_obj);
+  json_decref (attr_obj);
+  GNUNET_free (tmp_value);
+  GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
 }
 
 
 /**
- * List attributes for identity request
+ * Lists attestation for identity request
  *
  * @param con_handle the connection handle
  * @param url the url
  * @param cls the RequestHandle
  */
 static void
-delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
                        const char *url,
                        void *cls)
 {
-  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
   struct RequestHandle *handle = cls;
-  struct GNUNET_RECLAIM_ATTRIBUTE_Claim attr;
+  /* Check for substring "reference" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+        handle->url))
+  {
+    if ( strncmp ("reference/", (handle->url + strlen (
+                                   GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                                 + 1), strlen (
+                    "reference/")) == 0)
+    {
+      list_reference_cont (con_handle,url,cls);
+      return;
+    }
+  }
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
   struct EgoEntry *ego_entry;
-  char *identity_id_str;
   char *identity;
-  char *id;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attributes.\n");
-  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Getting attestations for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
+        handle->url))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  identity_id_str =
-    strdup (handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1);
-  identity = strtok (identity_id_str, "/");
-  id = strtok (NULL, "/");
-  if ((NULL == identity) || (NULL == id))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
-    GNUNET_free (identity_id_str);
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
-  }
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
 
   for (ego_entry = handle->ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
   handle->resp_object = json_array ();
+
+
   if (NULL == ego_entry)
   {
     // Done
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
-    GNUNET_free (identity_id_str);
     GNUNET_SCHEDULER_add_now (&return_response, handle);
     return;
   }
   priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
   handle->idp = GNUNET_RECLAIM_connect (cfg);
-  memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim));
-  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
-  attr.name = "";
-  handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp,
-                                                    priv_key,
-                                                    &attr,
-                                                    &delete_finished_cb,
-                                                    handle);
-  GNUNET_free (identity_id_str);
+  handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
+                                                         priv_key,
+                                                         &collect_error_cb,
+                                                         handle,
+                                                         &attest_collect,
+                                                         handle,
+                                                         &collect_finished_cb,
+                                                         handle);
 }
 
-
+/**
+ * Deletes reference from an identity
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
 static void
-revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
-                    const char *url,
-                    void *cls)
+delete_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                             const char *url,
+                             void *cls)
+{
+  struct RequestHandle *handle = cls;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  struct EgoEntry *ego_entry;
+  char *identity;
+  char *identity_id_str;
+  char *id;
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+
+  struct GNUNET_JSON_Specification attrspec[] =
+  { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attr),
+    GNUNET_JSON_spec_end () };
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Deleting attestation reference.\n");
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+        "reference/") + 1 >= strlen (
+        handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity_id_str = strdup (handle->url + strlen (
+                              GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                            + strlen ("reference/")
+                            + 1);
+  identity = strtok (identity_id_str, "/");
+  id = strtok (NULL, "/");
+
+  if ((NULL == identity) || (NULL == id))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+  handle->resp_object = json_array ();
+  if (NULL == ego_entry)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
+    GNUNET_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  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);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+  json_decref (data_json);
+  if (NULL == attr)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse attestation reference from %s\n",
+                term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr->id, sizeof(uint64_t));
+
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  handle->idp_op = GNUNET_RECLAIM_attestation_reference_delete (handle->idp,
+                                                                priv_key,
+                                                                attr,
+                                                                &
+                                                                delete_finished_cb,
+                                                                handle);
+  GNUNET_JSON_parse_free (attrspec);
+}
+
+
+/**
+ * Deletes attestation from an identity
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                         const char *url,
+                         void *cls)
+{
+  struct RequestHandle *handle = cls;
+  /* Check for substring "reference" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+        handle->url))
+  {
+    if ( strncmp ("reference", (handle->url + strlen (
+                                  GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                                + 1), strlen (
+                    "reference")) == 0)
+    {
+      delete_attestation_ref_cont (con_handle,url,cls);
+      return;
+    }
+  }
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct GNUNET_RECLAIM_ATTESTATION_Claim attr;
+  struct EgoEntry *ego_entry;
+  char *identity_id_str;
+  char *identity;
+  char *id;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attestation.\n");
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
+        handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity_id_str =
+    strdup (handle->url + strlen (
+              GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1);
+  identity = strtok (identity_id_str, "/");
+  id = strtok (NULL, "/");
+  if ((NULL == identity) || (NULL == id))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
+    GNUNET_free (identity_id_str);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+  handle->resp_object = json_array ();
+  if (NULL == ego_entry)
+  {
+    // Done
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
+    GNUNET_free (identity_id_str);
+    GNUNET_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim));
+  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
+  attr.name = "";
+  handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp,
+                                                      priv_key,
+                                                      &attr,
+                                                      &delete_finished_cb,
+                                                      handle);
+  GNUNET_free (identity_id_str);
+}
+
+/**
+ * List tickets for identity request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                   const char *url,
+                   void *cls)
+{
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  char *identity;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Getting tickets for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= strlen (handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
+
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+  handle->resp_object = json_array ();
+
+  if (NULL == ego_entry)
+  {
+    // Done
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
+    GNUNET_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  handle->ticket_it =
+    GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
+                                           priv_key,
+                                           &collect_error_cb,
+                                           handle,
+                                           &ticket_collect,
+                                           handle,
+                                           &collect_finished_cb,
+                                           handle);
+}
+
+
+static void
+add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                    const char *url,
+                    void *cls)
+{
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
+  const char *identity;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
+  struct GNUNET_TIME_Relative exp;
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+  struct GNUNET_JSON_Specification attrspec[] =
+  { GNUNET_RECLAIM_JSON_spec_claim (&attribute), GNUNET_JSON_spec_end () };
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Adding an attribute for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
+
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+
+  if (NULL == ego_entry)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
+    return;
+  }
+  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+
+  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);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+  json_decref (data_json);
+  if (NULL == attribute)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse attribute from %s\n",
+                term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  /**
+   * New ID for attribute
+   */
+  if (0 == attribute->id)
+    attribute->id =
+      GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  exp = GNUNET_TIME_UNIT_HOURS;
+  handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
+                                                   identity_priv,
+                                                   attribute,
+                                                   &exp,
+                                                   &finished_cont,
+                                                   handle);
+  GNUNET_JSON_parse_free (attrspec);
+}
+
+/**
+ * Parse a JWT and return the respective claim value as Attribute
+ *
+ * @param attest the jwt attestation
+ * @param claim the name of the claim in the JWT
+ *
+ * @return a GNUNET_RECLAIM_ATTRIBUTE_Claim, containing the new value
+ */
+struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
+parse_jwt (const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+           const char *claim)
+{
+  char *jwt_string;
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
+  char delim[] = ".";
+  const char *type_str = NULL;
+  const char *val_str = NULL;
+  char *data;
+  size_t data_size;
+  uint32_t type;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
+  char *decoded_jwt;
+  json_t *json_val;
+  json_error_t *json_err = NULL;
+
+  jwt_string = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
+                                                           attest->data,
+                                                           attest->data_size);
+  char *jwt_body = strtok (jwt_string, delim);
+  jwt_body = strtok (NULL, delim);
+  GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
+                                (void **) &decoded_jwt);
+  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+  const char *key;
+  json_t *value;
+  json_object_foreach (json_val, key, value) {
+    if (0 == strcasecmp (key,claim))
+    {
+      val_str = json_dumps (value, JSON_ENCODE_ANY);
+    }
+  }
+  type_str = "String";
+  type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
+  if (GNUNET_SYSERR ==(GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,val_str,
+                                                                 (void **) &data,
+                                                                 &data_size)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attribute value from JWT Parser invalid!\n");
+    GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
+                                              "Error: Referenced Claim Name not Found",
+                                              (void **) &data,
+                                              &data_size);
+    attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
+    attr->id = attest->id;
+    attr->flag = 1;
+  }
+  else
+  {
+    attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
+    attr->id = attest->id;
+    attr->flag = 1;
+  }
+  return attr;
+}
+
+
+/**
+ * Collect all attributes for an ego
+ *
+ */
+static void
+attr_collect (void *cls,
+              const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+              const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+              const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
+{
+  struct RequestHandle *handle = cls;
+  json_t *attr_obj;
+  const char *type;
+  char *id_str;
+
+  if ((NULL == attr) && (NULL == reference))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attribute Collection with empty Attribute/Reference\n");
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    return;
+  }
+
+  if (NULL == attr)
+  {
+
+    if ((NULL == reference->name) || (NULL == reference->reference_value))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute Collection with empty Reference Name/Value\n");
+      return;
+    }
+    struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr2;
+    attr2 = parse_jwt (attest, reference->reference_value);
+    if (NULL == attr2)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute Collection with unparsed Attestation\n");
+      return;
+    }
+    attr2->name = reference->name;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference as attribute: %s\n",
+                reference->name);
+    char *tmp_value;
+    tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr2->type,
+                                                          attr2->data,
+                                                          attr2->data_size);
+    attr_obj = json_object ();
+
+    json_object_set_new (attr_obj, "value", json_string (tmp_value));
+    json_object_set_new (attr_obj, "name", json_string (attr2->name));
+    json_object_set_new (attr_obj, "flag", json_string ("1"));
+    type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr2->type);
+    json_object_set_new (attr_obj, "type", json_string (type));
+    id_str = GNUNET_STRINGS_data_to_string_alloc (&attr2->id, sizeof(uint64_t));
+    json_object_set_new (attr_obj, "id", json_string (id_str));
+    json_array_append (handle->resp_object, attr_obj);
+    json_decref (attr_obj);
+    GNUNET_free (tmp_value);
+  }
+  else
+  {
+    if ((NULL == attr->name) || (NULL == attr->data))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute Collection with empty Attribute Name/Value\n");
+      GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+      return;
+    }
+    char *tmp_value;
+    char *flag_str;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
+
+    tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
+                                                          attr->data,
+                                                          attr->data_size);
+
+    attr_obj = json_object ();
+    json_object_set_new (attr_obj, "value", json_string (tmp_value));
+    json_object_set_new (attr_obj, "name", json_string (attr->name));
+    GNUNET_asprintf (&flag_str,"%d",attr->flag);
+    json_object_set_new (attr_obj, "flag", json_string (flag_str));
+    type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
+    json_object_set_new (attr_obj, "type", json_string (type));
+    id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
+    json_object_set_new (attr_obj, "id", json_string (id_str));
+    json_array_append (handle->resp_object, attr_obj);
+    json_decref (attr_obj);
+    GNUNET_free (tmp_value);
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+  }
+}
+
+/**
+ * List attributes for identity request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                     const char *url,
+                     void *cls)
+{
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  char *identity;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Getting attributes for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
+
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+  handle->resp_object = json_array ();
+
+
+  if (NULL == ego_entry)
+  {
+    // Done
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
+    GNUNET_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
+                                                         priv_key,
+                                                         &collect_error_cb,
+                                                         handle,
+                                                         &attr_collect,
+                                                         handle,
+                                                         &collect_finished_cb,
+                                                         handle);
+}
+
+
+/**
+ * List attributes for identity request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                       const char *url,
+                       void *cls)
+{
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct RequestHandle *handle = cls;
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim attr;
+  struct EgoEntry *ego_entry;
+  char *identity_id_str;
+  char *identity;
+  char *id;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attributes.\n");
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity_id_str =
+    strdup (handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1);
+  identity = strtok (identity_id_str, "/");
+  id = strtok (NULL, "/");
+  if ((NULL == identity) || (NULL == id))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
+    GNUNET_free (identity_id_str);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+  handle->resp_object = json_array ();
+  if (NULL == ego_entry)
+  {
+    // Done
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
+    GNUNET_free (identity_id_str);
+    GNUNET_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim));
+  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
+  attr.name = "";
+  handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp,
+                                                    priv_key,
+                                                    &attr,
+                                                    &delete_finished_cb,
+                                                    handle);
+  GNUNET_free (identity_id_str);
+}
+
+
+static void
+revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                    const char *url,
+                    void *cls)
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
   struct RequestHandle *handle = cls;
@@ -825,7 +1603,9 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
 static void
 consume_cont (void *cls,
               const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+              const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+              const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
   char *val_str;
@@ -968,6 +1748,15 @@ init_cont (struct RequestHandle *handle)
     { MHD_HTTP_METHOD_DELETE,
       GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
       &delete_attribute_cont },
+    { MHD_HTTP_METHOD_GET,
+      GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
+      &list_attestation_cont },
+    { MHD_HTTP_METHOD_POST,
+      GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
+      &add_attestation_cont },
+    { MHD_HTTP_METHOD_DELETE,
+      GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
+      &delete_attestation_cont },
     { MHD_HTTP_METHOD_GET,
       GNUNET_REST_API_NS_IDENTITY_TICKETS,
       &list_tickets_cont },
index 8e731812e92d970f5742c0273dc0c83d9ce558b0..ff953a0963fc304bb9f41f698001c047a6ea8127 100644 (file)
@@ -153,6 +153,45 @@ struct AttributeResultMessage
    */
 };
 
+/**
+ * Reference plus Attestation is returned from the idp.
+ */
+struct ReferenceResultMessage
+{
+  /**
+   * Message header
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Unique identifier for this request (for key collisions).
+   */
+  uint32_t id GNUNET_PACKED;
+
+  /**
+   * Length of serialized attestation data
+   */
+  uint16_t attest_len GNUNET_PACKED;
+
+  /**
+   * Length of serialized reference data
+   */
+  uint16_t ref_len GNUNET_PACKED;
+
+  /**
+   * always zero (for alignment)
+   */
+  uint16_t reserved GNUNET_PACKED;
+
+  /**
+   * The public key of the identity.
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey identity;
+
+  /* followed by:
+   * serialized reference data + attestation data
+   */
+};
 
 /**
  * Start a attribute iteration for the given identity
index 7d4d7588a73e9ea822e0595d7a5948acf05b1876..847abb58a1536e3dcbaaf2ab36ed204a4c814692 100644 (file)
@@ -486,7 +486,7 @@ handle_consume_ticket_result (void *cls,
   uint32_t r_id = ntohl (msg->id);
 
   attrs_len = ntohs (msg->attrs_len);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
 
 
   for (op = h->op_head; NULL != op; op = op->next)
@@ -498,22 +498,36 @@ handle_consume_ticket_result (void *cls,
   {
     struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
     struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
     attrs =
       GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &msg[1], attrs_len);
     if (NULL != op->ar_cb)
     {
       if (NULL == attrs)
       {
-        op->ar_cb (op->cls, &msg->identity, NULL);
+        op->ar_cb (op->cls, &msg->identity, NULL, NULL, NULL);
       }
       else
       {
         for (le = attrs->list_head; NULL != le; le = le->next)
-          op->ar_cb (op->cls, &msg->identity, le->claim);
+        {
+          if (le->reference != NULL && le->attest == NULL)
+          {
+            for (le2 = attrs->list_head; NULL != le2; le2 = le2->next)
+            {
+              if (le2->attest != NULL && le2->attest->id == le->reference->id_attest)
+              {
+                op->ar_cb (op->cls, &msg->identity, le->claim, le2->attest, le->reference);
+                break;
+              }
+
+            }
+          }
+        }
         GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
         attrs = NULL;
       }
-      op->ar_cb (op->cls, NULL, NULL);
+      op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
     }
     GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
     free_op (op);
@@ -597,7 +611,7 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
     if (NULL != op)
     {
       if (NULL != op->ar_cb)
-        op->ar_cb (op->cls, NULL, NULL);
+        op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
       GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
       free_op (op);
     }
@@ -610,12 +624,111 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
     if (NULL != it)
     {
       if (NULL != it->proc)
-        it->proc (it->proc_cls, &msg->identity, attr);
+        it->proc (it->proc_cls, &msg->identity, attr, NULL, NULL);
+    }
+    else if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, &msg->identity, attr, NULL, NULL);
+    }
+    GNUNET_free (attr);
+    return;
+  }
+  GNUNET_assert (0);
+}
+
+/**
+   * Handle an incoming message of type
+   * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
+   *
+   * @param cls
+   * @param msg the message we received
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+   */
+static int
+check_attestation_result (void *cls, const struct AttributeResultMessage *msg)
+{
+  size_t msg_len;
+  size_t attr_len;
+
+  msg_len = ntohs (msg->header.size);
+  attr_len = ntohs (msg->attr_len);
+  if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
+ *
+ * @param cls
+ * @param msg the message we received
+ */
+static void
+handle_attestation_result (void *cls, const struct AttributeResultMessage *msg)
+{
+  static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
+  struct GNUNET_RECLAIM_Handle *h = cls;
+  struct GNUNET_RECLAIM_AttributeIterator *it;
+  struct GNUNET_RECLAIM_Operation *op;
+  size_t attr_len;
+  uint32_t r_id = ntohl (msg->id);
+
+  attr_len = ntohs (msg->attr_len);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attestation result.\n");
+
+
+  for (it = h->it_head; NULL != it; it = it->next)
+    if (it->r_id == r_id)
+      break;
+  for (op = h->op_head; NULL != op; op = op->next)
+    if (op->r_id == r_id)
+      break;
+  if ((NULL == it) && (NULL == op))
+    return;
+
+  if ((0 ==
+       (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
+  {
+    if ((NULL == it) && (NULL == op))
+    {
+      GNUNET_break (0);
+      force_reconnect (h);
+      return;
+    }
+    if (NULL != it)
+    {
+      if (NULL != it->finish_cb)
+        it->finish_cb (it->finish_cb_cls);
+      free_it (it);
+    }
+    if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
+      GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
+      free_op (op);
+    }
+    return;
+  }
+
+  {
+    struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+    attr = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1], attr_len);
+    if (NULL != it)
+    {
+      if (NULL != it->proc)
+        it->proc (it->proc_cls, &msg->identity, NULL, attr, NULL);
     }
     else if (NULL != op)
     {
       if (NULL != op->ar_cb)
-        op->ar_cb (op->cls, &msg->identity, attr);
+        op->ar_cb (op->cls, &msg->identity, NULL, attr, NULL);
     }
     GNUNET_free (attr);
     return;
@@ -623,6 +736,110 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
   GNUNET_assert (0);
 }
 
+/**
+   * Handle an incoming message of type
+   * #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
+   *
+   * @param cls
+   * @param msg the message we received
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+   */
+static int
+check_reference_result (void *cls, const struct ReferenceResultMessage *msg)
+{
+  size_t msg_len;
+  size_t attr_len;
+  size_t ref_len;
+
+  msg_len = ntohs (msg->header.size);
+  attr_len = ntohs (msg->attest_len);
+  ref_len = ntohs (msg->ref_len);
+  if (msg_len != sizeof(struct ReferenceResultMessage) + attr_len + ref_len)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+/**
+* Handle an incoming message of type
+* #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
+*
+* @param cls
+* @param msg the message we received
+*/
+static void
+handle_reference_result (void *cls, const struct ReferenceResultMessage *msg)
+{
+  static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
+  struct GNUNET_RECLAIM_Handle *h = cls;
+  struct GNUNET_RECLAIM_AttributeIterator *it;
+  struct GNUNET_RECLAIM_Operation *op;
+  size_t attest_len;
+  size_t ref_len;
+  uint32_t r_id = ntohl (msg->id);
+  attest_len = ntohs (msg->attest_len);
+  ref_len = ntohs (msg->ref_len);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing reference result.\n");
+  for (it = h->it_head; NULL != it; it = it->next)
+    if (it->r_id == r_id)
+      break;
+  for (op = h->op_head; NULL != op; op = op->next)
+    if (op->r_id == r_id)
+      break;
+  if ((NULL == it) && (NULL == op))
+    return;
+
+  if ((0 ==
+       (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
+  {
+    if ((NULL == it) && (NULL == op))
+    {
+      GNUNET_break (0);
+      force_reconnect (h);
+      return;
+    }
+    if (NULL != it)
+    {
+      if (NULL != it->finish_cb)
+        it->finish_cb (it->finish_cb_cls);
+      free_it (it);
+    }
+    if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
+      GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
+      free_op (op);
+    }
+    return;
+  }
+
+  {
+    struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
+    struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+    attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1],
+                                                     attest_len);
+    ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &msg[1]
+                                                      + attest_len,
+                                                      ref_len);
+    if (NULL != it)
+    {
+      if (NULL != it->proc)
+        it->proc (it->proc_cls, &msg->identity, NULL, attest, ref);
+    }
+    else if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, &msg->identity, NULL, attest, ref);
+    }
+    GNUNET_free (ref);
+    GNUNET_free (attest);
+    return;
+  }
+  GNUNET_assert (0);
+}
 
 /**
  * Handle an incoming message of type
@@ -742,6 +959,14 @@ reconnect (struct GNUNET_RECLAIM_Handle *h)
                            GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
                            struct AttributeResultMessage,
                            h),
+    GNUNET_MQ_hd_var_size (attestation_result,
+                           GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT,
+                           struct AttributeResultMessage,
+                           h),
+    GNUNET_MQ_hd_var_size (reference_result,
+                           GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT,
+                           struct ReferenceResultMessage,
+                           h),
     GNUNET_MQ_hd_fixed_size (ticket_result,
                              GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
                              struct TicketResultMessage,
@@ -925,6 +1150,185 @@ GNUNET_RECLAIM_attribute_delete (
   return op;
 }
 
+/**
+   * Store an attestation.  If the attestation is already present,
+   * it is replaced with the new attestation.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey private key of the identity
+   * @param attr the attestation value
+   * @param exp_interval the relative expiration interval for the attestation
+   * @param cont continuation to call when done
+   * @param cont_cls closure for @a cont
+   * @return handle to abort the request
+   */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_store (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  const struct GNUNET_TIME_Relative *exp_interval,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls)
+{
+  struct GNUNET_RECLAIM_Operation *op;
+  struct AttributeStoreMessage *sam;
+  size_t attr_len;
+
+  op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+  op->h = h;
+  op->as_cb = cont;
+  op->cls = cont_cls;
+  op->r_id = h->r_id_gen++;
+  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+  attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attr);
+  op->env = GNUNET_MQ_msg_extra (sam,
+                                 attr_len,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE);
+  sam->identity = *pkey;
+  sam->id = htonl (op->r_id);
+  sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
+
+  GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &sam[1]);
+
+  sam->attr_len = htons (attr_len);
+  if (NULL != h->mq)
+    GNUNET_MQ_send_copy (h->mq, op->env);
+  return op;
+}
+
+/**
+   * Delete an attestation. Tickets used to share this attestation are updated
+   * accordingly.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey Private key of the identity to add an attribute to
+   * @param attr The attestation
+   * @param cont Continuation to call when done
+   * @param cont_cls Closure for @a cont
+   * @return handle Used to to abort the request
+   */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls)
+{
+  struct GNUNET_RECLAIM_Operation *op;
+  struct AttributeDeleteMessage *dam;
+  size_t attr_len;
+
+  op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+  op->h = h;
+  op->as_cb = cont;
+  op->cls = cont_cls;
+  op->r_id = h->r_id_gen++;
+  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+  attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attr);
+  op->env = GNUNET_MQ_msg_extra (dam,
+                                 attr_len,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE);
+  dam->identity = *pkey;
+  dam->id = htonl (op->r_id);
+  GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &dam[1]);
+
+  dam->attr_len = htons (attr_len);
+  if (NULL != h->mq)
+    GNUNET_MQ_send_copy (h->mq, op->env);
+  return op;
+}
+
+/**
+   * Store an attestation reference.  If the reference is already present,
+   * it is replaced with the new reference.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey private key of the identity
+   * @param attr the reference value
+   * @param exp_interval the relative expiration interval for the reference
+   * @param cont continuation to call when done
+   * @param cont_cls closure for @a cont
+   * @return handle to abort the request
+   */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_store (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  const struct GNUNET_TIME_Relative *exp_interval,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls)
+{
+  struct GNUNET_RECLAIM_Operation *op;
+  struct AttributeStoreMessage *sam;
+  size_t attr_len;
+  op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+  op->h = h;
+  op->as_cb = cont;
+  op->cls = cont_cls;
+  op->r_id = h->r_id_gen++;
+  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+  attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
+  op->env = GNUNET_MQ_msg_extra (sam,
+                                 attr_len,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE);
+  sam->identity = *pkey;
+  sam->id = htonl (op->r_id);
+  sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
+
+  GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &sam[1]);
+
+  sam->attr_len = htons (attr_len);
+  if (NULL != h->mq)
+    GNUNET_MQ_send_copy (h->mq, op->env);
+  return op;
+}
+
+/**
+ * Delete an attestation reference. Tickets used to share this reference are updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to delete the reference from
+ * @param attr The reference
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls)
+{
+
+  struct GNUNET_RECLAIM_Operation *op;
+  struct AttributeDeleteMessage *dam;
+  size_t attr_len;
+
+  op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+  op->h = h;
+  op->as_cb = cont;
+  op->cls = cont_cls;
+  op->r_id = h->r_id_gen++;
+  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+  attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
+  op->env = GNUNET_MQ_msg_extra (dam,
+                                 attr_len,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE);
+  dam->identity = *pkey;
+  dam->id = htonl (op->r_id);
+  GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &dam[1]);
+
+  dam->attr_len = htons (attr_len);
+  if (NULL != h->mq)
+    GNUNET_MQ_send_copy (h->mq, op->env);
+  return op;
+}
 
 /**
  * List all attributes for a local identity.
index c37a34ab795ed7e1f8129ac8236d389fc06006e3..077c0409aef601b64206604ea1293fa15b7d138b 100644 (file)
@@ -1527,15 +1527,15 @@ test_transport_api_slow_ats_peer2.conf \
   tcp_server_mst_legacy.c \
   tcp_server_legacy.c \
   tcp_service_legacy.c \
-test_communicator_basic_unix_peer1.conf \
-test_communicator_basic_unix_peer2.conf \
-test_communicator_basic_tcp_peer1.conf \
-test_communicator_basic_tcp_peer2.conf \
-test_communicator_basic_udp_peer1.conf \
-test_communicator_basic_udp_peer2.conf \
-test_communicator_rekey_tcp_peer1.conf \
-test_communicator_rekey_tcp_peer2.conf \
-test_communicator_rekey_udp_peer1.conf \
-test_communicator_rekey_udp_peer2.conf \
-test_communicator_backchannel_udp_peer1.conf \
-test_communicator_backchannel_udp_peer2.conf
+test_communicator_unix_basic_peer1.conf \
+test_communicator_unix_basic_peer2.conf \
+test_communicator_tcp_basic_peer1.conf \
+test_communicator_tcp_basic_peer2.conf \
+test_communicator_udp_basic_peer1.conf \
+test_communicator_udp_basic_peer2.conf \
+test_communicator_tcp_rekey_peer1.conf \
+test_communicator_tcp_rekey_peer2.conf \
+test_communicator_udp_rekey_peer1.conf \
+test_communicator_udp_rekey_peer2.conf \
+test_communicator_udp_backchannel_peer1.conf \
+test_communicator_udp_backchannel_peer2.conf
diff --git a/src/transport/test_communicator_unix_basic_peer1.conf b/src/transport/test_communicator_unix_basic_peer1.conf
new file mode 100644 (file)
index 0000000..d505880
--- /dev/null
@@ -0,0 +1,30 @@
+@INLINE@ test_transport_defaults.conf
+
+[PATHS]
+GNUNET_TEST_HOME = $GNUNET_TMP/test-communicator-unix-1/
+
+[PEER]
+PRIVATE_KEY = $GNUNET_TMP/test-communicator-unix-1/private.key
+
+[transport-tcp]
+PORT = 52400
+
+[transport-udp]
+PORT = 52401
+
+[transport]
+PORT = 60000
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
+
+[nat]
+UNIXPATH = $GNUNET_TMP/communicator-unix-1/nat.sock
+ENABLE_IPSCAN = YES
+
+[communicator-unix]
+UNIXPATH = $GNUNET_RUNTIME_DIR/communicator-unix-1.sock
+
+[communicator-tcp]
+BINDTO = 60002
+
+[communicator-udp]
+BINDTO = 60002
diff --git a/src/transport/test_communicator_unix_peer1.conf b/src/transport/test_communicator_unix_peer1.conf
deleted file mode 100644 (file)
index d505880..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-@INLINE@ test_transport_defaults.conf
-
-[PATHS]
-GNUNET_TEST_HOME = $GNUNET_TMP/test-communicator-unix-1/
-
-[PEER]
-PRIVATE_KEY = $GNUNET_TMP/test-communicator-unix-1/private.key
-
-[transport-tcp]
-PORT = 52400
-
-[transport-udp]
-PORT = 52401
-
-[transport]
-PORT = 60000
-UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
-
-[nat]
-UNIXPATH = $GNUNET_TMP/communicator-unix-1/nat.sock
-ENABLE_IPSCAN = YES
-
-[communicator-unix]
-UNIXPATH = $GNUNET_RUNTIME_DIR/communicator-unix-1.sock
-
-[communicator-tcp]
-BINDTO = 60002
-
-[communicator-udp]
-BINDTO = 60002
index 01ebcc8345d5e762b884ba619148eb4fe373dd49..84c13708ec1e8d6aa9e4145d439a70cf25b8cbf9 100644 (file)
@@ -1,6 +1,7 @@
 test_common_logging_dummy
 gnunet-config
 gnunet-config-diff
+gnunet-crypto-tvg
 gnunet-ecc
 gnunet-qr
 gnunet-resolver
@@ -30,6 +31,7 @@ test_container_multihashmap32
 test_container_multipeermap
 test_crypto_crc
 test_crypto_ecc_dlog
+test_crypto_ecdh_ecdsa
 test_crypto_ecdh_eddsa
 test_crypto_ecdhe
 test_crypto_ecdsa
index 0f6251f96100076863c7c907279133692055c8f1..fc8f424dc6bef418eea520c152b65aef9e4372e8 100644 (file)
@@ -39,6 +39,7 @@ libgnunetutil_la_SOURCES = \
   bandwidth.c \
   $(BENCHMARK) \
   bio.c \
+  buffer.c \
   client.c \
   common_allocation.c \
   common_endian.c \
@@ -138,41 +139,11 @@ libgnunetutil_la_LDFLAGS = \
   $(GN_LIB_LDFLAGS) \
   -version-info 13:2:0
 
-libgnunetutil_taler_wallet_la_SOURCES = \
-  common_allocation.c \
-  common_endian.c \
-  common_logging.c \
-  container_heap.c \
-  container_multihashmap.c \
-  container_multihashmap32.c \
-  crypto_symmetric.c \
-  crypto_crc.c \
-  crypto_ecc.c \
-  crypto_hash.c \
-  crypto_hkdf.c \
-  crypto_kdf.c \
-  crypto_mpi.c \
-  crypto_random.c \
-  crypto_rsa.c \
-  strings.c \
-  time.c
-
-libgnunetutil_taler_wallet_la_LIBADD = \
-  $(LIBGCRYPT_LIBS) \
-  -lunistring
-
-libgnunetutil_taler_wallet_la_LDFLAGS = \
-  $(GN_LIB_LDFLAGS) \
-  -version-info 0:0:0
-
 if HAVE_TESTING
   GNUNET_ECC = gnunet-ecc
   GNUNET_SCRYPT = gnunet-scrypt
 endif
 
-if TALER_ONLY
-lib_LTLIBRARIES = libgnunetutil_taler_wallet.la
-else
 lib_LTLIBRARIES = libgnunetutil.la
 
 libexec_PROGRAMS = \
@@ -182,6 +153,7 @@ libexec_PROGRAMS = \
 bin_PROGRAMS = \
  gnunet-resolver \
  gnunet-config \
+ gnunet-crypto-tvg \
  $(GNUNET_ECC) \
  $(GNUNET_SCRYPT) \
  gnunet-uri
@@ -199,8 +171,6 @@ AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PAT
 TESTS = $(check_PROGRAMS)
 endif
 
-endif
-
 gnunet_timeout_SOURCES = \
  gnunet-timeout.c
 
@@ -220,6 +190,11 @@ gnunet_resolver_LDADD = \
   libgnunetutil.la \
   $(GN_LIBINTL)
 
+gnunet_crypto_tvg_SOURCES = \
+ gnunet-crypto-tvg.c
+gnunet_crypto_tvg_LDADD = \
+  libgnunetutil.la \
+  $(GN_LIBINTL) -lgcrypt
 
 gnunet_ecc_SOURCES = \
  gnunet-ecc.c
@@ -298,6 +273,7 @@ check_PROGRAMS = \
  test_crypto_eddsa \
  test_crypto_ecdhe \
  test_crypto_ecdh_eddsa \
+ test_crypto_ecdh_ecdsa \
  test_crypto_ecc_dlog \
  test_crypto_hash \
  test_crypto_hash_context \
@@ -476,6 +452,13 @@ test_crypto_ecdh_eddsa_LDADD = \
  libgnunetutil.la \
  $(LIBGCRYPT_LIBS)
 
+test_crypto_ecdh_ecdsa_SOURCES = \
+ test_crypto_ecdh_ecdsa.c
+test_crypto_ecdh_ecdsa_LDADD = \
+ libgnunetutil.la \
+ $(LIBGCRYPT_LIBS)
+
+
 test_crypto_hash_SOURCES = \
  test_crypto_hash.c
 test_crypto_hash_LDADD = \
diff --git a/src/util/buffer.c b/src/util/buffer.c
new file mode 100644 (file)
index 0000000..d89565d
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+  This file is part of GNUnet
+  Copyright (C) 2020 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, 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
+  GNUnet; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file buffer.c
+ * @brief Common buffer management functions.
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_buffer_lib.h"
+
+/**
+ * Initialize a buffer with the given capacity.
+ *
+ * When a buffer is allocated with this function, a warning is logged
+ * when the buffer exceeds the initial capacity.
+ *
+ * @param buf the buffer to initialize
+ * @param capacity the capacity (in bytes) to allocate for @a buf
+ */
+void
+GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity)
+{
+  /* Buffer should be zero-initialized */
+  GNUNET_assert (0 == buf->mem);
+  GNUNET_assert (0 == buf->capacity);
+  GNUNET_assert (0 == buf->position);
+  buf->mem = GNUNET_malloc (capacity);
+  buf->capacity = capacity;
+  buf->warn_grow = GNUNET_YES;
+}
+
+
+/**
+ * Make sure that at least @a n bytes remaining in the buffer.
+ *
+ * @param buf buffer to potentially grow
+ * @param n number of bytes that should be available to write
+ */
+void
+GNUNET_buffer_ensure_remaining (struct GNUNET_Buffer *buf, size_t n)
+{
+  size_t new_capacity = buf->position + n;
+
+  if (new_capacity <= buf->capacity)
+    return;
+  /* warn if calculation of expected size was wrong */
+  GNUNET_break (GNUNET_YES != buf->warn_grow);
+  if (new_capacity < buf->capacity * 2)
+    new_capacity = buf->capacity * 2;
+  buf->capacity = new_capacity;
+  if (NULL != buf->mem)
+    buf->mem = GNUNET_realloc (buf->mem, new_capacity);
+  else
+    buf->mem = GNUNET_malloc (new_capacity);
+}
+
+
+/**
+ * Write bytes to the buffer.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf buffer to write to
+ * @param data data to read from
+ * @param len number of bytes to copy from @a data to @a buf
+ *
+ */
+void
+GNUNET_buffer_write (struct GNUNET_Buffer *buf, const char *data, size_t len)
+{
+  GNUNET_buffer_ensure_remaining (buf, len);
+  memcpy (buf->mem + buf->position, data, len);
+  buf->position += len;
+}
+
+
+/**
+ * Write a 0-terminated string to a buffer, excluding the 0-terminator.
+ *
+ * @param buf the buffer to write to
+ * @param str the string to write to @a buf
+ */
+void
+GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str)
+{
+  size_t len = strlen (str);
+
+  GNUNET_buffer_write (buf, str, len);
+}
+
+
+/**
+ * Clear the buffer and return the string it contained.
+ * The caller is responsible to eventually #GNUNET_free
+ * the returned string.
+ *
+ * The returned string is always 0-terminated.
+ *
+ * @param buf the buffer to reap the string from
+ * @returns the buffer contained in the string
+ */
+char *
+GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf)
+{
+  char *res;
+
+  /* ensure 0-termination */
+  if ( (0 == buf->position) || ('\0' != buf->mem[buf->position - 1]))
+  {
+    GNUNET_buffer_ensure_remaining (buf, 1);
+    buf->mem[buf->position++] = '\0';
+  }
+  res = buf->mem;
+  *buf = (struct GNUNET_Buffer) { 0 };
+  return res;
+}
+
+
+/**
+ * Free the backing memory of the given buffer.
+ * Does not free the memory of the buffer control structure,
+ * which is typically stack-allocated.
+ */
+void
+GNUNET_buffer_clear (struct GNUNET_Buffer *buf)
+{
+  GNUNET_free_non_null (buf->mem);
+  *buf = (struct GNUNET_Buffer) { 0 };
+}
+
+
+/**
+ * Write a path component to a buffer, ensuring that
+ * there is exactly one slash between the previous contents
+ * of the buffer and the new string.
+ *
+ * @param buf buffer to write to
+ * @param str string containing the new path component
+ */
+void
+GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str)
+{
+  size_t len = strlen (str);
+
+  while ( (0 != len) && ('/' == str[0]) )
+  {
+    str++;
+    len--;
+  }
+  if ( (0 == buf->position) || ('/' != buf->mem[buf->position - 1]) )
+  {
+    GNUNET_buffer_ensure_remaining (buf, 1);
+    buf->mem[buf->position++] = '/';
+  }
+  GNUNET_buffer_write (buf, str, len);
+}
+
+
+/**
+ * Write a 0-terminated formatted string to a buffer, excluding the
+ * 0-terminator.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf the buffer to write to
+ * @param fmt format string
+ * @param ... format arguments
+ */
+void
+GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...)
+{
+  va_list args;
+
+  va_start (args, fmt);
+  GNUNET_buffer_write_vfstr (buf, fmt, args);
+  va_end (args);
+}
+
+
+/**
+ * Write a 0-terminated formatted string to a buffer, excluding the
+ * 0-terminator.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf the buffer to write to
+ * @param fmt format string
+ * @param args format argument list
+ */
+void
+GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf,
+                          const char *fmt,
+                          va_list args)
+{
+  int res;
+  va_list args2;
+
+  va_copy (args2, args);
+  res = vsnprintf (NULL, 0, fmt, args2);
+  va_end (args2);
+
+  GNUNET_assert (res >= 0);
+  GNUNET_buffer_ensure_remaining (buf, res + 1);
+
+  va_copy (args2, args);
+  res = vsnprintf (buf->mem + buf->position, res + 1, fmt, args2);
+  va_end (args2);
+
+  GNUNET_assert (res >= 0);
+  buf->position += res;
+  GNUNET_assert (buf->position <= buf->capacity);
+}
index 430f75e708d4a7a54fcf3963a2147263b1c5c782..27ac88a05e351f2bca9a751ec2b64c6ebb2a90c3 100644 (file)
@@ -294,7 +294,6 @@ resize_logdefs ()
 }
 
 
-#if ! TALER_WALLET_ONLY
 /**
  * Rotate logs, deleting the oldest log.
  *
@@ -403,9 +402,6 @@ setup_log_file (const struct tm *tm)
 }
 
 
-#endif
-
-
 /**
  * Utility function - adds a parsed definition to logdefs array.
  *
@@ -731,7 +727,7 @@ GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
   log_file_name = GNUNET_STRINGS_filename_expand (logfile);
   if (NULL == log_file_name)
     return GNUNET_SYSERR;
-#if TALER_WALLET_ONLY || defined(GNUNET_CULL_LOGGING)
+#if defined(GNUNET_CULL_LOGGING)
   /* log file option not allowed for wallet logic */
   GNUNET_assert (NULL == logfile);
   return GNUNET_OK;
@@ -1023,7 +1019,7 @@ mylog (enum GNUNET_ErrorType kind,
     }
 
     vsnprintf (buf, size, message, va);
-#if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY)
+#if ! defined(GNUNET_CULL_LOGGING)
     if (NULL != tmptr)
       (void) setup_log_file (tmptr);
 #endif
index bd7c425d40cc7b84909e85e4b3902e38b431b7fc..237062eb7489e615c1a544e8a6220a94a224b867 100644 (file)
@@ -173,22 +173,8 @@ GNUNET_CRYPTO_ecdsa_key_get_public (
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
   struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
 {
-  gcry_sexp_t sexp;
-  gcry_ctx_t ctx;
-  gcry_mpi_t q;
-
   BENCHMARK_START (ecdsa_key_get_public);
-
-  sexp = decode_private_ecdsa_key (priv);
-  GNUNET_assert (NULL != sexp);
-  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
-  gcry_sexp_release (sexp);
-  q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
-  GNUNET_assert (NULL != q);
-  GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof(pub->q_y), q);
-  gcry_mpi_release (q);
-  gcry_ctx_release (ctx);
-
+  GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (pub->q_y, priv->d);
   BENCHMARK_END (ecdsa_key_get_public);
 }
 
@@ -1040,45 +1026,6 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (
 }
 
 
-/**
- * Take point from ECDH and convert it to key material.
- *
- * @param result point from ECDH
- * @param ctx ECC context
- * @param key_material[out] set to derived key material
- * @return #GNUNET_OK on success
- */
-static int
-point_to_hash (gcry_mpi_point_t result,
-               gcry_ctx_t ctx,
-               struct GNUNET_HashCode *key_material)
-{
-  gcry_mpi_t result_x;
-  unsigned char xbuf[256 / 8];
-  size_t rsize;
-
-  /* finally, convert point to string for hashing */
-  result_x = gcry_mpi_new (256);
-  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
-    return GNUNET_SYSERR;
-  }
-
-  rsize = sizeof(xbuf);
-  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
-  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
-     as that does not include the sign bit; x should be a 255-bit
-     value, so with the sign it should fit snugly into the 256-bit
-     xbuf */
-  GNUNET_assert (
-    0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
-  GNUNET_CRYPTO_hash (xbuf, rsize, key_material);
-  gcry_mpi_release (result_x);
-  return GNUNET_OK;
-}
-
-
 /**
  * @ingroup crypto
  * Derive key material from a ECDH public key and a private EdDSA key.
@@ -1125,41 +1072,18 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
                           const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
                           struct GNUNET_HashCode *key_material)
 {
-  gcry_mpi_point_t result;
-  gcry_mpi_point_t q;
-  gcry_mpi_t d;
-  gcry_ctx_t ctx;
-  gcry_sexp_t pub_sexpr;
-  int ret;
+  uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
+  uint8_t d_rev[GNUNET_TWEETNACL_SCALARMULT_BYTES];
 
   BENCHMARK_START (ecdsa_ecdh);
-
-  /* first, extract the q = dP value from the public key */
-  if (0 != gcry_sexp_build (&pub_sexpr,
-                            NULL,
-                            "(public-key(ecc(curve " CURVE ")(q %b)))",
-                            (int) sizeof(pub->q_y),
-                            pub->q_y))
-    return GNUNET_SYSERR;
-  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
-  gcry_sexp_release (pub_sexpr);
-  q = gcry_mpi_ec_get_point ("q", ctx, 0);
-
-  /* second, extract the d value from our private key */
-  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
-
-  /* then call the 'multiply' function, to compute the product */
-  result = gcry_mpi_point_new (0);
-  gcry_mpi_ec_mul (result, d, q, ctx);
-  gcry_mpi_point_release (q);
-  gcry_mpi_release (d);
-
-  /* finally, convert point to string for hashing */
-  ret = point_to_hash (result, ctx, key_material);
-  gcry_mpi_point_release (result);
-  gcry_ctx_release (ctx);
+  for (size_t i = 0; i < 32; i++)
+    d_rev[i] = priv->d[31 - i];
+  GNUNET_TWEETNACL_scalarmult_curve25519 (p, d_rev, pub->q_y);
+  GNUNET_CRYPTO_hash (p,
+                      GNUNET_TWEETNACL_SCALARMULT_BYTES,
+                      key_material);
   BENCHMARK_END (ecdsa_ecdh);
-  return ret;
+  return GNUNET_OK;
 }
 
 
@@ -1191,7 +1115,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
 /**
  * @ingroup crypto
  * Derive key material from a ECDSA public key and a private ECDH key.
- * Dual to #GNUNET_CRRYPTO_eddsa_ecdh.
+ * Dual to #GNUNET_CRYPTO_ecdsa_ecdh.
  *
  * @param priv private key to use for the ECDH (y)
  * @param pub public key from ECDSA to use for the ECDH (X=h(x)G)
@@ -1203,10 +1127,13 @@ GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
                           const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
                           struct GNUNET_HashCode *key_material)
 {
-  return GNUNET_CRYPTO_ecdh_eddsa (priv,
-                                   (const struct GNUNET_CRYPTO_EddsaPublicKey *)
-                                   pub,
-                                   key_material);
+  uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
+  uint8_t curve25510_pk[GNUNET_TWEETNACL_SIGN_PUBLICBYTES];
+
+  GNUNET_TWEETNACL_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y);
+  GNUNET_TWEETNACL_scalarmult_curve25519 (p, priv->d, curve25510_pk);
+  GNUNET_CRYPTO_hash (p, GNUNET_TWEETNACL_SCALARMULT_BYTES, key_material);
+  return GNUNET_OK;
 }
 
 
diff --git a/src/util/gnunet-crypto-tvg.c b/src/util/gnunet-crypto-tvg.c
new file mode 100644 (file)
index 0000000..7d151c1
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2020 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 util/gnunet-crypto-tgv.c
+ * @brief Generate test vectors for cryptographic operations.
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_signatures.h"
+#include "gnunet_testing_lib.h"
+#include <gcrypt.h>
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Sample signature struct.
+ *
+ * Purpose is #GNUNET_SIGNATURE_PURPOSE_TEST
+ */
+struct TestSignatureDataPS
+{
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+  uint32_t testval;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Print data base32-crockford with a preceding label.
+ *
+ * @param label label to print
+ * @param data data to print
+ * @param size size of data
+ */
+static void
+display_data (char *label, void *data, size_t size)
+{
+  char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size);
+  printf ("%s %s\n", label, enc);
+  GNUNET_free (enc);
+}
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  {
+    struct GNUNET_HashCode hc;
+    char *str = "Hello, GNUnet";
+
+    GNUNET_CRYPTO_hash (str, strlen (str), &hc);
+
+    printf ("hash code:\n");
+    display_data ("  input", str, strlen (str));
+    display_data ("  output", &hc, sizeof (struct GNUNET_HashCode));
+  }
+  {
+    struct GNUNET_CRYPTO_EcdhePrivateKey *priv1;
+    struct GNUNET_CRYPTO_EcdhePublicKey pub1;
+    struct GNUNET_CRYPTO_EcdhePrivateKey *priv2;
+    struct GNUNET_HashCode skm;
+    priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
+    priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
+    GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &skm));
+
+    printf ("ecdhe key:\n");
+    display_data ("  priv1", priv1, sizeof (struct
+                                            GNUNET_CRYPTO_EcdhePrivateKey));
+    display_data ("  pub1", &pub1, sizeof (struct
+                                           GNUNET_CRYPTO_EcdhePublicKey));
+    display_data ("  priv2", priv2, sizeof (struct
+                                            GNUNET_CRYPTO_EcdhePrivateKey));
+    display_data ("  skm", &skm, sizeof (struct GNUNET_HashCode));
+    GNUNET_free (priv1);
+    GNUNET_free (priv2);
+  }
+
+  {
+    struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
+    struct GNUNET_CRYPTO_EddsaPublicKey pub;
+    priv = GNUNET_CRYPTO_eddsa_key_create ();
+    GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
+
+    printf ("eddsa key:\n");
+    display_data ("  priv", priv, sizeof (struct
+                                          GNUNET_CRYPTO_EddsaPrivateKey));
+    display_data ("  pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+    GNUNET_free (priv);
+  }
+  {
+    struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
+    struct GNUNET_CRYPTO_EddsaPublicKey pub;
+    struct GNUNET_CRYPTO_EddsaSignature sig;
+    struct TestSignatureDataPS data = { 0 };
+    priv = GNUNET_CRYPTO_eddsa_key_create ();
+    GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
+    data.purpose.size = htonl (sizeof (struct TestSignatureDataPS));
+    data.purpose.size = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (priv, &data.purpose,
+                                                          &sig));
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_verify (0,
+                                                            &data.purpose,
+                                                            &sig,
+                                                            &pub));
+
+    printf ("eddsa sig:\n");
+    display_data ("  priv", priv, sizeof (struct
+                                          GNUNET_CRYPTO_EddsaPrivateKey));
+    display_data ("  pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+    display_data ("  data", &data, sizeof (struct TestSignatureDataPS));
+    display_data ("  sig", &sig, sizeof (struct GNUNET_CRYPTO_EddsaSignature));
+    GNUNET_free (priv);
+  }
+
+  {
+    size_t out_len = 64;
+    char out[out_len];
+    char *ikm = "I'm the secret input key material";
+    char *salt = "I'm very salty";
+    char *ctx = "I'm a context chunk, also known as 'info' in the RFC";
+
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_kdf (&out,
+                                                   out_len,
+                                                   salt,
+                                                   strlen (salt),
+                                                   ikm,
+                                                   strlen (ikm),
+                                                   ctx,
+                                                   strlen (ctx),
+                                                   NULL));
+
+    printf ("kdf:\n");
+    display_data ("  salt", salt, strlen (salt));
+    display_data ("  ikm", ikm, strlen (ikm));
+    display_data ("  ctx", ctx, strlen (ctx));
+    printf ("  out_len %u\n", (unsigned int) out_len);
+    display_data ("  out", out, out_len);
+  }
+  {
+    struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdhe;
+    struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe;
+    struct GNUNET_CRYPTO_EddsaPrivateKey *priv_eddsa;
+    struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa;
+    struct GNUNET_HashCode key_material;
+    priv_ecdhe = GNUNET_CRYPTO_ecdhe_key_create ();
+    GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdhe, &pub_ecdhe);
+    priv_eddsa = GNUNET_CRYPTO_eddsa_key_create ();
+    GNUNET_CRYPTO_eddsa_key_get_public (priv_eddsa, &pub_eddsa);
+    GNUNET_CRYPTO_ecdh_eddsa (priv_ecdhe, &pub_eddsa, &key_material);
+
+    printf ("eddsa_ecdh:\n");
+    display_data ("  priv_ecdhe", priv_ecdhe, sizeof (struct
+                                                      GNUNET_CRYPTO_EcdhePrivateKey));
+    display_data ("  pub_ecdhe", &pub_ecdhe, sizeof (struct
+                                                     GNUNET_CRYPTO_EcdhePublicKey));
+    display_data ("  priv_eddsa", priv_eddsa, sizeof (struct
+                                                      GNUNET_CRYPTO_EddsaPrivateKey));
+    display_data ("  pub_eddsa", &pub_eddsa, sizeof (struct
+                                                     GNUNET_CRYPTO_EddsaPublicKey));
+    display_data ("  key_material", &key_material, sizeof (struct
+                                                           GNUNET_HashCode));
+  }
+
+  {
+    struct GNUNET_CRYPTO_RsaPrivateKey *skey;
+    struct GNUNET_CRYPTO_RsaPublicKey *pkey;
+    struct GNUNET_HashCode message_hash;
+    struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
+    struct GNUNET_CRYPTO_RsaSignature *blinded_sig;
+    struct GNUNET_CRYPTO_RsaSignature *sig;
+    char *blinded_data;
+    size_t blinded_len;
+    char *public_enc_data;
+    size_t public_enc_len;
+    char *blinded_sig_enc_data;
+    size_t blinded_sig_enc_length;
+    char *sig_enc_data;
+    size_t sig_enc_length;
+    skey = GNUNET_CRYPTO_rsa_private_key_create (2048);
+    pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey);
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &message_hash,
+                                sizeof (struct GNUNET_HashCode));
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &bks, sizeof (struct
+                                                                          GNUNET_CRYPTO_RsaBlindingKeySecret));
+    GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_blind (&message_hash, &bks,
+                                                          pkey, &blinded_data,
+                                                          &blinded_len));
+    blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data,
+                                                  blinded_len);
+    sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey);
+    GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig,
+                                                           pkey));
+    public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey,
+                                                          &public_enc_data);
+    blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig,
+                                                                 &
+                                                                 blinded_sig_enc_data);
+    sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data);
+    printf ("blind signing:\n");
+    display_data ("  message_hash", &message_hash, sizeof (struct
+                                                           GNUNET_HashCode));
+    display_data ("  rsa_public_key", public_enc_data, public_enc_len);
+    display_data ("  blinding_key_secret", &bks, sizeof (struct
+                                                         GNUNET_CRYPTO_RsaBlindingKeySecret));
+    display_data ("  blinded_message", blinded_data, blinded_len);
+    display_data ("  blinded_sig", blinded_sig_enc_data,
+                  blinded_sig_enc_length);
+    display_data ("  sig", sig_enc_data, sig_enc_length);
+    GNUNET_CRYPTO_rsa_private_key_free (skey);
+    GNUNET_CRYPTO_rsa_public_key_free (pkey);
+    GNUNET_CRYPTO_rsa_signature_free (sig);
+    GNUNET_CRYPTO_rsa_signature_free (blinded_sig);
+  }
+}
+
+
+/**
+ * The main function of the test vector generation tool.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc,
+      char *const *argv)
+{
+  const struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_log_setup ("gnunet-crypto-tvg",
+                                   "INFO",
+                                   NULL));
+  if (GNUNET_OK !=
+      GNUNET_PROGRAM_run (argc, argv,
+                          "gnunet-crypto-tvg",
+                          "Generate test vectors for cryptographic operations",
+                          options,
+                          &run, NULL))
+    return 1;
+  return 0;
+}
+
+/* end of gnunet-crypto-tvg.c */
diff --git a/src/util/test_crypto_ecdh_ecdsa.c b/src/util/test_crypto_ecdh_ecdsa.c
new file mode 100644 (file)
index 0000000..8a581ef
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2002-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
+
+ */
+/**
+ * @file util/test_crypto_ecdh_ecdsa.c
+ * @brief testcase for ECC DH key exchange with ECDSA private keys.
+ * @author Christian Grothoff
+ * @author Bart Polot
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include <gcrypt.h>
+
+
+static int
+test_ecdh ()
+{
+  struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_dsa;
+  struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh;
+  struct GNUNET_CRYPTO_EcdsaPublicKey id1;
+  struct GNUNET_CRYPTO_EcdhePublicKey id2;
+  struct GNUNET_HashCode dh[2];
+
+  /* Generate keys */
+  priv_dsa = GNUNET_CRYPTO_ecdsa_key_create ();
+  GNUNET_CRYPTO_ecdsa_key_get_public (priv_dsa,
+                                      &id1);
+  for (unsigned int j = 0; j < 4; j++)
+  {
+    fprintf (stderr, ",");
+    priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create ();
+    /* Extract public keys */
+    GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh,
+                                        &id2);
+    /* Do ECDH */
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecdsa_ecdh (priv_dsa,
+                                             &id2,
+                                             &dh[0]));
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecdh_ecdsa (priv_ecdh,
+                                             &id1,
+                                             &dh[1]));
+    /* Check that both DH results are equal. */
+    GNUNET_assert (0 == memcmp (&dh[0],
+                                &dh[1],
+                                sizeof(struct GNUNET_HashCode)));
+    GNUNET_free (priv_ecdh);
+  }
+  GNUNET_free (priv_dsa);
+  return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  if (! gcry_check_version ("1.6.0"))
+  {
+    fprintf (stderr,
+             _ (
+               "libgcrypt has not the expected version (version %s is required).\n"),
+             "1.6.0");
+    return 0;
+  }
+  if (getenv ("GNUNET_GCRYPT_DEBUG"))
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+  GNUNET_log_setup ("test-crypto-ecdh-ecdsa", "WARNING", NULL);
+  for (unsigned int i = 0; i < 4; i++)
+  {
+    fprintf (stderr,
+             ".");
+    if (0 != test_ecdh ())
+      return 1;
+  }
+  return 0;
+}
+
+
+/* end of test_crypto_ecdh_ecdsa.c */
index 1c27730a4876fcc34a572b1874aedd950dc7c6bd..f01667adbd455f3e282388708fc1dd359ecc9bc9 100644 (file)
@@ -424,8 +424,24 @@ GNUNET_TWEETNACL_sign_pk_from_seed (u8 *pk, const u8 *seed)
   d[31] &= 127;
   d[31] |= 64;
 
-  scalarbase (p,d);
-  pack (pk,p);
+  scalarbase (p, d);
+  pack (pk, p);
+}
+
+void
+GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (u8 *pk, const u8 *s)
+{
+  u8 d[64];
+  gf p[4];
+
+  // Treat s as little endian.
+  for (u32 i = 0; i < 32; i++)
+    d[i] = s[31 - i];
+
+  // For GNUnet, we don't normalize d
+
+  scalarbase (p, d);
+  pack (pk, p);
 }
 
 void
index 239166ffc2bb32dc8759d3bfc20322bf9832e1c4..d052d8824779de68b7434912f22400813352e301 100644 (file)
@@ -47,4 +47,8 @@ GNUNET_TWEETNACL_sign_detached (uint8_t *sig,
                                 const uint8_t *m,
                                 uint64_t n,
                                 const uint8_t *sk);
+
+void
+GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (uint8_t *pk, const uint8_t *s);
+
 #endif
index 50c990b3a49a71ec617dc02dad4a987fada86c13..62bc45e414a583c4987db52f75b680da947cd1f2 100644 (file)
@@ -2940,7 +2940,8 @@ run (void *cls,
   struct in6_addr v6;
   char *binary;
 
-  binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn");
+  cfg = cfg_;
+  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-vpn");
 
   if (GNUNET_YES !=
       GNUNET_OS_check_helper_binary (
@@ -2949,8 +2950,8 @@ run (void *cls,
         "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) // ipv4 only please!
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "`%s' is not SUID, refusing to run.\n",
-                "gnunet-helper-vpn");
+                "`%s' is not SUID or the path is invalid, refusing to run.\n",
+                binary);
     GNUNET_free (binary);
     global_ret = 1;
     /* we won't "really" exit here, as the 'service' is still running;
@@ -2958,8 +2959,6 @@ run (void *cls,
        anything either */
     return;
   }
-  GNUNET_free (binary);
-  cfg = cfg_;
   stats = GNUNET_STATISTICS_create ("vpn", cfg);
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_number (cfg,
@@ -2989,6 +2988,7 @@ run (void *cls,
       GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
   {
     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
+    GNUNET_free (binary);
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
@@ -3006,6 +3006,7 @@ run (void *cls,
                                  "VPN",
                                  "IPV6ADDR",
                                  _ ("Must specify valid IPv6 address"));
+      GNUNET_free (binary);
       GNUNET_SCHEDULER_shutdown ();
       GNUNET_free_non_null (ipv6addr);
       return;
@@ -3033,6 +3034,7 @@ run (void *cls,
                                  "VPN",
                                  "IPV4MASK",
                                  _ ("Must specify valid IPv6 mask"));
+      GNUNET_free (binary);
       GNUNET_SCHEDULER_shutdown ();
       return;
     }
@@ -3058,6 +3060,7 @@ run (void *cls,
                                  "VPN",
                                  "IPV4ADDR",
                                  _ ("Must specify valid IPv4 address"));
+      GNUNET_free (binary);
       GNUNET_SCHEDULER_shutdown ();
       GNUNET_free_non_null (ipv4addr);
       return;
@@ -3074,6 +3077,7 @@ run (void *cls,
                                  "VPN",
                                  "IPV4MASK",
                                  _ ("Must specify valid IPv4 mask"));
+      GNUNET_free (binary);
       GNUNET_SCHEDULER_shutdown ();
       GNUNET_free_non_null (ipv4mask);
       return;
@@ -3093,11 +3097,12 @@ run (void *cls,
   cadet_handle = GNUNET_CADET_connect (cfg_);
   // FIXME never opens ports???
   helper_handle = GNUNET_HELPER_start (GNUNET_NO,
-                                       "gnunet-helper-vpn",
+                                       binary,
                                        vpn_argv,
                                        &message_token,
                                        NULL,
                                        NULL);
+  GNUNET_free (binary);
   GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL);
 }