Skip to content

Commit

Permalink
[#163] - Sort out expired prekey profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
olabini committed Oct 6, 2018
1 parent eda970e commit 2b4c13e
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 39 deletions.
3 changes: 2 additions & 1 deletion src/client_callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ otrng_client_callbacks_ensure_needed_exist(const otrng_client_callbacks_s *cb) {
cb->create_client_profile != NULL &&
cb->store_expired_client_profile != NULL &&
cb->create_prekey_profile != NULL &&
cb->write_expired_prekey_profile != NULL &&
cb->store_expired_prekey_profile != NULL &&
cb->load_expired_prekey_profile != NULL &&
cb->get_shared_session_state != NULL &&
cb->display_error_message != NULL && cb->load_privkey_v4 != NULL &&
cb->load_client_profile != NULL && cb->load_prekey_profile != NULL &&
Expand Down
11 changes: 6 additions & 5 deletions src/client_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ typedef struct otrng_client_callbacks_s {
void (*load_expired_client_profile)(struct otrng_client_s *client);

/* REQUIRED */
void (*create_prekey_profile)(struct otrng_client_s *client,
const struct otrng_client_id_s client_opdata);
void (*store_expired_prekey_profile)(struct otrng_client_s *client);

/* REQUIRED */
void (*load_expired_prekey_profile)(struct otrng_client_s *client);

/* REQUIRED */
void (*write_expired_prekey_profile)(
struct otrng_client_s *client,
const struct otrng_client_id_s client_opdata);
void (*create_prekey_profile)(struct otrng_client_s *client,
const struct otrng_client_id_s client_opdata);

/* OPTIONAL */
void (*gone_secure)(const struct otrng_s *);
Expand Down
92 changes: 84 additions & 8 deletions src/client_orchestration.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ tstatic void load_expired_client_profile_from_storage(otrng_client_s *client) {
otrng_debug_exit("orchestration.load_expired_client_profile_from_storage");
}

tstatic void load_expired_prekey_profile_from_storage(otrng_client_s *client) {
otrng_debug_enter("orchestration.load_expired_prekey_profile_from_storage");
client->global_state->callbacks->load_expired_prekey_profile(client);
otrng_debug_exit("orchestration.load_expired_prekey_profile_from_storage");
}

tstatic void create_client_profile(otrng_client_s *client) {
otrng_debug_enter("orchestration.create_client_profile");
client->global_state->callbacks->create_client_profile(client,
Expand Down Expand Up @@ -119,6 +125,13 @@ tstatic void clean_expired_client_profile(otrng_client_s *client) {
}
}

tstatic void clean_expired_prekey_profile(otrng_client_s *client) {
if (client->exp_prekey_profile != NULL) {
otrng_prekey_profile_free(client->exp_prekey_profile);
client->exp_prekey_profile = NULL;
}
}

tstatic void clean_prekey_profile(otrng_client_s *client) {
if (client->prekey_profile != NULL) {
otrng_prekey_profile_free(client->prekey_profile);
Expand Down Expand Up @@ -236,6 +249,19 @@ tstatic otrng_bool verify_valid_expired_client_profile(otrng_client_s *client) {
client->exp_client_profile, itag, client->profiles_extra_valid_time);
}

tstatic otrng_bool verify_valid_expired_prekey_profile(otrng_client_s *client) {
uint32_t itag;

if (client->exp_prekey_profile == NULL) {
return otrng_false;
}

itag = otrng_client_get_instance_tag(client);
return otrng_prekey_profile_is_expired_but_valid(
client->exp_prekey_profile, itag, client->profiles_extra_valid_time,
client->keypair->pub);
}

tstatic otrng_bool verify_valid_prekey_profile(otrng_client_s *client) {
uint32_t instag;

Expand Down Expand Up @@ -263,6 +289,21 @@ tstatic void move_client_profile_to_expired(otrng_client_s *client) {
otrng_debug_exit("move_client_profile_to_expired");
}

tstatic void move_prekey_profile_to_expired(otrng_client_s *client) {
otrng_debug_enter("move_prekey_profile_to_expired");

if (client->exp_prekey_profile) {
otrng_prekey_profile_free(client->exp_prekey_profile);
client->exp_prekey_profile = NULL;
}
client->exp_prekey_profile = client->prekey_profile;
client->prekey_profile = NULL;

client->global_state->callbacks->store_expired_prekey_profile(client);

otrng_debug_exit("move_prekey_profile_to_expired");
}

tstatic void check_if_expired_client_profile(otrng_client_s *client) {
uint32_t itag;
if (client->client_profile) {
Expand All @@ -274,6 +315,18 @@ tstatic void check_if_expired_client_profile(otrng_client_s *client) {
}
}

tstatic void check_if_expired_prekey_profile(otrng_client_s *client) {
uint32_t itag;
if (client->prekey_profile) {
itag = otrng_client_get_instance_tag(client);
if (otrng_prekey_profile_is_expired_but_valid(
client->prekey_profile, itag, client->profiles_extra_valid_time,
client->keypair->pub)) {
move_prekey_profile_to_expired(client);
}
}
}

tstatic otrng_bool
check_if_close_to_expired_client_profile(otrng_client_s *client) {
if (otrng_client_profile_is_close_to_expiry(client->client_profile,
Expand All @@ -284,6 +337,16 @@ check_if_close_to_expired_client_profile(otrng_client_s *client) {
return otrng_true;
}

tstatic otrng_bool
check_if_close_to_expired_prekey_profile(otrng_client_s *client) {
if (otrng_prekey_profile_is_close_to_expiry(client->prekey_profile,
client->profiles_buffer_time)) {
move_prekey_profile_to_expired(client);
return otrng_false;
}
return otrng_true;
}

tstatic void ensure_valid_client_profile(otrng_client_s *client) {
if (verify_valid_client_profile(client)) {
return;
Expand Down Expand Up @@ -316,23 +379,35 @@ tstatic void ensure_valid_client_profile(otrng_client_s *client) {
}

tstatic void ensure_valid_expired_client_profile(otrng_client_s *client) {
otrng_debug_enter("verify_valid_expired_client_profile");
if (verify_valid_expired_client_profile(client)) {
otrng_debug_exit("verify_valid_expired_client_profile.exit.1");
return;
}

clean_expired_client_profile(client);
load_expired_client_profile_from_storage(client);

if (verify_valid_expired_client_profile(client)) {
otrng_debug_exit("verify_valid_expired_client_profile.exit.2");
return;
}

clean_expired_client_profile(client);
client->global_state->callbacks->store_expired_client_profile(client);
otrng_debug_exit("verify_valid_expired_client_profile.exit.3");
}

tstatic void ensure_valid_expired_prekey_profile(otrng_client_s *client) {
if (verify_valid_expired_prekey_profile(client)) {
return;
}

clean_expired_prekey_profile(client);
load_expired_prekey_profile_from_storage(client);

if (verify_valid_expired_prekey_profile(client)) {
return;
}

clean_expired_prekey_profile(client);
client->global_state->callbacks->store_expired_prekey_profile(client);
}

tstatic void ensure_valid_prekey_profile(otrng_client_s *client) {
Expand All @@ -342,9 +417,12 @@ tstatic void ensure_valid_prekey_profile(otrng_client_s *client) {

clean_prekey_profile(client);
load_prekey_profile_from_storage(client);
check_if_expired_prekey_profile(client);

if (verify_valid_prekey_profile(client)) {
return;
if (!check_if_close_to_expired_prekey_profile(client)) {
return;
}
}

clean_prekey_profile(client);
Expand Down Expand Up @@ -439,9 +517,7 @@ API void otrng_client_ensure_correct_state(otrng_client_s *client) {
ensure_valid_client_profile(client);
ensure_valid_expired_client_profile(client);
ensure_valid_prekey_profile(client);

// TODO: @ola here we should check if the prekeyprofile is close to expiring,
// and in that case move it to the expired part and create a new one
ensure_valid_expired_prekey_profile(client);

ensure_enough_prekey_messages(client);

Expand Down
9 changes: 0 additions & 9 deletions src/persistence.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,15 +723,6 @@ otrng_client_prekey_profile_read_from(otrng_client_s *client, FILE *profilef) {
return result;
}

if (otrng_prekey_profile_expired(profile.expires)) {
client->global_state->callbacks->write_expired_prekey_profile(
client, client->client_id);

// TODO: I'm suspecting this will make a lot of tests fail, so
// no return for the moment
// return OTRNG_SUCCESS;
}

otrng_prekey_profile_free(client->prekey_profile);
client->prekey_profile = NULL;

Expand Down
36 changes: 29 additions & 7 deletions src/prekey_profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ INTERNAL otrng_bool otrng_prekey_profile_invalid(time_t expires,
return difftime(expires + extra_valid_time, time(NULL)) <= 0;
}

INTERNAL otrng_bool otrng_prekey_profile_valid(
tstatic otrng_bool otrng_prekey_profile_valid_without_expiry(
const otrng_prekey_profile_s *profile, const uint32_t sender_instance_tag,
const otrng_public_key pub) {
/* 1. Verify that the Prekey Profile signature is valid. */
Expand All @@ -385,12 +385,7 @@ INTERNAL otrng_bool otrng_prekey_profile_valid(
return otrng_false;
}

/* 3. Verify that the Prekey Profile has not expired. */
if (otrng_prekey_profile_expired(profile->expires)) {
return otrng_false;
}

/* 4. Validate that the Public Shared Prekey is on the curve Ed448-Goldilocks.
/* 3. Validate that the Public Shared Prekey is on the curve Ed448-Goldilocks.
*/
if (!otrng_ec_point_valid(profile->shared_prekey)) {
return otrng_false;
Expand All @@ -399,6 +394,33 @@ INTERNAL otrng_bool otrng_prekey_profile_valid(
return otrng_true;
}

INTERNAL otrng_bool otrng_prekey_profile_valid(
const otrng_prekey_profile_s *profile, const uint32_t sender_instance_tag,
const otrng_public_key pub) {
if (!otrng_prekey_profile_valid_without_expiry(profile, sender_instance_tag,
pub)) {
return otrng_false;
}

return !otrng_prekey_profile_expired(profile->expires);
}

/* This function should be called on a profile that is valid - it
assumes this, and doesn't verify it. */
INTERNAL otrng_bool otrng_prekey_profile_is_close_to_expiry(
const otrng_prekey_profile_s *profile, uint64_t buffer_time) {
return otrng_prekey_profile_expired(profile->expires + buffer_time);
}

INTERNAL otrng_bool otrng_prekey_profile_is_expired_but_valid(
const otrng_prekey_profile_s *profile, const uint32_t sender_instance_tag,
uint64_t extra_valid_time, const otrng_public_key pub) {
return otrng_prekey_profile_valid_without_expiry(profile, sender_instance_tag,
pub) &&
otrng_prekey_profile_expired(profile->expires) &&
!otrng_prekey_profile_invalid(profile->expires, extra_valid_time);
}

API void
otrng_prekey_profile_start_publishing(otrng_prekey_profile_s *profile) {
profile->is_publishing = otrng_true;
Expand Down
7 changes: 7 additions & 0 deletions src/prekey_profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ INTERNAL otrng_bool otrng_prekey_profile_expired(time_t expires);
INTERNAL otrng_bool otrng_prekey_profile_invalid(time_t expires,
uint64_t extra_valid_time);

INTERNAL otrng_bool otrng_prekey_profile_is_close_to_expiry(
const otrng_prekey_profile_s *profile, uint64_t buffer_time);

INTERNAL otrng_bool otrng_prekey_profile_is_expired_but_valid(
const otrng_prekey_profile_s *profile, uint32_t itag,
uint64_t extra_valid_time, const otrng_public_key pub);

INTERNAL otrng_bool otrng_prekey_profile_valid(
const otrng_prekey_profile_s *profile, const uint32_t sender_instance_tag,
const otrng_public_key pub);
Expand Down
7 changes: 2 additions & 5 deletions src/test/test_fixtures.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ otrng_client_callbacks_s test_callbacks[1] = {{
.create_client_profile = &create_client_profile_cb,
.store_expired_client_profile = &write_expired_client_profile_cb_empty,
.create_prekey_profile = &create_prekey_profile_cb,
.write_expired_prekey_profile = &write_expired_prekey_profile_cb_empty,
.store_expired_prekey_profile = &write_expired_prekey_profile_cb_empty,
.get_shared_session_state = &get_shared_session_state_cb,
.display_error_message = &display_error_message_cb,
.load_privkey_v4 = &load_privkey_v4_cb_empty,
Expand Down Expand Up @@ -442,11 +442,8 @@ void create_prekey_profile_cb_empty(
(void)client_opdata;
}

void write_expired_prekey_profile_cb_empty(
struct otrng_client_s *client,
const struct otrng_client_id_s client_opdata) {
void write_expired_prekey_profile_cb_empty(struct otrng_client_s *client) {
(void)client;
(void)client_opdata;
}

otrng_shared_session_state_s
Expand Down
4 changes: 1 addition & 3 deletions src/test/test_fixtures.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ void create_prekey_profile_cb_empty(
struct otrng_client_s *client,
const struct otrng_client_id_s client_opdata);

void write_expired_prekey_profile_cb_empty(
struct otrng_client_s *client,
const struct otrng_client_id_s client_opdata);
void write_expired_prekey_profile_cb_empty(struct otrng_client_s *client);

void create_shared_prekey_cb_empty(
struct otrng_client_s *client,
Expand Down
2 changes: 1 addition & 1 deletion src/test/units/test_messaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static otrng_client_callbacks_s empty_callbacks[1] = {{
.create_privkey_v4 = &create_privkey_v4_cb_empty,
.create_forging_key = &create_forging_key_cb_empty,
.store_expired_client_profile = &write_expired_client_profile_cb_empty,
.write_expired_prekey_profile = &write_expired_prekey_profile_cb_empty,
.store_expired_prekey_profile = &write_expired_prekey_profile_cb_empty,
.display_error_message = &display_error_message_cb_empty,
.load_privkey_v4 = &load_privkey_v4_cb_empty,
.load_client_profile = &load_client_profile_cb_empty,
Expand Down

0 comments on commit 2b4c13e

Please sign in to comment.