diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2017-02-13 07:56:33 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2017-02-13 09:09:08 +0300 |
commit | 193f645f65ad4ffdec3186e4176b23af10861199 (patch) | |
tree | e1b16b48ac74c5f03f99a98798e849f6dd9752cc /libs/libaxolotl/src/session_builder.c | |
parent | 36c32a13878d3bd94e88bd9c764f1eadb05ea1ed (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.c | 689 |
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( - ¶meters, - 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( ¶meters, 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(¶meters, + result = alice_signal_protocol_parameters_create(¶meters, 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( - ¶meters, - 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( - ¶meters, - 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(¶meters_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( - ¶meters, - 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; } |