[WIP] exchangedb adjustments for denominations

- all prepared statements re: denominations now handle age_mask

- signatures parameters adjusted.

Now compiles and Tests run but fail.

- good: we find denoms[] and age_restricted_denoms[] filled correctly in
  output to /keys

- bad: fails at exchange_api_handle.c:882, signature verification of
  denom.
This commit is contained in:
Özgür Kesim 2022-02-07 13:56:25 +01:00
parent f8b1c3f8db
commit d02b5e213a
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
6 changed files with 66 additions and 38 deletions

View File

@ -3037,6 +3037,7 @@ do_show (char *const *args)
keys = parse_keys_input ("show"); keys = parse_keys_input ("show");
if (NULL == keys) if (NULL == keys)
return; return;
if (GNUNET_OK != if (GNUNET_OK !=
load_offline_key (GNUNET_NO)) load_offline_key (GNUNET_NO))
return; return;

View File

@ -743,33 +743,30 @@ static struct TALER_AgeMask
load_age_mask (const char*section_name) load_age_mask (const char*section_name)
{ {
static const struct TALER_AgeMask null_mask = {0}; static const struct TALER_AgeMask null_mask = {0};
struct TALER_AgeMask age_mask; enum GNUNET_GenericReturnValue ret;
struct TALER_AgeMask age_mask = TALER_extensions_age_restriction_ageMask ();
TALER_extensions_init ();
age_mask = TALER_extensions_age_restriction_ageMask ();
if (age_mask.mask == 0) if (age_mask.mask == 0)
return null_mask; return null_mask;
if (GNUNET_OK == (GNUNET_CONFIGURATION_have_value ( if (GNUNET_OK != (GNUNET_CONFIGURATION_have_value (
TEH_cfg, TEH_cfg,
section_name, section_name,
"AGE_RESTRICTED"))) "AGE_RESTRICTED")))
{ return null_mask;
enum GNUNET_GenericReturnValue ret;
if (GNUNET_SYSERR == (ret = GNUNET_CONFIGURATION_get_value_yesno (TEH_cfg,
section_name,
"AGE_RESTRICTED")))
{
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
section_name,
"AGE_RESTRICTED",
"Value must be YES or NO\n");
return null_mask;
}
}
return age_mask; ret = GNUNET_CONFIGURATION_get_value_yesno (TEH_cfg,
section_name,
"AGE_RESTRICTED");
if (GNUNET_YES == ret)
return age_mask;
if (GNUNET_SYSERR == ret)
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
section_name,
"AGE_RESTRICTED",
"Value must be YES or NO\n");
return null_mask;
} }
@ -1177,6 +1174,8 @@ denomination_info_cb (
dk->meta = *meta; dk->meta = *meta;
dk->master_sig = *master_sig; dk->master_sig = *master_sig;
dk->recoup_possible = recoup_possible; dk->recoup_possible = recoup_possible;
dk->denom_pub.age_mask = meta->age_mask;
GNUNET_assert ( GNUNET_assert (
GNUNET_OK == GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (ksh->denomkey_map, GNUNET_CONTAINER_multihashmap_put (ksh->denomkey_map,
@ -1965,16 +1964,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
/* Put the denom into the correct array - denoms or age_restricted_denoms - /* Put the denom into the correct array - denoms or age_restricted_denoms -
* depending on the settings and the properties of the denomination */ * depending on the settings and the properties of the denomination */
if (age_restriction_active && if (age_restriction_active &&
(0 != dk->meta.age_mask.mask)) (0 != dk->denom_pub.age_mask.mask))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"got agerestricted denom %p (mask %d) with mask %x (%s)\n",
&dk->denom_pub,
dk->denom_pub.age_mask.mask,
dk->meta.age_mask.mask,
TALER_age_mask_to_string (&dk->meta.age_mask));
array = age_restricted_denoms; array = age_restricted_denoms;
}
else else
array = denoms; array = denoms;
@ -2664,10 +2655,9 @@ load_extension_data (const char *section_name,
TEH_currency); TEH_currency);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
meta->age_mask = load_age_mask (section_name); meta->age_mask = load_age_mask (section_name);
if (0 != meta->age_mask.mask)
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "XXXX age mask is NON zero: %s!\n",
TALER_age_mask_to_string (&meta->age_mask));
return GNUNET_OK; return GNUNET_OK;
} }

View File

@ -204,6 +204,7 @@ add_keys (void *cls,
TALER_denom_pub_free (&denom_pub); TALER_denom_pub_free (&denom_pub);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if (is_active) if (is_active)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -211,6 +212,7 @@ add_keys (void *cls,
GNUNET_h2s (&d->h_denom_pub.hash)); GNUNET_h2s (&d->h_denom_pub.hash));
continue; /* skip, already known */ continue; /* skip, already known */
} }
qs = TEH_plugin->add_denomination_key ( qs = TEH_plugin->add_denomination_key (
TEH_plugin->cls, TEH_plugin->cls,
&d->h_denom_pub, &d->h_denom_pub,

View File

@ -25,7 +25,7 @@ CREATE TABLE IF NOT EXISTS denominations
(denominations_serial BIGSERIAL UNIQUE (denominations_serial BIGSERIAL UNIQUE
,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) ,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
,denom_type INT4 NOT NULL DEFAULT (1) -- 1 == RSA (for now, remove default later!) ,denom_type INT4 NOT NULL DEFAULT (1) -- 1 == RSA (for now, remove default later!)
,age_restrictions INT4 NOT NULL DEFAULT (0) ,age_mask INT4 NOT NULL DEFAULT (0)
,denom_pub BYTEA NOT NULL ,denom_pub BYTEA NOT NULL
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
,valid_from INT8 NOT NULL ,valid_from INT8 NOT NULL
@ -47,7 +47,7 @@ COMMENT ON TABLE denominations
IS 'Main denominations table. All the valid denominations the exchange knows about.'; IS 'Main denominations table. All the valid denominations the exchange knows about.';
COMMENT ON COLUMN denominations.denom_type COMMENT ON COLUMN denominations.denom_type
IS 'determines cipher type for blind signatures used with this denomination; 0 is for RSA'; IS 'determines cipher type for blind signatures used with this denomination; 0 is for RSA';
COMMENT ON COLUMN denominations.age_restrictions COMMENT ON COLUMN denominations.age_mask
IS 'bitmask with the age restrictions that are being used for this denomination; 0 if denomination does not support the use of age restrictions'; IS 'bitmask with the age restrictions that are being used for this denomination; 0 if denomination does not support the use of age restrictions';
COMMENT ON COLUMN denominations.denominations_serial COMMENT ON COLUMN denominations.denominations_serial
IS 'needed for exchange-auditor replication logic'; IS 'needed for exchange-auditor replication logic';

View File

@ -231,10 +231,11 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac" ",fee_refresh_frac"
",fee_refund_val" ",fee_refund_val"
",fee_refund_frac" ",fee_refund_frac"
",age_mask"
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
" $11, $12, $13, $14, $15, $16, $17);", " $11, $12, $13, $14, $15, $16, $17, $18);",
17), 18),
/* Used in #postgres_iterate_denomination_info() */ /* Used in #postgres_iterate_denomination_info() */
GNUNET_PQ_make_prepare ( GNUNET_PQ_make_prepare (
"denomination_iterate", "denomination_iterate",
@ -255,6 +256,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refund_val" ",fee_refund_val"
",fee_refund_frac" ",fee_refund_frac"
",denom_pub" ",denom_pub"
",age_mask"
" FROM denominations;", " FROM denominations;",
0), 0),
/* Used in #postgres_iterate_denominations() */ /* Used in #postgres_iterate_denominations() */
@ -278,6 +280,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refund_val" ",fee_refund_val"
",fee_refund_frac" ",fee_refund_frac"
",denom_pub" ",denom_pub"
",age_mask"
" FROM denominations" " FROM denominations"
" LEFT JOIN " " LEFT JOIN "
" denomination_revocations USING (denominations_serial);", " denomination_revocations USING (denominations_serial);",
@ -341,6 +344,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac" ",fee_refresh_frac"
",fee_refund_val" ",fee_refund_val"
",fee_refund_frac" ",fee_refund_frac"
",age_mask"
" FROM denominations" " FROM denominations"
" WHERE denom_pub_hash=$1;", " WHERE denom_pub_hash=$1;",
1), 1),
@ -2071,7 +2075,6 @@ prepare_statements (struct PostgresClosure *pg)
"SELECT" "SELECT"
" denominations_serial AS serial" " denominations_serial AS serial"
",denom_type" ",denom_type"
",age_restrictions"
",denom_pub" ",denom_pub"
",master_sig" ",master_sig"
",valid_from" ",valid_from"
@ -2088,6 +2091,7 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac" ",fee_refresh_frac"
",fee_refund_val" ",fee_refund_val"
",fee_refund_frac" ",fee_refund_frac"
",age_mask"
" FROM denominations" " FROM denominations"
" WHERE denominations_serial > $1" " WHERE denominations_serial > $1"
" ORDER BY denominations_serial ASC;", " ORDER BY denominations_serial ASC;",
@ -2390,10 +2394,11 @@ prepare_statements (struct PostgresClosure *pg)
",fee_refresh_frac" ",fee_refresh_frac"
",fee_refund_val" ",fee_refund_val"
",fee_refund_frac" ",fee_refund_frac"
",age_mask"
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10," "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
" $11, $12, $13, $14, $15, $16, $17, $18);", " $11, $12, $13, $14, $15, $16, $17, $18, $19);",
18), 19),
GNUNET_PQ_make_prepare ( GNUNET_PQ_make_prepare (
"insert_into_table_denomination_revocations", "insert_into_table_denomination_revocations",
"INSERT INTO denomination_revocations" "INSERT INTO denomination_revocations"
@ -3096,9 +3101,12 @@ postgres_insert_denomination_info (
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_deposit), 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_refresh),
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refund), 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_PQ_query_param_end
}; };
GNUNET_assert (denom_pub->age_mask.mask == issue->age_mask.mask);
GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
GNUNET_TIME_timestamp_ntoh ( GNUNET_TIME_timestamp_ntoh (
issue->properties.start).abs_time)); issue->properties.start).abs_time));
@ -3172,6 +3180,8 @@ postgres_get_denomination_info (
&issue->properties.fee_refresh), &issue->properties.fee_refresh),
TALER_PQ_RESULT_SPEC_AMOUNT_NBO ("fee_refund", TALER_PQ_RESULT_SPEC_AMOUNT_NBO ("fee_refund",
&issue->properties.fee_refund), &issue->properties.fee_refund),
GNUNET_PQ_result_spec_uint32 ("age_mask",
&issue->age_mask.mask),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
@ -3258,12 +3268,15 @@ domination_cb_helper (void *cls,
&issue.properties.fee_refund), &issue.properties.fee_refund),
TALER_PQ_result_spec_denom_pub ("denom_pub", TALER_PQ_result_spec_denom_pub ("denom_pub",
&denom_pub), &denom_pub),
GNUNET_PQ_result_spec_uint32 ("age_mask",
&issue.age_mask.mask),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
memset (&issue.properties.master, memset (&issue.properties.master,
0, 0,
sizeof (issue.properties.master)); sizeof (issue.properties.master));
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_PQ_extract_result (result, GNUNET_PQ_extract_result (result,
rs, rs,
@ -3272,6 +3285,13 @@ domination_cb_helper (void *cls,
GNUNET_break (0); GNUNET_break (0);
return; 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 issue.properties.purpose.size
= htonl (sizeof (struct TALER_DenominationKeyValidityPS)); = htonl (sizeof (struct TALER_DenominationKeyValidityPS));
issue.properties.purpose.purpose issue.properties.purpose.purpose
@ -3387,6 +3407,8 @@ dominations_cb_helper (void *cls,
&meta.fee_refund), &meta.fee_refund),
TALER_PQ_result_spec_denom_pub ("denom_pub", TALER_PQ_result_spec_denom_pub ("denom_pub",
&denom_pub), &denom_pub),
GNUNET_PQ_result_spec_uint32 ("age_mask",
&meta.age_mask.mask),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
@ -3398,6 +3420,10 @@ dominations_cb_helper (void *cls,
GNUNET_break (0); GNUNET_break (0);
return; return;
} }
/* make sure the mask information is the same */
denom_pub.age_mask = meta.age_mask;
TALER_denom_pub_hash (&denom_pub, TALER_denom_pub_hash (&denom_pub,
&h_denom_pub); &h_denom_pub);
dic->cb (dic->cb_cls, dic->cb (dic->cb_cls,
@ -10193,6 +10219,8 @@ postgres_lookup_denomination_key (
&meta->fee_refresh), &meta->fee_refresh),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund", TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
&meta->fee_refund), &meta->fee_refund),
GNUNET_PQ_result_spec_uint32 ("age_mask",
&meta->age_mask.mask),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
@ -10236,6 +10264,7 @@ postgres_add_denomination_key (
TALER_PQ_query_param_amount (&meta->fee_deposit), TALER_PQ_query_param_amount (&meta->fee_deposit),
TALER_PQ_query_param_amount (&meta->fee_refresh), TALER_PQ_query_param_amount (&meta->fee_refresh),
TALER_PQ_query_param_amount (&meta->fee_refund), TALER_PQ_query_param_amount (&meta->fee_refund),
GNUNET_PQ_query_param_uint32 (&meta->age_mask.mask),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };

View File

@ -70,6 +70,12 @@ struct TALER_EXCHANGEDB_DenominationKeyInformationP
* Signed properties of the denomination key. * Signed properties of the denomination key.
*/ */
struct TALER_DenominationKeyValidityPS properties; struct TALER_DenominationKeyValidityPS properties;
/**
* If denomination was setup for age restriction, non-zero age mask.
* Note that the mask is not part of the signature.
*/
struct TALER_AgeMask age_mask;
}; };