From 7c510388b9d789c35fc05bead7677b3de52a318e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Wed, 10 Nov 2021 17:25:11 +0100 Subject: age restriction progress 2/n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Özgür Kesim --- src/include/taler_amount_lib.h | 3 ++ src/include/taler_crypto_lib.h | 60 ++++++++++++++++++++++++--------- src/include/taler_extensions.h | 35 +++++++++++++++++++ src/json/json_helper.c | 2 +- src/json/json_pack.c | 2 +- src/lib/exchange_api_deposit.c | 5 +-- src/lib/exchange_api_refreshes_reveal.c | 1 + src/pq/pq_query_helper.c | 2 +- src/pq/pq_result_helper.c | 2 +- src/util/Makefile.am | 1 + src/util/crypto.c | 1 + src/util/crypto_helper_denom.c | 21 +++++++++++- src/util/denom.c | 8 ++--- src/util/extension_age_restriction.c | 49 +++++++++++++++++++++++++++ src/util/taler-exchange-secmod-rsa.c | 3 +- 15 files changed, 168 insertions(+), 27 deletions(-) create mode 100644 src/include/taler_extensions.h create mode 100644 src/util/extension_age_restriction.c diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h index c1f42e473..c6d2f474e 100644 --- a/src/include/taler_amount_lib.h +++ b/src/include/taler_amount_lib.h @@ -21,6 +21,9 @@ #ifndef TALER_AMOUNT_LIB_H #define TALER_AMOUNT_LIB_H +#include +#include "gnunet/gnunet_common.h" + #ifdef __cplusplus extern "C" { diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index c521541fe..7261d4de5 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -280,6 +280,37 @@ struct TALER_MasterSignatureP struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; }; +/* + * @brief Type of a list of age groups, represented as bit mask. + * + * The bits set in the mask mark the edges at the beginning of a next age + * group. F.e. for the age groups + * 0-7, 8-9, 10-11, 12-14, 14-15, 16-17, 18-21, 21-* + * the following bits are set: + * + * 31 24 16 8 0 + * | | | | | + * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1 + * + * A value of 0 means that the exchange does not support the extension for + * age-restriction. + */ +struct TALER_AgeMask +{ + uint32_t mask; +}; + +/** + * @brief Age restriction commitment of a coin. + */ +struct TALER_AgeHash +{ + /** + * The commitment is a SHA-256 hash code. + */ + struct GNUNET_ShortHashCode shash; +}; + /** * @brief Type of public keys for Taler coins. The same key material is used @@ -292,6 +323,10 @@ struct TALER_CoinSpendPublicKeyP */ struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub; + /* + * If age restriction applies to the coin, it must come with a hash of the age commitment + */ + struct TALER_AgeHash age_commitment_hash; }; @@ -345,18 +380,6 @@ struct TALER_RefreshCommitmentP }; -/** - * Age restriction commitment of a coin. - */ -struct TALER_AgeHash -{ - /** - * The commitment is a SHA-256 hash code. - */ - struct GNUNET_ShortHashCode shash; -}; - - /** * Token used for access control to the merchant's unclaimed * orders. @@ -569,7 +592,7 @@ struct TALER_DenominationPublicKey /** * Age restriction mask used for the key. */ - uint32_t age_mask; + struct TALER_AgeMask age_mask; /** * Details, depending on @e cipher. @@ -630,6 +653,11 @@ struct TALER_CoinPublicInfo */ struct TALER_DenominationHash denom_pub_hash; + /** + * Hash of the age commitment. + */ + struct TALER_AgeHash age_commitment_hash; + /** * (Unblinded) signature over @e coin_pub with @e denom_pub, * which demonstrates that the coin is valid. @@ -880,7 +908,7 @@ TALER_blinded_denom_sig_cmp ( */ void TALER_denom_priv_to_pub (const struct TALER_DenominationPrivateKey *denom_priv, - uint32_t age_mask, + const struct TALER_AgeMask age_mask, struct TALER_DenominationPublicKey *denom_pub); @@ -929,7 +957,6 @@ TALER_coin_ev_hash (const void *coin_ev, /** * Compute the hash of a coin. - * FIXME-Oec: add age restriction hash here! * * @param coin_pub public key of the coin * @param[out] coin_h where to write the hash @@ -1020,6 +1047,9 @@ struct TALER_FreshCoin */ struct TALER_CoinSpendPrivateKeyP coin_priv; + /** + * FIXME-Oec: Age-verification vector, as pointer: Dyn alloc! + */ }; diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h new file mode 100644 index 000000000..c22a23b86 --- /dev/null +++ b/src/include/taler_extensions.h @@ -0,0 +1,35 @@ +/* + This file is part of TALER + Copyright (C) 2014-2021 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file include/taler_extensions.h + * @brief Interface for extensions + * @author Özgür Kesim + */ +#ifndef TALER_EXTENSIONS_H +#define TALER_EXTENSIONS_H + +/** + * + * @param cfg + * @param[out] mask for age restriction + * @return Error if extension for age restriction was set but age groups were + * invalid, OK otherwise. + */ +enum GNUNET_GenericReturnValue +TALER_get_age_mask (const struct GNUNET_CONFIGURATION_Handle *cfg, struct + TALER_AgeMask *mask); + +#endif diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 1684e7f35..468d13569 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -444,7 +444,7 @@ parse_denom_pub (void *cls, GNUNET_JSON_spec_uint32 ("cipher", &cipher), GNUNET_JSON_spec_uint32 ("age_mask", - &denom_pub->age_mask), + &denom_pub->age_mask.mask), GNUNET_JSON_spec_end () }; const char *emsg; diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 59e3afb77..f41ba5234 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -104,7 +104,7 @@ TALER_JSON_pack_denom_pub ( GNUNET_JSON_pack_uint64 ("cipher", TALER_DENOMINATION_RSA), GNUNET_JSON_pack_uint64 ("age_mask", - pk->age_mask), + pk->age_mask.mask), GNUNET_JSON_pack_rsa_public_key ("rsa_public_key", pk->details.rsa_public_key)); break; diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index e857c8ea1..39397425a 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -462,9 +462,9 @@ handle_deposit_finished (void *cls, * @param h_wire hash of the merchant’s account details * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) * @param coin_pub coin’s public key + * @param denom_sig exchange’s unblinded signature of the coin * @param denom_pub denomination key with which the coin is signed * @param denom_pub_hash hash of @a denom_pub - * @param denom_sig exchange’s unblinded signature of the coin * @param timestamp timestamp when the deposit was finalized * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed) @@ -512,7 +512,8 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, struct TALER_CoinPublicInfo coin_info = { .coin_pub = *coin_pub, .denom_pub_hash = *denom_pub_hash, - .denom_sig = *denom_sig + .denom_sig = *denom_sig, + .age_commitment_hash = coin_pub->age_commitment_hash }; if (GNUNET_YES != diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index c275e0a4d..6e679d23d 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -167,6 +167,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh, GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv, &coin_pub.eddsa_pub); TALER_coin_pub_hash (&coin_pub, + /* FIXME-Oec: Age commitment hash */ &coin_hash); if (GNUNET_OK != TALER_planchet_to_coin (pk, diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 618877608..43b8374a2 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -185,7 +185,7 @@ qconv_denom_pub (void *cls, GNUNET_assert (scratch_length > 0); GNUNET_break (NULL == cls); be[0] = htonl ((uint32_t) denom_pub->cipher); - be[1] = htonl (denom_pub->age_mask); + be[1] = htonl (denom_pub->age_mask.mask); switch (denom_pub->cipher) { case TALER_DENOMINATION_RSA: diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 2f570b6bb..ea815a9c2 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -551,7 +551,7 @@ extract_denom_pub (void *cls, res += sizeof (be); len -= sizeof (be); pk->cipher = ntohl (be[0]); - pk->age_mask = ntohl (be[1]); + pk->age_mask.mask = ntohl (be[1]); switch (pk->cipher) { case TALER_DENOMINATION_RSA: diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 556c3b6f3..3c9a72646 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -71,6 +71,7 @@ libtalerutil_la_SOURCES = \ crypto_wire.c \ denom.c \ exchange_signatures.c \ + extension_age_restriction.c \ getopt.c \ lang.c \ iban.c \ diff --git a/src/util/crypto.c b/src/util/crypto.c index 2c81554b9..67cf14b42 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -320,6 +320,7 @@ void TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub, struct TALER_CoinPubHash *coin_h) { + // FIXME-Oec: hash over age-restriction, too GNUNET_CRYPTO_hash (&coin_pub->eddsa_pub, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), &coin_h->hash); diff --git a/src/util/crypto_helper_denom.c b/src/util/crypto_helper_denom.c index 4dfd32fbd..e1cd2b6ba 100644 --- a/src/util/crypto_helper_denom.c +++ b/src/util/crypto_helper_denom.c @@ -20,6 +20,7 @@ */ #include "platform.h" #include "taler_util.h" +#include "taler_extensions.h" #include "taler_signatures.h" #include "taler-exchange-secmod-rsa.h" #include @@ -62,6 +63,11 @@ struct TALER_CRYPTO_DenominationHelper * Have we ever been sync'ed? */ bool synced; + + /** + * Age Mask that applies to this denomination. + */ + struct TALER_AgeMask age_mask; }; @@ -273,6 +279,19 @@ TALER_CRYPTO_helper_denom_connect ( TALER_CRYPTO_helper_denom_disconnect (dh); return NULL; } + + /* Extract the age groups from the config, if the extension has been set, + * and serialize them into the age mask */ + if (GNUNET_OK != + TALER_get_age_mask (cfg, &dh->age_mask)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + "extensions", /* FIXME: right section etc? */ + "age-restriction", + "invalid age groups"); + TALER_CRYPTO_helper_denom_disconnect (dh); + return NULL; + } } TALER_CRYPTO_helper_denom_poll (dh); return dh; @@ -320,7 +339,7 @@ handle_mt_avail (struct TALER_CRYPTO_DenominationHelper *dh, struct TALER_DenominationHash h_denom_pub; denom_pub.cipher = TALER_DENOMINATION_RSA; - denom_pub.age_mask = 0; // FIXME-Oec! + denom_pub.age_mask = dh->age_mask; denom_pub.details.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf, ntohs (kan->pub_size)); diff --git a/src/util/denom.c b/src/util/denom.c index cdcfc5c3a..a5305343b 100644 --- a/src/util/denom.c +++ b/src/util/denom.c @@ -161,7 +161,7 @@ TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, struct TALER_DenominationHash *denom_hash) { uint32_t opt[2] = { - htonl (denom_pub->age_mask), + htonl (denom_pub->age_mask.mask), htonl ((uint32_t) denom_pub->cipher) }; @@ -197,7 +197,7 @@ TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, void TALER_denom_priv_to_pub (const struct TALER_DenominationPrivateKey *denom_priv, - uint32_t age_mask, + const struct TALER_AgeMask age_mask, struct TALER_DenominationPublicKey *denom_pub) { switch (denom_priv->cipher) @@ -446,8 +446,8 @@ TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1, { if (denom1->cipher != denom2->cipher) return (denom1->cipher > denom2->cipher) ? 1 : -1; - if (denom1->age_mask != denom2->age_mask) - return (denom1->age_mask > denom2->age_mask) ? 1 : -1; + if (denom1->age_mask.mask != denom2->age_mask.mask) + return (denom1->age_mask.mask > denom2->age_mask.mask) ? 1 : -1; switch (denom1->cipher) { case TALER_DENOMINATION_INVALID: diff --git a/src/util/extension_age_restriction.c b/src/util/extension_age_restriction.c new file mode 100644 index 000000000..64ecaa31e --- /dev/null +++ b/src/util/extension_age_restriction.c @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2014-2020 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file extension_age_restriction.c + * @brief Utility functions regarding age restriction + * @author Özgür Kesim + */ +#include "platform.h" +#include "taler_util.h" + + +/** + * + * @param cfg + * @param[out] mask for age restriction + * @return Error if extension for age restriction was set but age groups were + * invalid, OK otherwise. + */ +enum GNUNET_GenericReturnValue +TALER_get_age_mask (const struct GNUNET_CONFIGURATION_Handle *cfg, struct + TALER_AgeMask *mask) +{ + /* FIXME-Oec: + * + * - Detect if age restriction is enabled in config + * - if not, return 0 mask + * - else, parse age group and serialize into mask + * - return Error on + * + * */ + mask->mask = 0; + return GNUNET_OK; +} + + +/* end of extension_age_restriction.c */ diff --git a/src/util/taler-exchange-secmod-rsa.c b/src/util/taler-exchange-secmod-rsa.c index 1248b126d..e996f14ee 100644 --- a/src/util/taler-exchange-secmod-rsa.c +++ b/src/util/taler-exchange-secmod-rsa.c @@ -1422,9 +1422,10 @@ parse_key (struct Denomination *denom, struct TALER_DenominationPublicKey pub; struct DenominationKey *dk; struct DenominationKey *before; + struct TALER_AgeMask age_mask = { .mask = 0 }; /* FIXME-Oec */ TALER_denom_priv_to_pub (&priv, - 0 /* FIXME-Oec */, + age_mask, &pub); dk = GNUNET_new (struct DenominationKey); dk->denom_priv = priv; -- cgit v1.2.3