diff options
Diffstat (limited to 'src/util/age_restriction.c')
-rw-r--r-- | src/util/age_restriction.c | 89 |
1 files changed, 82 insertions, 7 deletions
diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c index f0d99fe66..6f0702298 100644 --- a/src/util/age_restriction.c +++ b/src/util/age_restriction.c @@ -23,6 +23,7 @@ #include "taler_signatures.h" #include <gnunet/gnunet_json_lib.h> #include <gcrypt.h> +#include <stdint.h> struct #ifndef AGE_RESTRICTION_WITH_ECDSA @@ -76,7 +77,7 @@ TALER_age_commitment_hash ( * defined by the given mask. */ uint8_t -get_age_group ( +TALER_get_age_group ( const struct TALER_AgeMask *mask, uint8_t age) { @@ -95,6 +96,27 @@ get_age_group ( } +uint8_t +TALER_get_lowest_age ( + const struct TALER_AgeMask *mask, + uint8_t age) +{ + uint32_t m = mask->bits; + uint8_t group = TALER_get_age_group (mask, age); + uint8_t lowest = 0; + + while (group > 0) + { + m = m >> 1; + if (m & 1) + group--; + lowest++; + } + + return lowest; +} + + #ifdef AGE_RESTRICTION_WITH_ECDSA /* @brief Helper function to generate a ECDSA private key * @@ -150,7 +172,7 @@ TALER_age_restriction_commit ( GNUNET_assert (mask->bits & 1); /* first bit must have been set */ num_pub = __builtin_popcount (mask->bits) - 1; - num_priv = get_age_group (mask, age); + num_priv = TALER_get_age_group (mask, age); GNUNET_assert (31 > num_priv); GNUNET_assert (num_priv <= num_pub); @@ -335,8 +357,8 @@ TALER_age_commitment_attest ( GNUNET_assert (NULL != attest); GNUNET_assert (NULL != cp); - group = get_age_group (&cp->commitment.mask, - age); + group = TALER_get_age_group (&cp->commitment.mask, + age); GNUNET_assert (group < 32); @@ -386,8 +408,8 @@ TALER_age_commitment_verify ( GNUNET_assert (NULL != attest); GNUNET_assert (NULL != comm); - group = get_age_group (&comm->mask, - age); + group = TALER_get_age_group (&comm->mask, + age); GNUNET_assert (group < 32); @@ -604,7 +626,7 @@ TALER_age_restriction_from_secret ( GNUNET_assert (mask->bits & 1); /* fist bit must have been set */ num_pub = __builtin_popcount (mask->bits) - 1; - num_priv = get_age_group (mask, max_age); + num_priv = TALER_get_age_group (mask, max_age); GNUNET_assert (31 > num_priv); GNUNET_assert (num_priv <= num_pub); @@ -689,4 +711,57 @@ TALER_age_restriction_from_secret ( } +enum GNUNET_GenericReturnValue +TALER_parse_coarse_date ( + const char *in, + const struct TALER_AgeMask *mask, + uint32_t *out) +{ + struct tm date = {0}; + struct tm limit = {0}; + time_t seconds; + + if (NULL == in) + { + /* FIXME[oec]: correct behaviour? */ + *out = 0; + return GNUNET_OK; + } + + GNUNET_assert (NULL !=mask); + GNUNET_assert (NULL !=out); + + if (NULL == strptime (in, "%Y-%0m-%0d", &date)) + { + if (NULL == strptime (in, "%Y-%0m-00", &date)) + if (NULL == strptime (in, "%Y-00-00", &date)) + return GNUNET_SYSERR; + + /* turns out that the day is off by one in the last two cases */ + date.tm_mday += 1; + } + + seconds = mktime (&date); + if (-1 == seconds) + return GNUNET_SYSERR; + + /* calculate the limit date for the largest age group */ + localtime_r (&(time_t){time (NULL)}, &limit); + limit.tm_year -= TALER_adult_age (mask); + GNUNET_assert (-1 != mktime (&limit)); + + if ((limit.tm_year < date.tm_year) + || ((limit.tm_year == date.tm_year) + && (limit.tm_mon < date.tm_mon)) + || ((limit.tm_year == date.tm_year) + && (limit.tm_mon == date.tm_mon) + && (limit.tm_mday < date.tm_mday))) + *out = seconds / 60 / 60 / 24; + else + *out = 0; + + return GNUNET_OK; +} + + /* end util/age_restriction.c */ |