summaryrefslogtreecommitdiff
path: root/libs/libaxolotl/src/session_builder.c
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-02-13 07:56:33 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-02-13 09:09:08 +0300
commit193f645f65ad4ffdec3186e4176b23af10861199 (patch)
treee1b16b48ac74c5f03f99a98798e849f6dd9752cc /libs/libaxolotl/src/session_builder.c
parent36c32a13878d3bd94e88bd9c764f1eadb05ea1ed (diff)
libs:
libaxolotl: updated libaxolotl (libsignal-c) from (https://github.com/WhisperSystems/libsignal-protocol-c)
Diffstat (limited to 'libs/libaxolotl/src/session_builder.c')
-rw-r--r--libs/libaxolotl/src/session_builder.c689
1 files changed, 87 insertions, 602 deletions
diff --git a/libs/libaxolotl/src/session_builder.c b/libs/libaxolotl/src/session_builder.c
index b962c21b5f..2bfd62015f 100644
--- a/libs/libaxolotl/src/session_builder.c
+++ b/libs/libaxolotl/src/session_builder.c
@@ -1,36 +1,29 @@
#include "session_builder.h"
+#include "session_builder_internal.h"
#include <assert.h>
#include <string.h>
-#include "axolotl_internal.h"
#include "session_pre_key.h"
#include "session_record.h"
#include "session_state.h"
#include "ratchet.h"
#include "protocol.h"
#include "key_helper.h"
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
+#include "signal_protocol_internal.h"
struct session_builder
{
- axolotl_store_context *store;
- const axolotl_address *remote_address;
- axolotl_context *global_context;
+ signal_protocol_store_context *store;
+ const signal_protocol_address *remote_address;
+ signal_context *global_context;
};
-static int session_builder_process_pre_key_whisper_message_v2(session_builder *builder,
- session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id);
-static int session_builder_process_pre_key_whisper_message_v3(session_builder *builder,
- session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id);
-static int session_builder_process_initiate(session_builder *builder,
- key_exchange_message *message, key_exchange_message **response_message);
-static int session_builder_process_response(session_builder *builder,
- key_exchange_message *message);
+static int session_builder_process_pre_key_signal_message_v3(session_builder *builder,
+ session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id);
int session_builder_create(session_builder **builder,
- axolotl_store_context *store, const axolotl_address *remote_address,
- axolotl_context *global_context)
+ signal_protocol_store_context *store, const signal_protocol_address *remote_address,
+ signal_context *global_context)
{
session_builder *result = 0;
@@ -39,7 +32,7 @@ int session_builder_create(session_builder **builder,
result = malloc(sizeof(session_builder));
if(!result) {
- return AX_ERR_NOMEM;
+ return SG_ERR_NOMEM;
}
memset(result, 0, sizeof(session_builder));
@@ -51,43 +44,33 @@ int session_builder_create(session_builder **builder,
return 0;
}
-int session_builder_process_pre_key_whisper_message(session_builder *builder,
- session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id)
+int session_builder_process_pre_key_signal_message(session_builder *builder,
+ session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id)
{
int result = 0;
int has_unsigned_pre_key_id_result = 0;
uint32_t unsigned_pre_key_id_result = 0;
- int message_version = pre_key_whisper_message_get_message_version(message);
- ec_public_key *their_identity_key = pre_key_whisper_message_get_identity_key(message);
+ ec_public_key *their_identity_key = pre_key_signal_message_get_identity_key(message);
- result = axolotl_identity_is_trusted_identity(builder->store,
- builder->remote_address->name, builder->remote_address->name_len,
+ result = signal_protocol_identity_is_trusted_identity(builder->store,
+ builder->remote_address,
their_identity_key);
if(result < 0) {
goto complete;
}
if(result == 0) {
- result = AX_ERR_UNTRUSTED_IDENTITY;
+ result = SG_ERR_UNTRUSTED_IDENTITY;
goto complete;
}
- if(message_version == 2) {
- result = session_builder_process_pre_key_whisper_message_v2(builder, record, message, &unsigned_pre_key_id_result);
- }
- else if(message_version == 3) {
- result = session_builder_process_pre_key_whisper_message_v3(builder, record, message, &unsigned_pre_key_id_result);
- }
- else {
- axolotl_log(builder->global_context, AX_LOG_WARNING, "Unknown version: %d", message_version);
- result = AX_ERR_INVALID_VERSION;
- }
+ result = session_builder_process_pre_key_signal_message_v3(builder, record, message, &unsigned_pre_key_id_result);
if(result < 0) {
goto complete;
}
has_unsigned_pre_key_id_result = result;
- result = axolotl_identity_save_identity(builder->store,
- builder->remote_address->name, builder->remote_address->name_len,
+ result = signal_protocol_identity_save_identity(builder->store,
+ builder->remote_address,
their_identity_key);
if(result < 0) {
goto complete;
@@ -102,195 +85,92 @@ complete:
return result;
}
-static int session_builder_process_pre_key_whisper_message_v2(session_builder *builder,
- session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id)
-{
- int result = 0;
- uint32_t unsigned_pre_key_id_result = 0;
- session_pre_key *our_pre_key = 0;
- ratchet_identity_key_pair *our_identity_key = 0;
- bob_axolotl_parameters *parameters = 0;
- uint32_t pre_key_id = 0;
- int contains_session = 0;
- session_state *state = 0;
- int contains_key = 0;
- uint32_t local_registration_id = 0;
-
- if(!pre_key_whisper_message_has_pre_key_id(message)) {
- axolotl_log(builder->global_context, AX_LOG_WARNING, "V2 message requires one time pre key ID!");
- result = AX_ERR_INVALID_KEY_ID;
- goto complete;
- }
-
- pre_key_id = pre_key_whisper_message_get_pre_key_id(message);
-
- contains_key = axolotl_pre_key_contains_key(builder->store, pre_key_id);
- if(contains_key < 0) {
- result = contains_key;
- goto complete;
- }
-
- contains_session = axolotl_session_contains_session(builder->store, builder->remote_address);
- if(contains_session < 0) {
- result = contains_session;
- goto complete;
- }
-
- if(!contains_key && contains_session) {
- axolotl_log(builder->global_context, AX_LOG_INFO, "We've already processed the prekey part of this V2 session, letting bundled message fall through...");
- result = 0;
- goto complete;
- }
-
- result = axolotl_pre_key_load_key(builder->store, &our_pre_key, pre_key_id);
- if(result < 0) {
- goto complete;
- }
-
- result = axolotl_identity_get_key_pair(builder->store, &our_identity_key);
- if(result < 0) {
- goto complete;
- }
-
- result = bob_axolotl_parameters_create(
- &parameters,
- our_identity_key,
- session_pre_key_get_key_pair(our_pre_key),
- 0,
- session_pre_key_get_key_pair(our_pre_key),
- pre_key_whisper_message_get_identity_key(message),
- pre_key_whisper_message_get_base_key(message));
- if(result < 0) {
- goto complete;
- }
-
- if(!session_record_is_fresh(record)) {
- session_record_archive_current_state(record);
- }
-
- state = session_record_get_state(record);
-
- result = ratcheting_session_bob_initialize(
- state,
- pre_key_whisper_message_get_message_version(message),
- parameters, builder->global_context);
- if(result < 0) {
- goto complete;
- }
-
- result = axolotl_identity_get_local_registration_id(builder->store, &local_registration_id);
- if(result < 0) {
- goto complete;
- }
-
- session_state_set_local_registration_id(state, local_registration_id);
- session_state_set_remote_registration_id(state,
- pre_key_whisper_message_get_registration_id(message));
- session_state_set_alice_base_key(state,
- pre_key_whisper_message_get_base_key(message));;
-
- if(pre_key_whisper_message_get_pre_key_id(message) != PRE_KEY_MEDIUM_MAX_VALUE) {
- unsigned_pre_key_id_result = pre_key_whisper_message_get_pre_key_id(message);
- result = 1;
- }
- else {
- result = 0;
- }
-
-complete:
- AXOLOTL_UNREF(parameters);
- AXOLOTL_UNREF(our_identity_key);
- AXOLOTL_UNREF(our_pre_key);
- if(result >= 0) {
- *unsigned_pre_key_id = unsigned_pre_key_id_result;
- }
- return result;
-}
-
-static int session_builder_process_pre_key_whisper_message_v3(session_builder *builder,
- session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id)
+static int session_builder_process_pre_key_signal_message_v3(session_builder *builder,
+ session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id)
{
int result = 0;
uint32_t unsigned_pre_key_id_result = 0;
session_signed_pre_key *our_signed_pre_key = 0;
ratchet_identity_key_pair *our_identity_key = 0;
- bob_axolotl_parameters *parameters = 0;
+ bob_signal_protocol_parameters *parameters = 0;
session_pre_key *session_our_one_time_pre_key = 0;
ec_key_pair *our_one_time_pre_key = 0;
session_state *state = 0;
uint32_t local_registration_id = 0;
int has_session_state = session_record_has_session_state(record,
- pre_key_whisper_message_get_message_version(message),
- pre_key_whisper_message_get_base_key(message));
+ pre_key_signal_message_get_message_version(message),
+ pre_key_signal_message_get_base_key(message));
if(has_session_state) {
- axolotl_log(builder->global_context, AX_LOG_INFO, "We've already setup a session for this V3 message, letting bundled message fall through...");
+ signal_log(builder->global_context, SG_LOG_INFO, "We've already setup a session for this V3 message, letting bundled message fall through...");
result = 0;
goto complete;
}
- result = axolotl_signed_pre_key_load_key(builder->store,
+ result = signal_protocol_signed_pre_key_load_key(builder->store,
&our_signed_pre_key,
- pre_key_whisper_message_get_signed_pre_key_id(message));
+ pre_key_signal_message_get_signed_pre_key_id(message));
if(result < 0) {
goto complete;
}
- result = axolotl_identity_get_key_pair(builder->store, &our_identity_key);
+ result = signal_protocol_identity_get_key_pair(builder->store, &our_identity_key);
if(result < 0) {
goto complete;
}
- if(pre_key_whisper_message_has_pre_key_id(message)) {
- result = axolotl_pre_key_load_key(builder->store,
+ if(pre_key_signal_message_has_pre_key_id(message)) {
+ result = signal_protocol_pre_key_load_key(builder->store,
&session_our_one_time_pre_key,
- pre_key_whisper_message_get_pre_key_id(message));
+ pre_key_signal_message_get_pre_key_id(message));
if(result < 0) {
goto complete;
}
our_one_time_pre_key = session_pre_key_get_key_pair(session_our_one_time_pre_key);
}
- result = bob_axolotl_parameters_create(
+ result = bob_signal_protocol_parameters_create(
&parameters,
our_identity_key,
session_signed_pre_key_get_key_pair(our_signed_pre_key),
our_one_time_pre_key,
session_signed_pre_key_get_key_pair(our_signed_pre_key),
- pre_key_whisper_message_get_identity_key(message),
- pre_key_whisper_message_get_base_key(message));
+ pre_key_signal_message_get_identity_key(message),
+ pre_key_signal_message_get_base_key(message));
if(result < 0) {
goto complete;
}
if(!session_record_is_fresh(record)) {
- session_record_archive_current_state(record);
+ result = session_record_archive_current_state(record);
+ if(result < 0) {
+ goto complete;
+ }
}
state = session_record_get_state(record);
result = ratcheting_session_bob_initialize(
- state,
- pre_key_whisper_message_get_message_version(message),
- parameters, builder->global_context);
+ state, parameters,
+ builder->global_context);
if(result < 0) {
goto complete;
}
- result = axolotl_identity_get_local_registration_id(builder->store, &local_registration_id);
+ result = signal_protocol_identity_get_local_registration_id(builder->store, &local_registration_id);
if(result < 0) {
goto complete;
}
session_state_set_local_registration_id(state, local_registration_id);
session_state_set_remote_registration_id(state,
- pre_key_whisper_message_get_registration_id(message));
+ pre_key_signal_message_get_registration_id(message));
session_state_set_alice_base_key(state,
- pre_key_whisper_message_get_base_key(message));;
+ pre_key_signal_message_get_base_key(message));;
- if(pre_key_whisper_message_has_pre_key_id(message) &&
- pre_key_whisper_message_get_pre_key_id(message) != PRE_KEY_MEDIUM_MAX_VALUE) {
- unsigned_pre_key_id_result = pre_key_whisper_message_get_pre_key_id(message);
+ if(pre_key_signal_message_has_pre_key_id(message) &&
+ pre_key_signal_message_get_pre_key_id(message) != PRE_KEY_MEDIUM_MAX_VALUE) {
+ unsigned_pre_key_id_result = pre_key_signal_message_get_pre_key_id(message);
result = 1;
}
else {
@@ -298,10 +178,10 @@ static int session_builder_process_pre_key_whisper_message_v3(session_builder *b
}
complete:
- AXOLOTL_UNREF(parameters);
- AXOLOTL_UNREF(our_identity_key);
- AXOLOTL_UNREF(our_signed_pre_key);
- AXOLOTL_UNREF(session_our_one_time_pre_key);
+ SIGNAL_UNREF(parameters);
+ SIGNAL_UNREF(our_identity_key);
+ SIGNAL_UNREF(our_signed_pre_key);
+ SIGNAL_UNREF(session_our_one_time_pre_key);
if(result >= 0) {
*unsigned_pre_key_id = unsigned_pre_key_id_result;
}
@@ -314,10 +194,9 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre
session_record *record = 0;
ec_key_pair *our_base_key = 0;
ratchet_identity_key_pair *our_identity_key = 0;
- alice_axolotl_parameters *parameters = 0;
+ alice_signal_protocol_parameters *parameters = 0;
ec_public_key *signed_pre_key = 0;
ec_public_key *pre_key = 0;
- int supports_v3 = 0;
ec_public_key *their_identity_key = 0;
ec_public_key *their_signed_pre_key = 0;
ec_public_key *their_one_time_pre_key = 0;
@@ -329,16 +208,16 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre
assert(builder);
assert(builder->store);
assert(bundle);
- axolotl_lock(builder->global_context);
+ signal_lock(builder->global_context);
- result = axolotl_identity_is_trusted_identity(builder->store,
- builder->remote_address->name, builder->remote_address->name_len,
+ result = signal_protocol_identity_is_trusted_identity(builder->store,
+ builder->remote_address,
session_pre_key_bundle_get_identity_key(bundle));
if(result < 0) {
goto complete;
}
if(result == 0) {
- result = AX_ERR_UNTRUSTED_IDENTITY;
+ result = SG_ERR_UNTRUSTED_IDENTITY;
goto complete;
}
@@ -347,40 +226,38 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre
if(signed_pre_key) {
ec_public_key *identity_key = session_pre_key_bundle_get_identity_key(bundle);
- axolotl_buffer *signature = session_pre_key_bundle_get_signed_pre_key_signature(bundle);
+ signal_buffer *signature = session_pre_key_bundle_get_signed_pre_key_signature(bundle);
- axolotl_buffer *serialized_signed_pre_key = 0;
+ signal_buffer *serialized_signed_pre_key = 0;
result = ec_public_key_serialize(&serialized_signed_pre_key, signed_pre_key);
if(result < 0) {
goto complete;
}
result = curve_verify_signature(identity_key,
- axolotl_buffer_data(serialized_signed_pre_key),
- axolotl_buffer_len(serialized_signed_pre_key),
- axolotl_buffer_data(signature),
- axolotl_buffer_len(signature));
+ signal_buffer_data(serialized_signed_pre_key),
+ signal_buffer_len(serialized_signed_pre_key),
+ signal_buffer_data(signature),
+ signal_buffer_len(signature));
- axolotl_buffer_free(serialized_signed_pre_key);
+ signal_buffer_free(serialized_signed_pre_key);
if(result == 0) {
- axolotl_log(builder->global_context, AX_LOG_WARNING, "invalid signature on device key!");
- result = AX_ERR_INVALID_KEY;
+ signal_log(builder->global_context, SG_LOG_WARNING, "invalid signature on device key!");
+ result = SG_ERR_INVALID_KEY;
}
if(result < 0) {
goto complete;
}
}
- if(!signed_pre_key && !pre_key) {
- result = AX_ERR_INVALID_KEY;
- axolotl_log(builder->global_context, AX_LOG_WARNING, "both signed and unsigned pre keys are absent!");
+ if(!signed_pre_key) {
+ result = SG_ERR_INVALID_KEY;
+ signal_log(builder->global_context, SG_LOG_WARNING, "no signed pre key!");
goto complete;
}
- supports_v3 = (signed_pre_key != 0);
-
- result = axolotl_session_load_session(builder->store, &record, builder->remote_address);
+ result = signal_protocol_session_load_session(builder->store, &record, builder->remote_address);
if(result < 0) {
goto complete;
}
@@ -391,8 +268,7 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre
}
their_identity_key = session_pre_key_bundle_get_identity_key(bundle);
- their_signed_pre_key = supports_v3 ? signed_pre_key : pre_key;
-
+ their_signed_pre_key = signed_pre_key;
their_one_time_pre_key = pre_key;
if(their_one_time_pre_key) {
@@ -400,31 +276,33 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre
their_one_time_pre_key_id = session_pre_key_bundle_get_pre_key_id(bundle);
}
- result = axolotl_identity_get_key_pair(builder->store, &our_identity_key);
+ result = signal_protocol_identity_get_key_pair(builder->store, &our_identity_key);
if(result < 0) {
goto complete;
}
- result = alice_axolotl_parameters_create(&parameters,
+ result = alice_signal_protocol_parameters_create(&parameters,
our_identity_key,
our_base_key,
their_identity_key,
their_signed_pre_key,
- supports_v3 ? their_one_time_pre_key : 0,
+ their_one_time_pre_key,
their_signed_pre_key);
if(result < 0) {
goto complete;
}
if(!session_record_is_fresh(record)) {
- session_record_archive_current_state(record);
+ result = session_record_archive_current_state(record);
+ if(result < 0) {
+ goto complete;
+ }
}
state = session_record_get_state(record);
result = ratcheting_session_alice_initialize(
- state,
- supports_v3 ? 3 : 2, parameters,
+ state, parameters,
builder->global_context);
if(result < 0) {
goto complete;
@@ -435,7 +313,7 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre
session_pre_key_bundle_get_signed_pre_key_id(bundle),
ec_key_pair_get_public(our_base_key));
- result = axolotl_identity_get_local_registration_id(builder->store, &local_registration_id);
+ result = signal_protocol_identity_get_local_registration_id(builder->store, &local_registration_id);
if(result < 0) {
goto complete;
}
@@ -445,417 +323,24 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre
session_pre_key_bundle_get_registration_id(bundle));
session_state_set_alice_base_key(state, ec_key_pair_get_public(our_base_key));
- axolotl_session_store_session(builder->store, builder->remote_address, record);
- axolotl_identity_save_identity(builder->store,
- builder->remote_address->name, builder->remote_address->name_len,
- their_identity_key);
-
-complete:
- AXOLOTL_UNREF(record);
- AXOLOTL_UNREF(our_base_key);
- AXOLOTL_UNREF(our_identity_key);
- AXOLOTL_UNREF(parameters);
- axolotl_unlock(builder->global_context);
- return result;
-}
-
-int session_builder_process_key_exchange_message(session_builder *builder, key_exchange_message *message, key_exchange_message **response_message)
-{
- int result = 0;
- key_exchange_message *result_response_message = 0;
-
- assert(builder);
- assert(builder->store);
- axolotl_lock(builder->global_context);
-
- result = axolotl_identity_is_trusted_identity(builder->store,
- builder->remote_address->name, builder->remote_address->name_len,
- key_exchange_message_get_identity_key(message));
- if(result < 0) {
- goto complete;
- }
- if(result == 0) {
- result = AX_ERR_UNTRUSTED_IDENTITY;
- goto complete;
- }
- result = 0;
-
- if(key_exchange_message_is_initiate(message)) {
- result = session_builder_process_initiate(builder, message, &result_response_message);
- }
- else {
- result = session_builder_process_response(builder, message);
- }
-
-complete:
- if(result >= 0) {
- *response_message = result_response_message;
- }
- else {
- AXOLOTL_UNREF(result_response_message);
- }
- axolotl_unlock(builder->global_context);
- return result;
-}
-
-static int session_builder_process_initiate(session_builder *builder, key_exchange_message *message, key_exchange_message **response_message)
-{
- int result = 0;
- key_exchange_message *result_response_message = 0;
-
- uint32_t flags = KEY_EXCHANGE_RESPONSE_FLAG;
- session_record *record = 0;
- session_state *state = 0;
- ratchet_identity_key_pair *identity_key_pair = 0;
- ec_key_pair *our_base_key = 0;
- ec_key_pair *our_ratchet_key = 0;
- symmetric_axolotl_parameters *parameters = 0;
- ratchet_identity_key_pair *parameters_identity_key = 0;
- ec_key_pair *parameters_base_key = 0;
- axolotl_buffer *parameters_public_base_key_serialized = 0;
- ec_key_pair *parameters_ratchet_key = 0;
- axolotl_buffer *base_key_signature = 0;
-
- result = axolotl_session_load_session(builder->store, &record, builder->remote_address);
+ result = signal_protocol_session_store_session(builder->store, builder->remote_address, record);
if(result < 0) {
goto complete;
}
- if(key_exchange_message_get_version(message) >= 3) {
- ec_public_key *message_identity_key = key_exchange_message_get_identity_key(message);
- ec_public_key *message_base_key = key_exchange_message_get_base_key(message);
- axolotl_buffer *message_base_key_serialized = 0;
- uint8_t *message_base_key_signature = 0;
-
- ec_public_key_serialize(&message_base_key_serialized, message_base_key);
-
- message_base_key_signature = key_exchange_message_get_base_key_signature(message);
-
- result = curve_verify_signature(message_identity_key,
- axolotl_buffer_data(message_base_key_serialized),
- axolotl_buffer_len(message_base_key_serialized),
- message_base_key_signature, CURVE_SIGNATURE_LEN);
- axolotl_buffer_free(message_base_key_serialized);
- if(result < 0) {
- goto complete;
- }
- if(result != 1) {
- axolotl_log(builder->global_context, AX_LOG_WARNING, "Bad signature!");
- result = AX_ERR_INVALID_KEY;
- goto complete;
- }
- }
-
- state = session_record_get_state(record);
- if(!session_state_has_pending_key_exchange(state)) {
- result = axolotl_identity_get_key_pair(builder->store, &identity_key_pair);
- if(result < 0) {
- goto complete;
- }
-
- result = curve_generate_key_pair(builder->global_context, &our_base_key);
- if(result < 0) {
- goto complete;
- }
-
- result = curve_generate_key_pair(builder->global_context, &our_ratchet_key);
- if(result < 0) {
- goto complete;
- }
-
- result = symmetric_axolotl_parameters_create(
- &parameters,
- identity_key_pair,
- our_base_key,
- our_ratchet_key,
- key_exchange_message_get_base_key(message),
- key_exchange_message_get_ratchet_key(message),
- key_exchange_message_get_identity_key(message));
- if(result < 0) {
- goto complete;
- }
- }
- else {
- result = symmetric_axolotl_parameters_create(
- &parameters,
- session_state_get_pending_key_exchange_identity_key(state),
- session_state_get_pending_key_exchange_base_key(state),
- session_state_get_pending_key_exchange_ratchet_key(state),
- key_exchange_message_get_base_key(message),
- key_exchange_message_get_ratchet_key(message),
- key_exchange_message_get_identity_key(message));
- if(result < 0) {
- goto complete;
- }
-
- flags |= KEY_EXCHANGE_SIMULTAENOUS_INITIATE_FLAG;
- }
-
- if(!session_record_is_fresh(record)) {
- session_record_archive_current_state(record);
- }
-
- state = session_record_get_state(record);
- result = ratcheting_session_symmetric_initialize(state,
- MIN(key_exchange_message_get_max_version(message), (uint32_t)CIPHERTEXT_CURRENT_VERSION),
- parameters, builder->global_context);
- if(result < 0) {
- goto complete;
- }
-
- result = axolotl_session_store_session(builder->store, builder->remote_address, record);
- if(result < 0) {
- goto complete;
- }
-
- result = axolotl_identity_save_identity(builder->store,
- builder->remote_address->name, builder->remote_address->name_len,
- key_exchange_message_get_identity_key(message));
- if(result < 0) {
- goto complete;
- }
-
- parameters_identity_key = symmetric_axolotl_parameters_get_our_identity_key(parameters);
- parameters_base_key = symmetric_axolotl_parameters_get_our_base_key(parameters);
- parameters_ratchet_key = symmetric_axolotl_parameters_get_our_ratchet_key(parameters);
-
- result = ec_public_key_serialize(&parameters_public_base_key_serialized,
- ec_key_pair_get_public(parameters_base_key));
- if(result < 0) {
- goto complete;
- }
-
- result = curve_calculate_signature(builder->global_context,
- &base_key_signature,
- ratchet_identity_key_pair_get_private(parameters_identity_key),
- axolotl_buffer_data(parameters_public_base_key_serialized),
- axolotl_buffer_len(parameters_public_base_key_serialized));
- if(result < 0) {
- goto complete;
- }
-
- result = key_exchange_message_create(&result_response_message,
- session_state_get_session_version(state),
- key_exchange_message_get_sequence(message),
- flags,
- ec_key_pair_get_public(parameters_base_key),
- axolotl_buffer_data(base_key_signature),
- ec_key_pair_get_public(parameters_ratchet_key),
- ratchet_identity_key_pair_get_public(parameters_identity_key));
-
-complete:
- axolotl_buffer_free(parameters_public_base_key_serialized);
- axolotl_buffer_free(base_key_signature);
- AXOLOTL_UNREF(our_base_key);
- AXOLOTL_UNREF(our_ratchet_key);
- AXOLOTL_UNREF(identity_key_pair);
- AXOLOTL_UNREF(parameters);
- AXOLOTL_UNREF(record);
- if(result >= 0) {
- *response_message = result_response_message;
- }
- else {
- AXOLOTL_UNREF(result_response_message);
- }
- return result;
-}
-
-static int session_builder_process_response(session_builder *builder, key_exchange_message *message)
-{
- int result = 0;
- session_record *record = 0;
- session_state *state = 0;
- int has_pending_key_exchange = 0;
- int is_simultaneous_initiate_response = 0;
- symmetric_axolotl_parameters *parameters = 0;
-
- result = axolotl_session_load_session(builder->store, &record, builder->remote_address);
- if(result < 0) {
- goto complete;
- }
-
- state = session_record_get_state(record);
- has_pending_key_exchange = session_state_has_pending_key_exchange(state);
- is_simultaneous_initiate_response = key_exchange_message_is_response_for_simultaneous_initiate(message);
-
- if(!has_pending_key_exchange ||
- session_state_get_pending_key_exchange_sequence(state) != key_exchange_message_get_sequence(message)) {
- axolotl_log(builder->global_context, AX_LOG_INFO, "No matching sequence for response. Is simultaneous initiate response: %d", is_simultaneous_initiate_response);
- if(!is_simultaneous_initiate_response) {
- result = AX_ERR_STALE_KEY_EXCHANGE;
- goto complete;
- }
- else {
- result = AX_SUCCESS;
- goto complete;
- }
- }
-
- result = symmetric_axolotl_parameters_create(
- &parameters,
- session_state_get_pending_key_exchange_identity_key(state),
- session_state_get_pending_key_exchange_base_key(state),
- session_state_get_pending_key_exchange_ratchet_key(state),
- key_exchange_message_get_base_key(message),
- key_exchange_message_get_ratchet_key(message),
- key_exchange_message_get_identity_key(message));
- if(result < 0) {
- goto complete;
- }
-
- if(!session_record_is_fresh(record)) {
- session_record_archive_current_state(record);
- }
-
- state = session_record_get_state(record);
- result = ratcheting_session_symmetric_initialize(state,
- MIN(key_exchange_message_get_max_version(message), (uint32_t)CIPHERTEXT_CURRENT_VERSION),
- parameters, builder->global_context);
- if(result < 0) {
- goto complete;
- }
-
- result = axolotl_session_store_session(builder->store, builder->remote_address, record);
- if(result < 0) {
- goto complete;
- }
-
- if(session_state_get_session_version(state) >= 3) {
- ec_public_key *message_identity_key = key_exchange_message_get_identity_key(message);
- ec_public_key *message_base_key = key_exchange_message_get_base_key(message);
- axolotl_buffer *message_base_key_serialized = 0;
- uint8_t *message_base_key_signature = 0;
-
- ec_public_key_serialize(&message_base_key_serialized, message_base_key);
-
- message_base_key_signature = key_exchange_message_get_base_key_signature(message);
-
- result = curve_verify_signature(message_identity_key,
- axolotl_buffer_data(message_base_key_serialized),
- axolotl_buffer_len(message_base_key_serialized),
- message_base_key_signature, CURVE_SIGNATURE_LEN);
- axolotl_buffer_free(message_base_key_serialized);
- if(result < 0) {
- goto complete;
- }
- if(result != 1) {
- axolotl_log(builder->global_context, AX_LOG_WARNING, "Base key signature doesn't match!");
- result = AX_ERR_INVALID_KEY;
- goto complete;
- }
- }
-
- result = axolotl_session_store_session(builder->store, builder->remote_address, record);
- if(result < 0) {
- goto complete;
- }
-
- result = axolotl_identity_save_identity(builder->store,
- builder->remote_address->name, builder->remote_address->name_len,
- key_exchange_message_get_identity_key(message));
- if(result < 0) {
- goto complete;
- }
-
-complete:
- AXOLOTL_UNREF(parameters);
- AXOLOTL_UNREF(record);
- return result;
-}
-
-int session_builder_process(session_builder *builder, key_exchange_message **message)
-{
- int result = 0;
- key_exchange_message *result_message = 0;
- int random_value = 0;
- uint32_t sequence = 0;
- uint32_t flags = KEY_EXCHANGE_INITIATE_FLAG;
- ec_key_pair *base_key = 0;
- ec_key_pair *ratchet_key = 0;
- ratchet_identity_key_pair *identity_key = 0;
- axolotl_buffer *base_key_public_serialized = 0;
- axolotl_buffer *base_key_signature = 0;
- session_record *record = 0;
- session_state *state = 0;
-
- assert(builder);
- assert(builder->store);
- axolotl_lock(builder->global_context);
-
- result = axolotl_key_helper_get_random_sequence(&random_value, 65534, builder->global_context);
- if(result < 0) {
- goto complete;
- }
- sequence = ((uint32_t)random_value) + 1;
-
- result = curve_generate_key_pair(builder->global_context, &base_key);
- if(result < 0) {
- goto complete;
- }
-
- result = curve_generate_key_pair(builder->global_context, &ratchet_key);
- if(result < 0) {
- goto complete;
- }
-
- result = axolotl_identity_get_key_pair(builder->store, &identity_key);
- if(result < 0) {
- goto complete;
- }
-
- result = ec_public_key_serialize(&base_key_public_serialized, ec_key_pair_get_public(base_key));
- if(result < 0) {
- goto complete;
- }
-
- result = curve_calculate_signature(builder->global_context, &base_key_signature,
- ratchet_identity_key_pair_get_private(identity_key),
- axolotl_buffer_data(base_key_public_serialized),
- axolotl_buffer_len(base_key_public_serialized));
- if(result < 0) {
- goto complete;
- }
-
- if(axolotl_buffer_len(base_key_signature) != CURVE_SIGNATURE_LEN) {
- result = AX_ERR_UNKNOWN;
- goto complete;
- }
-
- result = axolotl_session_load_session(builder->store, &record, builder->remote_address);
- if(result < 0) {
- goto complete;
- }
-
- state = session_record_get_state(record);
- session_state_set_pending_key_exchange(state, sequence, base_key, ratchet_key, identity_key);
-
- result = axolotl_session_store_session(builder->store, builder->remote_address, record);
+ result = signal_protocol_identity_save_identity(builder->store,
+ builder->remote_address,
+ their_identity_key);
if(result < 0) {
goto complete;
}
- result = key_exchange_message_create(&result_message,
- 2, sequence, flags,
- ec_key_pair_get_public(base_key),
- axolotl_buffer_data(base_key_signature),
- ec_key_pair_get_public(ratchet_key),
- ratchet_identity_key_pair_get_public(identity_key));
-
complete:
- AXOLOTL_UNREF(record);
- axolotl_buffer_free(base_key_signature);
- axolotl_buffer_free(base_key_public_serialized);
- AXOLOTL_UNREF(identity_key);
- AXOLOTL_UNREF(ratchet_key);
- AXOLOTL_UNREF(base_key);
- if(result >= 0) {
- *message = result_message;
- }
- else {
- result = AX_ERR_INVALID_KEY;
- AXOLOTL_UNREF(result_message);
- }
- axolotl_unlock(builder->global_context);
+ SIGNAL_UNREF(record);
+ SIGNAL_UNREF(our_base_key);
+ SIGNAL_UNREF(our_identity_key);
+ SIGNAL_UNREF(parameters);
+ signal_unlock(builder->global_context);
return result;
}