*/
struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
+ /**
+ * Offset
+ */
+ uint32_t offset;
/**
* request id
static void
send_ticket_result (struct IdpClient *client,
uint32_t r_id,
- const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
{
struct TicketResultMessage *irm;
struct GNUNET_MQ_Envelope *env;
/* store ticket in DB */
if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
- ticket))
+ ticket,
+ attrs))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unable to store ticket after issue\n");
}
send_ticket_result (handle->client,
handle->r_id,
- &handle->ticket);
+ &handle->ticket,
+ handle->attrs);
cleanup_ticket_issue_handle (handle);
}
int
-serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle,
+serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
const struct GNUNET_CRYPTO_AbeKey *rp_key,
struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
char **result)
size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
(void**)&serialized_key);
attrs_str_len = 0;
- for (le = handle->attrs->list_head; NULL != le; le = le->next) {
+ for (le = attrs->list_head; NULL != le; le = le->next) {
attrs_str_len += strlen (le->attribute->name) + 1;
}
buf = GNUNET_malloc (attrs_str_len + size);
write_ptr = buf;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Writing attributes\n");
- for (le = handle->attrs->list_head; NULL != le; le = le->next) {
+ for (le = attrs->list_head; NULL != le; le = le->next) {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s\n", le->attribute->name);
enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
// Derived key K = H(eB)
GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
- &handle->ticket.audience,
+ &ticket->audience,
&new_key_hash));
create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
attrs);
//TODO review this wireformat
- code_record_len = serialize_abe_keyinfo2 (ih,
+ code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
+ ih->attrs,
rp_key,
&ecdhe_privkey,
&code_record_data);
}
+/**
+ * Process ticket from database
+ *
+ * @param cls struct TicketIterationProcResult
+ * @param ticket the ticket
+ * @param attrs the attributes
+ */
+static void
+ticket_reissue_proc (void *cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs);
+
+
+static void
+reissue_ticket_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct TicketRevocationHandle *rh = cls;
+
+ rh->ns_qe = NULL;
+ if (GNUNET_SYSERR == success)
+ {
+ //TODO cleanup_ticket_revocation_handle (handle);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
+ "Unknown Error\n");
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+ }
+ rh->offset++;
+ GNUNET_assert (GNUNET_SYSERR !=
+ TKT_database->iterate_tickets (TKT_database->cls,
+ &rh->ticket.identity,
+ GNUNET_NO,
+ rh->offset,
+ &ticket_reissue_proc,
+ rh));
+}
+
+
+
+/**
+ * Process ticket from database
+ *
+ * @param cls struct TicketIterationProcResult
+ * @param ticket the ticket
+ * @param attrs the attributes
+ */
+static void
+ticket_reissue_proc (void *cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
+{
+ struct TicketRevocationHandle *rh = cls;
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
+ struct GNUNET_GNSRECORD_Data code_record[1];
+ struct GNUNET_CRYPTO_AbeKey *rp_key;
+ char *code_record_data;
+ char **attr_arr;
+ char *label;
+ int attrs_len;
+ int i;
+ size_t code_record_len;
+
+
+ if (NULL == ticket)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Iteration done\n");
+ /* Send reply ? */
+ GNUNET_break (0);
+ return;
+ }
+ //Create new ABE key for RP
+ attrs_len = 0;
+ for (le = attrs->list_head; NULL != le; le = le->next)
+ attrs_len++;
+ attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
+ i = 0;
+ for (le = attrs->list_head; NULL != le; le = le->next) {
+ attr_arr[i] = (char*) le->attribute->name;
+ i++;
+ }
+ attr_arr[i] = NULL;
+ rp_key = GNUNET_CRYPTO_cpabe_create_key (rh->abe_key,
+ attr_arr);
+
+ //TODO review this wireformat
+ code_record_len = serialize_abe_keyinfo2 (&rh->ticket,
+ rh->attrs,
+ rp_key,
+ &ecdhe_privkey,
+ &code_record_data);
+ code_record[0].data = code_record_data;
+ code_record[0].data_size = code_record_len;
+ code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
+ code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
+ code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+
+ label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
+ sizeof (uint64_t));
+ //Publish record
+ rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
+ &rh->identity,
+ label,
+ 1,
+ code_record,
+ &reissue_ticket_cont,
+ rh);
+ GNUNET_free (ecdhe_privkey);
+ GNUNET_free (label);
+ GNUNET_free (attr_arr);
+ GNUNET_free (code_record_data);
+
+}
+
+
static void
attr_reenc_cont (void *cls,
int32_t success,
struct GNUNET_GNSRECORD_Data rd[1];
size_t buf_size;
char *buf;
+ int ret;
if (GNUNET_SYSERR == success)
{
if (NULL == rh->attrs->list_head)
{
/* Done, issue new keys */
- GNUNET_break (0); //TODO
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Revocation Phase IV: Reissuing Tickets\n");
+ if (GNUNET_SYSERR ==
+ (ret = TKT_database->iterate_tickets (TKT_database->cls,
+ &rh->ticket.identity,
+ GNUNET_NO,
+ rh->offset,
+ &ticket_reissue_proc,
+ rh)))
+ {
+ GNUNET_break (0);
+ }
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
if (NULL == rh->attrs->list_head)
{
/* No attributes to reencrypt, this is odd... */
+ GNUNET_break (0);
} else {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Re-encrypting attribute\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Revocation Phase III: Re-encrypting attributes\n");
buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute);
buf = GNUNET_malloc (buf_size);
revoke_collect_iter_finished (void *cls)
{
struct TicketRevocationHandle *rh = cls;
-
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Revocation Phase II: Invalidating old ABE Master\n");
/* Bootstrap new abe key */
bootstrap_abe (&rh->identity, &reenc_after_abe_bootstrap, rh, GNUNET_YES);
}
rh->abe_key = cls;
GNUNET_assert (NULL != abe_key);
-
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Revocation Phase I: Collecting attributes\n");
/* Reencrypt all attributes with new key */
rh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
&rh->identity,
/* Store ticket in DB */
if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
- &handle->ticket))
+ &handle->ticket,
+ handle->attrs))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unable to store ticket after consume\n");
*/
static void
ticket_iterate_proc (void *cls,
- const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
{
struct TicketIterationProcResult *proc = cls;
proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
send_ticket_result (proc->ti->client,
proc->ti->r_id,
- ticket);
+ ticket,
+ attrs);
}
#include "platform.h"
#include "gnunet_identity_provider_service.h"
#include "gnunet_identity_provider_plugin.h"
+#include "identity_attribute.h"
#include "gnunet_sq_lib.h"
#include <sqlite3.h>
"CREATE TABLE identity001tickets ("
" identity BLOB NOT NULL DEFAULT '',"
" audience BLOB NOT NULL DEFAULT '',"
- " rnd INT8 NOT NULL DEFAULT ''"
+ " rnd INT8 NOT NULL DEFAULT '',"
+ " attributes BLOB NOT NULL DEFAULT ''"
")",
NULL, NULL, NULL) != SQLITE_OK))
{
if ( (SQLITE_OK !=
sq_prepare (plugin->dbh,
- "INSERT INTO identity001tickets (identity, audience, rnd)"
- " VALUES (?, ?, ?)",
+ "INSERT INTO identity001tickets (identity, audience, rnd, attributes)"
+ " VALUES (?, ?, ?, ?)",
&plugin->store_ticket)) ||
(SQLITE_OK !=
sq_prepare (plugin->dbh,
&plugin->delete_ticket)) ||
(SQLITE_OK !=
sq_prepare (plugin->dbh,
- "SELECT identity,audience,rnd"
+ "SELECT identity,audience,rnd,attributes"
" FROM identity001tickets WHERE identity=?"
" ORDER BY rnd LIMIT 1 OFFSET ?",
&plugin->iterate_tickets)) ||
(SQLITE_OK !=
sq_prepare (plugin->dbh,
- "SELECT identity,audience,rnd"
+ "SELECT identity,audience,rnd,attributes"
" FROM identity001tickets WHERE audience=?"
" ORDER BY rnd LIMIT 1 OFFSET ?",
&plugin->iterate_tickets_by_audience)) )
*/
static int
identity_provider_sqlite_store_ticket (void *cls,
- const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
{
struct Plugin *plugin = cls;
+ size_t attrs_len;
+ char *attrs_ser;
int n;
{
n = sqlite3_step (plugin->delete_ticket);
GNUNET_SQ_reset (plugin->dbh,
plugin->delete_ticket);
-
+
+ attrs_len = attribute_list_serialize_get_size (attrs);
+ attrs_ser = GNUNET_malloc (attrs_len);
+ attribute_list_serialize (attrs,
+ attrs_ser);
struct GNUNET_SQ_QueryParam sparams[] = {
GNUNET_SQ_query_param_auto_from_type (&ticket->identity),
GNUNET_SQ_query_param_auto_from_type (&ticket->audience),
GNUNET_SQ_query_param_uint64 (&ticket->rnd),
+ GNUNET_SQ_query_param_fixed_size (attrs_ser, attrs_len),
GNUNET_SQ_query_param_end
};
n = sqlite3_step (plugin->store_ticket);
GNUNET_SQ_reset (plugin->dbh,
plugin->store_ticket);
+ GNUNET_free (attrs_ser);
}
switch (n)
{
void *iter_cls)
{
struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
+ struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
int ret;
int sret;
+ size_t attrs_len;
+ char *attrs_ser;
ret = GNUNET_NO;
if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
GNUNET_SQ_result_spec_auto_from_type (&ticket.identity),
GNUNET_SQ_result_spec_auto_from_type (&ticket.audience),
GNUNET_SQ_result_spec_uint64 (&ticket.rnd),
+ GNUNET_SQ_result_spec_variable_size ((void**)&attrs_ser,
+ &attrs_len),
GNUNET_SQ_result_spec_end
};
}
else
{
- if (NULL != iter)
- iter (iter_cls,
- &ticket);
- ret = GNUNET_YES;
+ attrs = attribute_list_deserialize (attrs_ser,
+ attrs_len);
+ if (NULL != iter)
+ iter (iter_cls,
+ &ticket,
+ attrs);
+ ret = GNUNET_YES;
}
GNUNET_SQ_cleanup_result (rs);
}