aboutsummaryrefslogtreecommitdiff
path: root/src/util/age_restriction.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/age_restriction.c')
-rw-r--r--src/util/age_restriction.c89
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 */