diff options
author | George Hazan <ghazan@miranda.im> | 2019-03-26 13:06:41 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-03-26 13:06:41 +0300 |
commit | aec8f049d43d79c6c8c26a7d9ddfd9460d267275 (patch) | |
tree | 5e75220de26fda9b7b0527d550204c78a86ad90c /libs/libsignal/src/group_session_builder.c | |
parent | f2764176c58829d24fee7a830a3c9ac2b57d1906 (diff) |
libaxolotl doesn't exist anymore, it's renamed to libsignal
Diffstat (limited to 'libs/libsignal/src/group_session_builder.c')
-rw-r--r-- | libs/libsignal/src/group_session_builder.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/libs/libsignal/src/group_session_builder.c b/libs/libsignal/src/group_session_builder.c new file mode 100644 index 0000000000..13db334c8e --- /dev/null +++ b/libs/libsignal/src/group_session_builder.c @@ -0,0 +1,149 @@ +#include "group_session_builder.h" + +#include <assert.h> +#include <string.h> +#include "sender_key_record.h" +#include "sender_key_state.h" +#include "sender_key.h" +#include "protocol.h" +#include "key_helper.h" +#include "signal_protocol_internal.h" + +struct group_session_builder +{ + signal_protocol_store_context *store; + signal_context *global_context; +}; + +int group_session_builder_create(group_session_builder **builder, + signal_protocol_store_context *store, signal_context *global_context) +{ + group_session_builder *result = 0; + + assert(store); + assert(global_context); + + result = malloc(sizeof(group_session_builder)); + if(!result) { + return SG_ERR_NOMEM; + } + memset(result, 0, sizeof(group_session_builder)); + + result->store = store; + result->global_context = global_context; + + *builder = result; + return 0; +} + +int group_session_builder_process_session(group_session_builder *builder, + const signal_protocol_sender_key_name *sender_key_name, + sender_key_distribution_message *distribution_message) +{ + int result = 0; + sender_key_record *record = 0; + + assert(builder); + assert(builder->store); + signal_lock(builder->global_context); + + result = signal_protocol_sender_key_load_key(builder->store, &record, sender_key_name); + if(result < 0) { + goto complete; + } + + result = sender_key_record_add_sender_key_state(record, + sender_key_distribution_message_get_id(distribution_message), + sender_key_distribution_message_get_iteration(distribution_message), + sender_key_distribution_message_get_chain_key(distribution_message), + sender_key_distribution_message_get_signature_key(distribution_message)); + if(result < 0) { + goto complete; + } + + result = signal_protocol_sender_key_store_key(builder->store, sender_key_name, record); + +complete: + SIGNAL_UNREF(record); + signal_unlock(builder->global_context); + return result; +} + +int group_session_builder_create_session(group_session_builder *builder, + sender_key_distribution_message **distribution_message, + const signal_protocol_sender_key_name *sender_key_name) +{ + int result = 0; + sender_key_record *record = 0; + sender_key_state *state = 0; + uint32_t sender_key_id = 0; + signal_buffer *sender_key = 0; + ec_key_pair *sender_signing_key = 0; + sender_chain_key *chain_key = 0; + signal_buffer *seed = 0; + + assert(builder); + assert(builder->store); + signal_lock(builder->global_context); + + result = signal_protocol_sender_key_load_key(builder->store, &record, sender_key_name); + if(result < 0) { + goto complete; + } + + if(sender_key_record_is_empty(record)) { + result = signal_protocol_key_helper_generate_sender_key_id(&sender_key_id, builder->global_context); + if(result < 0) { + goto complete; + } + + result = signal_protocol_key_helper_generate_sender_key(&sender_key, builder->global_context); + if(result < 0) { + goto complete; + } + + result = signal_protocol_key_helper_generate_sender_signing_key(&sender_signing_key, builder->global_context); + if(result < 0) { + goto complete; + } + + result = sender_key_record_set_sender_key_state(record, sender_key_id, 0, sender_key, sender_signing_key); + if(result < 0) { + goto complete; + } + + result = signal_protocol_sender_key_store_key(builder->store, sender_key_name, record); + if(result < 0) { + goto complete; + } + } + + result = sender_key_record_get_sender_key_state(record, &state); + if(result < 0) { + goto complete; + } + + chain_key = sender_key_state_get_chain_key(state); + seed = sender_chain_key_get_seed(chain_key); + + result = sender_key_distribution_message_create(distribution_message, + sender_key_state_get_key_id(state), + sender_chain_key_get_iteration(chain_key), + signal_buffer_data(seed), signal_buffer_len(seed), + sender_key_state_get_signing_key_public(state), + builder->global_context); + +complete: + signal_buffer_free(sender_key); + SIGNAL_UNREF(sender_signing_key); + SIGNAL_UNREF(record); + signal_unlock(builder->global_context); + return result; +} + +void group_session_builder_free(group_session_builder *builder) +{ + if(builder) { + free(builder); + } +} |