add attribute expiration
authorSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>
Tue, 10 Apr 2018 09:26:46 +0000 (11:26 +0200)
committerSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>
Tue, 10 Apr 2018 09:26:46 +0000 (11:26 +0200)
src/identity-attribute/identity_attribute.h
src/identity-provider/gnunet-idp.c
src/identity-provider/gnunet-service-identity-provider.c
src/identity-provider/identity_provider.h
src/identity-provider/identity_provider_api.c
src/identity-provider/plugin_rest_identity_provider.c
src/include/gnunet_identity_provider_service.h

index 8dfc1752119f4d98790e10fa07a376280d23fb7d..da0cef1ca361f4ea550b326fdabdbf45853ca863 100644 (file)
@@ -39,7 +39,7 @@ struct Attribute
    * Attribute version
    */
   uint32_t attribute_version;
-  
+
   /**
    * Name length
    */
index 995dd577529791cc497a13a75f068dab4cdb2cd6..95e9f398df917e68f88cf1516ddf87295e1d64cc 100644 (file)
@@ -126,6 +126,11 @@ static struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
  */
 static struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attr_list;
 
+/**
+ * Attribute expiration interval
+ */
+static struct GNUNET_TIME_Relative exp_interval;
+
 static void
 do_cleanup(void *cls)
 {
@@ -272,6 +277,7 @@ iter_finished (void *cls)
   idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle,
                                                      pkey,
                                                      claim,
+                                                     &exp_interval,
                                                      &store_attr_cont,
                                                      NULL);
 
@@ -383,6 +389,7 @@ run (void *cls,
 int
 main(int argc, char *const argv[])
 {
+  exp_interval = GNUNET_TIME_UNIT_HOURS;
   struct GNUNET_GETOPT_CommandLineOption options[] = {
 
     GNUNET_GETOPT_option_string ('a',
@@ -430,6 +437,12 @@ main(int argc, char *const argv[])
                                  NULL,
                                  gettext_noop ("Type of attribute"),
                                  &type_str),
+    GNUNET_GETOPT_option_relative_time ('E',
+                                        "expiration",
+                                        NULL,
+                                        gettext_noop ("Expiration interval of the attribute"),
+                                        &exp_interval),
+
     GNUNET_GETOPT_OPTION_END
   };
   return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "ct",
index 207923d5e9da34c89e8bd3fe3b01683bdf634751..a518d00aed64c3ba75ede33e24eda17ddaf113d0 100644 (file)
@@ -363,6 +363,11 @@ struct AttributeStoreHandle
    */
   struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim;
 
+  /**
+   * The attribute expiration interval
+   */
+  struct GNUNET_TIME_Relative exp;
+
   /**
    * request id
    */
@@ -1308,12 +1313,29 @@ revocation_reissue_tickets (struct TicketRevocationHandle *rh)
 }
 
 /**
- * Revoke next attribte by reencryption with
- * new ABE master
+ * Failed to check for attribute
  */
 static void
-reenc_next_attribute (struct TicketRevocationHandle *rh)
+check_attr_error (void *cls)
+{
+  struct TicketRevocationHandle *rh = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Unable to check for existing attribute\n");
+  send_revocation_finished (rh, GNUNET_SYSERR);
+  cleanup_revoke_ticket_handle (rh);
+}
+
+/**
+ * Check for existing attribute and overwrite
+ */
+static void
+check_attr_cb (void *cls,
+               const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+               const char *label,
+               unsigned int rd_count,
+               const struct GNUNET_GNSRECORD_Data *rd_old)
 {
+  struct TicketRevocationHandle *rh = cls;
   struct GNUNET_GNSRECORD_Data rd[1];
   char* buf;
   char* enc_buf;
@@ -1323,15 +1345,11 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
   char* policy;
   uint32_t attr_ver;
 
-  if (NULL == rh->attrs->list_head)
-  {
-    revocation_reissue_tickets (rh);
-    return;
-  }
+
   buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
   buf = GNUNET_malloc (buf_size);
   GNUNET_IDENTITY_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
-                       buf);
+                                       buf);
   rh->attrs->list_head->claim->version++;
   GNUNET_asprintf (&policy, "%s_%lu",
                    rh->attrs->list_head->claim->name,
@@ -1342,10 +1360,10 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
    * Encrypt the attribute value and store in namestore
    */
   enc_size = GNUNET_ABE_cpabe_encrypt (buf,
-                                          buf_size,
-                                          policy, //Policy
-                                          rh->abe_key,
-                                          (void**)&enc_buf);
+                                       buf_size,
+                                       policy, //Policy
+                                       rh->abe_key,
+                                       (void**)&enc_buf);
   GNUNET_free (buf);
   if (GNUNET_SYSERR == enc_size)
   {
@@ -1371,7 +1389,7 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
   rd[0].data = rd_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?
+  rd[0].expiration_time = rd_old[0].expiration_time;
   rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
                                               &rh->identity,
                                               rh->attrs->list_head->claim->name,
@@ -1383,6 +1401,30 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
   GNUNET_free (rd_buf);
 }
 
+
+/**
+ * Revoke next attribte by reencryption with
+ * new ABE master
+ */
+static void
+reenc_next_attribute (struct TicketRevocationHandle *rh)
+{
+  if (NULL == rh->attrs->list_head)
+  {
+    revocation_reissue_tickets (rh);
+    return;
+  }
+  /* First check if attribute still exists */
+  rh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
+                                               &rh->identity,
+                                               rh->attrs->list_head->claim->name,
+                                               &check_attr_error,
+                                               rh,
+                                               &check_attr_cb,
+                                               rh);
+}
+
+
 /**
  * Namestore callback after revoked attribute
  * is stored
@@ -1878,7 +1920,7 @@ attr_store_task (void *cls)
   rd[0].data = rd_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?
+  rd[0].expiration_time = as_handle->exp.rel_value_us;
   as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
                                                      &as_handle->identity,
                                                      as_handle->claim->name,
@@ -1936,6 +1978,7 @@ handle_attribute_store_message (void *cls,
 
   as_handle->r_id = ntohl (sam->id);
   as_handle->identity = sam->identity;
+  as_handle->exp.rel_value_us = GNUNET_ntohll (sam->exp);
   GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
                                       &as_handle->identity_pkey);
 
index b1fe6e1fd53caea121cd3c5822875c397c776041..625b8f96df4797907c46111e3e15f9ac91bb1a55 100644 (file)
@@ -53,6 +53,11 @@ struct AttributeStoreMessage
    */
   uint32_t attr_len GNUNET_PACKED;
 
+  /**
+   * The expiration interval of the attribute
+   */
+  uint64_t exp GNUNET_PACKED;
+
   /**
    * Identity
    */
index e993a1ac784ed20412e3cd63e0350585d4f78fec..21ce6e3d67db26807166aff7c9ee942dd5f619cf 100644 (file)
@@ -908,6 +908,7 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
  * @param h handle to the identity provider
  * @param pkey private key of the identity
  * @param attr the attribute value
+ * @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
@@ -916,6 +917,7 @@ struct GNUNET_IDENTITY_PROVIDER_Operation *
 GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
                                           const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
                                           const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
+                                          const struct GNUNET_TIME_Relative *exp_interval,
                                           GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
                                           void *cont_cls)
 {
@@ -937,6 +939,7 @@ GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle
                                  GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
   sam->identity = *pkey;
   sam->id = htonl (op->r_id);
+  sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
 
   GNUNET_IDENTITY_ATTRIBUTE_serialize (attr,
                                        (char*)&sam[1]);
index 398d09cd2d0fff586133ec50a230310076da880d..03279983b0db1b32e6f90bcc1f1a9be468a42640 100644 (file)
@@ -546,6 +546,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
   const char* identity;
   const char* name_str;
   const char* value_str;
+  const char* exp_str;
 
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
@@ -553,9 +554,11 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
   struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attribute;
   struct GNUNET_JSONAPI_Document *json_obj;
   struct GNUNET_JSONAPI_Resource *json_res;
+  struct GNUNET_TIME_Relative exp;
   char term_data[handle->rest_handle->data_size+1];
   json_t *value_json;
   json_t *data_json;
+  json_t *exp_json;
   json_error_t err;
   struct GNUNET_JSON_Specification docspec[] = {
     GNUNET_JSON_spec_jsonapi_document (&json_obj),
@@ -635,6 +638,18 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
     return;
   }
   name_str = GNUNET_JSONAPI_resource_get_id (json_res);
+  exp_json = GNUNET_JSONAPI_resource_read_attr (json_res,
+                                                "exp");
+  exp_str = json_string_value (exp_json);
+  if (NULL == exp_str) {
+    exp = GNUNET_TIME_UNIT_HOURS;
+  } else {
+    if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (exp_str,
+                                           &exp)) {
+      exp = GNUNET_TIME_UNIT_HOURS;
+    }
+  }
+
   value_json = GNUNET_JSONAPI_resource_read_attr (json_res,
                                                   "value");
   value_str = json_string_value (value_json);
@@ -646,6 +661,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
   handle->idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (handle->idp,
                                                              identity_priv,
                                                              attribute,
+                                                             &exp,
                                                              &finished_cont,
                                                              handle);
   GNUNET_free (attribute);
index be935e898fb32487d43734c143ff919f757305f0..bc666a216d4696fc1efbff5ec92057c396d1946d 100644 (file)
@@ -115,6 +115,7 @@ typedef void
  * @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
@@ -123,6 +124,7 @@ struct GNUNET_IDENTITY_PROVIDER_Operation *
 GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
                                           const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
                                           const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
+                                          const struct GNUNET_TIME_Relative *exp_interval,
                                           GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
                                           void *cont_cls);