gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: expand DB API with AML functions


From: gnunet
Subject: [taler-exchange] branch master updated: expand DB API with AML functions, fix purse refund calculations in libtalerexchange
Date: Thu, 29 Dec 2022 11:49:01 +0100

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

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 26aa9d98 expand DB API with AML functions, fix purse refund 
calculations in libtalerexchange
26aa9d98 is described below

commit 26aa9d985e2f9ba6ce3895e7e2625226e2008bfb
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Dec 29 11:48:57 2022 +0100

    expand DB API with AML functions, fix purse refund calculations in 
libtalerexchange
---
 src/exchangedb/0003-aml_history.sql               |   2 +-
 src/exchangedb/0003-aml_staff.sql                 |   3 +
 src/exchangedb/0003-aml_status.sql                |   2 +-
 src/exchangedb/pg_lookup_kyc_process_by_account.c |   3 +-
 src/exchangedb/pg_select_purse.c                  |  28 +-
 src/include/taler_crypto_lib.h                    |  40 +++
 src/include/taler_exchangedb_plugin.h             | 307 ++++++++++++++++++++++
 src/lib/exchange_api_common.c                     |  17 +-
 src/testing/test_exchange_p2p.c                   |  14 +-
 src/util/offline_signatures.c                     |   8 +-
 10 files changed, 382 insertions(+), 42 deletions(-)

diff --git a/src/exchangedb/0003-aml_history.sql 
b/src/exchangedb/0003-aml_history.sql
index 009f79d8..d3650f6c 100644
--- a/src/exchangedb/0003-aml_history.sql
+++ b/src/exchangedb/0003-aml_history.sql
@@ -57,7 +57,7 @@ BEGIN
     ,partition_suffix
   );
   PERFORM comment_partitioned_column(
-     '0 for AML decision required, 1 for AML is OK, -1 for account is frozen 
(prevents further transactions)'
+     '0 for all OK, 1 for AML decision required, 2 for account is frozen 
(prevents further transactions)'
     ,'new_status'
     ,table_name
     ,partition_suffix
diff --git a/src/exchangedb/0003-aml_staff.sql 
b/src/exchangedb/0003-aml_staff.sql
index dca0fc8d..00f60985 100644
--- a/src/exchangedb/0003-aml_staff.sql
+++ b/src/exchangedb/0003-aml_staff.sql
@@ -21,6 +21,7 @@ CREATE TABLE aml_staff
   ,master_sig BYTEA CHECK (LENGTH(master_sig)=64)
   ,decider_name VARCHAR NOT NULL
   ,is_active BOOLEAN NOT NULL
+  ,read_only BOOLEAN NOT NULL
   ,last_change INT8 NOT NULL
   );
 COMMENT ON TABLE aml_staff
@@ -33,5 +34,7 @@ COMMENT ON COLUMN aml_staff.decider_name
   IS 'Name of the staff member.';
 COMMENT ON COLUMN aml_staff.is_active
   IS 'true if we are currently supporting the use of this AML staff member.';
+COMMENT ON COLUMN aml_staff.is_active
+  IS 'true if the member has read-only access.';
 COMMENT ON COLUMN aml_staff.last_change
   IS 'Latest time when active status changed. Used to detect replays of old 
messages.';
diff --git a/src/exchangedb/0003-aml_status.sql 
b/src/exchangedb/0003-aml_status.sql
index 1e676bc1..c0683c0d 100644
--- a/src/exchangedb/0003-aml_status.sql
+++ b/src/exchangedb/0003-aml_status.sql
@@ -53,7 +53,7 @@ BEGIN
     ,partition_suffix
   );
   PERFORM comment_partitioned_column(
-     '0 for AML decision required, 1 for AML is OK, -1 for account is frozen 
(prevents further transactions)'
+     '0 for all OK, 1 for AML decision required, 2 for account is frozen 
(prevents further transactions)'
     ,'status'
     ,table_name
     ,partition_suffix
diff --git a/src/exchangedb/pg_lookup_kyc_process_by_account.c 
b/src/exchangedb/pg_lookup_kyc_process_by_account.c
index 6183ae7a..79a9d6c8 100644
--- a/src/exchangedb/pg_lookup_kyc_process_by_account.c
+++ b/src/exchangedb/pg_lookup_kyc_process_by_account.c
@@ -25,6 +25,7 @@
 #include "pg_lookup_kyc_process_by_account.h"
 #include "pg_helper.h"
 
+
 enum GNUNET_DB_QueryStatus
 TEH_PG_lookup_kyc_process_by_account (
   void *cls,
@@ -59,7 +60,7 @@ TEH_PG_lookup_kyc_process_by_account (
 
   *provider_account_id = NULL;
   *provider_legitimization_id = NULL;
-   /* Used in #postgres_lookup_kyc_process_by_account() */
+  /* Used in #postgres_lookup_kyc_process_by_account() */
   PREPARE (pg,
            "lookup_process_by_account",
            "SELECT "
diff --git a/src/exchangedb/pg_select_purse.c b/src/exchangedb/pg_select_purse.c
index 9143e872..6496d4a2 100644
--- a/src/exchangedb/pg_select_purse.c
+++ b/src/exchangedb/pg_select_purse.c
@@ -66,20 +66,20 @@ TEH_PG_select_purse (
   PREPARE (pg,
            "select_purse",
            "SELECT "
-           " merge_pub"
-           ",purse_creation"
-           ",purse_expiration"
-           ",h_contract_terms"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",balance_val"
-           ",balance_frac"
-           ",merge_timestamp"
-           ",purse_sig IS NOT NULL AS purse_deleted"
-           " FROM purse_requests"
-           " LEFT JOIN purse_merges USING (purse_pub)"
-           " LEFT JOIN purse_deletion USING (purse_pub)"
-           " WHERE purse_pub=$1;");
+           " pr.merge_pub"
+           ",pr.purse_creation"
+           ",pr.purse_expiration"
+           ",pr.h_contract_terms"
+           ",pr.amount_with_fee_val"
+           ",pr.amount_with_fee_frac"
+           ",pr.balance_val"
+           ",pr.balance_frac"
+           ",pm.merge_timestamp"
+           ",pd.purse_sig IS NOT NULL AS purse_deleted"
+           " FROM purse_requests pr"
+           " LEFT JOIN purse_merges pm ON (pm.purse_pub = pr.purse_pub)"
+           " LEFT JOIN purse_deletion pd ON (pd.purse_pub = pr.purse_pub)"
+           " WHERE pr.purse_pub=$1;");
   *merge_timestamp = GNUNET_TIME_UNIT_FOREVER_TS;
   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "select_purse",
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index d63fd7cc..5e7ea605 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -146,6 +146,18 @@ struct TALER_ReserveSignatureP
 };
 
 
+/**
+ * (Symmetric) key used to encrypt KYC attribute data in the database.
+ */
+struct TALER_AttributeKeyP
+{
+  /**
+   * Actual key material.
+   */
+  struct GNUNET_HashCode key;
+};
+
+
 /**
  * @brief Type of public keys to for merchant authorizations.
  * Merchants can issue refunds using the corresponding
@@ -536,6 +548,30 @@ struct TALER_AmlOfficerSignatureP
 };
 
 
+/**
+ * Bitmask with possible AML decision states.
+ */
+enum TALER_AmlDecisionState
+{
+
+  /**
+   * All AML requirements are currently satisfied.
+   */
+  TALER_AML_NONE = 0,
+
+  /**
+   * An AML investigation is pending.
+   */
+  TALER_AML_PENDING = 1,
+
+  /**
+   * An AML decision has concluded that the funds must be frozen.
+   */
+  TALER_AML_FROZEN = 2
+
+};
+
+
 /**
  * @brief Type of blinding keys for Taler.
  * must be 32 bytes (DB)
@@ -4597,6 +4633,7 @@ TALER_exchange_online_purse_status_verify (
  * @param officer_name name of the officer
  * @param change_date when to affect the status change
  * @param is_active true to enable the officer
+ * @param read_only true to only allow read-only access
  * @param master_priv private key to sign with
  * @param[out] master_sig where to write the signature
  */
@@ -4606,6 +4643,7 @@ TALER_exchange_offline_aml_officer_status_sign (
   const char *officer_name,
   struct GNUNET_TIME_Timestamp change_date,
   bool is_active,
+  bool read_only,
   const struct TALER_MasterPrivateKeyP *master_priv,
   struct TALER_MasterSignatureP *master_sig);
 
@@ -4617,6 +4655,7 @@ TALER_exchange_offline_aml_officer_status_sign (
  * @param officer_name name of the officer
  * @param change_date when to affect the status change
  * @param is_active true to enable the officer
+ * @param read_only true to only allow read-only access
  * @param master_pub public key to verify against
  * @param master_sig the signature the signature
  * @return #GNUNET_OK if the signature is valid
@@ -4627,6 +4666,7 @@ TALER_exchange_offline_aml_officer_status_verify (
   const char *officer_name,
   struct GNUNET_TIME_Timestamp change_date,
   bool is_active,
+  bool read_only,
   const struct TALER_MasterPublicKeyP *master_pub,
   const struct TALER_MasterSignatureP *master_sig);
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index da28262a..bba59355 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -2244,6 +2244,31 @@ typedef void
                                              size_t buf_size);
 
 
+/**
+ * Callback with KYC attributes about a particular user.
+ *
+ * @param cls closure
+ * @param h_payto account for which the attribute data is stored
+ * @param provider_section provider that must be checked
+ * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
+ *        digits can be 0 if exact day, month or year are unknown
+ * @param collection_time when was the data collected
+ * @param expiration_time when does the data expire
+ * @param enc_attributes_size number of bytes in @a enc_attributes
+ * @param enc_attributes encrypted attribute data
+ */
+typedef void
+(*TALER_EXCHANGEDB_AttributeCallback)(
+  void *cls,
+  const struct TALER_PaytoHashP *h_payto,
+  const char *provider_section,
+  const char *birthdate,
+  struct GNUNET_TIME_Timestamp collection_time,
+  struct GNUNET_TIME_Timestamp expiration_time,
+  size_t enc_attributes_size,
+  const void *enc_attributes);
+
+
 /**
  * Function called with details about deposits that have been made,
  * with the goal of auditing the deposit's execution.
@@ -3100,6 +3125,46 @@ typedef void
   const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue);
 
 
+/**
+ * Return AML status.
+ *
+ * @param cls closure
+ * @param row_id current row in AML status table
+ * @param h_payto account for which the attribute data is stored
+ * @param threshold currently monthly threshold that would trigger an AML check
+ * @param decision_time when was the last decision made
+ */
+typedef void
+(*TALER_EXCHANGEDB_AmlStatusCallback)(
+  void *cls,
+  uint64_t row_id,
+  const struct TALER_PaytoHashP *h_payto,
+  const struct TALER_Amount *threshold,
+  enum TALER_AmlDecisionState status);
+
+
+/**
+ * Return historic AML decision.
+ *
+ * @param cls closure
+ * @param new_threshold new monthly threshold that would trigger an AML check
+ * @param new_status AML decision status
+ * @param decision_time when was the decision made
+ * @param justification human-readable text justifying the decision
+ * @param decider_pub public key of the staff member
+ * @param decider_sig signature of the staff member
+ */
+typedef void
+(*TALER_EXCHANGEDB_AmlHistoryCallback)(
+  void *cls,
+  const struct TALER_Amount *new_threshold,
+  enum TALER_AmlDecisionState new_status,
+  struct GNUNET_TIME_Absolute decision_time,
+  const char *justification,
+  const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+  const struct TALER_AmlOfficerSignatureP *decider_sig);
+
+
 /**
  * @brief The plugin API, returned from the plugin's "init" function.
  * The argument given to "init" is simply a configuration handle.
@@ -6435,6 +6500,248 @@ struct TALER_EXCHANGEDB_Plugin
     void *kac_cls);
 
 
+  // FIXME: functions below here not yet implemented!
+
+  /**
+   * Store KYC attribute data.
+   *
+   * @param cls closure
+   * @param h_payto account for which the attribute data is stored
+   * @param kyc_prox key for similarity search
+   * @param provider_section provider that must be checked
+   * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
+   *        digits can be 0 if exact day, month or year are unknown
+   * @param collection_time when was the data collected
+   * @param expiration_time when does the data expire
+   * @param enc_attributes_size number of bytes in @a enc_attributes
+   * @param enc_attributes encrypted attribute data
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_kyc_attributes)(
+    void *cls,
+    const struct TALER_PaytoHashP *h_payto,
+    const struct GNUNET_ShortHashCode *kyc_prox,
+    const char *provider_section,
+    const char *birthdate,
+    struct GNUNET_TIME_Timestamp collection_time,
+    struct GNUNET_TIME_Timestamp expiration_time,
+    size_t enc_attributes_size,
+    const void *enc_attributes);
+
+
+  /**
+   * Update KYC attribute data.
+   *
+   * @param cls closure
+   * @param h_payto account for which the attribute data is stored
+   * @param kyc_prox key for similarity search
+   * @param provider_section provider that must be checked
+   * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
+   *        digits can be 0 if exact day, month or year are unknown
+   * @param collection_time when was the data collected
+   * @param expiration_time when does the data expire
+   * @param enc_attributes_size number of bytes in @a enc_attributes
+   * @param enc_attributes encrypted attribute data
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*update_kyc_attributes)(
+    void *cls,
+    const struct TALER_PaytoHashP *h_payto,
+    const struct GNUNET_ShortHashCode *kyc_prox,
+    const char *provider_section,
+    const char *birthdate,
+    struct GNUNET_TIME_Timestamp collection_time,
+    struct GNUNET_TIME_Timestamp expiration_time,
+    size_t enc_attributes_size,
+    const void *enc_attributes);
+
+
+  /**
+   * Lookup similar KYC attribute data.
+   *
+   * @param cls closure
+   * @param h_payto account for which the attribute data is stored
+   * @param kyc_prox key for similarity search
+   * @param cb callback to invoke on each match
+   * @param cb_cls closure for @a cb
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*select_similar_kyc_attributes)(
+    void *cls,
+    const struct GNUNET_ShortHashCode *kyc_prox,
+    TALER_EXCHANGEDB_AttributeCallback cb,
+    void *cb_cls);
+
+
+  /**
+   * Lookup KYC attribute data for a specific account.
+   *
+   * @param cls closure
+   * @param h_payto account for which the attribute data is stored
+   * @param cb callback to invoke on each match
+   * @param cb_cls closure for @a cb
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*select_kyc_attributes)(
+    void *cls,
+    const struct TALER_PaytoHashP *h_payto,
+    TALER_EXCHANGEDB_AttributeCallback cb,
+    void *cb_cls);
+
+
+  /**
+   * Insert AML staff record.
+   *
+   * @param cls closure
+   * @param decider_pub public key of the staff member
+   * @param master_sig offline signature affirming the AML officer
+   * @param decider_name full name of the staff member
+   * @param is_active true to enable, false to set as inactive
+   * @param read_only true to set read-only access
+   * @param last_change when was the change made effective
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_aml_officer)(
+    void *cls,
+    const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+    const struct TALER_MasterSignatureP *master_sig,
+    const char *decider_name,
+    bool is_active,
+    bool read_only,
+    struct GNUNET_TIME_Absolute last_change);
+
+
+  /**
+   * Update AML staff record.
+   *
+   * @param cls closure
+   * @param decider_pub public key of the staff member
+   * @param master_sig offline signature affirming the AML officer
+   * @param decider_name full name of the staff member
+   * @param is_active true to enable, false to set as inactive
+   * @param read_only true to set read-only access
+   * @param last_change when was the change made effective
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*update_aml_officer)(
+    void *cls,
+    const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+    const struct TALER_MasterSignatureP *master_sig,
+    const char *decider_name,
+    bool is_active,
+    bool read_only,
+    struct GNUNET_TIME_Absolute last_change);
+
+
+  /**
+   * Fetch AML staff record.
+   *
+   * @param cls closure
+   * @param decider_pub public key of the staff member
+   * @param[out] master_sig offline signature affirming the AML officer
+   * @param[out] decider_name full name of the staff member
+   * @param[out] is_active true to enable, false to set as inactive
+   * @param[out] read_only true to set read-only access
+   * @param[out] last_change when was the change made effective
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*lookup_aml_officer)(
+    void *cls,
+    const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+    struct TALER_MasterSignatureP *master_sig,
+    char **decider_name,
+    bool *is_active,
+    bool *read_only,
+    struct GNUNET_TIME_Absolute *last_change);
+
+
+  /**
+   * Trigger AML process, an account has crossed the threshold. Inserts or
+   * updates the AML status.
+   *
+   * @param cls closure
+   * @param h_payto account for which the attribute data is stored
+   * @param threshold_crossed existing threshold that was crossed
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*trigger_aml_process)(
+    void *cls,
+    const struct TALER_PaytoHashP *h_payto,
+    const struct TALER_Amount *threshold_crossed);
+
+
+  /**
+   * Lookup AML decisions that have a particular state.
+   *
+   * @param cls closure
+   * @param decision which decision states to filter by
+   * @param row_off offset to start from
+   * @param forward true to go forward in time, false to go backwards
+   * @param cb callback to invoke on each match
+   * @param cb_cls closure for @a cb
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*select_aml_processes)(
+    void *cls,
+    enum TALER_AmlDecisionState decision,
+    uint64_t row_off,
+    bool forward,
+    TALER_EXCHANGEDB_AmlStatusCallback cb,
+    void *cb_cls);
+
+
+  /**
+   * Lookup AML decision history for a particular account.
+   *
+   * @param cls closure
+   * @param h_payto which account should we return the AML decision history for
+   * @param cb callback to invoke on each match
+   * @param cb_cls closure for @a cb
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*select_aml_history)(
+    void *cls,
+    const struct TALER_PaytoHashP *h_payto,
+    TALER_EXCHANGEDB_AmlHistoryCallback cb,
+    void *cb_cls);
+
+
+  /**
+   * Insert an AML decision. Inserts into AML history and insert or updates AML
+   * status.
+   *
+   * @param cls closure
+   * @param h_payto account for which the attribute data is stored
+   * @param new_threshold new monthly threshold that would trigger an AML check
+   * @param new_status AML decision status
+   * @param decision_time when was the decision made
+   * @param justification human-readable text justifying the decision
+   * @param decider_pub public key of the staff member
+   * @param decider_sig signature of the staff member
+   * @return database transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_aml_decision)(
+    void *cls,
+    const struct TALER_PaytoHashP *h_payto,
+    const struct TALER_Amount *new_threshold,
+    enum TALER_AmlDecisionState new_status,
+    struct GNUNET_TIME_Absolute decision_time,
+    const char *justification,
+    const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+    const struct TALER_AmlOfficerSignatureP *decider_sig);
+
+
 };
 
 #endif /* _TALER_EXCHANGE_DB_H */
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 3807b997..b895bf9a 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -1336,15 +1336,11 @@ help_purse_deposit (struct CoinHistoryParseContext *pc,
   }
   if (refunded)
   {
-    /* We add the amount to refunds here, the original
-       deposit will be added to the balance later because
-       we still return GNUNET_YES, thus effectively
-       cancelling out this operation with respect to
-       the final balance. */
+    /* We wave the deposit fee. */
     if (0 >
         TALER_amount_add (&pc->rtotal,
                           &pc->rtotal,
-                          amount))
+                          &pc->dk->fees.deposit))
     {
       /* overflow in refund history? inconceivable! Bad exchange! */
       GNUNET_break_op (0);
@@ -1415,15 +1411,6 @@ help_purse_refund (struct CoinHistoryParseContext *pc,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
-  if (0 >
-      TALER_amount_add (&pc->rtotal,
-                        &pc->rtotal,
-                        amount))
-  {
-    /* overflow in refund history? inconceivable! Bad exchange! */
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
   return GNUNET_NO;
 }
 
diff --git a/src/testing/test_exchange_p2p.c b/src/testing/test_exchange_p2p.c
index ad95bf63..7c3bdd57 100644
--- a/src/testing/test_exchange_p2p.c
+++ b/src/testing/test_exchange_p2p.c
@@ -174,17 +174,17 @@ run (void *cls,
     TALER_TESTING_cmd_purse_create_with_deposit (
       "purse-with-deposit",
       MHD_HTTP_OK,
-      "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
+      "{\"amount\":\"EUR:0.99\",\"summary\":\"ice cream\"}",
       true, /* upload contract */
       GNUNET_TIME_UNIT_MINUTES, /* expiration */
       "withdraw-coin-1",
-      "EUR:1.01",
+      "EUR:1.00",
       NULL),
     TALER_TESTING_cmd_purse_poll (
       "push-poll-purse-before-merge",
       MHD_HTTP_OK,
       "purse-with-deposit",
-      "EUR:1",
+      "EUR:0.99",
       true,
       GNUNET_TIME_UNIT_MINUTES),
     TALER_TESTING_cmd_contract_get (
@@ -206,13 +206,13 @@ run (void *cls,
     TALER_TESTING_cmd_status (
       "push-check-post-merge-reserve-balance-get",
       "create-reserve-1",
-      "EUR:1.03",
+      "EUR:1.02",
       MHD_HTTP_OK),
     /* POST history doesn't yet support P2P transfers */
     TALER_TESTING_cmd_reserve_status (
       "push-check-post-merge-reserve-balance-post",
       "create-reserve-1",
-      "EUR:1.03",
+      "EUR:1.02",
       MHD_HTTP_OK),
     /* Test conflicting merge */
     TALER_TESTING_cmd_purse_merge (
@@ -261,12 +261,12 @@ run (void *cls,
     TALER_TESTING_cmd_status (
       "pull-check-post-merge-reserve-balance-get",
       "create-reserve-1",
-      "EUR:2.02",
+      "EUR:2.01",
       MHD_HTTP_OK),
     TALER_TESTING_cmd_reserve_status (
       "push-check-post-merge-reserve-balance-post",
       "create-reserve-1",
-      "EUR:2.02",
+      "EUR:2.01",
       MHD_HTTP_OK),
     /* create 2nd purse for a deposit conflict */
     TALER_TESTING_cmd_purse_create_with_reserve (
diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c
index d6638998..b1e3b93a 100644
--- a/src/util/offline_signatures.c
+++ b/src/util/offline_signatures.c
@@ -54,7 +54,7 @@ struct TALER_MasterAmlOfficerStatusPS
   struct GNUNET_HashCode h_officer_name GNUNET_PACKED;
 
   /**
-   * 1 if enabled, 0 if disabled, in NBO.
+   * Bitmask: 1 if enabled; 2 for read-only access. in NBO.
    */
   uint32_t is_active GNUNET_PACKED;
 };
@@ -67,6 +67,7 @@ TALER_exchange_offline_aml_officer_status_sign (
   const char *officer_name,
   struct GNUNET_TIME_Timestamp change_date,
   bool is_active,
+  bool read_only,
   const struct TALER_MasterPrivateKeyP *master_priv,
   struct TALER_MasterSignatureP *master_sig)
 {
@@ -75,7 +76,7 @@ TALER_exchange_offline_aml_officer_status_sign (
     .purpose.size = htonl (sizeof (as)),
     .change_date = GNUNET_TIME_timestamp_hton (change_date),
     .officer_pub = *officer_pub,
-    .is_active = htonl (is_active ? 1 : 0)
+    .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
   };
 
   GNUNET_CRYPTO_hash (officer_name,
@@ -93,6 +94,7 @@ TALER_exchange_offline_aml_officer_status_verify (
   const char *officer_name,
   struct GNUNET_TIME_Timestamp change_date,
   bool is_active,
+  bool read_only,
   const struct TALER_MasterPublicKeyP *master_pub,
   const struct TALER_MasterSignatureP *master_sig)
 {
@@ -101,7 +103,7 @@ TALER_exchange_offline_aml_officer_status_verify (
     .purpose.size = htonl (sizeof (as)),
     .change_date = GNUNET_TIME_timestamp_hton (change_date),
     .officer_pub = *officer_pub,
-    .is_active = htonl (is_active ? 1 : 0)
+    .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
   };
 
   GNUNET_CRYPTO_hash (officer_name,

-- 
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]