summaryrefslogtreecommitdiff
path: root/src/credential
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2016-12-28 18:40:17 +0100
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2016-12-28 18:40:17 +0100
commita84624407eedd5418d36de590571da47d2f47015 (patch)
tree2f8d9fd84df5f1dba55a4e85c7d98722cc42cada /src/credential
parent43b34377e10d329075327104e4a295ee9d3c53b4 (diff)
-change api
Diffstat (limited to 'src/credential')
-rw-r--r--src/credential/Makefile.am1
-rw-r--r--src/credential/credential.h47
-rw-r--r--src/credential/credential_api.c142
-rw-r--r--src/credential/credential_misc.c1
-rw-r--r--src/credential/credential_serialization.c175
-rw-r--r--src/credential/credential_serialization.h17
-rw-r--r--src/credential/gnunet-credential.c171
-rw-r--r--src/credential/gnunet-service-credential.c367
-rw-r--r--src/credential/plugin_rest_credential.c3
-rwxr-xr-xsrc/credential/test_credential_collect.sh47
-rw-r--r--src/credential/test_credential_lookup.conf2
-rwxr-xr-xsrc/credential/test_credential_verify.sh5
12 files changed, 781 insertions, 197 deletions
diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am
index db3bc8027..ca11c5e4f 100644
--- a/src/credential/Makefile.am
+++ b/src/credential/Makefile.am
@@ -69,6 +69,7 @@ gnunet_service_credential_LDADD = \
libgnunetcredential.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/gns/libgnunetgns.la \
+ $(top_builddir)/src/namestore/libgnunetnamestore.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(GN_LIBINTL)
diff --git a/src/credential/credential.h b/src/credential/credential.h
index c5c0183cc..f16249c1b 100644
--- a/src/credential/credential.h
+++ b/src/credential/credential.h
@@ -30,6 +30,41 @@
GNUNET_NETWORK_STRUCT_BEGIN
/**
+ * Message from client to Credential service to collect credentials.
+ */
+struct CollectMessage
+{
+ /**
+ * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Subject public key
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey subject_key;
+
+ /**
+ * Trust anchor
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
+
+ /**
+ * Length of the issuer attribute
+ */
+ uint16_t issuer_attribute_len;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+ /* Followed by the zero-terminated attribute */
+
+};
+
+
+/**
* Message from client to Credential service to verify attributes.
*/
struct VerifyMessage
@@ -50,21 +85,21 @@ struct VerifyMessage
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
/**
- * Length of the issuer attribute
+ * Number of credentials
*/
- uint16_t issuer_attribute_len;
+ uint32_t c_count;
/**
- * Length of the subject attribute
+ * Length of the issuer attribute
*/
- uint16_t subject_attribute_len;
+ uint16_t issuer_attribute_len;
/**
* Unique identifier for this request (for key collisions).
*/
uint32_t id GNUNET_PACKED;
- /* Followed by the zero-terminated attributes to look up */
+ /* Followed by the zero-terminated attribute and credentials to look up */
};
@@ -72,7 +107,7 @@ struct VerifyMessage
/**
* Message from CREDENTIAL service to client: new results.
*/
-struct VerifyResultMessage
+struct DelegationChainResultMessage
{
/**
* Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT
diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c
index e991b4153..b201d4d9c 100644
--- a/src/credential/credential_api.c
+++ b/src/credential/credential_api.c
@@ -61,7 +61,7 @@ struct GNUNET_CREDENTIAL_Request
/**
* processor to call on verify result
*/
- GNUNET_CREDENTIAL_VerifyResultProcessor verify_proc;
+ GNUNET_CREDENTIAL_CredentialResultProcessor verify_proc;
/**
* @e verify_proc closure
@@ -100,12 +100,12 @@ struct GNUNET_CREDENTIAL_Handle
/**
* Head of linked list of active verify requests.
*/
- struct GNUNET_CREDENTIAL_Request *verify_head;
+ struct GNUNET_CREDENTIAL_Request *request_head;
/**
* Tail of linked list of active verify requests.
*/
- struct GNUNET_CREDENTIAL_Request *verify_tail;
+ struct GNUNET_CREDENTIAL_Request *request_tail;
/**
* Reconnect task
@@ -185,7 +185,6 @@ mq_error_handler (void *cls,
force_reconnect (handle);
}
-
/**
* Check validity of message received from the CREDENTIAL service
*
@@ -194,7 +193,7 @@ mq_error_handler (void *cls,
*/
static int
check_result (void *cls,
- const struct VerifyResultMessage *vr_msg)
+ const struct DelegationChainResultMessage *vr_msg)
{
//TODO
return GNUNET_OK;
@@ -209,7 +208,7 @@ check_result (void *cls,
*/
static void
handle_result (void *cls,
- const struct VerifyResultMessage *vr_msg)
+ const struct DelegationChainResultMessage *vr_msg)
{
struct GNUNET_CREDENTIAL_Handle *handle = cls;
uint32_t r_id = ntohl (vr_msg->id);
@@ -219,30 +218,30 @@ handle_result (void *cls,
uint32_t c_count = ntohl (vr_msg->c_count);
struct GNUNET_CREDENTIAL_Delegation d_chain[d_count];
struct GNUNET_CREDENTIAL_Credential creds[c_count];
- GNUNET_CREDENTIAL_VerifyResultProcessor proc;
+ GNUNET_CREDENTIAL_CredentialResultProcessor 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)
+ for (vr = handle->request_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,
+ GNUNET_CONTAINER_DLL_remove (handle->request_head,
+ handle->request_tail,
vr);
GNUNET_MQ_discard (vr->env);
GNUNET_free (vr);
GNUNET_assert (GNUNET_OK ==
GNUNET_CREDENTIAL_delegation_chain_deserialize (mlen,
- (const char*) &vr_msg[1],
- d_count,
- d_chain,
- c_count,
- creds));
+ (const char*) &vr_msg[1],
+ d_count,
+ d_chain,
+ c_count,
+ creds));
if (GNUNET_NO == ntohl (vr_msg->cred_found))
{
proc (proc_cls,
@@ -271,7 +270,11 @@ 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,
+ struct DelegationChainResultMessage,
+ handle),
+ GNUNET_MQ_hd_var_size (result,
+ GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT_RESULT,
+ struct DelegationChainResultMessage,
handle),
GNUNET_MQ_handler_end ()
};
@@ -287,7 +290,7 @@ reconnect (struct GNUNET_CREDENTIAL_Handle *handle)
handle);
if (NULL == handle->mq)
return;
- for (vr = handle->verify_head; NULL != vr; vr = vr->next)
+ for (vr = handle->request_head; NULL != vr; vr = vr->next)
GNUNET_MQ_send_copy (handle->mq,
vr->env);
}
@@ -334,7 +337,7 @@ GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle)
GNUNET_SCHEDULER_cancel (handle->reconnect_task);
handle->reconnect_task = NULL;
}
- GNUNET_assert (NULL == handle->verify_head);
+ GNUNET_assert (NULL == handle->request_head);
GNUNET_free (handle);
}
@@ -349,13 +352,81 @@ 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,
+ GNUNET_CONTAINER_DLL_remove (handle->request_head,
+ handle->request_tail,
vr);
GNUNET_MQ_discard (vr->env);
GNUNET_free (vr);
}
+
+/**
+ * Performs attribute collection.
+ * Collects all credentials of subject to fulfill the
+ * attribute, if possible
+ *
+ * @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 credential_count number of credentials provided
+ * @param credentials subject credentials
+ * @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_collect (struct GNUNET_CREDENTIAL_Handle *handle,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
+ const char *issuer_attribute,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key,
+ GNUNET_CREDENTIAL_CredentialResultProcessor proc,
+ void *proc_cls)
+{
+ /* IPC to shorten credential names, return shorten_handle */
+ struct CollectMessage *c_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 collect `%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 (c_msg,
+ nlen,
+ GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT);
+ c_msg->id = htonl (vr->r_id);
+ c_msg->subject_key = *subject_key;
+ c_msg->issuer_key = *issuer_key;
+ c_msg->issuer_attribute_len = htons(strlen(issuer_attribute));
+ GNUNET_memcpy (&c_msg[1],
+ issuer_attribute,
+ strlen (issuer_attribute));
+ GNUNET_CONTAINER_DLL_insert (handle->request_head,
+ handle->request_tail,
+ vr);
+ if (NULL != handle->mq)
+ GNUNET_MQ_send_copy (handle->mq,
+ vr->env);
+ return vr;
+}
/**
* Performs attribute verification.
* Checks if there is a delegation chain from
@@ -368,7 +439,8 @@ GNUNET_CREDENTIAL_verify_cancel (struct GNUNET_CREDENTIAL_Request *vr)
* @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 credential_count number of credentials provided
+ * @param credentials subject credentials
* @param proc function to call on result
* @param proc_cls closure for processor
* @return handle to the queued request
@@ -378,25 +450,31 @@ 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,
+ uint32_t credential_count,
+ const struct GNUNET_CREDENTIAL_Credential *credentials,
+ GNUNET_CREDENTIAL_CredentialResultProcessor proc,
void *proc_cls)
{
/* IPC to shorten credential names, return shorten_handle */
struct VerifyMessage *v_msg;
struct GNUNET_CREDENTIAL_Request *vr;
size_t nlen;
+ size_t clen;
- if (NULL == issuer_attribute || NULL == subject_attribute)
+ if (NULL == issuer_attribute || NULL == credentials)
{
GNUNET_break (0);
return NULL;
}
+
+ clen = GNUNET_CREDENTIAL_credentials_get_size (credential_count,
+ credentials);
+
//DEBUG LOG
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Trying to verify `%s' in CREDENTIAL\n",
issuer_attribute);
- nlen = strlen (issuer_attribute) + strlen (subject_attribute) + 1;
+ nlen = strlen (issuer_attribute) + 1 + clen;
if (nlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*vr))
{
GNUNET_break (0);
@@ -412,17 +490,19 @@ GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle,
GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY);
v_msg->id = htonl (vr->r_id);
v_msg->subject_key = *subject_key;
+ v_msg->c_count = htonl(credential_count);
v_msg->issuer_key = *issuer_key;
v_msg->issuer_attribute_len = htons(strlen(issuer_attribute));
- v_msg->subject_attribute_len = htons(strlen(subject_attribute));
GNUNET_memcpy (&v_msg[1],
issuer_attribute,
strlen (issuer_attribute));
- GNUNET_memcpy (((char*)&v_msg[1]) + strlen (issuer_attribute),
- subject_attribute,
- strlen (subject_attribute));
- GNUNET_CONTAINER_DLL_insert (handle->verify_head,
- handle->verify_tail,
+ GNUNET_CREDENTIAL_credentials_serialize (credential_count,
+ credentials,
+ clen,
+ ((char*)&v_msg[1])
+ + strlen (issuer_attribute) + 1);
+ GNUNET_CONTAINER_DLL_insert (handle->request_head,
+ handle->request_tail,
vr);
if (NULL != handle->mq)
GNUNET_MQ_send_copy (handle->mq,
diff --git a/src/credential/credential_misc.c b/src/credential/credential_misc.c
index f1be433e0..7849e81e6 100644
--- a/src/credential/credential_misc.c
+++ b/src/credential/credential_misc.c
@@ -105,6 +105,7 @@ GNUNET_CREDENTIAL_credential_from_string (const char* s)
GNUNET_memcpy (&cred[1],
name,
strlen (name)+1);
+ cred->issuer_attribute_len = strlen ((char*)&cred[1]);
cred->issuer_attribute = (char*)&cred[1];
return cred;
}
diff --git a/src/credential/credential_serialization.c b/src/credential/credential_serialization.c
index 0586e6baa..76bf491c9 100644
--- a/src/credential/credential_serialization.c
+++ b/src/credential/credential_serialization.c
@@ -138,6 +138,121 @@ GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len,
}
return GNUNET_OK;
}
+
+
+/**
+ * Calculate how many bytes we will need to serialize
+ * the credentials
+ *
+ * @param c_count number of credential entries
+ * @param cd a #GNUNET_CREDENTIAL_Credential
+ * @return the required size to serialize
+ */
+size_t
+GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count,
+ const struct GNUNET_CREDENTIAL_Credential *cd)
+{
+ unsigned int i;
+ size_t ret;
+
+ ret = sizeof (struct CredentialEntry) * (c_count);
+
+ for (i=0; i<c_count;i++)
+ {
+ GNUNET_assert ((ret + cd[i].issuer_attribute_len) >= ret);
+ ret += cd[i].issuer_attribute_len;
+ }
+ return ret;
+}
+/**
+ * Serizalize the given credentials
+ *
+ * @param c_count number of credential entries
+ * @param cd a #GNUNET_CREDENTIAL_Credential
+ * @param dest_size size of the destination
+ * @param dest where to store the result
+ * @return the size of the data, -1 on failure
+ */
+ssize_t
+GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count,
+ const struct GNUNET_CREDENTIAL_Credential *cd,
+ size_t dest_size,
+ char *dest)
+{
+ struct CredentialEntry c_rec;
+ unsigned int i;
+ size_t off;
+
+ off = 0;
+ for (i=0;i<c_count;i++)
+ {
+ c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
+ c_rec.issuer_key = cd[i].issuer_key;
+ c_rec.subject_key = cd[i].subject_key;
+ c_rec.signature = cd[i].signature;
+ c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
+ c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
+ c_rec.expiration = htonl ((uint32_t) cd[i].expiration.abs_value_us);
+ if (off + sizeof (c_rec) > dest_size)
+ return -1;
+ GNUNET_memcpy (&dest[off],
+ &c_rec,
+ sizeof (c_rec));
+ off += sizeof (c_rec);
+ if (off + cd[i].issuer_attribute_len > dest_size)
+ return -1;
+ GNUNET_memcpy (&dest[off],
+ cd[i].issuer_attribute,
+ cd[i].issuer_attribute_len);
+ off += cd[i].issuer_attribute_len;
+ }
+
+ return off;
+}
+
+
+
+/**
+ * Deserialize the given destination
+ *
+ * @param len size of the serialized creds
+ * @param src the serialized data
+ * @param c_count the number of credential entries
+ * @param cd where to put the credential data
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+int
+GNUNET_CREDENTIAL_credentials_deserialize (size_t len,
+ const char *src,
+ unsigned int c_count,
+ struct GNUNET_CREDENTIAL_Credential *cd)
+{
+ struct CredentialEntry c_rec;
+ unsigned int i;
+ size_t off;
+
+ off = 0;
+ for (i=0;i<c_count;i++)
+ {
+ if (off + sizeof (c_rec) > len)
+ return GNUNET_SYSERR;
+ GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
+ cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
+ cd[i].issuer_key = c_rec.issuer_key;
+ cd[i].subject_key = c_rec.subject_key;
+ cd[i].signature = c_rec.signature;
+ cd[i].expiration.abs_value_us = ntohl((uint32_t) c_rec.expiration);
+ off += sizeof (c_rec);
+ if (off + cd[i].issuer_attribute_len > len)
+ return GNUNET_SYSERR;
+ cd[i].issuer_attribute = &src[off];
+ off += cd[i].issuer_attribute_len;
+ }
+ return GNUNET_OK;
+}
+
+
+
/**
* Calculate how many bytes we will need to serialize
* the given delegation chain and credential
@@ -158,7 +273,6 @@ GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count,
size_t ret;
ret = sizeof (struct ChainEntry) * (d_count);
- ret += sizeof (struct CredentialEntry) * (c_count);
for (i=0; i<d_count;i++)
{
@@ -167,11 +281,7 @@ GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count,
dd[i].subject_attribute_len) >= ret);
ret += dd[i].issuer_attribute_len + dd[i].subject_attribute_len;
}
- for (i=0; i<c_count;i++)
- {
- GNUNET_assert ((ret + cd[i].issuer_attribute_len) >= ret);
- ret += cd[i].issuer_attribute_len;
- }
+ return ret+GNUNET_CREDENTIAL_credentials_get_size(c_count, cd);
return ret;
}
@@ -195,7 +305,6 @@ GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count,
char *dest)
{
struct ChainEntry rec;
- struct CredentialEntry c_rec;
unsigned int i;
size_t off;
@@ -227,30 +336,10 @@ GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count,
dd[i].subject_attribute_len);
off += dd[i].subject_attribute_len;
}
- for (i=0;i<c_count;i++)
- {
- c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
- c_rec.issuer_key = cd[i].issuer_key;
- c_rec.subject_key = cd[i].subject_key;
- c_rec.signature = cd[i].signature;
- c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
- c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
- c_rec.expiration = htonl ((uint32_t) cd[i].expiration.abs_value_us);
- if (off + sizeof (c_rec) > dest_size)
- return -1;
- GNUNET_memcpy (&dest[off],
- &c_rec,
- sizeof (c_rec));
- off += sizeof (c_rec);
- if (off + cd[i].issuer_attribute_len > dest_size)
- return -1;
- GNUNET_memcpy (&dest[off],
- cd[i].issuer_attribute,
- cd[i].issuer_attribute_len);
- off += cd[i].issuer_attribute_len;
- }
-
- return off;
+ return off+GNUNET_CREDENTIAL_credentials_serialize (c_count,
+ cd,
+ dest_size-off,
+ &dest[off]);
}
@@ -274,7 +363,6 @@ GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len,
struct GNUNET_CREDENTIAL_Credential *cd)
{
struct ChainEntry rec;
- struct CredentialEntry c_rec;
unsigned int i;
size_t off;
@@ -298,26 +386,11 @@ GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len,
dd[i].subject_attribute = &src[off];
off += dd[i].subject_attribute_len;
}
- for (i=0;i<c_count;i++)
- {
- if (off + sizeof (c_rec) > len)
- return GNUNET_SYSERR;
- GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
- cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
- cd[i].issuer_key = c_rec.issuer_key;
- cd[i].subject_key = c_rec.subject_key;
- cd[i].signature = c_rec.signature;
- cd[i].expiration.abs_value_us = ntohl((uint32_t) c_rec.expiration);
- off += sizeof (c_rec);
- if (off + cd[i].issuer_attribute_len > len)
- return GNUNET_SYSERR;
- cd[i].issuer_attribute = &src[off];
- off += cd[i].issuer_attribute_len;
- }
- return GNUNET_OK;
+ return GNUNET_CREDENTIAL_credentials_deserialize (len-off,
+ &src[off],
+ c_count,
+ cd);
}
-
-
int
GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred,
char **data)
diff --git a/src/credential/credential_serialization.h b/src/credential/credential_serialization.h
index eb1327f34..b870d47dc 100644
--- a/src/credential/credential_serialization.h
+++ b/src/credential/credential_serialization.h
@@ -130,6 +130,23 @@ GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len,
struct GNUNET_CREDENTIAL_Delegation *dd,
unsigned int c_count,
struct GNUNET_CREDENTIAL_Credential *cd);
+ size_t
+ GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count,
+ const struct GNUNET_CREDENTIAL_Credential *cd);
+
+ssize_t
+GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count,
+ const struct GNUNET_CREDENTIAL_Credential *cd,
+ size_t dest_size,
+ char *dest);
+
+
+int
+GNUNET_CREDENTIAL_credentials_deserialize (size_t len,
+ const char *src,
+ unsigned int c_count,
+ struct GNUNET_CREDENTIAL_Credential *cd);
+
int
GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred,
diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c
index b31c2f66e..fb7bdb7f8 100644
--- a/src/credential/gnunet-credential.c
+++ b/src/credential/gnunet-credential.c
@@ -55,6 +55,11 @@ static struct GNUNET_TIME_Relative timeout;
static struct GNUNET_CREDENTIAL_Request *verify_request;
/**
+ * Handle to collect request
+ */
+static struct GNUNET_CREDENTIAL_Request *collect_request;
+
+/**
* Task scheduled to handle timeout.
*/
static struct GNUNET_SCHEDULER_Task *tt;
@@ -91,9 +96,9 @@ struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey;
static char *issuer_key;
/**
- * Issuer ego
+ * ego
*/
-static char *issuer_ego_name;
+static char *ego_name;
/**
* Issuer attribute
@@ -110,6 +115,10 @@ static uint32_t verify;
*/
static uint32_t create_cred;
+/**
+ * Collect mode
+ */
+static uint32_t collect;
/**
* Task run on shutdown. Cleans up everything.
@@ -149,6 +158,39 @@ do_timeout (void *cls)
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_collect_result (void *cls,
+ unsigned int d_count,
+ struct GNUNET_CREDENTIAL_Delegation *dc,
+ unsigned int c_count,
+ struct GNUNET_CREDENTIAL_Credential *cred)
+{
+ int i;
+ char* line;
+
+ verify_request = NULL;
+ if (NULL != cred)
+ {
+ for (i=0;i<c_count;i++)
+ {
+ line = GNUNET_CREDENTIAL_credential_to_string (&cred[i]);
+ printf ("%s\n",
+ line);
+ GNUNET_free (line);
+ }
+ }
+
+
+ GNUNET_SCHEDULER_shutdown ();
+}
+
/**
* Function called with the result of a Credential lookup.
@@ -230,15 +272,42 @@ identity_cb (void *cls,
el = NULL;
if (NULL == ego)
{
- if (NULL != issuer_ego_name)
+ if (NULL != ego_name)
{
fprintf (stderr,
_("Ego `%s' not known to identity service\n"),
- issuer_ego_name);
+ ego_name);
}
GNUNET_SCHEDULER_shutdown ();
return;
}
+
+ if (GNUNET_YES == collect)
+ {
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
+ strlen (issuer_key),
+ &issuer_pkey))
+ {
+ fprintf (stderr,
+ _("Issuer public key `%s' is not well-formed\n"),
+ issuer_key);
+ GNUNET_SCHEDULER_shutdown ();
+ }
+ privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
+
+ collect_request = GNUNET_CREDENTIAL_collect(credential,
+ &issuer_pkey,
+ issuer_attr, //TODO argument
+ privkey,
+ &handle_collect_result,
+ NULL);
+ return;
+ }
+
+ //Else issue
+
if (NULL == expiration)
{
fprintf (stderr,
@@ -261,8 +330,8 @@ identity_cb (void *cls,
privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
- GNUNET_free_non_null (issuer_ego_name);
- issuer_ego_name = NULL;
+ GNUNET_free_non_null (ego_name);
+ ego_name = NULL;
crd = GNUNET_CREDENTIAL_credential_issue (privkey,
&subject_pkey,
issuer_attr,
@@ -299,7 +368,46 @@ run (void *cls,
&do_timeout, NULL);
GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
+ if (GNUNET_YES == collect) {
+ if (NULL == issuer_key)
+ {
+ fprintf (stderr,
+ _("Issuer public key not well-formed\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+
+ }
+
+ credential = GNUNET_CREDENTIAL_connect (cfg);
+
+ if (NULL == credential)
+ {
+ fprintf (stderr,
+ _("Failed to connect to CREDENTIAL\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ }
+ if (NULL == issuer_attr)
+ {
+ fprintf (stderr,
+ _("You must provide issuer the attribute\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ }
+
+ if (NULL == ego_name)
+ {
+ fprintf (stderr,
+ _("ego required\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+
+ }
+ el = GNUNET_IDENTITY_ego_lookup (cfg,
+ ego_name,
+ &identity_cb,
+ (void *) cfg);
+ return;
+ }
if (NULL == subject_key)
{
@@ -320,7 +428,6 @@ run (void *cls,
GNUNET_SCHEDULER_shutdown ();
return;
}
-
if (GNUNET_YES == verify) {
if (NULL == issuer_key)
{
@@ -348,7 +455,6 @@ run (void *cls,
_("Failed to connect to CREDENTIAL\n"));
GNUNET_SCHEDULER_shutdown ();
}
-
if (NULL == issuer_attr || NULL == subject_credential)
{
fprintf (stderr,
@@ -356,18 +462,50 @@ run (void *cls,
GNUNET_SCHEDULER_shutdown ();
}
- printf ("Trying to find a chain from a credential under %s of %s to the attribute %s issued by %s\n",
- subject_credential, subject_key, issuer_attr, issuer_key);
+ //Subject credentials are comma separated
+ char *tmp = GNUNET_strdup (subject_credential);
+ char *tok = strtok (tmp, ",");
+ if (NULL == tok)
+ {
+ fprintf (stderr,
+ "Invalid subject credentials\n");
+ GNUNET_free (tmp);
+ GNUNET_SCHEDULER_shutdown ();
+ }
+ int count = 1;
+ int i;
+ while (NULL != (tok = strtok(NULL, ",")))
+ count++;
+ struct GNUNET_CREDENTIAL_Credential credentials[count];
+ struct GNUNET_CREDENTIAL_Credential *cred;
+ GNUNET_free (tmp);
+ tmp = GNUNET_strdup (subject_credential);
+ tok = strtok (tmp, ",");
+ for (i=0;i<count;i++)
+ {
+ cred = GNUNET_CREDENTIAL_credential_from_string (tok);
+ GNUNET_memcpy (&credentials[i],
+ cred,
+ sizeof (struct GNUNET_CREDENTIAL_Credential));
+ credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute);
+ tok = strtok(NULL, ",");
+ GNUNET_free (cred);
+ }
verify_request = GNUNET_CREDENTIAL_verify(credential,
&issuer_pkey,
issuer_attr, //TODO argument
&subject_pkey,
- subject_credential,
+ count,
+ credentials,
&handle_verify_result,
NULL);
+ for (i=0;i<count;i++)
+ {
+ GNUNET_free ((char*)credentials[i].issuer_attribute);
+ }
} else if (GNUNET_YES == create_cred) {
- if (NULL == issuer_ego_name)
+ if (NULL == ego_name)
{
fprintf (stderr,
_("Issuer ego required\n"));
@@ -376,7 +514,7 @@ run (void *cls,
}
el = GNUNET_IDENTITY_ego_lookup (cfg,
- issuer_ego_name,
+ ego_name,
&identity_cb,
(void *) cfg);
return;
@@ -416,14 +554,17 @@ main (int argc, char *const *argv)
gettext_noop ("The public key of the authority to verify the credential against"), 1,
&GNUNET_GETOPT_set_string, &issuer_key},
{'e', "ego", "EGO",
- gettext_noop ("The ego to use to issue"), 1,
- &GNUNET_GETOPT_set_string, &issuer_ego_name},
+ gettext_noop ("The ego to use"), 1,
+ &GNUNET_GETOPT_set_string, &ego_name},
{'a', "attribute", "ATTR",
gettext_noop ("The issuer attribute to verify against or to issue"), 1,
&GNUNET_GETOPT_set_string, &issuer_attr},
{'T', "ttl", "EXP",
gettext_noop ("The time to live for the credential"), 1,
&GNUNET_GETOPT_set_string, &expiration},
+ {'g', "collect", NULL,
+ gettext_noop ("collect credentials"), 0,
+ &GNUNET_GETOPT_set_one, &collect},
GNUNET_GETOPT_OPTION_END
};
int ret;
diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c
index 942b38652..4841370b3 100644
--- a/src/credential/gnunet-service-credential.c
+++ b/src/credential/gnunet-service-credential.c
@@ -31,15 +31,11 @@
#include "gnunet_protocols.h"
#include "gnunet_signatures.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
@@ -311,6 +307,16 @@ struct VerifyRequestHandle
*/
uint64_t pending_lookups;
+ /**
+ * Credential iterator
+ */
+ struct GNUNET_NAMESTORE_ZoneIterator *cred_collection_iter;
+
+ /**
+ * Collect task
+ */
+ struct GNUNET_SCHEDULER_Task *collect_next_task;
+
};
@@ -335,6 +341,11 @@ static struct GNUNET_STATISTICS_Handle *statistics;
static struct GNUNET_GNS_Handle *gns;
+/**
+ * Handle to namestore service
+ */
+static struct GNUNET_NAMESTORE_Handle *namestore;
+
static void
cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry)
{
@@ -444,6 +455,11 @@ shutdown_task (void *cls)
GNUNET_GNS_disconnect (gns);
gns = NULL;
}
+ if (NULL != namestore)
+ {
+ GNUNET_NAMESTORE_disconnect (namestore);
+ namestore = NULL;
+ }
if (NULL != statistics)
{
GNUNET_STATISTICS_destroy (statistics,
@@ -453,42 +469,7 @@ shutdown_task (void *cls)
}
-/**
- * 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;
- const char* attrs;
- msg_size = ntohs (v_msg->header.size);
- if (msg_size < sizeof (struct VerifyMessage))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if ((ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) ||
- (ntohs (v_msg->subject_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- attrs = (const char *) &v_msg[1];
-
- if ( ('\0' != attrs[ntohs(v_msg->header.size) - sizeof (struct VerifyMessage) - 1]) ||
- (strlen (attrs) > GNUNET_CREDENTIAL_MAX_LENGTH * 2) )
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
/**
* Send.
@@ -499,7 +480,7 @@ static void
send_lookup_response (struct VerifyRequestHandle *vrh)
{
struct GNUNET_MQ_Envelope *env;
- struct VerifyResultMessage *rmsg;
+ struct DelegationChainResultMessage *rmsg;
struct DelegationChainEntry *dce;
struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
@@ -792,21 +773,14 @@ backward_resolution (void* cls,
* @param rd the record data
*/
static void
-handle_credential_query (void* cls,
- uint32_t rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
+delegation_chain_resolution_start (void* cls)
{
struct VerifyRequestHandle *vrh = cls;
struct DelegationSetQueueEntry *ds_entry;
- struct GNUNET_CREDENTIAL_Credential *crd;
struct CredentialRecordEntry *cr_entry;
- int cred_record_count;
- int i;
-
vrh->lookup_request = NULL;
- cred_record_count = 0;
- if (0 == rd_count)
+ if (0 == vrh->cred_chain_size)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"No credentials found\n");
@@ -814,31 +788,13 @@ handle_credential_query (void* cls,
return;
}
- for (i=0; i < rd_count; i++)
+ for (cr_entry = vrh->cred_chain_head; cr_entry != NULL; cr_entry = cr_entry->next)
{
- if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
- continue;
- cred_record_count++;
- crd = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data,
- rd[i].data_size);
- if (NULL == crd)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid credential found\n");
- continue;
- }
- cr_entry = GNUNET_new (struct CredentialRecordEntry);
- cr_entry->credential = crd;
- GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head,
- vrh->cred_chain_tail,
- cr_entry);
- vrh->cred_chain_size++;
-
- if (0 != memcmp (&crd->issuer_key,
+ if (0 != memcmp (&cr_entry->credential->issuer_key,
&vrh->issuer_key,
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
continue;
- if (0 != strcmp (crd->issuer_attribute, vrh->issuer_attribute))
+ if (0 != strcmp (cr_entry->credential->issuer_attribute, vrh->issuer_attribute))
continue;
//Found match prematurely
send_lookup_response (vrh);
@@ -878,6 +834,40 @@ handle_credential_query (void* cls,
ds_entry);
}
+/**
+ * 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;
+ const char* attr;
+
+ msg_size = ntohs (v_msg->header.size);
+ if (msg_size < sizeof (struct VerifyMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ attr = (const char *) &v_msg[1];
+
+ if ( strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
/**
* Handle Credential verification requests from client
@@ -890,12 +880,11 @@ static void
handle_verify (void *cls,
const struct VerifyMessage *v_msg)
{
- char attrs[GNUNET_CREDENTIAL_MAX_LENGTH*2 + 1];
+ char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
- char subject_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1 + 4];
struct VerifyRequestHandle *vrh;
struct GNUNET_SERVICE_Client *client = cls;
- char *attrptr = attrs;
+ char *attrptr = attr;
const char *utf_in;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -904,12 +893,8 @@ handle_verify (void *cls,
utf_in = (const char *) &v_msg[1];
GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
- GNUNET_memcpy (issuer_attribute, attrs, ntohs (v_msg->issuer_attribute_len));
+ GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
- GNUNET_memcpy (subject_attribute, attrs+strlen(issuer_attribute), ntohs (v_msg->subject_attribute_len));
- strcpy (subject_attribute+ntohs (v_msg->subject_attribute_len),
- ".gnu");
- subject_attribute[ntohs (v_msg->subject_attribute_len)+4] = '\0';
vrh = GNUNET_new (struct VerifyRequestHandle);
GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
vrh->client = client;
@@ -917,14 +902,169 @@ handle_verify (void *cls,
vrh->issuer_key = v_msg->issuer_key;
vrh->subject_key = v_msg->subject_key;
vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
-
- if (NULL == subject_attribute)
+ if (NULL == issuer_attribute)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No subject attribute provided!\n");
+ "No issuer attribute provided!\n");
+ send_lookup_response (vrh);
+ return;
+ }
+ /**
+ * First, collect credentials
+ * TODO: cleanup!
+ */
+ uint32_t credentials_count = ntohl(v_msg->c_count);
+ int i;
+ uint32_t credential_data_size = ntohs (v_msg->header.size)
+ - sizeof (struct VerifyMessage)
+ - ntohs (v_msg->issuer_attribute_len)
+ - 1;
+ struct GNUNET_CREDENTIAL_Credential credentials[credentials_count];
+ char *credential_data = (char*)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
+ struct CredentialRecordEntry *cr_entry;
+ if (GNUNET_OK != GNUNET_CREDENTIAL_credentials_deserialize (credential_data_size,
+ credential_data,
+ credentials_count,
+ credentials))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Cannot deserialize credentials!\n");
send_lookup_response (vrh);
return;
}
+
+ for (i=0;i<credentials_count;i++) {
+ cr_entry = GNUNET_new (struct CredentialRecordEntry);
+ cr_entry->credential = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) +
+ strlen (credentials[i].issuer_attribute) + 1);
+ GNUNET_memcpy (cr_entry->credential,
+ &credentials[i],
+ sizeof (struct GNUNET_CREDENTIAL_Credential));
+ GNUNET_memcpy (&cr_entry->credential[1],
+ credentials[i].issuer_attribute,
+ strlen (credentials[i].issuer_attribute));
+ cr_entry->credential->issuer_attribute = (char*)&cr_entry->credential[1];
+ GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head,
+ vrh->cred_chain_tail,
+ cr_entry);
+ vrh->cred_chain_size++;
+ }
+
+ delegation_chain_resolution_start (vrh);
+
+}
+
+/**
+ * We encountered an error while collecting
+ */
+static void
+handle_cred_collection_error_cb (void *cls)
+{
+ struct VerifyRequestHandle *vrh = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Got disconnected from namestore database.\n");
+ vrh->cred_collection_iter = NULL;
+ send_lookup_response (vrh);
+}
+
+static void
+collect_next (void *cls)
+{
+ struct VerifyRequestHandle *vrh = cls;
+ vrh->collect_next_task = NULL;
+ GNUNET_assert (NULL != vrh->cred_collection_iter);
+ GNUNET_NAMESTORE_zone_iterator_next (vrh->cred_collection_iter);
+}
+
+/**
+ * Store credential
+ */
+static void
+handle_cred_collection_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct VerifyRequestHandle *vrh = cls;
+ struct GNUNET_CREDENTIAL_Credential *crd;
+ struct CredentialRecordEntry *cr_entry;
+ int cred_record_count;
+ int i;
+
+ cred_record_count = 0;
+ for (i=0; i < rd_count; i++)
+ {
+ if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
+ continue;
+ cred_record_count++;
+ crd = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data,
+ rd[i].data_size);
+ if (NULL == crd)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Invalid credential found\n");
+ continue;
+ }
+ cr_entry = GNUNET_new (struct CredentialRecordEntry);
+ cr_entry->credential = crd;
+ GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head,
+ vrh->cred_chain_tail,
+ cr_entry);
+ vrh->cred_chain_size++;
+ }
+ vrh->collect_next_task = GNUNET_SCHEDULER_add_now (&collect_next,
+ vrh);
+}
+
+/**
+ * We encountered an error while collecting
+ */
+static void
+handle_cred_collection_finished_cb (void *cls)
+{
+ struct VerifyRequestHandle *vrh = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Done collecting credentials.\n");
+ vrh->cred_collection_iter = NULL;
+ delegation_chain_resolution_start (vrh);
+}
+
+/**
+ * Handle Credential collection requests from client
+ *
+ * @param cls the closure
+ * @param client the client
+ * @param message the message
+ */
+static void
+handle_collect (void *cls,
+ const struct CollectMessage *c_msg)
+{
+ char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
+ char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
+ struct VerifyRequestHandle *vrh;
+ struct GNUNET_SERVICE_Client *client = cls;
+ char *attrptr = attr;
+ const char *utf_in;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received COLLECT message\n");
+
+ utf_in = (const char *) &c_msg[1];
+ GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
+
+ GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
+ issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0';
+ vrh = GNUNET_new (struct VerifyRequestHandle);
+ GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
+ vrh->client = client;
+ vrh->request_id = c_msg->id;
+ vrh->issuer_key = c_msg->issuer_key;
+ GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key,
+ &vrh->subject_key);
+ vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
+
if (NULL == issuer_attribute)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -933,23 +1073,58 @@ handle_verify (void *cls,
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Looking up %s\n",
- subject_attribute);
+ "Getting credentials for subject\n");
/**
* First, get attribute from subject
*/
- vrh->lookup_request = GNUNET_GNS_lookup (gns,
- subject_attribute,
- &v_msg->subject_key, //subject_pkey,
- GNUNET_GNSRECORD_TYPE_CREDENTIAL,
- GNUNET_GNS_LO_DEFAULT,
- NULL, //shorten_key, always NULL
- &handle_credential_query,
- vrh);
+ vrh->cred_collection_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore,
+ &c_msg->subject_key,
+ &handle_cred_collection_error_cb,
+ vrh,
+ &handle_cred_collection_cb,
+ vrh,
+ &handle_cred_collection_finished_cb,
+ vrh);
}
/**
+ * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT message
+ *
+ * @param cls client sending the message
+ * @param v_msg message of type `struct CollectMessage`
+ * @return #GNUNET_OK if @a v_msg is well-formed
+ */
+static int
+check_collect (void *cls,
+ const struct CollectMessage *c_msg)
+{
+ size_t msg_size;
+ const char* attr;
+
+ msg_size = ntohs (c_msg->header.size);
+ if (msg_size < sizeof (struct CollectMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ attr = (const char *) &c_msg[1];
+
+ if ( ('\0' != attr[ntohs(c_msg->header.size) - sizeof (struct CollectMessage) - 1]) ||
+ (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) )
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+/**
* One of our clients disconnected, clean up after it.
*
* @param cls NULL
@@ -1003,6 +1178,12 @@ run (void *cls,
fprintf (stderr,
_("Failed to connect to GNS\n"));
}
+ namestore = GNUNET_NAMESTORE_connect (c);
+ if (NULL == namestore)
+ {
+ fprintf (stderr,
+ _("Failed to connect to namestore\n"));
+ }
statistics = GNUNET_STATISTICS_create ("credential", c);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
@@ -1023,6 +1204,10 @@ GNUNET_SERVICE_MAIN
GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY,
struct VerifyMessage,
NULL),
+ GNUNET_MQ_hd_var_size (collect,
+ GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT,
+ struct CollectMessage,
+ NULL),
GNUNET_MQ_handler_end());
/* end of gnunet-service-credential.c */
diff --git a/src/credential/plugin_rest_credential.c b/src/credential/plugin_rest_credential.c
index 651de0075..f13e26cd4 100644
--- a/src/credential/plugin_rest_credential.c
+++ b/src/credential/plugin_rest_credential.c
@@ -492,7 +492,8 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
&handle->issuer_key,
handle->issuer_attr,
&handle->subject_key,
- handle->subject_attr,
+ 0,
+ NULL,//TODOhandle->subject_attr,
&handle_verify_response,
handle);
diff --git a/src/credential/test_credential_collect.sh b/src/credential/test_credential_collect.sh
new file mode 100755
index 000000000..6c713063f
--- /dev/null
+++ b/src/credential/test_credential_collect.sh
@@ -0,0 +1,47 @@
+#!/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`
+
+# (1) PKEY1.user -> PKEY2.resu.user
+# (2) PKEY2.resu -> PKEY3
+# (3) PKEY3.user -> PKEY4
+
+
+which timeout &> /dev/null && DO_TIMEOUT="timeout 30"
+
+TEST_ATTR="test"
+TEST_ATTR2="test2"
+gnunet-arm -s -c test_credential_lookup.conf
+gnunet-identity -C testissuer -c test_credential_lookup.conf
+gnunet-identity -C testsubject -c test_credential_lookup.conf
+SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}')
+ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}')
+#TODO1 Get credential and store it with subject (3)
+CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf`
+$DO_TIMEOUT gnunet-namestore -a -z testsubject -n c1 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
+CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR2 --ttl=5m -c test_credential_lookup.conf`
+$DO_TIMEOUT gnunet-namestore -a -z testsubject -n c2 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
+CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$ISSUER_KEY --attribute=$TEST_ATTR --ego=testsubject -c test_credential_lookup.conf | paste -d, -s`
+echo $CREDS
+RES=$?
+gnunet-arm -e -c test_credential_lookup.conf
+
+if test $? != 0
+then
+ echo "Error collecting..."
+ exit 1
+fi
+
diff --git a/src/credential/test_credential_lookup.conf b/src/credential/test_credential_lookup.conf
index 7aa193abd..93b4864d9 100644
--- a/src/credential/test_credential_lookup.conf
+++ b/src/credential/test_credential_lookup.conf
@@ -11,7 +11,7 @@ PLUGINS =
[credential]
AUTOSTART = YES
-#PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/credlog
+PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/credlog
[rest]
#PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/restlog
diff --git a/src/credential/test_credential_verify.sh b/src/credential/test_credential_verify.sh
index 6d69e337b..d042bcfe6 100755
--- a/src/credential/test_credential_verify.sh
+++ b/src/credential/test_credential_verify.sh
@@ -57,8 +57,11 @@ CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --
# Alice stores the credential under "mygnunetcreds"
gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf
+CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$SERVICE_KEY --attribute=$USER_ATTR --ego=alice -c test_credential_lookup.conf | paste -d, -s`
+
+echo gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential=\'$CREDS\' -c test_credential_lookup.conf
#TODO2 Add -z swich like in gnunet-gns
-RES_CRED=`gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf`
+gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential="$CREDS" -c test_credential_lookup.conf
#TODO cleanup properly