#define GNUNET_MESSAGE_TYPE_ZKLAIM_RESULT_CODE 991
+#define GNUNET_MESSAGE_TYPE_ZKLAIM_ISSUE 992
+
+#define GNUNET_MESSAGE_TYPE_ZKLAIM_LOOKUP_CTX 993
+
+#define GNUNET_MESSAGE_TYPE_ZKLAIM_RESULT_CTX 994
+
/******************************************************************************/
/*********************************** CADET **********************************/
/******************************************************************************/
+++ /dev/null
-/*
- This file is part of GNUnet.
- Copyright (C) 2001-2018 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 include/gnunet_zklaim_lib.h
- * @brief ZKlaim functions for GNUnet
- *
- * @author Martin Schanzenbach
- *
- * @defgroup zklaim ZKlaim library: Zero-Knowledge Credentials
- *
- */
-#ifndef GNUNET_ZKLAIM_LIB_H
-#define GNUNET_ZKLAIM_LIB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include "gnunet_common.h"
-
-/**
- * @brief type for ZKlaim context
- */
-struct GNUNET_ZKLAIM_Context;
-
-/**
- * @brief type for ZKlaim payload
- */
-struct GNUNET_ZKLAIM_Payload;
-
-
-/**
- * @ingroup zklaim
- * Create a new ZKlaim context. Caller must free return value.
- * TODO: parameters: keys etc.
- *
- * @return fresh context; free using #GNUNET_free
- */
-struct GNUNET_ZKLAIM_Context *
-GNUNET_ZKLAIM_context_create (void);
-
-/**
- * @ingroup zklaim
- * Create a payload.
- * TODO: parameters, attributes etc.
- *
- * @return fresh payload; free using #GNUNET_free
- */
-void
-GNUNET_ZKLAIM_payload_create (void);
-
-/**
- * @ingroup zklaim
- * Create a payload.
- * TODO: parameters, attributes etc.
- *
- * @return GNUNET_OK is successful
- */
-int
-GNUNET_ZKLAIM_context_add_payload (struct GNUNET_ZKLAIM_Context *ctx,
- struct GNUNET_ZKLAIM_Payload* pl);
-
-
-/**
- * @ingroup zklaim
- * Create a payload.
- * TODO: parameters, attributes etc.
- *
- * @return size needed for serialized context, -1 on error
- */
-ssize_t
-GNUNET_ZKLAIM_context_serialize_get_size (struct GNUNET_ZKLAIM_Context *ctx);
-
-
-/**
- * @ingroup zklaim
- * Create a payload.
- * TODO: parameters, attributes etc.
- *
- */
-void
-GNUNET_ZKLAIM_context_serialize (struct GNUNET_ZKLAIM_Context *ctx,
- char* buf);
-
-
-/**
- * @ingroup zklaim
- * Create a payload.
- * TODO: parameters, attributes etc.
- *
- * @return fresh payload; free using #GNUNET_free
- */
-char *
-GNUNET_ZKLAIM_context_to_string (struct GNUNET_ZKLAIM_Context *ctx);
-
-
-
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-
-/* ifndef GNUNET_ZKLAIM_LIB_H */
-#endif
-/* end of gnunet_zklaim_lib.h */
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2016 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @author Martin Schanzenbach
+ *
+ * @file
+ * ZKlaim service. Manage ZKlaim issuers etc.
+ *
+ * @defgroup zklaim ZKlaim service
+ * @{
+ */
+#ifndef GNUNET_ZKLAIM_SERVICE_H
+#define GNUNET_ZKLAIM_SERVICE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0 /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+#include "gnunet_util_lib.h"
+
+/**
+ * Version number of GNUnet Identity Provider API.
+ */
+#define GNUNET_ZKLAIM_VERSION 0x00000000
+
+/**
+ * Handle to access the identity service.
+ */
+struct GNUNET_ZKLAIM_Handle;
+
+/**
+ * Handle for an operation with the zklaim service.
+ */
+struct GNUNET_ZKLAIM_Operation;
+
+/**
+ * Context
+ */
+struct GNUNET_ZKLAIM_Context;
+
+/**
+ * Connect to the ZKlaim service.
+ *
+ * @param cfg Configuration to contact the service.
+ * @return handle to communicate with the service
+ */
+struct GNUNET_ZKLAIM_Handle *
+GNUNET_ZKLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+/**
+ * Iterator called for each attribute and data.
+ *
+ * @param cls closure
+ * @param name name of attribute
+ * @param data attribute data (can be modified)
+ */
+typedef void
+(*GNUNET_ZKLAIM_PayloadIterator) (void *cls,
+ const char* name,
+ uint64_t *data);
+
+
+
+/**
+ * Continuation called to notify client about result of the
+ * operation.
+ *
+ * @param cls closure
+ * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
+ * #GNUNET_NO if content was already there or not found
+ * #GNUNET_YES (or other positive value) on success
+ * @param emsg NULL on success, otherwise an error message
+ */
+typedef void
+(*GNUNET_ZKLAIM_ContextResult) (void *cls,
+ const struct GNUNET_ZKLAIM_Context *ctx);
+
+
+
+/**
+ * Continuation called to notify client about result of the
+ * operation.
+ *
+ * @param cls closure
+ * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
+ * #GNUNET_NO if content was already there or not found
+ * #GNUNET_YES (or other positive value) on success
+ * @param emsg NULL on success, otherwise an error message
+ */
+typedef void
+(*GNUNET_ZKLAIM_ContinuationWithStatus) (void *cls,
+ int32_t success,
+ const char *emsg);
+
+
+/**
+ * Create a new issuer context
+ *
+ * @param h handle to the identity provider
+ * @param pkey private key of the identity
+ * @param attr the attribute
+ * @param exp_interval the relative expiration interval for the attribute
+ * @param cont continuation to call when done
+ * @param cont_cls closure for @a cont
+ * @return handle to abort the request
+ */
+struct GNUNET_ZKLAIM_Operation *
+GNUNET_ZKLAIM_context_create (struct GNUNET_ZKLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+ const char *context_name,
+ const char *attr_list,
+ GNUNET_ZKLAIM_ContinuationWithStatus cont,
+ void *cont_cls);
+
+/**
+ * Disconnect from service.
+ *
+ * @param h service to disconnect
+ */
+void
+GNUNET_ZKLAIM_disconnect (struct GNUNET_ZKLAIM_Handle *h);
+
+
+/**
+ * Cancel an operation. Note that the operation MAY still
+ * be executed; this merely cancels the continuation; if the request
+ * was already transmitted, the service may still choose to complete
+ * the operation.
+ *
+ * @param op operation to cancel
+ */
+void
+GNUNET_ZKLAIM_cancel (struct GNUNET_ZKLAIM_Operation *op);
+
+#if 0 /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+
+/* ifndef GNUNET_ZKLAIM_SERVICE_H */
+#endif
+
+/** @} */ /* end of group identity */
+
+/* end of gnunet_zklaim_service.h */
libgnunetzklaim_la_SOURCES = \
zklaim_api.c \
- zklaim_api.h
+ zklaim_functions.c
libgnunetzklaim_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(GN_LIBINTL) $(XLIB)
*/
struct CreateContextHandle *create_op_tail;
+ /**
+ * Head of DLL of context issue ops
+ */
+ struct LookupHandle *lookup_op_head;
+
+ /**
+ * Tail of DLL of attribute store ops
+ */
+ struct LookupHandle *lookup_op_tail;
+
+
};
struct CreateContextHandle
};
+struct LookupHandle
+{
+ /**
+ * DLL
+ */
+ struct LookupHandle *next;
+
+ /**
+ * DLL
+ */
+ struct LookupHandle *prev;
+
+ /**
+ * Client connection
+ */
+ struct ZkClient *client;
+
+ /**
+ * Issuer private key
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey private_key;
+
+ /**
+ * Issuer public key
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
+
+ /**
+ * QueueEntry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The context name
+ */
+ char *name;
+
+};
+
+
/**
* Cleanup task
*/
{
if (NULL != handle->ns_qe)
GNUNET_NAMESTORE_cancel (handle->ns_qe);
- if (NULL != handle->name)
- GNUNET_free (handle->name);
+ GNUNET_free_non_null (handle->name);
+ GNUNET_free_non_null (handle->name);
+ GNUNET_free_non_null (handle->attrs);
GNUNET_free (handle);
}
GNUNET_MQ_send (cch->client->mq,
env);
cleanup_create_handle (cch);
-
+ GNUNET_CONTAINER_DLL_remove (cch->client->create_op_head,
+ cch->client->create_op_tail,
+ cch);
}
static void
struct CreateContextHandle *cch = cls;
cch->ns_qe = NULL;
- GNUNET_CONTAINER_DLL_remove (cch->client->create_op_head,
- cch->client->create_op_tail,
- cch);
-
if (GNUNET_SYSERR == success)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to create context %s\n",
emsg);
-
send_result (success, cch);
}
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Trusted Setup failed.\n");
- send_result(GNUNET_SYSERR, cch);
+ send_result (GNUNET_SYSERR, cch);
zklaim_ctx_free (ctx);
return;
}
ctx_record.record_type = GNUNET_GNSRECORD_TYPE_ZKLAIM_CTX;
ctx_record.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
cch->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
- &cch->private_key,
- cch->name,
- 1,
- &ctx_record,
- &context_store_cont,
- cch);
+ &cch->private_key,
+ cch->name,
+ 1,
+ &ctx_record,
+ &context_store_cont,
+ cch);
GNUNET_free (rdata);
GNUNET_free (data);
}
+/**
+ * Cleanup attribute store handle
+ *
+ * @param handle handle to clean up
+ */
+static void
+cleanup_lookup_handle (struct LookupHandle *handle)
+{
+ if (NULL != handle->ns_qe)
+ GNUNET_NAMESTORE_cancel (handle->ns_qe);
+ GNUNET_free_non_null (handle->name);
+ GNUNET_free (handle);
+}
+
+
+static void
+send_ctx_result (struct LookupHandle *lh,
+ const char* ctx,
+ size_t len)
+{
+ struct GNUNET_MQ_Envelope *env;
+ struct ContextMessage *r_msg;
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending RESULT_CODE message\n");
+ env = GNUNET_MQ_msg_extra (r_msg,
+ len,
+ GNUNET_MESSAGE_TYPE_ZKLAIM_RESULT_CTX);
+ r_msg->ctx_len = htonl (len);
+ memcpy ((char*)&r_msg[1],
+ ctx,
+ len);
+ GNUNET_MQ_send (lh->client->mq,
+ env);
+ cleanup_lookup_handle (lh);
+ GNUNET_CONTAINER_DLL_remove (lh->client->lookup_op_head,
+ lh->client->lookup_op_tail,
+ lh);
+}
+
+
+static void
+ctx_not_found_cb (void* cls)
+{
+ struct LookupHandle *lh = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Context %s not found!\n",
+ lh->name);
+
+ send_ctx_result (lh, NULL, 0);
+}
+
+
+static void
+ctx_found_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct LookupHandle *lh = cls;
+
+ send_ctx_result (lh, (char*) rd->data, rd->data_size);
+}
+
+
+
+static int
+check_lookup_message(void *cls,
+ const struct LookupMessage *lm)
+{
+ uint16_t size;
+
+ size = ntohs (lm->header.size);
+ if (size <= sizeof (struct LookupMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+static void
+handle_lookup_message (void *cls,
+ const struct LookupMessage *lm)
+{
+ struct LookupHandle *lh;
+ struct ZkClient *zkc = cls;
+ size_t str_len;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received CREATE_REQUEST message\n");
+
+ str_len = ntohs (lm->name_len);
+
+ lh = GNUNET_new (struct LookupHandle);
+ lh->name = GNUNET_strndup ((char*)&lm[1], str_len-1);
+ lh->private_key = lm->private_key;
+ GNUNET_CRYPTO_ecdsa_key_get_public (&lm->private_key,
+ &lh->public_key);
+
+ GNUNET_SERVICE_client_continue (zkc->client);
+ lh->client = zkc;
+ GNUNET_CONTAINER_DLL_insert (zkc->lookup_op_head,
+ zkc->lookup_op_tail,
+ lh);
+
+ lh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
+ &lh->private_key,
+ lh->name,
+ &ctx_not_found_cb,
+ lh,
+ &ctx_found_cb,
+ lh);
+}
+
/**
GNUNET_MESSAGE_TYPE_ZKLAIM_CREATE,
struct CreateRequestMessage,
NULL),
+ GNUNET_MQ_hd_var_size (lookup_message,
+ GNUNET_MESSAGE_TYPE_ZKLAIM_LOOKUP_CTX,
+ struct LookupMessage,
+ NULL),
GNUNET_MQ_handler_end());
/* end of gnunet-service-zklaim.c */
#include "gnunet_zklaim_service.h"
#include "zklaim/zklaim.h"
#include "zklaim_api.h"
+#include "zklaim_functions.h"
#define LOG(kind,...) GNUNET_log_from (kind, "zklaim-api",__VA_ARGS__)
-/**
- * Handle for an ego.
- */
-struct GNUNET_ZKLAIM_Context
-{
- /**
- * ZKlaim context.
- */
- struct zklaim_ctx *zk_ctx;
-
- /**
- * Current name associated with this context.
- */
- char *name;
-
- /**
- * Attributes associated with context
- */
- char *attrs;
-
- /**
- * Client context associated with this ego.
- */
- void *ctx;
-
-};
-
/**
* Handle for an operation with the service.
*/
GNUNET_ZKLAIM_ContinuationWithStatus cont;
+ /**
+ * Context result
+ */
+ GNUNET_ZKLAIM_ContextResult ctx_cont;
+
/**
* Closure for @e cont or @e cb.
*/
GNUNET_free (op);
}
+/**
+ * We received a result code from the service. Check the message
+ * is well-formed.
+ *
+ * @param cls closure
+ * @param rcm result message received
+ * @return #GNUNET_OK if the message is well-formed
+ */
+static int
+check_zklaim_result_ctx (void *cls,
+ const struct ContextMessage *cm)
+{
+ //TODO check for data sanity
+ return GNUNET_OK;
+}
+
+
+/**
+ * We received a context result from the service.
+ *
+ * @param cls closure
+ * @param rcm result message received
+ */
+static void
+handle_zklaim_result_ctx (void *cls,
+ const struct ContextMessage *cm)
+{
+ struct GNUNET_ZKLAIM_Handle *h = cls;
+ struct GNUNET_ZKLAIM_Operation *op;
+ struct GNUNET_ZKLAIM_Context ctx;
+ uint16_t ctx_len = ntohs (cm->ctx_len);
+
+ op = h->op_head;
+ if (NULL == op)
+ {
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ GNUNET_CONTAINER_DLL_remove (h->op_head,
+ h->op_tail,
+ op);
+ ctx.attrs = (char*)&cm[1];
+ ctx.ctx = zklaim_context_new ();
+ zklaim_ctx_deserialize (ctx.ctx,
+ (unsigned char *) &cm[1]+ strlen (ctx.attrs) + 1,
+ ctx_len);
+ if (NULL != op->ctx_cont)
+ {
+ if (0 > ctx_len)
+ op->ctx_cont (op->cls,
+ &ctx);
+ else
+ op->ctx_cont (op->cls,
+ &ctx);
+ }
+ zklaim_ctx_free (ctx.ctx);
+ GNUNET_free (op);
+}
+
+
/**
* Try again to connect to the zklaim service.
GNUNET_MESSAGE_TYPE_ZKLAIM_RESULT_CODE,
struct ResultCodeMessage,
h),
+ GNUNET_MQ_hd_var_size (zklaim_result_ctx,
+ GNUNET_MESSAGE_TYPE_ZKLAIM_RESULT_CTX,
+ struct ContextMessage,
+ h),
GNUNET_MQ_handler_end ()
};
GNUNET_free (h);
}
+/**
+ * Lookup context
+ */
+struct GNUNET_ZKLAIM_Operation*
+GNUNET_ZKLAIM_lookup_context (struct GNUNET_ZKLAIM_Handle *h,
+ const char *name,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
+ GNUNET_ZKLAIM_ContextResult cont,
+ void* cont_cls)
+{
+ struct GNUNET_ZKLAIM_Operation *op;
+ struct GNUNET_MQ_Envelope *env;
+ struct LookupMessage *lm;
+ size_t slen;
+
+ if (NULL == h->mq)
+ return NULL;
+ slen = strlen (name) + 1;
+ if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct LookupMessage))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ op = GNUNET_new (struct GNUNET_ZKLAIM_Operation);
+ op->h = h;
+ op->ctx_cont = cont;
+ op->cls = cont_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
+ h->op_tail,
+ op);
+ env = GNUNET_MQ_msg_extra (lm,
+ slen,
+ GNUNET_MESSAGE_TYPE_ZKLAIM_CREATE);
+ lm->name_len = htons (slen);
+ lm->reserved = htons (0);
+ lm->private_key = *key;
+ GNUNET_memcpy (&lm[1],
+ name,
+ slen);
+ GNUNET_MQ_send (h->mq,
+ env);
+ return op;
+}
+
+void
+GNUNET_ZKLAIM_issue_from_context (struct GNUNET_ZKLAIM_Context *ctx,
+ struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
+ GNUNET_ZKLAIM_PayloadIterator iter,
+ void* iter_cls)
+{
+ ZKLAIM_context_issue (ctx,
+ key,
+ iter,
+ iter_cls);
+}
+
/* end of zklaim_api.c */
GNUNET_NETWORK_STRUCT_BEGIN
+/**
+ * Answer from service to client about last operation;
+ * GET_DEFAULT maybe answered with this message on failure;
+ * CREATE and RENAME will always be answered with this message.
+ */
+struct ContextMessage
+{
+ /**
+ * Type: #GNUNET_MESSAGE_TYPE_ZKLAIM_RESULT_CTX
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Length if the serialized context.
+ */
+ uint32_t ctx_len GNUNET_PACKED;
+
+ /* followed by 0-terminated error message (on error) */
+
+};
+
+
/**
* Answer from service to client about last operation;
};
+/**
+ * Client requests issue of a credential. Service
+ * will respond with a context.
+ */
+struct LookupMessage
+{
+ /**
+ * Type: #GNUNET_MESSAGE_TYPE_ZKLAIM_LOOKUP_CTX
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Number of bytes in name string including 0-termination, in NBO.
+ */
+ uint16_t name_len GNUNET_PACKED;
+
+ /**
+ * Always zero.
+ */
+ uint16_t reserved GNUNET_PACKED;
+
+ /**
+ * The private key
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey private_key;
+
+ /* followed by 0-terminated identity name */
+
+};
+
/**
* Client requests creation of an identity. Service
--- /dev/null
+#include "platform.h"
+#include "zklaim/zklaim.h"
+#include "gcrypt.h"
+#include "gnunet_zklaim_service.h"
+#include "zklaim_functions.h"
+
+int
+ZKLAIM_context_sign (struct GNUNET_ZKLAIM_Context *ctx,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *key)
+{
+ int rc;
+ gcry_sexp_t priv;
+
+ //TODO how to ensure not hashed??
+ zklaim_hash_ctx (ctx->ctx);
+ rc = gcry_sexp_build (&priv, NULL,
+ "(private-key(ecc(curve \"Ed25519\")"
+ "(d %b)))",
+ (int) sizeof (key->d), key->d);
+ if (0 != rc)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "GCRY error...\n");
+ //send_issue_response (ih, NULL, 0);
+ return GNUNET_SYSERR;
+ }
+ return zklaim_ctx_sign (ctx->ctx, priv);
+}
+
+void
+ZKLAIM_context_attributes_iterate (const struct GNUNET_ZKLAIM_Context *ctx,
+ GNUNET_ZKLAIM_PayloadIterator iter,
+ void *iter_cls)
+{
+ int i;
+ int j;
+ uint64_t data;
+ char *attr_name;
+ char *tmp;
+ zklaim_wrap_payload_ctx *plw;
+
+ tmp = GNUNET_strdup (ctx->attrs);
+ attr_name = strtok (tmp, ",");
+ plw = ctx->ctx->pl_ctx_head;
+
+ for (i = 0; i < ctx->ctx->num_of_payloads; i++)
+ {
+ for (j = 0; j < ZKLAIM_MAX_PAYLOAD_ATTRIBUTES; j++)
+ {
+ GNUNET_assert (NULL != attr_name);
+ iter (iter_cls, attr_name, &data);
+ zklaim_set_attr (&plw->pl,
+ data,
+ j);
+ attr_name = strtok (NULL, ",");
+ }
+ plw = plw->next;
+ GNUNET_assert (NULL != plw);
+ }
+ GNUNET_free (tmp);
+
+}
+
+void
+ZKLAIM_context_issue (struct GNUNET_ZKLAIM_Context *ctx,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
+ GNUNET_ZKLAIM_PayloadIterator iter,
+ void *iter_cls)
+{
+ ZKLAIM_context_attributes_iterate (ctx,
+ iter,
+ iter_cls);
+ ZKLAIM_context_sign (ctx,
+ key);
+}
--- /dev/null
+#ifndef GNUNET_ZKLAIM_FUNCTIONS_H
+#define GNUNET_ZKLAIM_FUNCTIONS_H
+
+#include "gnunet_zklaim_service.h"
+
+/**
+ * Handle for an ego.
+ */
+struct GNUNET_ZKLAIM_Context
+{
+ /**
+ * ZKlaim context.
+ */
+ struct zklaim_ctx *ctx;
+
+ /**
+ * Current name associated with this context.
+ */
+ char *name;
+
+ /**
+ * Attributes associated with context
+ */
+ char *attrs;
+
+};
+
+
+
+int
+ZKLAIM_context_sign (struct GNUNET_ZKLAIM_Context *ctx,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *key);
+
+
+void
+ZKLAIM_context_attributes_iterate (const struct GNUNET_ZKLAIM_Context *ctx,
+ GNUNET_ZKLAIM_PayloadIterator iter,
+ void *iter_cls);
+
+
+void
+ZKLAIM_context_issue (struct GNUNET_ZKLAIM_Context *ctx,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
+ GNUNET_ZKLAIM_PayloadIterator iter,
+ void *iter_cls);
+#endif