diff --git a/include/olm/inbound_group_session.h b/include/olm/inbound_group_session.h index 49992b2..0c5eb26 100644 --- a/include/olm/inbound_group_session.h +++ b/include/olm/inbound_group_session.h @@ -146,6 +146,27 @@ size_t olm_group_decrypt( ); +/** + * Get the number of bytes returned by olm_inbound_group_session_id() + */ +size_t olm_inbound_group_session_id_length( + const OlmInboundGroupSession *session +); + +/** + * Get a base64-encoded identifier for this session. + * + * Returns the length of the session id on success or olm_error() on + * failure. On failure last_error will be set with an error code. The + * last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too + * small. + */ +size_t olm_inbound_group_session_id( + OlmInboundGroupSession *session, + uint8_t * id, size_t id_length +); + + #ifdef __cplusplus } // extern "C" #endif diff --git a/javascript/olm_inbound_group_session.js b/javascript/olm_inbound_group_session.js index 9722c31..01bfd26 100644 --- a/javascript/olm_inbound_group_session.js +++ b/javascript/olm_inbound_group_session.js @@ -89,4 +89,15 @@ InboundGroupSession.prototype['decrypt'] = restore_stack(function( return Pointer_stringify(plaintext_buffer); }); +InboundGroupSession.prototype['session_id'] = restore_stack(function() { + var length = inbound_group_session_method( + Module['_olm_inbound_group_session_id_length'] + )(this.ptr); + var session_id = stack(length + NULL_BYTE_PADDING_LENGTH); + inbound_group_session_method(Module['_olm_inbound_group_session_id'])( + this.ptr, session_id, length + ); + return Pointer_stringify(session_id); +}); + olm_exports['InboundGroupSession'] = InboundGroupSession; diff --git a/python/olm/inbound_group_session.py b/python/olm/inbound_group_session.py index 6c01095..310620f 100644 --- a/python/olm/inbound_group_session.py +++ b/python/olm/inbound_group_session.py @@ -45,6 +45,9 @@ inbound_group_session_function( c_void_p, c_size_t, # plaintext ) +inbound_group_session_function(lib.olm_inbound_group_session_id_length) +inbound_group_session_function(lib.olm_inbound_group_session_id, c_void_p, c_size_t) + class InboundGroupSession(object): def __init__(self): self.buf = create_string_buffer(lib.olm_inbound_group_session_size()) @@ -84,3 +87,9 @@ class InboundGroupSession(object): plaintext_buffer, max_plaintext_length ) return plaintext_buffer.raw[:plaintext_length] + + def session_id(self): + id_length = lib.olm_inbound_group_session_id_length(self.ptr) + id_buffer = create_string_buffer(id_length) + lib.olm_inbound_group_session_id(self.ptr, id_buffer, id_length); + return id_buffer.raw diff --git a/src/inbound_group_session.c b/src/inbound_group_session.c index 82ff66f..65c6018 100644 --- a/src/inbound_group_session.c +++ b/src/inbound_group_session.c @@ -29,6 +29,7 @@ #define OLM_PROTOCOL_VERSION 3 +#define GROUP_SESSION_ID_LENGTH ED25519_PUBLIC_KEY_LENGTH #define PICKLE_VERSION 1 #define SESSION_KEY_VERSION 2 @@ -364,3 +365,23 @@ size_t olm_group_decrypt( plaintext, max_plaintext_length ); } + +size_t olm_inbound_group_session_id_length( + const OlmInboundGroupSession *session +) { + return _olm_encode_base64_length(GROUP_SESSION_ID_LENGTH); +} + +size_t olm_inbound_group_session_id( + OlmInboundGroupSession *session, + uint8_t * id, size_t id_length +) { + if (id_length < olm_inbound_group_session_id_length(session)) { + session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL; + return (size_t)-1; + } + + return _olm_encode_base64( + session->signing_key.public_key, GROUP_SESSION_ID_LENGTH, id + ); +} diff --git a/tests/test_group_session.cpp b/tests/test_group_session.cpp index ce889ad..094c744 100644 --- a/tests/test_group_session.cpp +++ b/tests/test_group_session.cpp @@ -133,6 +133,26 @@ int main() { inbound_session, 0U, session_key, session_key_len); assert_equals((size_t)0, res); + + /* Check the session ids */ + + size_t out_session_id_len = olm_outbound_group_session_id_length(session); + uint8_t out_session_id[out_session_id_len]; + assert_equals(out_session_id_len, olm_outbound_group_session_id( + session, out_session_id, out_session_id_len + )); + + size_t in_session_id_len = olm_inbound_group_session_id_length( + inbound_session + ); + uint8_t in_session_id[in_session_id_len]; + assert_equals(in_session_id_len, olm_inbound_group_session_id( + inbound_session, in_session_id, in_session_id_len + )); + + assert_equals(in_session_id_len, out_session_id_len); + assert_equals(out_session_id, in_session_id, in_session_id_len); + /* decode the message */ /* olm_group_decrypt_max_plaintext_length destroys the input so we have to