src/hello/Makefile
src/identity/Makefile
src/identity/identity.conf
+src/credential/Makefile
+src/credential/credential.conf
src/include/Makefile
src/integration-tests/Makefile
src/json/Makefile
revocation \
vpn \
gns \
+ credential \
$(CONVERSATION_DIR) \
fs \
exit \
--- /dev/null
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+EXTRA_DIST = \
+ test_credential_defaults.conf \
+ test_credential_lookup.conf
+# test_gns_nick_shorten.conf \
+#### test_gns_proxy.conf \
+# test_gns_simple_lookup.conf \
+# gns-helper-service-w32.conf \
+# w32nsp.def \
+# gnunet-gns-proxy-setup-ca \
+# zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \
+# zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \
+# zonefiles/test_zonekey \
+# $(check_SCRIPTS)
+
+
+if USE_COVERAGE
+ AM_CFLAGS = --coverage -O0
+endif
+
+pkgcfgdir = $(pkgdatadir)/config.d/
+
+libexecdir= $(pkglibdir)/libexec/
+
+plugindir = $(libdir)/gnunet
+
+pkgcfg_DATA = \
+ credential.conf
+
+
+# /usr/lib - compiles a layer which can be used to be communicagte with the service
+lib_LTLIBRARIES = \
+ libgnunetcredential.la
+
+# /usr/lib/gnunet/libexec - Business logic . Separate process
+libexec_PROGRAMS = \
+ gnunet-service-credential
+
+bin_PROGRAMS = \
+ gnunet-credential
+
+plugin_LTLIBRARIES = \
+ libgnunet_plugin_gnsrecord_credential.la
+
+
+#if HAVE_MHD
+#if HAVE_JSON
+#plugin_LTLIBRARIES += libgnunet_plugin_rest_gns.la
+#endif
+#endif
+
+
+gnunet_credential_SOURCES = \
+ gnunet-credential.c
+gnunet_credential_LDADD = \
+ libgnunetcredential.la \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/identity/libgnunetidentity.la \
+ $(GN_LIBINTL)
+
+
+libgnunet_plugin_gnsrecord_credential_la_SOURCES = \
+ plugin_gnsrecord_credential.c
+libgnunet_plugin_gnsrecord_credential_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(LTLIBINTL)
+libgnunet_plugin_gnsrecord_credential_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
+
+
+
+gnunet_service_credential_SOURCES = \
+ gnunet-service-credential.c
+gnunet_service_credential_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/gns/libgnunetgns.la \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(GN_LIBINTL)
+
+
+libgnunetcredential_la_SOURCES = \
+ credential_api.c credential.h
+libgnunetcredential_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la $(XLIB)
+libgnunetcredential_la_LDFLAGS = \
+ $(GN_LIB_LDFLAGS)
+
+
+#libgnunet_plugin_rest_gns_la_SOURCES = \
+# plugin_rest_gns.c
+#libgnunet_plugin_rest_gns_la_LIBADD = \
+# libgnunetgns.la \
+# $(top_builddir)/src/rest/libgnunetrest.la \
+# $(top_builddir)/src/identity/libgnunetidentity.la \
+# $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \
+# $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \
+# $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
+# $(LTLIBINTL) -ljansson -lmicrohttpd
+#libgnunet_plugin_rest_gns_la_LDFLAGS = \
+# $(GN_PLUGIN_LDFLAGS)
+
+
+#check_SCRIPTS = \
+ #test_gns_lookup.sh
+
+if ENABLE_TEST_RUN
+if HAVE_SQLITE
+ AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
+ TESTS = $(check_SCRIPTS)
+endif
+endif
--- /dev/null
+[credential]
+BINARY = gnunet-service-credential
+UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-credential.sock
+USER_SERVICE = YES
+OPTIONS = -L DEBUG
\ No newline at end of file
--- /dev/null
+/*
+ This file is part of GNUnet
+ Copyright (C) 2012-2013 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+/**
+ * @file credential/credential.h
+ * @brief IPC messages between CREDENTIAL API and CREDENTIAL service
+ * @author Adnan Husain
+ */
+#ifndef CREDENTIAL_H
+#define CREDENTIAL_H
+
+#include "gnunet_credential_service.h"
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message from client to Credential service to verify attributes.
+ */
+struct VerifyMessage
+{
+ /**
+ * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Subject public key
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+
+ /**
+ * Trust anchor
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+ /* Followed by the zero-terminated attributes to look up */
+
+};
+
+
+/**
+ * Message from CREDENTIAL service to client: new results.
+ */
+struct VerifyResultMessage
+{
+ /**
+ * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+
+ /**
+ * The number of credentials in the response
+ */
+ uint32_t ad_count GNUNET_PACKED;
+
+ /* followed by ad_count GNUNET_CREDENTIAL_RecordData structs*/
+
+};
+
+
+GNUNET_NETWORK_STRUCT_END
+
+#endif
+
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2009-2013, 2016 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file credential/credential_api.c
+ * @brief library to access the CREDENTIAL service
+ * @author Adnan Husain
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_arm_service.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_protocols.h"
+#include "credential.h"
+#include "gnunet_credential_service.h"
+#include "gnunet_identity_service.h"
+
+
+#define LOG(kind,...) GNUNET_log_from (kind, "credential-api",__VA_ARGS__)
+
+/**
+ * Handle to a verify request
+ */
+struct GNUNET_CREDENTIAL_Request
+{
+
+ /**
+ * DLL
+ */
+ struct GNUNET_CREDENTIAL_Request *next;
+
+ /**
+ * DLL
+ */
+ struct GNUNET_CREDENTIAL_Request *prev;
+
+ /**
+ * handle to credential service
+ */
+ struct GNUNET_CREDENTIAL_Handle *credential_handle;
+
+ /**
+ * processor to call on verify result
+ */
+ GNUNET_CREDENTIAL_VerifyResultProcessor verify_proc;
+
+ /**
+ * @e verify_proc closure
+ */
+ void *proc_cls;
+
+ /**
+ * Envelope with the message for this queue entry.
+ */
+ struct GNUNET_MQ_Envelope *env;
+
+ /**
+ * request id
+ */
+ uint32_t r_id;
+
+};
+
+
+/**
+ * Connection to the CREDENTIAL service.
+ */
+struct GNUNET_CREDENTIAL_Handle
+{
+
+ /**
+ * Configuration to use.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * Connection to service (if available).
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Head of linked list of active verify requests.
+ */
+ struct GNUNET_CREDENTIAL_Request *verify_head;
+
+ /**
+ * Tail of linked list of active verify requests.
+ */
+ struct GNUNET_CREDENTIAL_Request *verify_tail;
+
+ /**
+ * Reconnect task
+ */
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+ /**
+ * How long do we wait until we try to reconnect?
+ */
+ struct GNUNET_TIME_Relative reconnect_backoff;
+
+ /**
+ * Request Id generator. Incremented by one for each request.
+ */
+ uint32_t r_id_gen;
+
+};
+
+
+/**
+ * Reconnect to CREDENTIAL service.
+ *
+ * @param handle the handle to the CREDENTIAL service
+ */
+static void
+reconnect (struct GNUNET_CREDENTIAL_Handle *handle);
+
+
+/**
+ * Reconnect to CREDENTIAL
+ *
+ * @param cls the handle
+ */
+static void
+reconnect_task (void *cls)
+{
+ struct GNUNET_CREDENTIAL_Handle *handle = cls;
+
+ handle->reconnect_task = NULL;
+ reconnect (handle);
+}
+
+
+/**
+ * Disconnect from service and then reconnect.
+ *
+ * @param handle our handle
+ */
+static void
+force_reconnect (struct GNUNET_CREDENTIAL_Handle *handle)
+{
+ GNUNET_MQ_destroy (handle->mq);
+ handle->mq = NULL;
+ handle->reconnect_backoff
+ = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
+ handle->reconnect_task
+ = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
+ &reconnect_task,
+ handle);
+}
+
+
+/**
+ * Generic error handler, called with the appropriate error code and
+ * the same closure specified at the creation of the message queue.
+ * Not every message queue implementation supports an error handler.
+ *
+ * @param cls closure with the `struct GNUNET_CREDENTIAL_Handle *`
+ * @param error error code
+ */
+static void
+mq_error_handler (void *cls,
+ enum GNUNET_MQ_Error error)
+{
+ struct GNUNET_CREDENTIAL_Handle *handle = cls;
+
+ force_reconnect (handle);
+}
+
+
+/**
+ * Check validity of message received from the CREDENTIAL service
+ *
+ * @param cls the `struct GNUNET_CREDENTIAL_Handle *`
+ * @param loookup_msg the incoming message
+ */
+static int
+check_result (void *cls,
+ const struct VerifyResultMessage *vr_msg)
+{
+ //TODO
+ return GNUNET_OK;
+}
+
+
+/**
+ * Handler for messages received from the CREDENTIAL service
+ *
+ * @param cls the `struct GNUNET_CREDENTIAL_Handle *`
+ * @param loookup_msg the incoming message
+ */
+static void
+handle_result (void *cls,
+ const struct VerifyResultMessage *vr_msg)
+{
+ struct GNUNET_CREDENTIAL_Handle *handle = cls;
+ uint32_t r_id = ntohl (vr_msg->id);
+ struct GNUNET_CREDENTIAL_Request *vr;
+ GNUNET_CREDENTIAL_VerifyResultProcessor proc;
+ void *proc_cls;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received verify reply from CREDENTIAL service\n");
+ for (vr = handle->verify_head; NULL != vr; vr = vr->next)
+ if (vr->r_id == r_id)
+ break;
+ if (NULL == vr)
+ return;
+ proc = vr->verify_proc;
+ proc_cls = vr->proc_cls;
+ GNUNET_CONTAINER_DLL_remove (handle->verify_head,
+ handle->verify_tail,
+ vr);
+ GNUNET_free (vr);
+ /**
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CREDENTIAL_records_deserialize (mlen,
+ (const char*) &lookup_msg[1],
+ rd_count,
+ rd));
+ */
+ proc (proc_cls,
+ NULL,
+ GNUNET_NO); // TODO
+}
+
+
+/**
+ * Reconnect to CREDENTIAL service.
+ *
+ * @param handle the handle to the CREDENTIAL service
+ */
+static void
+reconnect (struct GNUNET_CREDENTIAL_Handle *handle)
+{
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_var_size (result,
+ GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT,
+ struct VerifyResultMessage,
+ NULL),
+ GNUNET_MQ_handler_end ()
+ };
+ struct GNUNET_CREDENTIAL_Request *vr;
+
+ GNUNET_assert (NULL == handle->mq);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to connect to CREDENTIAL\n");
+ handle->mq = GNUNET_CLIENT_connecT (handle->cfg,
+ "credential",
+ handlers,
+ &mq_error_handler,
+ handle);
+ if (NULL == handle->mq)
+ return;
+ for (vr = handle->verify_head; NULL != vr; vr = vr->next)
+ GNUNET_MQ_send_copy (handle->mq,
+ vr->env);
+}
+
+
+/**
+ * Initialize the connection with the CREDENTIAL service.
+ *
+ * @param cfg configuration to use
+ * @return handle to the CREDENTIAL service, or NULL on error
+ */
+struct GNUNET_CREDENTIAL_Handle *
+GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_CREDENTIAL_Handle *handle;
+
+ handle = GNUNET_new (struct GNUNET_CREDENTIAL_Handle);
+ handle->cfg = cfg;
+ reconnect (handle);
+ if (NULL == handle->mq)
+ {
+ GNUNET_free (handle);
+ return NULL;
+ }
+ return handle;
+}
+
+
+/**
+ * Shutdown connection with the CREDENTIAL service.
+ *
+ * @param handle handle of the CREDENTIAL connection to stop
+ */
+void
+GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle)
+{
+ if (NULL != handle->mq)
+ {
+ GNUNET_MQ_destroy (handle->mq);
+ handle->mq = NULL;
+ }
+ if (NULL != handle->reconnect_task)
+ {
+ GNUNET_SCHEDULER_cancel (handle->reconnect_task);
+ handle->reconnect_task = NULL;
+ }
+ GNUNET_assert (NULL == handle->verify_head);
+ GNUNET_free (handle);
+}
+
+
+/**
+ * Cancel pending verify request
+ *
+ * @param lr the verify request to cancel
+ */
+void
+GNUNET_CREDENTIAL_verify_cancel (struct GNUNET_CREDENTIAL_Request *vr)
+{
+ struct GNUNET_CREDENTIAL_Handle *handle = vr->credential_handle;
+
+ GNUNET_CONTAINER_DLL_remove (handle->verify_head,
+ handle->verify_tail,
+ vr);
+ GNUNET_MQ_discard (vr->env);
+ GNUNET_free (vr);
+}
+
+/**
+ * Performs attribute verification.
+ * Checks if there is a delegation chain from
+ * attribute ``issuer_attribute'' issued by the issuer
+ * with public key ``issuer_key'' maps to the attribute
+ * ``subject_attribute'' claimed by the subject with key
+ * ``subject_key''
+ *
+ * @param handle handle to the Credential service
+ * @param issuer_key the issuer public key
+ * @param issuer_attribute the issuer attribute
+ * @param subject_key the subject public key
+ * @param subject_attribute the attribute claimed by the subject
+ * @param proc function to call on result
+ * @param proc_cls closure for processor
+ * @return handle to the queued request
+ */
+struct GNUNET_CREDENTIAL_Request*
+GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
+ const char *issuer_attribute,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key,
+ const char *subject_attribute,
+ GNUNET_CREDENTIAL_VerifyResultProcessor proc,
+ void *proc_cls)
+{
+ /* IPC to shorten credential names, return shorten_handle */
+ struct VerifyMessage *v_msg;
+ struct GNUNET_CREDENTIAL_Request *vr;
+ size_t nlen;
+
+ if (NULL == issuer_attribute)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ //DEBUG LOG
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to verify `%s' in CREDENTIAL\n",
+ issuer_attribute);
+ nlen = strlen (issuer_attribute) + 1;
+ if (nlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*vr))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ vr = GNUNET_new (struct GNUNET_CREDENTIAL_Request);
+ vr->credential_handle = handle;
+ vr->verify_proc = proc;
+ vr->proc_cls = proc_cls;
+ vr->r_id = handle->r_id_gen++;
+ vr->env = GNUNET_MQ_msg_extra (v_msg,
+ nlen,
+ GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY);
+ v_msg->id = htonl (vr->r_id);
+ v_msg->subject_key = *subject_key;
+ v_msg->issuer_key = *issuer_key;
+ GNUNET_memcpy (&v_msg[1],
+ subject_attribute,
+ nlen);
+ GNUNET_CONTAINER_DLL_insert (handle->verify_head,
+ handle->verify_tail,
+ vr);
+ if (NULL != handle->mq)
+ GNUNET_MQ_send_copy (handle->mq,
+ vr->env);
+ return vr;
+}
+
+
+/* end of credential_api.c */
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2012-2013 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file gnunet-credential.c
+ * @brief command line tool to access command line Credential service
+ * @author Adnan Husain
+ */
+#include "platform.h"
+#include <gnunet_util_lib.h>
+#include <gnunet_identity_service.h>
+#include <gnunet_credential_service.h>
+
+/**
+ * Configuration we are using.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Handle to Credential service.
+ */
+static struct GNUNET_CREDENTIAL_Handle *credential;
+
+/**
+ * Desired timeout for the lookup (default is no timeout).
+ */
+static struct GNUNET_TIME_Relative timeout;
+
+/**
+ * Credential to lookup. (-u option)
+ */
+static char *lookup_credential;
+
+/**
+ * Handle to verify request
+ */
+static struct GNUNET_CREDENTIAL_Request *verify_request;
+
+/**
+ * Lookup an ego with the identity service.
+ */
+static struct GNUNET_IDENTITY_EgoLookup *el;
+
+/**
+ * Handle for identity service.
+ */
+static struct GNUNET_IDENTITY_Handle *identity;
+
+/**
+ * Active operation on identity service.
+ */
+static struct GNUNET_IDENTITY_Operation *id_op;
+
+/**
+ * Task scheduled to handle timeout.
+ */
+static struct GNUNET_SCHEDULER_Task *tt;
+
+/**
+ * Subject pubkey string
+ */
+static char *subject_key;
+
+/**
+ * Subject pubkey string
+ */
+static char *issuer_key;
+
+
+
+/**
+ * Identity of the zone to use for the lookup (-z option)
+ */
+static char *zone_ego_name;
+
+
+/**
+ * Task run on shutdown. Cleans up everything.
+ *
+ * @param cls unused
+ */
+static void
+do_shutdown (void *cls)
+{
+ if (NULL != el)
+ {
+ GNUNET_IDENTITY_ego_lookup_cancel (el);
+ el = NULL;
+ }
+ if (NULL != id_op)
+ {
+ GNUNET_IDENTITY_cancel (id_op);
+ id_op = NULL;
+ }
+ if (NULL != verify_request)
+ {
+ GNUNET_CREDENTIAL_verify_cancel (verify_request);
+ verify_request = NULL;
+ }
+ if (NULL != identity)
+ {
+ GNUNET_IDENTITY_disconnect (identity);
+ identity = NULL;
+ }
+ if (NULL != credential)
+ {
+ GNUNET_CREDENTIAL_disconnect (credential);
+ credential = NULL;
+ }
+ if (NULL != tt)
+ {
+ GNUNET_SCHEDULER_cancel (tt);
+ tt = NULL;
+ }
+}
+
+
+/**
+ * Task run on timeout. Triggers shutdown.
+ *
+ * @param cls unused
+ */
+static void
+do_timeout (void *cls)
+{
+ tt = NULL;
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Function called with the result of a Credential lookup.
+ *
+ * @param cls the 'const char *' name that was resolved
+ * @param cd_count number of records returned
+ * @param cd array of @a cd_count records with the results
+ */
+static void
+handle_verify_result (void *cls,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *issuer,
+ uint32_t status)
+{
+
+
+ verify_request = NULL;
+ if (GNUNET_NO == status)
+ printf ("Verify failed.\n");
+ else
+ printf ("Successful.\n");
+
+
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+
+
+/**
+ * Perform the actual resolution, with the subject pkey and
+ * the issuer public key
+ *
+ * @param pkey public key to use for the zone, can be NULL
+ * @param shorten_key private key used for shortening, can be NULL
+ */
+static void
+lookup_credentials (struct GNUNET_IDENTITY_Ego *ego)
+{
+
+ struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey;
+ struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey;
+
+ if (NULL != subject_key && NULL != issuer_key && NULL != lookup_credential)
+ {
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key,
+ strlen (subject_key),
+ &subject_pkey))
+ {
+ fprintf (stderr,
+ _("Subject public key `%s' is not well-formed\n"),
+ subject_key);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
+ strlen (issuer_key),
+ &issuer_pkey))
+ {
+ fprintf (stderr,
+ _("Authority public key `%s' is not well-formed\n"),
+ issuer_key);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+
+ verify_request = GNUNET_CREDENTIAL_verify(credential,
+ &issuer_pkey,
+ "test", //TODO argument
+ &subject_pkey,
+ lookup_credential,
+ &handle_verify_result,
+ NULL);
+ return;
+ }
+ else
+ {
+ fprintf (stderr,
+ _("Please specify name to lookup, subject key and issuer key!\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+}
+
+
+/**
+ * Method called to with the ego we are to use for the lookup,
+ * when the ego is the one for the default master zone.
+ *
+ * @param cls closure (NULL, unused)
+ * @param ego ego handle, NULL if not found
+ * @param ctx context for application to store data for this ego
+ * (during the lifetime of this process, initially NULL)
+ * @param name name assigned by the user for this ego,
+ * NULL if the user just deleted the ego and it
+ * must thus no longer be used
+ */
+static void
+identity_master_cb (void *cls,
+ struct GNUNET_IDENTITY_Ego *ego,
+ void **ctx,
+ const char *name)
+{
+
+ id_op = NULL;
+ if (NULL == ego)
+ {
+ fprintf (stderr,
+ _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+
+ lookup_credentials(ego);
+
+
+}
+
+
+/**
+ * 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 c configuration
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *c)
+{
+
+ cfg = c;
+ credential = GNUNET_CREDENTIAL_connect (cfg);
+ identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
+
+
+
+
+ if (NULL == credential)
+ {
+ fprintf (stderr,
+ _("Failed to connect to CREDENTIAL\n"));
+ return;
+ }
+ if (NULL == identity)
+ {
+ fprintf (stderr,
+ _("Failed to connect to IDENTITY\n"));
+ return;
+ }
+ tt = GNUNET_SCHEDULER_add_delayed (timeout,
+ &do_timeout, NULL);
+ GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
+
+
+
+ GNUNET_break (NULL == id_op);
+ id_op = GNUNET_IDENTITY_get (identity,
+ "gns-master",//# TODO: Create credential-master
+ &identity_master_cb,
+ cls);
+ GNUNET_assert (NULL != id_op);
+
+
+
+
+}
+
+
+/**
+ * The main function for gnunet-gns.
+ *
+ * @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)
+{
+ static const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ {'u', "lookup", "CREDENTIAL",
+ gettext_noop ("Lookup a record for the given credential"), 1,
+ &GNUNET_GETOPT_set_string, &lookup_credential},
+ /** { 'T', "timeout", "DELAY",
+ gettext_noop ("Specify timeout for the lookup"), 1,
+ &GNUNET_GETOPT_set_relative_time, &timeout },
+ {'t', "type", "TYPE",
+ gettext_noop ("Specify the type of the record to lookup"), 1,
+ &GNUNET_GETOPT_set_string, &lookup_type},**/
+ {'z', "zone", "NAME",
+ gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1,
+ &GNUNET_GETOPT_set_string, &zone_ego_name},
+ {'s', "subject", "PKEY",
+ gettext_noop ("Specify the public key of the subject to lookup the credential for"), 1,
+ &GNUNET_GETOPT_set_string, &subject_key},
+ {'i', "issuer", "PKEY",
+ gettext_noop ("Specify the public key of the authority to verify the credential against"), 1,
+ &GNUNET_GETOPT_set_string, &issuer_key},
+ GNUNET_GETOPT_OPTION_END
+ };
+ int ret;
+
+ timeout = GNUNET_TIME_UNIT_FOREVER_REL;
+ if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
+ return 2;
+
+ GNUNET_log_setup ("gnunet-credential", "WARNING", NULL);
+ ret =
+ (GNUNET_OK ==
+ GNUNET_PROGRAM_run (argc, argv, "gnunet-credential",
+ _("GNUnet credential resolver tool"),
+ options,
+ &run, NULL)) ? 0 : 1;
+ GNUNET_free ((void*) argv);
+ return ret;
+}
+
+/* end of gnunet-credential.c */
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2011-2013 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file gns/gnunet-service-credential.c
+ * @brief GNU Credential Service (main service)
+ * @author Adnan Husain
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_credential_service.h"
+#include "gnunet_statistics_service.h"
+#include "credential.h"
+#include "gnunet_protocols.h"
+
+// For Looking up GNS request
+#include <gnunet_dnsparser_lib.h>
+#include <gnunet_identity_service.h>
+#include <gnunet_gnsrecord_lib.h>
+#include <gnunet_namestore_service.h>
+#include <gnunet_gns_service.h>
+#include "gnunet_gns_service.h"
+
+
+
+
+#define GNUNET_CREDENTIAL_MAX_LENGTH 255
+
+/**
+ * DLL for record
+ */
+struct AttributeRecordEntry
+{
+ /**
+ * DLL
+ */
+ struct AttributeRecordEntry *next;
+
+ /**
+ * DLL
+ */
+ struct AttributeRecordEntry *prev;
+
+
+ /**
+ * Payload
+ */
+ struct GNUNET_CREDENTIAL_AttributeRecordData record_data;
+};
+
+/**
+ * Handle to a lookup operation from api
+ */
+struct VerifyRequestHandle
+{
+
+ /**
+ * We keep these in a DLL.
+ */
+ struct VerifyRequestHandle *next;
+
+ /**
+ * We keep these in a DLL.
+ */
+ struct VerifyRequestHandle *prev;
+
+ /**
+ * Handle to the requesting client
+ */
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Handle to GNS lookup
+ */
+ struct GNUNET_GNS_LookupRequest *lookup_request;
+
+ /**
+ * Issuer public key
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
+
+ /**
+ * Subject public key
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+
+ /**
+ * Attribute Chain
+ */
+ struct AttributeRecordEntry *attr_chain_head;
+
+ /**
+ * Attribute Chain
+ */
+ struct AttributeRecordEntry *attr_chain_tail;
+
+ /**
+ * request id
+ */
+ uint32_t request_id;
+
+};
+
+
+/**
+ * Head of the DLL.
+ */
+static struct VerifyRequestHandle *vrh_head;
+
+/**
+ * Tail of the DLL.
+ */
+static struct VerifyRequestHandle *vrh_tail;
+
+/**
+ * Handle to the statistics service
+ */
+static struct GNUNET_STATISTICS_Handle *statistics;
+
+
+
+/**
+ * Handle to GNS service.
+ */
+static struct GNUNET_GNS_Handle *gns;
+
+/**
+ * Task run during shutdown.
+ *
+ * @param cls unused
+ * @param tc unused
+ */
+static void
+shutdown_task (void *cls)
+{
+ struct VerifyRequestHandle *vrh;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Shutting down!\n");
+ while (NULL != (vrh = vrh_head))
+ {
+ //CREDENTIAL_resolver_lookup_cancel (clh->lookup);
+ GNUNET_CONTAINER_DLL_remove (vrh_head,
+ vrh_tail,
+ vrh);
+ GNUNET_free (vrh);
+ }
+
+
+ if (NULL != statistics)
+ {
+ GNUNET_STATISTICS_destroy (statistics,
+ GNUNET_NO);
+ statistics = NULL;
+ }
+
+}
+
+/**
+ * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY message
+ *
+ * @param cls client sending the message
+ * @param v_msg message of type `struct VerifyMessage`
+ * @return #GNUNET_OK if @a v_msg is well-formed
+ */
+static int
+check_verify (void *cls,
+ const struct VerifyMessage *v_msg)
+{
+ size_t msg_size;
+ size_t attr_len;
+ const char* s_attr;
+ const char* i_attr;
+
+ msg_size = ntohs (v_msg->header.size);
+ if (msg_size < sizeof (struct VerifyMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ i_attr = (const char *) &v_msg[1];
+ if ( ('\0' != i_attr[v_msg->header.size - sizeof (struct VerifyMessage) - 1]) ||
+ (strlen (i_attr) > GNUNET_CREDENTIAL_MAX_LENGTH) )
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ attr_len = strlen (i_attr);
+ s_attr = ((const char *) &v_msg[1]) + attr_len + 1;
+ if ( ('\0' != s_attr[v_msg->header.size - sizeof (struct VerifyMessage) - 1]) ||
+ (strlen (s_attr) > GNUNET_CREDENTIAL_MAX_LENGTH) )
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Result from GNS lookup.
+ *
+ * @param cls the closure (our client lookup handle)
+ * @param rd_count the number of records in @a rd
+ * @param rd the record data
+ */
+static void
+send_lookup_response (void* cls,
+ uint32_t rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct VerifyRequestHandle *vrh = cls;
+ size_t len;
+ int i;
+ int attr_record_count;
+ struct GNUNET_MQ_Envelope *env;
+ struct VerifyResultMessage *rmsg;
+ const struct GNUNET_CREDENTIAL_AttributeRecordData *ard;
+ struct AttributeRecordEntry *ar_entry;
+
+ attr_record_count = 0;
+ for (i=0; i < rd_count; i++)
+ {
+ if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
+ continue;
+ attr_record_count++;
+ ard = rd[i].data;
+ /**
+ * TODO:
+ * Check if we have already found our credential here
+ * If so return success
+ * Else
+ * Save all found attributes/issues and prepare forward
+ * resolution of issuer attribute
+ */
+ ar_entry = GNUNET_new (struct AttributeRecordEntry);
+ ar_entry->record_data = *ard;
+ GNUNET_CONTAINER_DLL_insert_tail (vrh->attr_chain_head,
+ vrh->attr_chain_tail,
+ ar_entry);
+
+ }
+
+ /**
+ * Get serialized record data size
+ */
+ len = attr_record_count * sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData);
+
+ /**
+ * Prepare a lookup result response message for the client
+ */
+ env = GNUNET_MQ_msg_extra (rmsg,
+ len,
+ GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT);
+ //Assign id so that client can find associated request
+ rmsg->id = vrh->request_id;
+ rmsg->ad_count = htonl (attr_record_count);
+
+ /**
+ * Get serialized record data
+ * Append at the end of rmsg
+ */
+ i = 0;
+ struct GNUNET_CREDENTIAL_AttributeRecordData *tmp_record = (struct GNUNET_CREDENTIAL_AttributeRecordData*) &rmsg[1];
+ for (ar_entry = vrh->attr_chain_head; NULL != ar_entry; ar_entry = ar_entry->next)
+ {
+ memcpy (tmp_record,
+ &ar_entry->record_data,
+ sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData));
+ tmp_record++;
+ }
+ GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(vrh->client),
+ env);
+
+ GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
+
+ /**
+ * TODO:
+ * - Free DLL
+ * - Refactor into cleanup_handle() function for this
+ */
+ GNUNET_free (vrh);
+
+ GNUNET_STATISTICS_update (statistics,
+ "Completed verifications", 1,
+ GNUNET_NO);
+ GNUNET_STATISTICS_update (statistics,
+ "Attributes resolved",
+ rd_count,
+ GNUNET_NO);
+}
+
+/**
+ * Handle attribute verification requests from client
+ *
+ * @param cls the closure
+ * @param client the client
+ * @param message the message
+ */
+static void
+handle_verify (void *cls,
+ const struct VerifyMessage *v_msg)
+{
+ char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
+ char subject_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
+ size_t issuer_attribute_len;
+ struct VerifyRequestHandle *vrh;
+ struct GNUNET_SERVICE_Client *client = cls;
+ char *attrptr = issuer_attribute;
+ const char *utf_in;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received VERIFY message\n");
+
+ utf_in = (const char *) &v_msg[1];
+ GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
+ issuer_attribute_len = strlen (utf_in);
+ utf_in = (const char *) (&v_msg[1] + issuer_attribute_len + 1);
+ attrptr = subject_attribute;
+ GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
+ vrh = GNUNET_new (struct VerifyRequestHandle);
+ GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
+ vrh->client = client;
+ vrh->request_id = v_msg->id;
+ vrh->issuer_key = v_msg->issuer_key;
+ vrh->subject_key = v_msg->subject_key;
+
+ if (NULL == subject_attribute)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No subject attribute provided!\n");
+ send_lookup_response (vrh, 0, NULL);
+ return;
+ }
+ if (NULL == issuer_attribute)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No issuer attribute provided!\n");
+ send_lookup_response (vrh, 0, NULL);
+ return;
+ }
+ /**
+ * First, get attribute from subject
+ */
+ vrh->lookup_request = GNUNET_GNS_lookup (gns,
+ subject_attribute,
+ &v_msg->subject_key, //subject_pkey,
+ GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
+ GNUNET_GNS_LO_DEFAULT,
+ NULL, //shorten_key, always NULL
+ &send_lookup_response,
+ vrh);
+}
+
+
+/**
+ * One of our clients disconnected, clean up after it.
+ *
+ * @param cls NULL
+ * @param client the client that disconnected
+ */
+static void
+client_disconnect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *client,
+ void *app_ctx)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p disconnected\n",
+ client);
+}
+
+/**
+ * Add a client to our list of active clients.
+ *
+ * @param cls NULL
+ * @param client client to add
+ * @param mq message queue for @a client
+ * @return this client
+ */
+static void *
+client_connect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *client,
+ struct GNUNET_MQ_Handle *mq)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p connected\n",
+ client);
+ return client;
+}
+
+/**
+ * Process Credential requests.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param c configuration to use
+ */
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
+ struct GNUNET_SERVICE_Handle *handle)
+{
+
+ gns = GNUNET_GNS_connect (c);
+ if (NULL == gns)
+ {
+ fprintf (stderr,
+ _("Failed to connect to GNS\n"));
+ }
+
+ statistics = GNUNET_STATISTICS_create ("credential", c);
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
+}
+
+
+/**
+ * Define "main" method using service macro
+ */
+GNUNET_SERVICE_MAIN
+("credential",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_var_size (verify,
+ GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY,
+ struct VerifyMessage,
+ NULL),
+ GNUNET_MQ_handler_end());
+
+/* end of gnunet-service-credential.c */
--- /dev/null
+/*
+ This file is part of GNUnet
+ Copyright (C) 2013 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file credential/plugin_gnsrecord_credential.c
+ * @brief gnsrecord plugin to provide the API for CREDENTIAL records
+ * @author Adnan Husain
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_gnsrecord_lib.h"
+#include "gnunet_credential_service.h"
+#include "gnunet_gnsrecord_plugin.h"
+
+
+/**
+ * Convert the 'value' of a record to a string.
+ *
+ * @param cls closure, unused
+ * @param type type of the record
+ * @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 *
+credential_value_to_string (void *cls,
+ uint32_t type,
+ const void *data,
+ size_t data_size)
+{
+
+ const char *cdata;
+
+ switch (type)
+ {
+ case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+ {
+ struct GNUNET_CREDENTIAL_AttributeRecordData cred;
+ char *cred_str;
+ char *subject_pkey;
+ char *issuer_pkey;
+ uint32_t cf; // Credential flags
+ if (data_size < sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData))
+ return NULL; /* malformed */
+ memcpy (&cred,
+ data,
+ sizeof (cred));
+ cdata = data;
+ subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key);
+ issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key);
+ cf = ntohl (cred.credential_flags);
+
+ GNUNET_asprintf (&cred_str,
+ "%s %s %u %s",
+ subject_pkey,
+ issuer_pkey,
+ (unsigned int) cf,
+ &cdata[sizeof (cred)]);
+ GNUNET_free (subject_pkey);
+ GNUNET_free (issuer_pkey);
+
+
+
+ return cred_str;
+ }
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ * Convert human-readable version of a 'value' of a record to the binary
+ * representation.
+ *
+ * @param cls closure, unused
+ * @param type type of the record
+ * @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
+credential_string_to_value (void *cls,
+ uint32_t type,
+ const char *s,
+ void **data,
+ size_t *data_size)
+{
+ if (NULL == s)
+ return GNUNET_SYSERR;
+ switch (type)
+ {
+ case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+ {
+ struct GNUNET_CREDENTIAL_AttributeRecordData *cred;
+ unsigned int cf; // credential flags
+
+ size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
+ if (enclen % 5 > 0)
+ enclen += 5 - enclen % 5;
+ enclen /= 5; /* 260/5 = 52 */
+ char subject_pkey[enclen + 1];
+ char issuer_pkey[enclen + 1];
+ char name[253 + 1];
+
+ if (5 != SSCANF (s,
+ "%52s %52s %u %253s",
+ subject_pkey,
+ issuer_pkey,
+ &cf,
+ name))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse CRED record string `%s'\n"),
+ s);
+ return GNUNET_SYSERR;
+ }
+ *data_size = sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData) + strlen (name) + 1;
+ *data = cred = GNUNET_malloc (*data_size);
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
+ strlen (subject_pkey),
+ &cred->subject_key);
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
+ strlen (issuer_pkey),
+ &cred->issuer_key);
+ cred->credential_flags = htonl (cf);
+ GNUNET_memcpy (&cred[1],
+ name,
+ strlen (name));
+
+
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+ }
+ default:
+ return GNUNET_SYSERR;
+ }
+}
+
+
+/**
+ * Mapping of record type numbers to human-readable
+ * record type names.
+ */
+static struct {
+ const char *name;
+ uint32_t number;
+} name_map[] = {
+ { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL },
+ { NULL, UINT32_MAX }
+};
+
+
+/**
+ * Convert a type name (i.e. "AAAA") to the corresponding number.
+ *
+ * @param cls closure, unused
+ * @param gns_typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+static uint32_t
+credential_typename_to_number (void *cls,
+ const char *gns_typename)
+{
+ unsigned int i;
+
+ i=0;
+ while ( (name_map[i].name != NULL) &&
+ (0 != strcasecmp (gns_typename, name_map[i].name)) )
+ i++;
+ return name_map[i].number;
+}
+
+
+/**
+ * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
+ *
+ * @param cls closure, unused
+ * @param type number of a type to convert
+ * @return corresponding typestring, NULL on error
+ */
+static const char *
+credential_number_to_typename (void *cls,
+ uint32_t type)
+{
+ unsigned int i;
+
+ i=0;
+ while ( (name_map[i].name != NULL) &&
+ (type != name_map[i].number) )
+ i++;
+ return name_map[i].name;
+}
+
+
+/**
+ * Entry point for the plugin.
+ *
+ * @param cls NULL
+ * @return the exported block API
+ */
+void *
+libgnunet_plugin_gnsrecord_credential_init (void *cls)
+{
+ struct GNUNET_GNSRECORD_PluginFunctions *api;
+
+ api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
+ api->value_to_string = &credential_value_to_string;
+ api->string_to_value = &credential_string_to_value;
+ api->typename_to_number = &credential_typename_to_number;
+ api->number_to_typename = &credential_number_to_typename;
+ return api;
+}
+
+
+/**
+ * Exit point from the plugin.
+ *
+ * @param cls the return value from #libgnunet_plugin_block_test_init
+ * @return NULL
+ */
+void *
+libgnunet_plugin_gnsrecord_credential_done (void *cls)
+{
+ struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
+
+ GNUNET_free (api);
+ return NULL;
+}
+
+/* end of plugin_gnsrecord_credential.c */
--- /dev/null
+#!/bin/bash
+trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT
+
+LOCATION=$(which gnunet-config)
+if [ -z $LOCATION ]
+then
+ LOCATION="gnunet-config"
+fi
+$LOCATION --version 1> /dev/null
+if test $? != 0
+then
+ echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
+ exit 77
+fi
+
+rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f`
+which timeout &> /dev/null && DO_TIMEOUT="timeout 30"
+TEST_CREDENTIAL="keySub keyIss credName"
+gnunet-arm -s -c test_credential_lookup.conf
+gnunet-identity -C testsubject -c test_credential_lookup.conf
+
+#TODO1 Plugin serialization functions see REVERSE in gns/plugin_gnsrecord_gns.c
+gnunet-namestore -p -z testsubject -a -n newcred -t CRED -V $TEST_CREDENTIAL -e never -c test_credential_lookup.conf
+
+#TODO2 Add -z swich like in gnunet-gns
+RES_IP=`$DO_TIMEOUT gnunet-credential -z testsubject -s testsubject -u credName -c test_credential_lookup.conf`
+gnunet-namestore -z testsubject -d -n newcred -t CRED -e never -c test_credential_lookup.conf
+gnunet-identity -D testsubject -c test_credential_lookup.conf
+gnunet-arm -e -c test_credential_lookup.conf
+
+#TODO3 proper test
+exit 0
+
+#if [ "$RES_IP" == "$TEST_CRED" ]
+#then
+# exit 0
+#else
+# echo "FAIL: Failed to resolve to proper IP, got $RES_IP."
+# exit 1
+#fi
#include "gnunet_util_lib.h"
#include "gnunet_gns_service.h"
+#include "gnunet_identity_service.h"
#ifdef __cplusplus
extern "C"
/**
* Handle to control a lookup operation.
*/
-struct GNUNET_CREDENTIAL_LookupRequest;
+struct GNUNET_CREDENTIAL_Request;
+
+/*
+* Enum used for checking whether the issuer has the authority to issue credentials or is just a subject
+*/
+enum GNUNET_CREDENTIAL_CredentialFlags {
+
+ //Subject had credentials before, but have been revoked now
+ GNUNET_CREDENTIAL_FLAG_REVOKED=0,
+
+ //Subject flag indicates that the subject is a holder of this credential and may present it as such
+ GNUNET_CREDENTIAL_FLAG_SUBJECT=1,
+
+ //Issuer flag is used to signify that the subject is allowed to issue this credential and delegate issuance
+ GNUNET_CREDENTIAL_FLAG_ISSUER=2
+
+};
+
+GNUNET_NETWORK_STRUCT_BEGIN
+/**
+ * The attribute record
+ */
+struct GNUNET_CREDENTIAL_AttributeRecordData {
+
+ /**
+ * Public key of the subject this credential was issued to
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+
+ /**
+ * Public key of the issuer
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
+
+ /**
+ * Flags for this credential
+ */
+ uint32_t credential_flags GNUNET_PACKED;
+
+ /**
+ * Expiration time of this credential
+ */
+ uint64_t expiration GNUNET_PACKED;
+
+ /**
+ * The signature for this credential by the issuer
+ */
+ struct GNUNET_CRYPTO_EcdsaSignature sig;
+
+ /**
+ * Followed by the attribute string
+ */
+};
+
+
+/**
+ * The attribute delegation record
+*/
+struct GNUNET_CREDENTIAL_AttributeDelegationRecordData {
+
+ /**
+ * Public key of the subject this attribute was delegated to
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+
+ /**
+ * Followed by the attribute that was delegated to as string
+ */
+};
+
+
+
+GNUNET_NETWORK_STRUCT_END
+
/**
* @param cfg configuration to use
* @return handle to the Credential service, or NULL on error
*/
-struct GNUNET_Credential_Handle *
+struct GNUNET_CREDENTIAL_Handle *
GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
/**
- * Iterator called on obtained result for a Credential lookup.
+ * Iterator called on obtained result for an attribute verification.
*
* @param cls closure
- * @param issuer the issuer chain
- * @param issuer_len length of issuer chain
+ * @param issuer the issuer of the attribute NULL if verification failed
+ * @param result the result of the verification
* @param rd the records in reply
*/
-typedef void (*GNUNET_CREDENTIAL_LookupResultProcessor) (void *cls,
- struct GNUNET_IDENTITY_Ego *issuer,
- uint16_t issuer_len,
- const struct GNUNET_CREDENTIAL_Value *value);
+typedef void (*GNUNET_CREDENTIAL_VerifyResultProcessor) (void *cls,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *issuer,
+ uint32_t result);
+
+/**
+ * Iterator called on obtained result for an attribute issuance.
+ *
+ * @param cls closure
+ * @param result the record data that can be handed to the subject
+ */
+typedef void (*GNUNET_CREDENTIAL_IssueResultProcessor) (void *cls,
+ struct GNUNET_CREDENTIAL_AttributeRecordData *data);
+/**
+ * Iterator called on obtained result for an attribute delegation.
+ *
+ * @param cls closure
+ * @param success GNUNET_YES if successful
+ * @param result the record data that can be handed to the subject
+ */
+typedef void (*GNUNET_CREDENTIAL_DelegateResultProcessor) (void *cls,
+ uint32_t success);
/**
- * Perform an asynchronous lookup operation for a credential.
+ * Iterator called on obtained result for an attribute delegation removal.
+ *
+ * @param cls closure
+ * @param success GNUNET_YES if successful
+ * @param result the record data that can be handed to the subject
+ */
+typedef void (*GNUNET_CREDENTIAL_RemoveDelegateResultProcessor) (void *cls,
+ uint32_t success);
+
+
+
+
+/**
+ * Performs attribute verification.
+ * Checks if there is a delegation chain from
+ * attribute ``issuer_attribute'' issued by the issuer
+ * with public key ``issuer_key'' maps to the attribute
+ * ``subject_attribute'' claimed by the subject with key
+ * ``subject_key''
*
* @param handle handle to the Credential service
- * @param credential the credential to look up
- * @param subject Ego to check the credential for
+ * @param issuer_key the issuer public key
+ * @param issuer_attribute the issuer attribute
+ * @param subject_key the subject public key
+ * @param subject_attribute the attribute claimed by the subject
* @param proc function to call on result
* @param proc_cls closure for processor
* @return handle to the queued request
*/
-struct GNUNET_CREDENTIAL_LookupRequest *
-GNUNET_CREDENTIAL_lookup (struct GNUNET_CREDENTIAL_Handle *handle,
- const char *credential,
- const struct GNUNET_IDENTITY_Ego *subject,
- GNUNET_CREDENTIAL_LookupResultProcessor proc,
- void *proc_cls);
+struct GNUNET_CREDENTIAL_Request*
+GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
+ const char *issuer_attribute,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key,
+ const char *subject_attribute,
+ GNUNET_CREDENTIAL_VerifyResultProcessor proc,
+ void *proc_cls);
+/**
+ * Delegate an attribute
+ *
+ * @param handle handle to the Credential service
+ * @param issuer the ego that should be used to delegate the attribute
+ * @param attribute the name of the attribute to delegate
+ * @param subject the subject of the delegation
+ * @param delegated_attribute the name of the attribute that is delegated to
+ * @return handle to the queued request
+ */
+struct GNUNET_CREDENTIAL_Request *
+GNUNET_CREDENTIAL_add_delegation (struct GNUNET_CREDENTIAL_Handle *handle,
+ struct GNUNET_IDENTITY_Ego *issuer,
+ const char *attribute,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
+ const char *delegated_attribute,
+ GNUNET_CREDENTIAL_DelegateResultProcessor proc,
+ void *proc_cls);
/**
- * Issue a credential to an identity
+ * Remove a delegation
*
* @param handle handle to the Credential service
- * @param issuer the identity that issues the credential
- * @param subject the subject of the credential
- * @param credential the name of the credential
- * @param value the value of the credential
+ * @param issuer the ego that was used to delegate the attribute
+ * @param attribute the name of the attribute that is delegated
* @return handle to the queued request
*/
-struct GNUNET_CREDENTIAL_IssueRequest *
+struct GNUNET_CREDENTIAL_Request *
+GNUNET_CREDENTIAL_remove_delegation (struct GNUNET_CREDENTIAL_Handle *handle,
+ struct GNUNET_IDENTITY_Ego *issuer,
+ const char *attribute,
+ GNUNET_CREDENTIAL_RemoveDelegateResultProcessor proc,
+ void *proc_cls);
+
+
+
+/**
+ * Issue an attribute to a subject
+ *
+ * @param handle handle to the Credential service
+ * @param issuer the ego that should be used to issue the attribute
+ * @param subject the subject of the attribute
+ * @param attribute the name of the attribute
+ * @return handle to the queued request
+ */
+struct GNUNET_CREDENTIAL_Request *
GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle,
struct GNUNET_IDENTITY_Ego *issuer,
- struct GNUNET_IDENTITY_Ego *subject,
- const char *credential,
- struct GNUNET_CREDENTIAL_Value *value,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
+ const char *attribute,
GNUNET_CREDENTIAL_IssueResultProcessor proc,
void *proc_cls);
+
/**
* Remove a credential
*
* @param credential the name of the credential
* @return handle to the queued request
*/
-struct GNUNET_CREDENTIAL_IssueRequest *
-GNUNET_CREDENTIAL_remove (struct GNUNET_CREDENTIAL_Handle *handle,
- struct GNUNET_IDENTITY_Ego *issuer,
- struct GNUNET_IDENTITY_Ego *subject,
- const char *credential,
- GNUNET_CREDENTIAL_IssueResultProcessor proc,
- void *proc_cls);
-
+/**
+ struct GNUNET_CREDENTIAL_IssueRequest *
+ GNUNET_CREDENTIAL_remove (struct GNUNET_CREDENTIAL_Handle *handle,
+ struct GNUNET_IDENTITY_Ego *issuer,
+ struct GNUNET_IDENTITY_Ego *subject,
+ const char *credential,
+ GNUNET_CREDENTIAL_IssueResultProcessor proc,
+ void *proc_cls);
+ */
/**
* @param lr the lookup request to cancel
*/
void
-GNUNET_CREDENTIAL_lookup_cancel (struct GNUNET_CREDENTIAL_LookupRequest *lr);
+GNUNET_CREDENTIAL_verify_cancel (struct GNUNET_CREDENTIAL_Request *vr);
#if 0 /* keep Emacsens' auto-indent happy */
*/
#define GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA 65546
+/**
+ * Record type for credential
+ */
+#define GNUNET_GNSRECORD_TYPE_CREDENTIAL 65547
+
/**
* Record type for reverse lookups
*/
#define GNUNET_GNSRECORD_TYPE_REVERSE 65548
+/**
+ * Record type for reverse lookups
+ */
+#define GNUNET_GNSRECORD_TYPE_ATTRIBUTE 65549
+
+
/**
* Flags that can be set for a record.
*/
#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT 964
+
+/**************************************************
+ *
+ * CREDENTIAL MESSAGE TYPES
+ */
+#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY 971
+
+#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT 972
+
/******************************************************************************/