-mem fixes, revocation finish
authorSchanzenbach, Martin <mschanzenbach@posteo.de>
Sat, 7 Oct 2017 11:01:52 +0000 (13:01 +0200)
committerSchanzenbach, Martin <mschanzenbach@posteo.de>
Sat, 7 Oct 2017 11:01:52 +0000 (13:01 +0200)
src/identity-provider/gnunet-idp.c
src/identity-provider/gnunet-service-identity-provider.c
src/identity-provider/identity_provider_api.c
src/identity-provider/plugin_identity_provider_sqlite.c
src/identity-provider/test_idp_revoke.sh [new file with mode: 0755]
src/util/crypto_abe.c

index d6544eb3b414fa4f42d69fc32224abef4e508394..6940220d7251b7525dbca0ef1c85336302f8489b 100644 (file)
@@ -61,6 +61,11 @@ static char* issue_attrs;
  */
 static char* consume_ticket;
 
+/**
+ * Ticket to revoke
+ */
+static char* revoke_ticket;
+
 /**
  * Ego name
  */
@@ -181,18 +186,32 @@ iter_error (void *cls)
   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
 }
 
+static void
+process_rvk (void *cls, int success, const char* msg)
+{
+  if (GNUNET_OK != success)
+    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+                "Revocation failed.\n");
+  else
+    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+                "Revocation successful.\n");
+  GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
+}
+
 static void
 iter_finished (void *cls)
 {
   struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
 
   attr_iterator = NULL;
-  if (list) {
+  if (list)
+  {
     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
     return;
   }
 
-  if (issue_attrs) {
+  if (issue_attrs)
+  {
     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_issue (idp_handle,
                                                     pkey,
                                                     &rp_key,
@@ -201,7 +220,8 @@ iter_finished (void *cls)
                                                     NULL);
     return;
   }
-  if (consume_ticket) {
+  if (consume_ticket)
+  {
     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume (idp_handle,
                                                       pkey,
                                                       &ticket,
@@ -209,6 +229,15 @@ iter_finished (void *cls)
                                                       NULL);
     return;
   }
+  if (revoke_ticket)
+  {
+    idp_op = GNUNET_IDENTITY_PROVIDER_ticket_revoke (idp_handle,
+                                                     pkey,
+                                                     &ticket,
+                                                     &process_rvk,
+                                                     NULL);
+    return;
+  }
   attr = GNUNET_IDENTITY_PROVIDER_attribute_new (attr_name,
                                                  GNUNET_IDENTITY_PROVIDER_AT_STRING,
                                                  attr_value,
@@ -279,6 +308,12 @@ ego_cb (void *cls,
                                    strlen (consume_ticket),
                                    &ticket,
                                    sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
+  if (NULL != revoke_ticket)
+    GNUNET_STRINGS_string_to_data (revoke_ticket,
+                                   strlen (revoke_ticket),
+                                   &ticket,
+                                   sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
+
 
   attr_list = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
 
@@ -358,6 +393,11 @@ main(int argc, char *const argv[])
                                  NULL,
                                  gettext_noop ("Consume a ticket"),
                                  &consume_ticket),
+    GNUNET_GETOPT_option_string ('R',
+                                 "revoke",
+                                 NULL,
+                                 gettext_noop ("Revoke a ticket"),
+                                 &revoke_ticket),
     GNUNET_GETOPT_OPTION_END
   };
   return GNUNET_PROGRAM_run (argc, argv, "ct",
index f9d3f3f92ee8e9c310d6f06702abf5b6cad813be..2f477370e7ee25c32866a2b5ab86efb7273514ed 100644 (file)
@@ -473,10 +473,15 @@ struct TicketRevocationHandle
   struct IdpClient *client;
 
   /**
-   * Attributes to issue
+   * Attributes to reissue
    */
   struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
 
+  /**
+   * Attributes to revoke
+   */
+  struct GNUNET_IDENTITY_PROVIDER_AttributeList *rvk_attrs;
+
   /**
    * Issuer Key
    */
@@ -679,6 +684,7 @@ bootstrap_store_task (void *cls)
                                                rd,
                                                &bootstrap_store_cont,
                                                abh);
+  GNUNET_free ((void*)rd[0].data);
 }
 
 /**
@@ -917,6 +923,7 @@ serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
                  enc_keyinfo,
                  enc_size);
   GNUNET_free (enc_keyinfo);
+  GNUNET_free (buf);
   return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
 }
 
@@ -978,6 +985,8 @@ issue_ticket_after_abe_bootstrap (void *cls,
   GNUNET_free (label);
   GNUNET_free (attrs);
   GNUNET_free (code_record_data);
+  GNUNET_CRYPTO_cpabe_delete_master_key (abe_key);
+  GNUNET_CRYPTO_cpabe_delete_key (rp_key);
 }
 
 
@@ -1049,8 +1058,10 @@ cleanup_revoke_ticket_handle (struct TicketRevocationHandle *handle)
 {
   if (NULL != handle->attrs)
     attribute_list_destroy (handle->attrs);
+  if (NULL != handle->rvk_attrs)
+    attribute_list_destroy (handle->rvk_attrs);
   if (NULL != handle->abe_key)
-    GNUNET_free (handle->abe_key);
+    GNUNET_CRYPTO_cpabe_delete_master_key (handle->abe_key);
   if (NULL != handle->ns_qe)
     GNUNET_NAMESTORE_cancel (handle->ns_qe);
   if (NULL != handle->ns_it)
@@ -1078,7 +1089,6 @@ send_revocation_finished (struct TicketRevocationHandle *rh,
   GNUNET_CONTAINER_DLL_remove (rh->client->revocation_list_head,
                                rh->client->revocation_list_tail,
                                rh);
-  cleanup_revoke_ticket_handle (rh);
 }
 
 
@@ -1101,6 +1111,7 @@ reissue_ticket_cont (void *cls,
                      const char *emsg)
 {
   struct TicketRevocationHandle *rh = cls;
+  int ret;
 
   rh->ns_qe = NULL;
   if (GNUNET_SYSERR == success)
@@ -1111,14 +1122,20 @@ reissue_ticket_cont (void *cls,
     cleanup_revoke_ticket_handle (rh);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continue DB iteration\n");
   rh->offset++;
-  GNUNET_assert (GNUNET_SYSERR !=
+  GNUNET_assert (GNUNET_SYSERR != (ret =
                  TKT_database->iterate_tickets (TKT_database->cls,
                                                 &rh->ticket.identity,
                                                 GNUNET_NO,
                                                 rh->offset,
                                                 &ticket_reissue_proc,
-                                                rh));
+                                                rh)));
+  if (GNUNET_NO == ret)
+  {
+    send_revocation_finished (rh, GNUNET_OK);
+    cleanup_revoke_ticket_handle (rh);
+  }
 }
 
 
@@ -1136,7 +1153,6 @@ ticket_reissue_proc (void *cls,
                      const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
 {
   struct TicketRevocationHandle *rh = cls;
-  const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs_to_reissue;
   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
   struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
   struct GNUNET_GNSRECORD_Data code_record[1];
@@ -1159,19 +1175,16 @@ ticket_reissue_proc (void *cls,
   }
   //Create new ABE key for RP
   attrs_len = 0;
-  attrs_to_reissue = attrs;
 
   /* If this is the RP we want to revoke attributes of, the do so */
-  if (0 == memcmp (&ticket->audience,
-                   &rh->ticket.audience,
-                   sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
-    attrs_to_reissue = rh->attrs;
 
-  for (le = attrs_to_reissue->list_head; NULL != le; le = le->next)
+  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_to_reissue->list_head; NULL != le; le = le->next) {
+  for (le = attrs->list_head; NULL != le; le = le->next) {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Recreating key with %s\n", (char*) le->attribute->name);
     attr_arr[i] = (char*) le->attribute->name;
     i++;
   }
@@ -1181,7 +1194,7 @@ ticket_reissue_proc (void *cls,
 
   //TODO review this wireformat
   code_record_len = serialize_abe_keyinfo2 (&rh->ticket,
-                                            rh->attrs,
+                                            attrs,
                                             rp_key,
                                             &ecdhe_privkey,
                                             &code_record_data);
@@ -1205,18 +1218,40 @@ ticket_reissue_proc (void *cls,
   GNUNET_free (label);
   GNUNET_free (attr_arr);
   GNUNET_free (code_record_data);
-
+  GNUNET_CRYPTO_cpabe_delete_key (rp_key);
 }
 
 
-
-
 /* Prototype for below function */
 static void
 attr_reenc_cont (void *cls,
                  int32_t success,
                  const char *emsg);
 
+static void
+revocation_reissue_tickets (struct TicketRevocationHandle *rh)
+{
+  int ret;
+  /* Done, issue new keys */
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "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);
+  }
+  if (GNUNET_NO == ret)
+  {
+    send_revocation_finished (rh, GNUNET_OK);
+    cleanup_revoke_ticket_handle (rh);
+  }
+
+}
+
 /**
  * Revoke next attribte by reencryption with
  * new ABE master
@@ -1226,8 +1261,15 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
 {
   struct GNUNET_GNSRECORD_Data rd[1];
   char* buf;
+  char* enc_buf;
   size_t buf_size;
 
+  if (NULL == rh->attrs->list_head)
+  {
+    revocation_reissue_tickets (rh);
+    return;
+  }
+
   buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute);
   buf = GNUNET_malloc (buf_size);
 
@@ -1241,8 +1283,9 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
                                                  buf_size,
                                                  rh->attrs->list_head->attribute->name, //Policy
                                                  rh->abe_key,
-                                                 (void**)&rd[0].data);
+                                                 (void**)&enc_buf);
   GNUNET_free (buf);
+  rd[0].data = enc_buf;
   rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
   rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
   rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
@@ -1253,7 +1296,7 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
                                               rd,
                                               &attr_reenc_cont,
                                               rh);
-  GNUNET_free ((void*)rd[0].data);
+  GNUNET_free (enc_buf);
 
 }
 
@@ -1268,7 +1311,6 @@ attr_reenc_cont (void *cls,
 {
   struct TicketRevocationHandle *rh = cls;
   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
-  int ret;
 
   if (GNUNET_SYSERR == success)
   {
@@ -1278,30 +1320,19 @@ attr_reenc_cont (void *cls,
     GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
     return;
   }
+  if (NULL == rh->attrs->list_head)
+  {
+    revocation_reissue_tickets (rh);
+    return;
+  }
   le = rh->attrs->list_head;
   GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
                                rh->attrs->list_tail,
-                               rh->attrs->list_head);
+                               le);
   GNUNET_free (le->attribute);
   GNUNET_free (le);
 
-  if (NULL == rh->attrs->list_head)
-  {
-    /* Done, issue new keys */
-    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,
               "Re-encrypting next attribute\n");
   reenc_next_attribute (rh);
@@ -1327,7 +1358,7 @@ reenc_after_abe_bootstrap (void *cls,
     cleanup_revoke_ticket_handle (rh);
     return;
   } else {
-    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Revocation Phase III: Re-encrypting attributes\n");
     reenc_next_attribute (rh);
   }
@@ -1357,7 +1388,7 @@ revoke_collect_iter_finished (void *cls)
 {
   struct TicketRevocationHandle *rh = cls;
   rh->ns_it = NULL;
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Revocation Phase II: Invalidating old ABE Master\n");
   /* Bootstrap new abe key */
   bootstrap_abe (&rh->identity, &reenc_after_abe_bootstrap, rh, GNUNET_YES);
@@ -1404,6 +1435,7 @@ revoke_collect_iter_cb (void *cls,
               "Attribute to reencrypt: %s\n", label);
   le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
   le->attribute = attribute_deserialize (attr_ser, attr_len);
+  GNUNET_free (attr_ser);
   GNUNET_CONTAINER_DLL_insert_tail (rh->attrs->list_head,
                                     rh->attrs->list_tail,
                                     le);
@@ -1419,9 +1451,9 @@ collect_after_abe_bootstrap (void *cls,
 {
   struct TicketRevocationHandle *rh = cls;
 
-  rh->abe_key = cls;
+  rh->abe_key = abe_key;
   GNUNET_assert (NULL != abe_key);
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Revocation Phase I: Collecting attributes\n");
   /* Reencrypt all attributes with new key */
   rh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
@@ -1480,7 +1512,8 @@ handle_revoke_ticket_message (void *cls,
   attrs_len = ntohs (rm->attrs_len);
   ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
   if (0 < attrs_len)
-    rh->attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len);
+    rh->rvk_attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len);
+  rh->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
   rh->ticket = *ticket;
   rh->r_id = ntohl (rm->id);
   rh->client = idp;
@@ -1502,7 +1535,7 @@ cleanup_as_handle (struct AttributeStoreHandle *handle)
   if (NULL != handle->attribute)
     GNUNET_free (handle->attribute);
   if (NULL != handle->abe_key)
-    GNUNET_free (handle->abe_key);
+    GNUNET_CRYPTO_cpabe_delete_master_key (handle->abe_key);
   GNUNET_free (handle);
 }
 
@@ -1625,7 +1658,7 @@ static void
 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
 {
   if (NULL != handle->key)
-    GNUNET_free (handle->key);
+    GNUNET_CRYPTO_cpabe_delete_key (handle->key);
   GNUNET_free (handle);
 }
 
index fb9926a2cb3cef621fdcf3d2455d0780a805ed69..1dec43b16bb5f240e665b83f82b647642c71c3fb 100644 (file)
@@ -1363,10 +1363,14 @@ GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *
   GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
                                     h->op_tail,
                                     op);
-  env = GNUNET_MQ_msg (msg,
-                       GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET);
+  env = GNUNET_MQ_msg_extra (msg,
+                             sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
+                             GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET);
   msg->id = htonl (rid);
   msg->identity = *identity;
+  memcpy (&msg[1],
+          ticket,
+          sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
   if (NULL == h->mq)
     op->env = env;
   else
index ac4e3c68685f1120198d0fd92847e908e8bfe8cf..c55366214a32dd89a262b8c666df88b2d25e6a65 100644 (file)
@@ -547,6 +547,7 @@ get_ticket_and_call_iterator (struct Plugin *plugin,
         iter (iter_cls,
               &ticket,
               attrs);
+      attribute_list_destroy (attrs);
       ret = GNUNET_YES;
     }
     GNUNET_SQ_cleanup_result (rs);
diff --git a/src/identity-provider/test_idp_revoke.sh b/src/identity-provider/test_idp_revoke.sh
new file mode 100755 (executable)
index 0000000..57872c5
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+trap "gnunet-arm -e -c test_idp.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_idp.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"
+gnunet-arm -s -c test_idp.conf
+gnunet-identity -C testego -c test_idp.conf
+gnunet-identity -C rpego -c test_idp.conf
+SUBJECT_KEY=$(gnunet-identity -d -c test_idp.conf | grep rpego | awk '{print $3}')
+TEST_KEY=$(gnunet-identity -d -c test_idp.conf | grep testego | awk '{print $3}')
+gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf
+gnunet-idp -e testego -a name -V John -c test_idp.conf
+#gnunet-idp -e testego -D -c test_idp.conf
+TICKET=$(gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf | awk '{print $1}')
+#echo "Consuming $TICKET"
+gnunet-idp -e testego -R $TICKET -c test_idp.conf
+gnunet-arm -e -c test_idp.conf
index 899965159932c3532d346c76faa8f34d3e5ec8cd..f52cd521316429c66727fc7fa3863cca3626086a 100644 (file)
@@ -108,7 +108,7 @@ aes_128_cbc_encrypt( char* pt,
   GNUNET_assert (0 == gcry_cipher_encrypt (handle, *ct, buf_size, buf, buf_size));
   gcry_cipher_close (handle);
   //AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT);
-
+  GNUNET_free (buf);
   return buf_size;
 }
 
@@ -300,6 +300,7 @@ GNUNET_CRYPTO_cpabe_decrypt (const void *block,
   }
   gabe_cph_free(cph);
   plt_len = aes_128_cbc_decrypt(aes_buf, aes_buf_size, m, (char**)result);
+  GNUNET_free (aes_buf);
   //freeing is buggy in gabe
   //gabe_prv_free (prv);
   //gabe_pub_free (pub);