gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-anastasis] 02/15: worked on recovery redux


From: gnunet
Subject: [taler-anastasis] 02/15: worked on recovery redux
Date: Sun, 31 Jan 2021 17:06:08 +0100

This is an automated email from the git hooks/post-receive script.

dennis-neufeld pushed a commit to branch master
in repository anastasis.

commit 1df205233d4ee116cff2c7a72ba33c30c7bad71e
Author: Dennis Neufeld <dennis.neufeld@students.bfh.ch>
AuthorDate: Wed Dec 30 20:26:46 2020 +0100

    worked on recovery redux
---
 contrib/Makefile.am                                |   7 +-
 contrib/test_resources/test_reducer_stateCPSTATE   |   0
 contrib/test_resources/test_reducer_stateCSOSTATE  |   0
 contrib/test_resources/test_reducer_stateCSSTATE   | 123 +++++++++++
 .../test_resources/test_reducer_stateCSSTATE_FINAL |   0
 contrib/test_resources/test_reducer_stateRFSTATE   |   0
 src/include/anastasis.h                            |  36 +++-
 src/lib/anastasis.c                                | 117 ++++++++--
 src/lib/anastasis_api_redux.c                      | 237 ++++++++++++++++++++-
 9 files changed, 492 insertions(+), 28 deletions(-)

diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 6bc6124..1736a77 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -21,4 +21,9 @@ pkgdata_DATA = \
   test_resources/test_reducer_stateSESTATE \
   test_resources/test_reducer_statePRSTATE \
   test_resources/test_reducer_stateAESTATE \
-  test_resources/test_reducer_stateAESTATE_FINAL 
+  test_resources/test_reducer_stateAESTATE_FINAL \
+  test_resources/test_reducer_stateCSSTATE \
+  test_resources/test_reducer_stateCSSTATE_FINAL \
+  test_resources/test_reducer_stateCPSTATE \
+  test_resources/test_reducer_stateCSOSTATE \
+  test_resources/test_reducer_stateRFSTATE
diff --git a/contrib/test_resources/test_reducer_stateCPSTATE 
b/contrib/test_resources/test_reducer_stateCPSTATE
new file mode 100644
index 0000000..e69de29
diff --git a/contrib/test_resources/test_reducer_stateCSOSTATE 
b/contrib/test_resources/test_reducer_stateCSOSTATE
new file mode 100644
index 0000000..e69de29
diff --git a/contrib/test_resources/test_reducer_stateCSSTATE 
b/contrib/test_resources/test_reducer_stateCSSTATE
new file mode 100644
index 0000000..c7c1b75
--- /dev/null
+++ b/contrib/test_resources/test_reducer_stateCSSTATE
@@ -0,0 +1,123 @@
+{
+  "recovery_state": "CHALLENGE_SELECTING",
+  "continents": [
+    "Europe",
+    "North_America"
+  ],
+  "selected_continent": "Europe",
+  "countries": [
+    {
+      "code": "ch",
+      "name": "Switzerland",
+      "continent": "Europe",
+      "name_i18n": {
+        "de_DE": "Schweiz",
+        "de_CH": "Schwiiz",
+        "fr": "Suisse",
+        "en": "Swiss"
+      },
+      "currency": "TESTKUDOS"
+    },
+    {
+      "code": "de",
+      "name": "Germany",
+      "continent": "Europe",
+      "continent_i18n": {
+        "de": "Europa"
+      },
+      "name_i18n": {
+        "de_DE": "Deutschland",
+        "de_CH": "Deutschland",
+        "fr": "Allemagne",
+        "en": "Germany"
+      },
+      "currency": "TESTKUDOS"
+    }
+  ],
+  "selected_country": "ch",
+  "currency": "TESTKUDOS",
+  "required_attributes": [
+    {
+      "type": "string",
+      "name": "full_name",
+      "label": "Full name",
+      "label_i18n": {
+        "de_DE": "Vollstaendiger Name",
+        "de_CH": "Vollstaendiger Name"
+      },
+      "widget": "anastasis_gtk_ia_full_name"
+    },
+    {
+      "type": "date",
+      "name": "birthdate",
+      "label": "Birthdate",
+      "label_i18n": {
+        "de_CH": "Geburtsdatum"
+      },
+      "widget": "anastasis_gtk_ia_birthdate"
+    },
+    {
+      "type": "string",
+      "name": "ahv_number",
+      "label": "AHV number",
+      "label_i18n": {
+        "de_DE": "AHV-Nummer",
+        "de_CH": "AHV-Nummer"
+      },
+      "widget": "anastasis_gtk_ia_ahv",
+      "validation-regex": "^(756).[0-9]{4}.[0-9]{4}.[0-9]{2}|(756)[0-9]{10}$",
+      "validation-logic": "CH_AVH_check"
+    }
+  ],
+  "authentication_providers": {
+    "question": [
+      {
+        "anastasis_04": {
+          "method_cost": "TESTKUDOS:0",
+          "annual_cost": "TESTKUDOS:0",
+          "insurance": "TESTKUDOS:1",
+          "provider_url": "localhost:8089/",
+          "provider_name": "Anastasis 4",
+          "provider_salt": "8HAPCKSH9D3MYJTS9536RHJHCW"
+        }
+      },
+      {
+        "anastasis_03": {
+          "method_cost": "TESTKUDOS:0",
+          "annual_cost": "TESTKUDOS:4.99",
+          "insurance": "TESTKUDOS:1",
+          "provider_url": "localhost:8088/",
+          "provider_name": "Anastasis 3",
+          "provider_salt": "8DAPCKSH9D3MYJTS9536RHJHCW"
+        }
+      },
+      {
+        "anastasis_02": {
+          "method_cost": "TESTKUDOS:0",
+          "annual_cost": "TESTKUDOS:1.99",
+          "insurance": "TESTKUDOS:1",
+          "provider_url": "localhost:8087/",
+          "provider_name": "Anastasis 2",
+          "provider_salt": "89APCKSH9D3MYJTS9536RHJHCW"
+        }
+      },
+      {
+        "anastasis_01": {
+          "method_cost": "TESTKUDOS:0",
+          "annual_cost": "TESTKUDOS:4.99",
+          "insurance": "TESTKUDOS:1",
+          "provider_url": "localhost:8086/",
+          "provider_name": "Anastasis 1",
+          "provider_salt": "85APCKSH9D3MYJTS9536RHJHCW"
+        }
+      }
+    ]
+  },
+  "identity_attributes": {
+    "full_name": "Max Musterman",
+    "ahv_number": "756.9217.0769.85",
+    "birth_year": 2000,
+    "birth_month": 1,
+    "birth_day": 1
+  }
+}
\ No newline at end of file
diff --git a/contrib/test_resources/test_reducer_stateCSSTATE_FINAL 
b/contrib/test_resources/test_reducer_stateCSSTATE_FINAL
new file mode 100644
index 0000000..e69de29
diff --git a/contrib/test_resources/test_reducer_stateRFSTATE 
b/contrib/test_resources/test_reducer_stateRFSTATE
new file mode 100644
index 0000000..e69de29
diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index 7bdb7c7..cafad61 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -163,6 +163,7 @@ ANASTASIS_challenge_answer (struct GNUNET_CURL_Context *ctx,
  * @param solved 1 if solved, else 0
  * @param truth_public_key Identifier of the challenge
  * @param currency Currency of the cost
+ * @param cb_cls callback closure
  */
 struct ANASTASIS_ChallengeInformation
 {
@@ -175,6 +176,7 @@ struct ANASTASIS_ChallengeInformation
   const struct ANASTASIS_CRYPTO_NonceP *nonce;
   char *currency;
   struct ANASTASIS_Challenge *challenge;
+  void *cb_cls;
 };
 
 /**
@@ -190,15 +192,13 @@ typedef void
                                enum TALER_ErrorCode ec); // i.e. payment 
missing
 
 /**
- * Starts the process for a defined escrow challenge. Has a reference to the 
challenge and opens a
- * challenge callback which returns the results of the request.
+ * Returns information of a challenge.
  *
  * @param challenge reference to the escrow challenge which is started
- * @param cc opens a callback for the requested information
+ * @return ANASTASIS_ChallengeInformation object
  */
-void
-ANASTASIS_get_challenge (struct ANASTASIS_Challenge *challenge,
-                         ANASTASIS_ChallengeCallback cc);
+struct ANASTASIS_ChallengeInformation *
+ANASTASIS_get_challenge (struct ANASTASIS_Challenge *challenge);
 
 /**
  * Defines a Callback for the payment of an escrow challenge. Sends back a 
payment link
@@ -263,6 +263,28 @@ typedef void
 */
 struct ANASTASIS_Recovery;
 
+
+/**
+ * Returns JSON-encoded recovery data.
+ *
+ * @param r object to return JSON encoding for
+ * @return JSON encoding of @a r
+ */
+json_t *
+ANASTASIS_recovery_to_json (const struct ANASTASIS_Recovery *r);
+
+
+/**
+ * Extracts recovery data from JSON.
+ *
+ * @param json JSON encoding to decode; recovery returned ONLY valid as long
+ *             as the JSON remains valid (do not decref until the recovery
+ *             is truly finished)
+ * @return decoded recovery object, NULL on error
+ */
+struct ANASTASIS_Recovery *
+ANASTASIS_recovery_from_json (const json_t *json);
+
 /**
 * Starts the recovery process by opening callbacks for the coresecret and a 
policy callback. A list of
 * providers is checked for policies and passed back to the client.
@@ -390,7 +412,7 @@ ANASTASIS_truth_from_json (const json_t *json);
 
 
 /**
- * Returns the size of a truth object.
+ * Returns JSON-encoded truth data.
  *
  * @param t object to return JSON encoding for
  * @return JSON encoding of @a t
diff --git a/src/lib/anastasis.c b/src/lib/anastasis.c
index b9f9eb0..a074048 100644
--- a/src/lib/anastasis.c
+++ b/src/lib/anastasis.c
@@ -279,6 +279,108 @@ struct ANASTASIS_ChallengeAnswerOperation
   struct ANASTASIS_Challenge *c;
 };
 
+
+// json_t *
+// ANASTASIS_recovery_to_json (const struct ANASTASIS_Recovery *r)
+// {
+//   return json_pack 
("{s:o,s:s,s:o,s:s,s:o,s:o,s:o,s:o,s:o,s:I,s:I,s:o,s:o,s:o,s:I,s:o}",
+//                     "pc",
+//                     GNUNET_JSON_from_data_auto (&r->pc),
+//                     "pc_cls",
+//                     r->pc_cls,
+//                     "csc",
+//                     GNUNET_JSON_from_data_auto (&r->csc),
+//                     "csc_cls",
+//                     r->csc_cls,
+//                     "id",
+//                     GNUNET_JSON_from_data_auto (&r->id),
+//                     "pub_key",
+//                     GNUNET_JSON_from_data_auto (&r->pub_key),
+//                     "ctx",
+//                     GNUNET_JSON_from_data_auto (r->ctx),
+//                     "plo",
+//                     GNUNET_JSON_from_data_auto (r->plo),
+//                     "encrypted_recovery_document",
+//                     GNUNET_JSON_from_data (r->encrypted_recovery_document,
+//                                            r->enc_rec_doc_size),
+//                     "http_status",
+//                     r->http_status,
+//                     "response_code",
+//                     r->response_code,
+//                     "enc_core_secret",
+//                     GNUNET_JSON_from_data (r->enc_core_secret,
+//                                            r->enc_core_secret_size),
+//                     "policy_salt",
+//                     GNUNET_JSON_from_data_auto (&r->policy_salt),
+//                     "solved_challenges",
+//                     GNUNET_JSON_from_data_auto (r->solved_challenges),
+//                     "solved_challenge_pos",
+//                     r->solved_challenge_pos,
+//                     "ri",
+//                     GNUNET_JSON_from_data_auto (r->ri));
+// }
+
+
+// struct ANASTASIS_Recovery *
+// ANASTASIS_recovery_from_json (const json_t *json)
+// {
+//   struct ANASTASIS_Recovery *r = GNUNET_new (struct ANASTASIS_Recovery);
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto ("pc",
+//                                  &r->pc),
+//     GNUNET_JSON_spec_string ("pc_cls",
+//                              &r->pc_cls),
+//     GNUNET_JSON_spec_fixed_auto ("csc",
+//                                  &r->csc),
+//     GNUNET_JSON_spec_string ("csc_cls",
+//                              &r->csc_cls),
+//     GNUNET_JSON_spec_fixed_auto ("id",
+//                                  &r->id),
+//     GNUNET_JSON_spec_fixed_auto ("pub_key",
+//                                  &r->pub_key),
+//     GNUNET_JSON_spec_fixed_auto ("ctx",
+//                                  &r->ctx),
+//     GNUNET_JSON_spec_fixed_auto ("plo",
+//                                  &r->plo),
+//     GNUNET_JSON_spec_fixed ("encrypted_recovery_document",
+//                             &r->encrypted_recovery_document,
+//                             &r->enc_rec_doc_size),
+//     GNUNET_JSON_spec_uint32 ("http_status",
+//                              &r->http_status),
+//     GNUNET_JSON_spec_uint32 ("response_code",
+//                              &r->response_code),
+//     GNUNET_JSON_spec_fixed ("enc_core_secret",
+//                             &r->enc_core_secret,
+//                             &r->enc_core_secret_size),
+//     GNUNET_JSON_spec_fixed_auto ("policy_salt",
+//                                  &r->policy_salt),
+//     GNUNET_JSON_spec_fixed_auto ("solved_challenges",
+//                                  &r->solved_challenges),
+//     GNUNET_JSON_spec_uint32 ("solved_challenge_pos",
+//                              &r->solved_challenge_pos),
+//     GNUNET_JSON_spec_fixed_auto ("ri",
+//                                  &r->ri),
+//     GNUNET_JSON_spec_end ()
+//   };
+//   const char *err_name;
+//   unsigned int err_line;
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (json,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Failed to parse recovery in line %u (%s)\n",
+//                 err_line,
+//                 err_name);
+//     return NULL;
+//   }
+//   return r;
+// }
+
+
 /**
  * Function called with the results of a #ANASTASIS_keyshare_lookup().
  *
@@ -506,21 +608,12 @@ ANASTASIS_challenge_answer (struct GNUNET_CURL_Context 
*ctx,
 }
 
 
-/**
- * Starts the process for a defined escrow challenge. Has a reference to the 
challenge and opens a
- * challenge callback which returns the results of the request.
- *
- * @param challenge reference to the escrow challenge which is started
- * @param cc opens a callback for the requested information
- */
-void
-ANASTASIS_get_challenge (struct ANASTASIS_Challenge *challenge,
-                         ANASTASIS_ChallengeCallback cc)
+struct ANASTASIS_ChallengeInformation *
+ANASTASIS_get_challenge (struct ANASTASIS_Challenge *challenge)
 {
   struct ANASTASIS_ChallengeInformation *ci;
 
   ci = GNUNET_new (struct ANASTASIS_ChallengeInformation);
-  challenge->cc = cc;
   ci->truth_public_key = &challenge->truth_public_key;
   ci->method = challenge->escrow_method;
   ci->url = challenge->url;
@@ -528,8 +621,6 @@ ANASTASIS_get_challenge (struct ANASTASIS_Challenge 
*challenge,
   ci->instructions = challenge->instructions;
   ci->solved = challenge->solved;
   ci->challenge = challenge;
-  challenge->cc (ci,
-                 200);
 }
 
 
diff --git a/src/lib/anastasis_api_redux.c b/src/lib/anastasis_api_redux.c
index 42d9ddf..8f61d89 100644
--- a/src/lib/anastasis_api_redux.c
+++ b/src/lib/anastasis_api_redux.c
@@ -181,6 +181,65 @@ struct SelectCountryHandle
 };
 
 
+/**
+ * State for a "recover secret" CMD.
+ */
+struct RecoverSecretState
+{
+  /**
+   * URL of the anastasis backend.
+   */
+  const char *anastasis_url;
+
+  /**
+   * Expected status code.
+   */
+  unsigned int http_status;
+
+  /**
+   * The /policy GET operation handle.
+   */
+  struct ANASTASIS_Recovery *recovery;
+
+  /**
+   * Identification data from the user
+   */
+  json_t *id_data;
+
+  /**
+   * version of the recovery document
+   */
+  unsigned int version;
+
+  /**
+   * Salt to be used to derive the id
+   */
+  struct ANASTASIS_CRYPTO_PowSalt *salt;
+
+  /**
+   * Recovery information from the lookup
+   */
+  struct ANASTASIS_RecoveryInformation *ri;
+
+  /**
+   * Coresecret to check if decryption worked
+   */
+  const void *core_secret;
+
+  /**
+   * Information about the challenges.
+   */
+  static struct ANASTASIS_ChallengeInformation *challenges;
+
+  /**
+   * Amount of challenges.
+   */
+  static unsigned int challenges_length;
+
+  struct GNUNET_SCHEDULER_Task *tt;
+};
+
+
 /**
  * JSON containing country specific identity attributes to ask the user for.
  */
@@ -880,6 +939,88 @@ unselect_continent (json_t *state,
 }
 
 
+static void
+policy_lookup_cb (void *cls,
+                  const struct ANASTASIS_RecoveryInformation *ri,
+                  const enum TALER_ErrorCode ec)
+{
+  struct RecoverSecretState *rss = cls;
+  rss->ri = (struct ANASTASIS_RecoveryInformation *) ri;
+  GNUNET_SCHEDULER_cancel (r->tt);
+  rss->tt = NULL;
+  if (NULL == ri)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  rss->http_status = MHD_HTTP_OK;
+  for (unsigned int i = 0; i < rss->ri->cs_len; i++)
+  {
+    struct ANASTASIS_ChallengeInformation *ci =
+      ANASTASIS_get_challenge (rss->ri->cs[i]);
+
+    unsigned int contains = 0;
+    for (unsigned int i = 0; i < rss->challenges_length; i++)
+    {
+      if (0 == memcmp (rss->challenges[i].nonce,
+                       ci->nonce,
+                       sizeof(struct ANASTASIS_CRYPTO_NonceP)))
+      {
+        contains = 1;
+        break;
+      }
+    }
+    if (0 == contains)
+      GNUNET_array_append (rss->challenges,
+                           rss->challenges_length,
+                           ci);
+  }
+
+}
+
+
+/**
+ * Function which collects the recovery information
+ * and calls the #ANASTASIS_ActionCallback.
+ *
+ * @param r a handle to a recovery begin operation
+ */
+static void
+conclude_recovery_begin (struct RecoverSecretState *r)
+{
+  if (MHD_HTTP_OK == r->http_status)
+  {
+    json_t *recovery_information =
+      json_object_get (state,
+                       "recovery_information");
+    if (NULL == recovery_information)
+    {
+
+    }
+    r->cb (NULL,
+           ANASTASIS_EC_NONE,
+           r->state);
+  }
+}
+
+
+/**
+ * Retries a "recovery begin" after timeout.
+ *
+ * @param cls closure for a "recovery begin" request
+ */
+static void
+policy_request_timeout (void *cls)
+{
+  struct RecoverSecretState *r = cls;
+
+  r->tt = NULL;
+  ANASTASIS_recovery_abort (r->recovery);
+  r->recovery = NULL;
+  conclude_recovery_begin (r);
+}
+
+
 /**
  * DispatchHandler/Callback function which is called for a
  * "enter_user_attributes" action.
@@ -980,6 +1121,9 @@ enter_user_attributes (json_t *state,
 
   if (0 == strcmp (s_mode, "backup_state"))
   {
+    json_object_set_new (state,
+                         "identity_attributes",
+                         attributes);
     json_object_set_new (state,
                          s_mode,
                          json_string (
@@ -989,22 +1133,101 @@ enter_user_attributes (json_t *state,
       json_object_set_new (state,
                            "authentication_providers",
                            auth_providers);
+    cb (cb_cls,
+        ANASTASIS_EC_NONE,
+        state);
+    return NULL;
   }
   else
   {
+    json_t *recovery_data;
+    json_t *version;
+    json_t *providers;
+    json_t *p_value;
+    char *p_key;
+    struct RecoverSecretState *rss
+      = GNUNET_new (struct RecoverSecretState);
+
+    providers = json_object_get (state,
+                                 "authentication_providers");
+    GNUNET_assert (NULL != providers);
+    rss->id_data = json_object_get (attributes,
+                                    "id_data");
+    GNUNET_assert (NULL != id_data);
+    version = json_object_get (attributes,
+                               "version");
+    rss->version = (unsigned int) json_integer_value (version);
+    rss->challenges_length = 0;
     json_object_set_new (state,
                          s_mode,
                          json_string (
                            ANASTASIS_recovery_state_to_string (
                              ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING)));
+
+    json_object_foreach (providers, p_key, p_value)
+    {
+      json_t *m_value;
+      size_t m_index;
+
+      GNUNET_assert (json_is_array (p_value));
+      json_array_foreach (p_value, m_index, m_value)
+      {
+        struct ANASTASIS_CRYPTO_PowSalt salt;
+        json_t *provider_data;
+        json_t *provider_url;
+        char *salt_str;
+        void *iter = json_object_iter (m_value);
+        char *key = json_object_iter_key (iter);
+
+        provider_data = json_object_get (m_value,
+                                         key);
+        GNUNET_assert (NULL != provider_data);
+        provider_url = json_object_get (provider_data,
+                                        "provider_url");
+        rss->anastasis_url = json_string_value (provider_url);
+        GNUNET_assert (NULL != provider_url);
+        salt_str = json_string_value (
+          json_object_get (provider_data,
+                           "provider_salt"));
+        GNUNET_assert (NULL != salt_str);
+        GNUNET_assert (
+          GNUNET_OK !=
+          GNUNET_STRINGS_string_to_data (salt_str,
+                                         strlen (salt_str),
+                                         &salt,
+                                         sizeof (struct
+                                                 ANASTASIS_CRYPTO_PowSalt)));
+        rss->recovery =
+          ANASTASIS_recovery_begin (
+            ctx,
+            rss->id_data,
+            (NULL != version)
+            ? rss->version
+            : 0),
+        rss->anastasis_url,
+        &salt,
+        &policy_lookup_cb,
+        rss,
+        NULL,
+        rss);
+
+        if (NULL == rss->recovery)
+        {
+          GNUNET_break (0);
+          cb (cb_cls,
+              ANASTASIS_EC_NONE,
+              state);
+          return NULL;
+        }
+        else
+        {
+          rss->tt = GNUNET_SCHEDULER_add_delayed (CONFIG_GENERIC_TIMEOUT,
+                                                  &policy_request_timeout,
+                                                  rss);
+        }
+      }
+    }
   }
-  json_object_set_new (state,
-                       "identity_attributes",
-                       attributes);
-  cb (cb_cls,
-      ANASTASIS_EC_NONE,
-      state);
-  return NULL;
 }
 
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]