commit e1a59ade9557cc2a7b0345397148dcfd2e16d35c Author: George Kadianakis desnacked@riseup.net Date: Mon Feb 13 15:31:34 2017 +0200
prop224: Add time period functions and unittests
This will be used by the build blinded key functions.
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/hs_common.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/or/hs_common.h | 22 ++++++++++++++++++++++ src/test/test_hs_service.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 107 insertions(+), 1 deletion(-)
diff --git a/src/or/hs_common.c b/src/or/hs_common.c index 4af3081..4250812 100644 --- a/src/or/hs_common.c +++ b/src/or/hs_common.c @@ -9,6 +9,8 @@ * protocol. **/
+#define HS_COMMON_PRIVATE + #include "or.h"
#include "config.h" @@ -50,6 +52,46 @@ hs_check_service_private_dir(const char *username, const char *path, return 0; }
+/** Get the default HS time period length in minutes from the consensus. */ +STATIC uint64_t +get_time_period_length(void) +{ + int32_t time_period_length = networkstatus_get_param(NULL, "hsdir-interval", + HS_TIME_PERIOD_LENGTH_DEFAULT, + HS_TIME_PERIOD_LENGTH_MIN, + HS_TIME_PERIOD_LENGTH_MAX); + /* Make sure it's a positive value. */ + tor_assert(time_period_length >= 0); + /* uint64_t will always be able to contain a int32_t */ + return (uint64_t) time_period_length; +} + +/** Get the HS time period number at time <b>now</b> */ +STATIC uint64_t +get_time_period_num(time_t now) +{ + uint64_t time_period_num; + uint64_t time_period_length = get_time_period_length(); + uint64_t minutes_since_epoch = now / 60; + + /* Now subtract half a day to fit the prop224 time period schedule (see + * section [TIME-PERIODS]). */ + tor_assert(minutes_since_epoch > HS_TIME_PERIOD_ROTATION_OFFSET); + minutes_since_epoch -= HS_TIME_PERIOD_ROTATION_OFFSET; + + /* Calculate the time period */ + time_period_num = minutes_since_epoch / time_period_length; + return time_period_num; +} + +/** Get the number of the _upcoming_ HS time period, given that the current + * time is <b>now</b>. */ +uint64_t +hs_get_next_time_period_num(time_t now) +{ + return get_time_period_num(now) + 1; +} + /* Create a new rend_data_t for a specific given <b>version</b>. * Return a pointer to the newly allocated data structure. */ static rend_data_t * diff --git a/src/or/hs_common.h b/src/or/hs_common.h index d7d4228..a8fded6 100644 --- a/src/or/hs_common.h +++ b/src/or/hs_common.h @@ -40,6 +40,15 @@ /* String prefix for the signature of ESTABLISH_INTRO */ #define ESTABLISH_INTRO_SIG_PREFIX "Tor establish-intro cell v1"
+/* The default HS time period length */ +#define HS_TIME_PERIOD_LENGTH_DEFAULT 1440 /* 1440 minutes == one day */ +/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */ +#define HS_TIME_PERIOD_LENGTH_MIN 30 /* minutes */ +/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */ +#define HS_TIME_PERIOD_LENGTH_MAX (60 * 24 * 10) /* 10 days or 14400 minutes */ +/* The time period rotation offset as seen in prop224 section [TIME-PERIODS] */ +#define HS_TIME_PERIOD_ROTATION_OFFSET (12 * 60) /* minutes */ + int hs_check_service_private_dir(const char *username, const char *path, unsigned int dir_group_readable, unsigned int create); @@ -60,5 +69,18 @@ const char *rend_data_get_desc_id(const rend_data_t *rend_data, const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out);
+uint64_t hs_get_next_time_period_num(time_t now); + +#ifdef HS_COMMON_PRIVATE + +#ifdef TOR_UNIT_TESTS + +STATIC uint64_t get_time_period_length(void); +STATIC uint64_t get_time_period_num(time_t now); + +#endif /* TOR_UNIT_TESTS */ + +#endif /* HS_COMMON_PRIVATE */ + #endif /* TOR_HS_COMMON_H */
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index ec9cc45..8207ddc 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -6,6 +6,7 @@ * \brief Test hidden service functionality. */
+#define HS_COMMON_PRIVATE #define HS_SERVICE_PRIVATE #define HS_INTROPOINT_PRIVATE
@@ -14,6 +15,7 @@ #include "crypto.h"
#include "hs/cell_establish_intro.h" +#include "hs_common.h" #include "hs_service.h" #include "hs_intropoint.h"
@@ -196,12 +198,52 @@ test_hs_ntor(void *arg) ; }
+/** Test that our HS time period calculation functions work properly */ +static void +test_time_period(void *arg) +{ + (void) arg; + unsigned int tn; + int retval; + time_t fake_time; + + /* Let's do the example in prop224 section [TIME-PERIODS] */ + retval = parse_rfc1123_time("Wed, 13 Apr 2016 11:00:00 UTC", + &fake_time); + tt_int_op(retval, ==, 0); + + /* Check that the time period number is right */ + tn = get_time_period_num(fake_time); + tt_int_op(tn, ==, 16903); + + /* Increase current time to 11:59:59 UTC and check that the time period + number is still the same */ + fake_time += 3599; + tn = get_time_period_num(fake_time); + tt_int_op(tn, ==, 16903); + + /* Now take time to 12:00:00 UTC and check that the time period rotated */ + fake_time += 1; + tn = get_time_period_num(fake_time); + tt_int_op(tn, ==, 16904); + + /* Now also check our hs_get_next_time_period_num() function */ + tn = hs_get_next_time_period_num(fake_time); + tt_int_op(tn, ==, 16905); + + done: + ; +} + struct testcase_t hs_service_tests[] = { { "gen_establish_intro_cell", test_gen_establish_intro_cell, TT_FORK, NULL, NULL }, { "gen_establish_intro_cell_bad", test_gen_establish_intro_cell_bad, TT_FORK, NULL, NULL }, - { "hs_ntor", test_hs_ntor, TT_FORK, NULL, NULL }, + { "hs_ntor", test_hs_ntor, TT_FORK, + NULL, NULL }, + { "time_period", test_time_period, TT_FORK, + NULL, NULL },
END_OF_TESTCASES };