aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb/plugin_exchangedb_postgres.c
diff options
context:
space:
mode:
authorÖzgür Kesim <oec-taler@kesim.org>2022-02-16 22:01:05 +0100
committerÖzgür Kesim <oec-taler@kesim.org>2022-02-16 22:01:05 +0100
commit8bdf6ab19df70c16d335ecf82f2c3b2117eeb70e (patch)
treefe38fc98807feb6892052ee091b2b5f0a70ab17a /src/exchangedb/plugin_exchangedb_postgres.c
parentb73be40ccd9ad0ef4a985f252099c867f698896d (diff)
[age restriction] progress 14/n - withdraw and deposit
Age restriction support for - withdraw is done and tested - deposit is done and tested TODOs: - melt/refresh/reveal - link ------ Added functions - TALER_age_restriction_commit - TALER_age_commitment_derive - TALER_age_commitment_hash - TALER_age_restriction_commitment_free_inside - Hash of age commitment passed around API boundaries Exchangedb adjustments for denominations - all prepared statements re: denominations now handle age_mask - signature parameters adjusted Hash and signature verification of /keys adjusted - Hashes of (normal) denominations and age-restricted denominations are calculated seperately - The hash of the age-restricted ones will then be added to the other hash - The total hash is signed/verified Tests for withdraw with age restriction added - TALER_EXCHANGE_DenomPublickey now carries age_mask - TALER_TESTING_cmd_withdraw_amount* takes age parameter - TALER_TESTING_find_pk takes boolean age_restricted - WithdrawState carries age_commitment and its hash - withdraw_run derives new age commitment, if applicable - Added age parameter to testing (13 as example) Various Fixes and changes - Fixes of post handler for /management/extensions - Fixes for offline tool extensions signing - Slight refactoring of extensions - Age restriction extension simplified - config is now global to extension - added global TEH_age_restriction_enabled and TEH_age_mask in taler-exchange-httpd - helper functions and macros introduced
Diffstat (limited to 'src/exchangedb/plugin_exchangedb_postgres.c')
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c105
1 files changed, 79 insertions, 26 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 98724fa04..878c36f96 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -231,10 +231,11 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac"
",fee_refund_val"
",fee_refund_frac"
+ ",age_mask"
") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
- " $11, $12, $13, $14, $15, $16, $17);",
- 17),
+ " $11, $12, $13, $14, $15, $16, $17, $18);",
+ 18),
/* Used in #postgres_iterate_denomination_info() */
GNUNET_PQ_make_prepare (
"denomination_iterate",
@@ -255,6 +256,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refund_val"
",fee_refund_frac"
",denom_pub"
+ ",age_mask"
" FROM denominations;",
0),
/* Used in #postgres_iterate_denominations() */
@@ -278,6 +280,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refund_val"
",fee_refund_frac"
",denom_pub"
+ ",age_mask"
" FROM denominations"
" LEFT JOIN "
" denomination_revocations USING (denominations_serial);",
@@ -341,6 +344,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac"
",fee_refund_val"
",fee_refund_frac"
+ ",age_mask"
" FROM denominations"
" WHERE denom_pub_hash=$1;",
1),
@@ -825,6 +829,7 @@ prepare_statements (struct PostgresClosure *pg)
",denoms.fee_refresh_frac"
",old_coin_pub"
",old_coin_sig"
+ ",h_age_commitment"
",amount_with_fee_val"
",amount_with_fee_frac"
",noreveal_index"
@@ -843,6 +848,7 @@ prepare_statements (struct PostgresClosure *pg)
"SELECT"
" denom.denom_pub"
",kc.coin_pub AS old_coin_pub"
+ ",h_age_commitment"
",old_coin_sig"
",amount_with_fee_val"
",amount_with_fee_frac"
@@ -1842,6 +1848,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac"
",fee_refund_val"
",fee_refund_frac"
+ ",age_mask"
" FROM denominations"
" WHERE denom_pub_hash=$1;",
1),
@@ -2069,7 +2076,6 @@ prepare_statements (struct PostgresClosure *pg)
"SELECT"
" denominations_serial AS serial"
",denom_type"
- ",age_restrictions"
",denom_pub"
",master_sig"
",valid_from"
@@ -2086,6 +2092,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac"
",fee_refund_val"
",fee_refund_frac"
+ ",age_mask"
" FROM denominations"
" WHERE denominations_serial > $1"
" ORDER BY denominations_serial ASC;",
@@ -2389,10 +2396,11 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac"
",fee_refund_val"
",fee_refund_frac"
+ ",age_mask"
") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
- " $11, $12, $13, $14, $15, $16, $17, $18);",
- 18),
+ " $11, $12, $13, $14, $15, $16, $17, $18, $19);",
+ 19),
GNUNET_PQ_make_prepare (
"insert_into_table_denomination_revocations",
"INSERT INTO denomination_revocations"
@@ -3096,9 +3104,12 @@ postgres_insert_denomination_info (
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_deposit),
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refresh),
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refund),
+ GNUNET_PQ_query_param_uint32 (&denom_pub->age_mask.mask),
GNUNET_PQ_query_param_end
};
+ GNUNET_assert (denom_pub->age_mask.mask == issue->age_mask.mask);
+
GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
GNUNET_TIME_timestamp_ntoh (
issue->properties.start).abs_time));
@@ -3172,6 +3183,8 @@ postgres_get_denomination_info (
&issue->properties.fee_refresh),
TALER_PQ_RESULT_SPEC_AMOUNT_NBO ("fee_refund",
&issue->properties.fee_refund),
+ GNUNET_PQ_result_spec_uint32 ("age_mask",
+ &issue->age_mask.mask),
GNUNET_PQ_result_spec_end
};
@@ -3258,12 +3271,15 @@ domination_cb_helper (void *cls,
&issue.properties.fee_refund),
TALER_PQ_result_spec_denom_pub ("denom_pub",
&denom_pub),
+ GNUNET_PQ_result_spec_uint32 ("age_mask",
+ &issue.age_mask.mask),
GNUNET_PQ_result_spec_end
};
memset (&issue.properties.master,
0,
sizeof (issue.properties.master));
+
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
@@ -3272,6 +3288,13 @@ domination_cb_helper (void *cls,
GNUNET_break (0);
return;
}
+
+ /* Unfortunately we have to carry the age mask in both, the
+ * TALER_DenominationPublicKey and
+ * TALER_EXCHANGEDB_DenominationKeyInformationP at different times.
+ * Here we use _both_ so let's make sure the values are the same. */
+ denom_pub.age_mask = issue.age_mask;
+
issue.properties.purpose.size
= htonl (sizeof (struct TALER_DenominationKeyValidityPS));
issue.properties.purpose.purpose
@@ -3357,10 +3380,10 @@ dominations_cb_helper (void *cls,
for (unsigned int i = 0; i<num_results; i++)
{
- struct TALER_EXCHANGEDB_DenominationKeyMetaData meta;
- struct TALER_DenominationPublicKey denom_pub;
- struct TALER_MasterSignatureP master_sig;
- struct TALER_DenominationHash h_denom_pub;
+ struct TALER_EXCHANGEDB_DenominationKeyMetaData meta = {0};
+ struct TALER_DenominationPublicKey denom_pub = {0};
+ struct TALER_MasterSignatureP master_sig = {0};
+ struct TALER_DenominationHash h_denom_pub = {0};
bool revoked;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("master_sig",
@@ -3387,6 +3410,8 @@ dominations_cb_helper (void *cls,
&meta.fee_refund),
TALER_PQ_result_spec_denom_pub ("denom_pub",
&denom_pub),
+ GNUNET_PQ_result_spec_uint32 ("age_mask",
+ &meta.age_mask.mask),
GNUNET_PQ_result_spec_end
};
@@ -3398,6 +3423,10 @@ dominations_cb_helper (void *cls,
GNUNET_break (0);
return;
}
+
+ /* make sure the mask information is the same */
+ denom_pub.age_mask = meta.age_mask;
+
TALER_denom_pub_hash (&denom_pub,
&h_denom_pub);
dic->cb (dic->cb_cls,
@@ -5741,11 +5770,13 @@ postgres_ensure_coin_known (void *cls,
const struct TALER_CoinPublicInfo *coin,
uint64_t *known_coin_id,
struct TALER_DenominationHash *denom_hash,
- struct TALER_AgeHash *age_hash)
+ struct TALER_AgeCommitmentHash *age_hash)
{
struct PostgresClosure *pg = cls;
enum GNUNET_DB_QueryStatus qs;
bool existed;
+ bool is_denom_pub_hash_null = false;
+ bool is_age_hash_null = false;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
GNUNET_PQ_query_param_auto_from_type (&coin->denom_pub_hash),
@@ -5753,24 +5784,22 @@ postgres_ensure_coin_known (void *cls,
TALER_PQ_query_param_denom_sig (&coin->denom_sig),
GNUNET_PQ_query_param_end
};
- bool is_null = false;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_bool ("existed",
&existed),
GNUNET_PQ_result_spec_uint64 ("known_coin_id",
known_coin_id),
GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_hash",
- age_hash),
- &is_null),
- GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
denom_hash),
- &is_null),
+ &is_denom_pub_hash_null),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("age_hash",
+ age_hash),
+ &is_age_hash_null),
GNUNET_PQ_result_spec_end
};
- GNUNET_break (GNUNET_is_zero (&coin->age_commitment_hash)); // FIXME-OEC
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"insert_known_coin",
params,
@@ -5790,21 +5819,24 @@ postgres_ensure_coin_known (void *cls,
return TALER_EXCHANGEDB_CKS_ADDED;
break; /* continued below */
}
- if ( (! is_null) &&
- (0 != GNUNET_memcmp (age_hash,
- &coin->age_commitment_hash)) )
+
+ if ( (! is_denom_pub_hash_null) &&
+ (0 != GNUNET_memcmp (&denom_hash->hash,
+ &coin->denom_pub_hash.hash)) )
{
- GNUNET_break (GNUNET_is_zero (age_hash)); // FIXME-OEC
GNUNET_break_op (0);
- return TALER_EXCHANGEDB_CKS_AGE_CONFLICT;
+ return TALER_EXCHANGEDB_CKS_DENOM_CONFLICT;
}
- if ( (! is_null) &&
- (0 != GNUNET_memcmp (denom_hash,
- &coin->denom_pub_hash)) )
+
+ if ( (! is_age_hash_null) &&
+ (0 != GNUNET_memcmp (age_hash,
+ &coin->age_commitment_hash)) )
{
+ GNUNET_break (GNUNET_is_zero (age_hash));
GNUNET_break_op (0);
- return TALER_EXCHANGEDB_CKS_DENOM_CONFLICT;
+ return TALER_EXCHANGEDB_CKS_AGE_CONFLICT;
}
+
return TALER_EXCHANGEDB_CKS_PRESENT;
}
@@ -6030,6 +6062,7 @@ postgres_get_melt (void *cls,
uint64_t *melt_serial_id)
{
struct PostgresClosure *pg = cls;
+ bool h_age_commitment_is_null;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (rc),
GNUNET_PQ_query_param_end
@@ -6046,6 +6079,10 @@ postgres_get_melt (void *cls,
&melt->session.coin.coin_pub),
GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
&melt->session.coin_sig),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("h_age_commitment",
+ &melt->session.h_age_commitment),
+ &h_age_commitment_is_null),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
&melt->session.amount_with_fee),
GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
@@ -6061,6 +6098,11 @@ postgres_get_melt (void *cls,
"get_melt",
params,
rs);
+ if (h_age_commitment_is_null)
+ memset (&melt->session.h_age_commitment,
+ 0,
+ sizeof(melt->session.h_age_commitment));
+
melt->session.rc = *rc;
return qs;
}
@@ -8225,6 +8267,8 @@ refreshs_serial_helper_cb (void *cls,
struct TALER_DenominationPublicKey denom_pub;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig;
+ struct TALER_AgeCommitmentHash h_age_commitment;
+ bool ac_isnull;
struct TALER_Amount amount_with_fee;
uint32_t noreveal_index;
uint64_t rowid;
@@ -8232,6 +8276,10 @@ refreshs_serial_helper_cb (void *cls,
struct GNUNET_PQ_ResultSpec rs[] = {
TALER_PQ_result_spec_denom_pub ("denom_pub",
&denom_pub),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("h_age_commitment",
+ &h_age_commitment),
+ &ac_isnull),
GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
&coin_pub),
GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
@@ -8257,9 +8305,11 @@ refreshs_serial_helper_cb (void *cls,
rsc->status = GNUNET_SYSERR;
return;
}
+
ret = rsc->cb (rsc->cb_cls,
rowid,
&denom_pub,
+ ac_isnull ? NULL : &h_age_commitment,
&coin_pub,
&coin_sig,
&amount_with_fee,
@@ -10198,6 +10248,8 @@ postgres_lookup_denomination_key (
&meta->fee_refresh),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
&meta->fee_refund),
+ GNUNET_PQ_result_spec_uint32 ("age_mask",
+ &meta->age_mask.mask),
GNUNET_PQ_result_spec_end
};
@@ -10241,6 +10293,7 @@ postgres_add_denomination_key (
TALER_PQ_query_param_amount (&meta->fee_deposit),
TALER_PQ_query_param_amount (&meta->fee_refresh),
TALER_PQ_query_param_amount (&meta->fee_refund),
+ GNUNET_PQ_query_param_uint32 (&meta->age_mask.mask),
GNUNET_PQ_query_param_end
};